Logo Search packages:      
Sourcecode: obdgpslogger version File versions  Download package

enum obd_serial_status getobdbytes ( int  fd,
unsigned int  mode,
unsigned int  cmd,
int  numbytes_expected,
unsigned int *  retvals,
unsigned int  retvals_size,
int *  numbytes_returned,
int  quiet 

Get the raw bits returned from an OBD command.

This returns some unsigned integers. Each contains eight bits in its low byte and zeros in the rest

fdthe serial port opened with openserial
cmdthe obd service command
numbytes_expectedthe number of bytes we expect in the response [optimisation]. Set to zero for safe-nothing-can-go-wrong
retvals_sizenumber of retvals allocated in the retvals array
retvalsarray of retvals_size items to stuff with retvalues
numbytes_returnedtells you how many of retvals were filled.
something from the obd_serial_status enum

Definition at line 677 of file obdserial.c.

References appendseriallog(), OBD_ERROR, OBD_NO_DATA, OBD_SUCCESS, OBD_UNABLE_TO_CONNECT, OBDCMD_NEWLINE, parseobdline(), and readserialdata().

Referenced by getnumobderrors(), getobderrorcodes(), and getobdvalue().


      char sendbuf[20]; // Command to send
      int sendbuflen; // Number of bytes in the send buffer

      char retbuf[4096]; // Buffer to store returned stuff

      int nbytes; // Number of bytes read

      if(mode == 0x03 || mode == 0x04) {
            sendbuflen = snprintf(sendbuf,sizeof(sendbuf),"%02X" OBDCMD_NEWLINE, mode);
      } else {
            if(0 == numbytes_expected) {
                  sendbuflen = snprintf(sendbuf,sizeof(sendbuf),"%02X%02X" OBDCMD_NEWLINE, mode, cmd);
            } else {
                  sendbuflen = snprintf(sendbuf,sizeof(sendbuf),"%02X%02X%01X" OBDCMD_NEWLINE, mode, cmd, numbytes_expected);

      appendseriallog(sendbuf, SERIAL_OUT);
      if(write(fd,sendbuf,sendbuflen) < sendbuflen) {
            return OBD_ERROR;

      nbytes = readserialdata(fd, retbuf, sizeof(retbuf));
      if(0 == nbytes) {
                  fprintf(stderr, "No data at all returned from serial port\n");
            return OBD_ERROR;
      } else if(-1 == nbytes) {
                  fprintf(stderr, "Error reading from serial port\n");
            return OBD_ERROR;

      // First some sanity checks on the data

      if(NULL != strstr(retbuf, "NO DATA")) {
                  fprintf(stderr, "OBD reported NO DATA for %02X %02X: %s\n", mode, cmd, retbuf);
            return OBD_NO_DATA;

      if(0 != strstr(retbuf, "?")) {
                  fprintf(stderr, "OBD reported ? for %02X %02X: %s\n", mode, cmd, retbuf);
            return OBD_NO_DATA;

      if(NULL != strstr(retbuf, "UNABLE TO CONNECT")) {
                  fprintf(stderr, "OBD reported UNABLE TO CONNECT for %02X %02X: %s\n", mode, cmd, retbuf);
            return OBD_UNABLE_TO_CONNECT;

            Good grief, this is ugly.
            1) We look go through the output line by line [strtokking]
            2) For each line, if it's a regular line, parse it
            3) If it has a colon near the start, it means it's a multi-line response
            4) So go into crazy C string handling mode.

      char *line = strtok(retbuf, "\r\n>");

      int values_returned = 0;
      enum obd_serial_status ret = OBD_ERROR;
      while(NULL != line) {
            char *colon;
            int joined_lines = 0; // Set if we joined some lines together
            char longline[1024] = "\0"; // Catenate other lines into this

            char *parseline = line; // The line to actually parse.

            while(NULL != line && NULL != (colon = strstr(line, ":"))) {
                  // printf("Colon line: %s\n", line);
                  strncat(longline, colon+1, sizeof(longline)-strlen(longline)-1);
                  parseline = longline;
                  joined_lines = 1;
                  line = strtok(NULL, "\r\n>");
            // We gracefully handle these lines without
            //   needing to actually parse them
            if(3 >= strlen(parseline)) continue;

            // printf("parseline: %s\n", parseline);

            unsigned int local_rets[20];
            unsigned int vals_read;

            ret = parseobdline(parseline, mode, cmd,
                  local_rets, sizeof(local_rets)/sizeof(local_rets[0]), &vals_read, quiet);

            if(OBD_SUCCESS == ret) {
                  int i;
                  for(i=0; i<vals_read; i++, values_returned++) {
                        retvals[values_returned] = local_rets[i];

            if(0 == joined_lines) {
                  // If we joined some lines together, this strtok was already done
                  line = strtok(NULL, "\r\n>");
      *numbytes_returned = values_returned;
      if(0 == values_returned) return ret;
      return OBD_SUCCESS;

Here is the call graph for this function:

Here is the caller graph for this function:

Generated by  Doxygen 1.6.0   Back to index