12 #define FILE_LOGGING 0 19 const int ocean::NMEA_MAX;
20 const int ocean::MAXTAGLEN;
21 const int ocean::MAXCHANNELS;
23 const int ocean::INPUT_BUF_SIZE;
24 const int ocean::OUTPUT_BUF_SIZE;
25 const unsigned int ocean::MAX_PACKET_LENGTH;
26 const int ocean::BAD_PACKET;
27 const int ocean::NO_PACKET;
28 const int ocean::NMEA_PACKET;
33 const struct ocean::regPair
ocean::regList[] = {
34 {
"Manufacturer Access" ,
"" , 0x00},
35 {
"Remaining Capacity Alarm" ,
"" , 0x01},
36 {
"Remaining Time Alarm" ,
"min" , 0x02},
37 {
"Battery Mode" ,
"" , 0x03},
38 {
"At Rate" ,
"mA" , 0x04},
39 {
"At Rate Time To Full" ,
"min" , 0x05},
40 {
"At Rate Time To Empty" ,
"min" , 0x06},
41 {
"At Rate OK" ,
"bool" , 0x07},
42 {
"Temperature" ,
"0.1 K" , 0x08},
43 {
"Voltage" ,
"mV" , 0x09},
44 {
"Current" ,
"mA" , 0x0a},
45 {
"Average Current" ,
"mA" , 0x0b},
46 {
"Max Error" ,
"%" , 0x0c},
47 {
"Relative State Of Charge" ,
"%" , 0x0d},
48 {
"Absolute State Of Charge" ,
"%" , 0x0e},
49 {
"Remaining Capacity" ,
"mAh" , 0x0f},
50 {
"Full Charge Capacity" ,
"mAh" , 0x10},
51 {
"Run Time To Empty" ,
"min" , 0x11},
52 {
"Average Time To Empty" ,
"min" , 0x12},
53 {
"Average Time To Full" ,
"min" , 0x13},
54 {
"Battery Status" ,
"" , 0x16},
55 {
"Cycle Count" ,
"cycle" , 0x17},
56 {
"Design Capacity" ,
"mAh" , 0x18},
57 {
"Design Voltage" ,
"mV" , 0x19},
58 {
"Specification Info" ,
"" , 0x1a},
59 {
"Manufacture Date" ,
"DMY" , 0x1b},
60 {
"Serial Number" ,
"uint" , 0x1c},
61 {
"Manufacture Name" ,
"string", 0x20},
62 {
"Device Name" ,
"string", 0x21},
63 {
"Device Chemistry" ,
"string", 0x22},
64 {
"Manufacture Data" ,
"" , 0x23}
79 for (uint i = 0; i <
server.battery.size(); ++i)
87 fprintf (stderr,
"failed closing serial device: %s\n", strerror (errno));
100 inputDevice = open (input_dev.c_str(), O_RDWR | O_NOCTTY);
104 fprintf (stderr,
"failed to open tty device [%s]: %s\n", input_dev.c_str(), strerror (errno));
108 fprintf (stderr,
"Device [%s] not a tty device.\n", input_dev.c_str());
114 ttyset.c_cflag &= ~(PARENB | PARODD | CRTSCTS);
115 ttyset.c_cflag |= CREAD | CLOCAL;
120 #if (FILE_LOGGING > 0) 122 sprintf ( logname,
"/tmp/oceanServer%c.log", input_dev[input_dev.length()-1]);
123 report (2,
"Logging to file: %s\n", logname);
125 outputFile = open( logname, (O_WRONLY | O_APPEND ) );
131 outputFile = open( logname, (O_WRONLY | O_CREAT), (S_IRWXU | S_IRWXG) );
136 report (2,
"Failed to open log file: %d\n", errno);
155 report (1,
"convertStringBase16 input NULL\n");
159 long int result = strtol( input, &endptr, 16 );
160 if( ((errno == ERANGE) && (( result == LONG_MIN ) || ( result == LONG_MAX ))) || ((errno != 0) && (result == 0)))
162 report (0,
"strtol failure\n");
166 if( endptr == input )
168 report (0,
"strtol No digits found\n");
172 if( *endptr !=
'\0' )
173 report( 1,
"strtol characters left after conversion: %s\n", endptr);
184 fprintf (stderr,
"failed to open tty file [%s]: %s\n", input.c_str(), strerror (errno));
199 int listenCount = 50;
206 report(5,
"commTest: call packet_get\n");
214 retval = select(
inputDevice + 1, &rfds, NULL, NULL, &tv);
216 report(0,
"select error\n");
220 report(5,
"calling packet_get\n");
226 report(2,
"select timeout\n");
235 report(5,
"NMEA packet\n");
241 report(5,
"non NMEA packet\n");
243 report(6,
"listenCount=%d\n", listenCount);
244 }
while( listenCount-- > 0);
252 report(5,
"Sending ocean reset string\n");
285 speed_t code = cfgetospeed (&
ttyset);
317 else if (newspeed < 1200)
319 else if (newspeed < 2400)
321 else if (newspeed < 4800)
323 else if (newspeed < 9600)
325 else if (newspeed < 19200)
327 else if (newspeed < 38400)
329 else if (newspeed < 57600)
331 else if (newspeed < 115200)
336 if (cfsetispeed (&
ttyset, B0) != 0)
337 report (0,
"Failed setting input speed\n");
338 if (cfsetospeed (&
ttyset, rate) != 0)
339 report (0,
"Failed setting output speed\n");
341 ttyset.c_iflag &= ~(PARMRK | INPCK);
342 ttyset.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD);
347 report (0,
"Failed to configure serial device\n");
350 report (1,
"set_speed speed=%d rate=%x\n", newspeed, rate);
361 char buf[BUFSIZ], buf2[BUFSIZ], *sp;
364 (void) strcpy (buf,
"ocean: ");
366 (void) vsnprintf (buf + strlen (buf),
sizeof (buf) - strlen (buf), fmt,
371 for (sp = buf; *sp !=
'\0'; sp++)
373 || (isspace (*sp) && (sp[1] ==
'\0' || sp[2] ==
'\0')))
374 (void) snprintf (buf2 + strlen (buf2), 2,
"%c", *sp);
376 (
void) snprintf (buf2 + strlen (buf2), 6,
"\\x%02x", (
unsigned) *sp);
378 (void) fputs (buf2, stderr);
399 (size_t) ((binbuflen >
401 char *ibuf = (
char *) binbuf;
402 memset (hexbuf, 0,
sizeof (hexbuf));
404 for (i = 0; i < len; i++)
406 (void) snprintf (hexbuf + (2 * i), 3,
"%02x",
407 (
unsigned int) (ibuf[i] & 0xff));
457 else if (!isprint (c))
486 memcpy ((
void *)
outbuffer, (
void *) inbuffer, packetlen);
491 report (6,
"Packet type %d accepted %d = %s\n",
497 report (1,
"Rejected too long packet type %d len %d\n",
498 packet_type, packetlen);
507 size_t remaining =
inbuflen - discard;
511 report (6,
"Packet discard of %d, chars remaining is %d = %s\n",
523 report (6,
"Character discarded, buffer %d chars = %s\n",
532 #define getword(i) (short)(session->inbuffer[2*(i)] | (session->inbuffer[2*(i)+1] << 8)) 540 report (6,
"Read %d chars to buffer offset %d (total %d): %s\n",
555 static const char *state_table[] = {
564 report (7,
"%08ld: character '%c' [%02x], new state: %s\n",
566 (isprint (c) ? c :
'.'), c, state_table[
packetState]);
575 bool checksum_ok =
true;
577 char *trailer = (
char *)
inbufptr - 5;
581 unsigned int n, crc = 0;
582 for (n = 1; (
char *)
inbuffer + n < trailer; n++)
584 (void) snprintf (csum,
sizeof (csum),
"%02X", crc);
585 checksum_ok = (toupper (csum[0]) == toupper (trailer[1])
586 && toupper (csum[1]) == toupper (trailer[2]));
598 return (ssize_t) newdata;
610 if ((newdata < 0) && (errno != EAGAIN))
612 else if ((newdata == 0) || ((newdata < 0) && (errno == EAGAIN)))
615 #if (FILE_LOGGING > 0) 643 report (2,
"processSystem message\n");
656 for(
int index = 1; index < count; )
659 int tmp = atoi(field[index]);
661 if( field[index] != NULL )
670 server.message.assign(field[index]);
672 report (5,
"processSystem message=%s\n",
server.message.c_str());
676 report (5,
"averageCharge=%x\n",
server.average_charge);
690 report (2,
"processController message\n");
712 for(
int index = 1; index < count; )
714 int tmp = atoi (field[index]);
718 report (5,
"switch=%d value=0x%x\n", tmp, value);
732 for(
int xx = 0; xx <
server.MAX_BAT_COUNT; ++xx)
734 server.battery[xx].present = value & 1;
741 for(
int xx = 0; xx <
server.MAX_BAT_COUNT; ++xx)
743 server.battery[xx].charging = value & 1;
750 for(
int xx = 0; xx <
server.MAX_BAT_COUNT; ++xx)
752 server.battery[xx].discharging = value & 1;
758 #if 0 //we don't care about reserved. --Curt 760 for(
int xx = 0; xx <
server.MAX_BAT_COUNT; ++xx)
762 server.battery[xx].reserved = value & 1;
770 for(
int xx = 0; xx <
server.MAX_BAT_COUNT; ++xx)
772 server.battery[xx].power_present = value & 1;
779 for(
int xx = 0; xx <
server.MAX_BAT_COUNT; ++xx)
781 server.battery[xx].power_no_good = value & 1;
788 for(
int xx = 0; xx <
server.MAX_BAT_COUNT; ++xx)
790 server.battery[xx].inhibited = value & 1;
806 report (2,
"processBattery %s\n", field[0]);
818 unsigned int battery = (
unsigned int)(field[0][2] -
'0');
820 report (5,
"processBattery count=%d \n", count);
821 report (5,
"currentBattery=%d \n", battery);
827 if( (count & 1) == 1 )
829 report (0,
"received odd count=%d \n", count);
830 count = count & 0xFE;
843 report (5,
"reg[%u]=%x \n", regNumber, value);
844 if(regNumber >=
server.MAX_BAT_REG)
846 report (2,
"Register greater than expected: %x MAX_BAT_REG=%x\n", regNumber,
server.MAX_BAT_REG);
850 server.battery[battery].battery_register[regNumber] = value;
851 server.battery[battery].battery_update_flag[regNumber] = 1;
885 static char zeroStr[] =
"0";
888 unsigned int retval = 0;
896 for (p = buf; (*p !=
'%') && (*p >=
' ');)
902 for (count = 0, p = (
char *) buf; (p != 0) && (*p != 0); p = strchr (p,
','))
911 field[count] = zeroStr;
917 for (i = 0; i < (unsigned) (
sizeof (nmea_phrase) /
sizeof (nmea_phrase[0])); ++i)
922 if (strncmp (nmea_phrase[i].
name, s, 2) == 0)
924 switch (nmea_phrase[i].funcNum)
945 report (5,
"Got Packet: type=%s\n",
tag);
957 unsigned char sum =
'\0';
958 char c, *p = sentence;
966 report (1,
"Bad NMEA sentence: '%s'\n", sentence);
968 while (((c = *p) !=
'*') && (c !=
'\0'))
974 (void) snprintf (p, 5,
"%02X\r\n", (
unsigned) sum);
986 (void) vsnprintf (buf,
sizeof (buf) - 5, fmt, ap);
994 strcat (buf,
"\r\n");
995 status = (int) write (
inputDevice, buf, strlen (buf));
996 if (status == (
int) strlen (buf))
998 report (3,
"=> OCEAN: %s\n", buf);
1003 report (3,
"=> OCEAN: %s FAILED\n", buf);
1016 (void) vsnprintf (buf,
sizeof (buf) - 5, fmt, ap);
1018 status = (int) write (
inputDevice, buf, strlen (buf));
1019 if (status == (
int) strlen (buf))
1021 report (3,
"=> Ocean: %s\n", buf);
1026 report (3,
"=> Ocean: %s FAILED\n", buf);
static const unsigned regListLength
int nmea_send(const char *fmt,...)
void set_speed(int speed)
char * gpsd_hexdump(void *binbuf, size_t binbuflen)
unsigned char outbuffer[OUTPUT_BUF_SIZE+1]
static const int BAD_PACKET
static const unsigned int MAX_PACKET_LENGTH
unsigned int nmea_parse()
unsigned char inbuffer[INPUT_BUF_SIZE+1]
static const int NMEA_PACKET
static const int NO_PACKET
static const int MAXTAGLEN
int string_send(const char *fmt,...)
unsigned long char_counter
void packet_accept(int packet_type)
void initialize(const std::string &input_dev)
unsigned int processSystem(int count, char *field[])
ssize_t packet_parse(size_t newdata)
void nextstate(unsigned char c)
static const int NMEA_MAX
unsigned int processBattery(int count, char *field[])
ocean(int id, int debug=0)
unsigned int processController(int count, char *field[])
void report(int errlevel, const char *fmt,...)
void nmea_add_checksum(char *sentence)
void read_file(const std::string &input)
long int convertStringBase16(const char *input)
static const struct regPair regList[]