Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * File:
- * sr.c
- *
- * Notes:
- * This file contains native routines for sending and receiving data from
- * a specified serial device.
- *
- * History:
- * 2013/07/06 Written by Simon Platten
- */
- #include <errno.h>
- #include <fcntl.h>
- #include <termios.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <time.h>
- #include <unistd.h>
- #include "sr.h"
- // Constants
- #define BUFFER_SIZE 32
- #define TD_BUFFER_SIZE 80
- #define BILLION ((long)1000000000)
- #define SERIAL_TIMEOUT 1000
- // Buffer to receive data into
- static char arycData[BUFFER_SIZE];
- // End of line
- static char* pstrEOL = ".\n";
- // Reference time used for detecting timeout
- struct timespec tsStartTime;
- // THe number of bytes in the receive buffer
- static int intTotalReceived;
- /**
- * Function:
- * elapsedTime
- *
- * Parameters:
- * ptsRef, a pointer to the reference time
- *
- * Returns:
- * The number of seconds between the reference time and now
- */
- static double elapsedTime(struct timespec* ptsRef) {
- // Get the time now
- struct timespec tsNow;
- if( ptsRef == NULL || clock_gettime( CLOCK_PROCESS_CPUTIME_ID, &tsNow ) == -1 ) {
- return 0;
- }
- return ((tsNow.tv_sec - ptsRef->tv_sec) +
- (double)(tsNow.tv_nsec - ptsRef->tv_nsec) / (double)BILLION);
- }
- /**
- * Returns a pointer to a human readable time and date stamp
- */
- static char* getTimestamp(void) {
- // Get the current time
- static char strBuffer[TD_BUFFER_SIZE];
- time_t curtime = time(NULL);
- // Convert time to local time representation
- struct tm* pLocalTime = localtime(&curtime);
- strftime(strBuffer, TD_BUFFER_SIZE, "%a, %Y-%b-%d %T", pLocalTime);
- return strBuffer;
- }
- /**
- * Function:
- * readDevice
- *
- * Parameters:
- * intFD, the port file descriptor
- * blnDebug, JNI_TRUE to enable debug messages
- *
- * Returns:
- * A pointer to the start of the input buffer or NULL if no content
- */
- static char* readDevice(int intFD, jboolean blnDebug) {
- int intRead, intSpaceInBuffer = sizeof(arycData)-1;
- char* pBuffer = arycData;
- intTotalReceived = 0;
- memset( arycData, 0, sizeof(arycData) );
- while( (intRead = read( intFD, pBuffer, 1 )) > 0 ) {
- pBuffer += intRead;
- intTotalReceived += intRead;
- intSpaceInBuffer -= intRead;
- if ( pBuffer[-1] == '\n' || intSpaceInBuffer <= 0 ) {
- break;
- }
- }
- if ( blnDebug == JNI_TRUE && intTotalReceived > 0 ) {
- int i;
- printf("%s, receive[%d]: ", getTimestamp(), intTotalReceived);
- for( i=0; i<intTotalReceived; i++ ) {
- printf("%c", arycData[i]);
- }
- printf(pstrEOL);
- }
- return ( intTotalReceived > 0 ) ? arycData : NULL;
- }
- /*
- * Class: cantley_co_uk_clsMain
- * Method: openDevice
- * Signature: (Ljava/lang/String;Z)I
- */
- JNIEXPORT jint JNICALL Java_cantley_co_uk_clsMain_openDevice
- (JNIEnv *pEnv, jclass obj, jstring strDevice, jboolean blnRx, jboolean blnDebug) {
- const char *pstrDevice = (*pEnv)->GetStringUTFChars(pEnv, strDevice, NULL);
- // Try to open the port
- int intFD = open(pstrDevice, O_RDWR | O_NOCTTY | O_NDELAY);
- if ( intFD >= 0 ) {
- struct termios options;
- // Get the current options for the port...
- tcgetattr(intFD, &options);
- // Set the baud rates to 115200...
- cfsetispeed(&options, B115200);
- cfsetospeed(&options, B115200);
- options.c_cflag |= (CLOCAL | CREAD);
- // No parity, 8 data bits 1 stop bit
- options.c_cflag &= ~PARENB;
- options.c_cflag &= ~CSTOPB;
- options.c_cflag &= ~CSIZE;
- options.c_cflag |= CS8;
- options.c_cflag &= ~CRTSCTS;
- // Disable Xon/Xoff ctrl
- options.c_cflag &= ~(IXON | IXOFF | IXANY);
- options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
- options.c_oflag &= ~OPOST;
- options.c_cc[VMIN] = 0;
- options.c_cc[VTIME] = 1;
- tcsetattr(intFD, TCSANOW, &options);
- fcntl(intFD, F_SETFL, FNDELAY);
- if ( blnRx == JNI_TRUE ) {
- // Device is being used for Rx flush any data that hasn't been received yet
- while( readDevice(intFD, JNI_FALSE) != NULL ) {
- }
- if ( blnDebug == JNI_TRUE ) {
- printf("%s port flushed%s", pstrDevice, pstrEOL);
- }
- // Get the start reference time
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tsStartTime);
- }
- if ( blnDebug == JNI_TRUE ) {
- printf("%s opened and ready for use%s", pstrDevice, pstrEOL);
- }
- } else if ( blnDebug == JNI_TRUE ) {
- printf("%s, port not ready%s", pstrDevice, pstrEOL);
- }
- (*pEnv)->ReleaseStringUTFChars(pEnv, strDevice, pstrDevice);
- return intFD;
- }
- /*
- * Class: cantley_co_uk_clsMain
- * Method: receive
- * Signature: (I)Ljava/lang/String;
- */
- JNIEXPORT jbyteArray JNICALL Java_cantley_co_uk_clsMain_receive
- (JNIEnv* pEnv, jclass obj, jint intFD, jboolean blnDebug) {
- jbyteArray aryRC = NULL;
- if ( intFD >= 0 ) {
- int intRead, intSpaceInBuffer = BUFFER_SIZE;
- char *pBuffer;
- // Loop until a packet has been received or a timeout occurs
- while( 1 ) {
- // Look for data in the receive buffer from the device
- pBuffer = readDevice(intFD, blnDebug);
- if ( pBuffer == NULL || arycData[0] != '$' ) {
- // Has timeout occurred?
- double lfElapsedTime = elapsedTime(&tsStartTime);
- if ( lfElapsedTime > SERIAL_TIMEOUT ) {
- if ( blnDebug == JNI_TRUE ) {
- printf("%s, receive timeout%s", getTimestamp(), pstrEOL);
- }
- return NULL;
- }
- } else {
- // A valid packet has been received, or it looks like it
- break;
- }
- }
- // Reset reference time
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tsStartTime);
- aryRC = (*pEnv)->NewByteArray(pEnv, BUFFER_SIZE);
- if ( aryRC ) {
- (*pEnv)->SetByteArrayRegion(pEnv, aryRC, 0,
- intTotalReceived, (jbyte*)pBuffer);
- }
- }
- return aryRC;
- }
- /*
- * Class: cantley_co_uk_clsMain
- * Method: send
- * Signature: (ILjava/lang/String;)V
- */
- JNIEXPORT void JNICALL Java_cantley_co_uk_clsMain_send
- (JNIEnv* pEnv, jclass obj, jint intFD, jstring strData, jboolean blnDebug) {
- const char *pstrData = (*pEnv)->GetStringUTFChars(pEnv, strData, NULL);
- int intLength;
- if ( intFD >= 0 && pstrData && (intLength = strlen(pstrData)) > 0 ) {
- // Write to the device
- int intWritten = write(intFD, pstrData, intLength);
- if ( blnDebug == JNI_TRUE ) {
- if ( intWritten <= 0 ) {
- printf("%s, send: failed%s",
- getTimestamp(), pstrEOL);
- } else {
- printf("%s, send[%d]: %s",
- getTimestamp(), intWritten, pstrData);
- }
- }
- }
- (*pEnv)->ReleaseStringUTFChars(pEnv, strData, pstrData);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement