Detective mode here:

 

family: http://www.castelecom.com/obd-gps-tracker

 

details: http://www.castelecom.com/idd-213gl

 

“DD-213GL is an intelligent on-board diagnostic device compatible with 
passenger and commercial vehicles, it features plug-and-play technology, could 
read diagnostic info from vehicle ECU and capture location data, then send them 
to backend server for real-time remote diagnostic and tracking purpose.​”

 

Sinocastel OBD GPS Tracker (IDD-213G)

http://www.sinocastel.com/product/item-3.html

 

Protocols supported:

SAE J1850 PWM 

SAE J1850 VPW 

ISO 9141-2 

ISO 14230-4 

ISO 15765-4 

SAE J1939 

SAE J1587/J1708

 

The user manual 
(http://hk1c3c14.hkpic1.websiteonline.cn/upload/213gusermanual(rev_napm.pdf) 
talks through the protocols in section 5.1 on page 16.

 

Some Google search results lead you to companies in the OBD Protocol business 
who explain these formats in detail: http://www.obdtester.com/obd2_protocols, 
one of which (NMEA 2000) is dear to my heart.

 

Finally I found a castel document about the output protocol, which is what we 
need to get started: (not ideal as this is the USA Aerospace protocol, but 
close enough to begin to understand the company’s device output). Look at 
section 1.1 on page 7:

http://roscica2.serverlet.com/owncloud/index.php/s/10A94CtG5cu5AJt#pdfviewer

 

A     protocol head, 2 bytes, fixed as @@,ASCIIcode

 

B     protocol length, 2 bytes, data type: U16, the length data bet of all ween 
protocol head and tail

 

C     Protocol version, 1 byte, data type: U8, it represents the count of the 
protocol version. Currently it is not necessary to analyze for device or 
platform. So it can be filled with the null character 0x00 or any other 
character.

 

D    Device ID: (DEVICE ID), 20 bytes, ASCII code. fill the null character 
"0X00" at the end if the device ID less than 20 bytes.

 

E     Protocol type,2 bytes,High byte means the main mark, low byte means 
sub-mark

 

F     protocol data, random length

 

G     CRC, 2 bytes, calculated from protocol head to protocol data, it doesn’t 
include CRC and protocol tail, refer to CRC Algorithm 1.5

 

H     protocol tail, 2 bytes, fixed as 0x0D 0x0A, ASCII code

 

Using this (and data type table 2.1 in page 8) to parse the data buffer we can 
see…

 

A: 0x40 0x40 (“@@”) as the protocol head

 

B: 0x99 0x00 (U16 0x0099 => 153 bytes) as the protocol size

 

C: 0x04 (decimal 4, so v4) as the protocol version.

 

D: hex 32 21 33 47 4c 32 30 31 34 30 31 35 31 38  27 00 00 00 00 00 (ASCII 
“2136GL2014015187”) which is the 20 byte device ID. (This string does not 
appear in the trillions of documents indexed by Google. That’s because it is a 
specific device ID, a serial number of sorts with a family name at the front 
and a numerical ‘given name’ at the end.)

 

E: 0x10 0x01 Protocol type, “v1.2” apparently from the above, or maybe “v2.1” 
depending on the “two bytes” in step E, which does not specify U16 so maybe it 
is just two bytes back to back, but I doubt it, since that would naturally be 
described as two steps, E1 and E2 which would labelled as E and F.

 

F: Protocol data, which is In hex, E9 18 8c 57 … 21 02 21. How many bytes? 153 
– 31 = 122. (31 is 2+2+1+20+2+2+2, that is, the size of A+B+C+D+E+G+H)

 

G: 0xE0 0x37 is the CRC, a U16 number (0x37E0 == 14304), the error detection 
code computed from the contents of parts A through F. The algorithm (in C code) 
in described in section 5.1 of the PDF. You will need to implement this to 
validate data packets. (Easy)

 

H: 0x0d 0x0a (ASCII CR LF) is the protocol tail

 

The fact that part H is a CR/LF may suggest to read the GPS data as 
CR/LF-terminated strings. This is not right…I see no reason why the various 
packet elements (size,  payoad,  checkum, etc. could not happen to have the two 
bytes 0x0d 0x0a in succession, which would fool the input parsing logic.

 

More robust would be something like:

 

ReadNextPacket : 

1.       consume bytes until you see 0x40 0x40. 

2.       get the next two bytes. Should be a length. Is it a reasonable size 
for that? If not, go back to 1

3.       read this many more bytes (minus the bytes in the 0x40 0x40 and the 
size) for the body.

4.       Does this end in 0x0d 0x0a? if not, synchronization error. Go back to 1

5.       Now we’re presumed logical.

6.       Examine fields C, D, and E. If you don’t know about C and E, or D 
displeases you, signal concern and go back to 1.

7.       Compute the CRC for F. if it does not match G the signal data 
transmission error and go to 1.

8.       Return packet for inspection or dive into the Protocol Data right here.

 

This is what real applications demand.

 

 

From: <golang-nuts@googlegroups.com> on behalf of Egon <egonel...@gmail.com>
Date: Tuesday, July 19, 2016 at 12:55 AM
To: golang-nuts <golang-nuts@googlegroups.com>
Subject: [go-nuts] Re: problems receiving data from a GPS

 

Usually in these cases it helps to bring up the diff between the bytes:

 

So the things I noticed here, 

* the data definitely is not ASCII

* it looks like some GPS protocol, find the spec how to properly parse it.

* Go data looks more what I would expect than Python; Python seems to be 
converting the data into ASCII range, notice how most of the differences are in 
bytes higher than 0x80.

 

So, find the GPS protocol spec and reference application and first implement 
that.

 

+ Egon

 

On Tuesday, 19 July 2016 06:58:58 UTC+3, EdgarAlejandro Vintimilla wrote:

In GO I get this data 

buf := make([]byte, 1024)
buf:  [64 64 153 0 4 50 49 51 71 76 50 48 49 52 48 49 53 49 56 55 0 0 0 0 0 16 
1 233 24 140 87 64 25 140 87 68 88 10 0 136 2 0 0 182 29 0 0 4 0 0 0 4 0 7 100 
1 17 19 0 3 0 1 17 7 16 23 43 59 76 94 160 0 244 82 243 16 7 0 0 0 0 73 68 68 
95 50 49 51 71 48 50 95 83 32 86 50 46 50 46 54 0 73 68 68 95 50 49 51 71 48 50 
95 72 32 86 50 46 50 46 54 0 13 0 1 24 2 24 1 26 1 30 1 31 2 31 3 31 4 31 5 31 
6 31 7 31 1 33 2 33 224 55 13 10] []uint8

 

cadena += fmt.Sprintf("%x ", buf[i])

cadena:  40 40 99 0 4 32 31 33 47 4c 32 30 31 34 30 31 35 31 38 37 0 0 0 0 0 10 
1 e9 18 8c 57 40 19 8c 57 44 58 a 0 88 2 0 0 b6 1d 0 0 4 0 0 0 4 0 7 64 1 11 13 
0 3 0 1 11 7 10 17 2b 3b 4c 5e a0 0 f4 52 f3 10 7 0 0 0 0 49 44 44 5f 32 31 33 
47 30 32 5f 53 20 56 32 2e 32 2e 36 0 49 44 44 5f 32 31 33 47 30 32 5f 48 20 56 
32 2e 32 2e 36 0 d 0 1 18 2 18 1 1a 1 1e 1 1f 2 1f 3 1f 4 1f 5 1f 6 1f 7 1f 1 
21 2 21 e0 37 d  string

 

 

and python

4040990004323133474c323031343031353138370000000000100111a38d5766a38d57855d0a0000000000c21d0000010000000400076401111e000300011307100331317e4aa000f245f310000000008c4944445f3231334730325f532056322e322e36004944445f3231334730325f482056322e322e36000d0001180218011a011e011f021f031f041f051f061f071f0121022171a40d0a

 


-------------------------------------------------------------------------------------------------------------------
On Monday, July 18, 2016 at 1:23:05 AM UTC-5, Egon wrote:

What is the difference in the data that you receive?

On Monday, 18 July 2016 05:42:36 UTC+3, EdgarAlejandro Vintimilla wrote:

now I have this, but still not the correct results

 

package main

 

import (

    "fmt"

    "net"

    "os"

    //"strconv"

    //"bytes"

 //"io/ioutil"

 //"net/http"

    "reflect"

    //"strings"

)

 

const (

    CONN_HOST = ""

    CONN_PORT = "5555"

    CONN_TYPE = "tcp"

)

 

func main() {

    // Listen for incoming connections.

    l, err := net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT)

    if err != nil {

        fmt.Println("Error listening:", err.Error())

        os.Exit(1)

    }

    // Close the listener when the application closes.

    defer l.Close()

    fmt.Println("Listening on " + CONN_HOST + ":" + CONN_PORT)

    for {

        // Listen for an incoming connection.

        conn, err := l.Accept()

        if err != nil {

            fmt.Println("Error accepting: ", err.Error())

            os.Exit(1)

        }

        // Handle connections in a new goroutine.

        go handleRequest(conn)

    }

}

 

// Handles incoming requests.

func handleRequest(conn net.Conn) {

 

  // Make a buffer to hold incoming data.

  buf := make([]byte, 1024)

 

  // Read the incoming connection into the buffer.

  reqLen, err := conn.Read(buf)

  buf = buf[:reqLen]

 

  if err != nil {

    fmt.Println("Error reading:", err.Error())

  }

 

  var cadena string = ""

  for i := 0; i < len(buf)-1; i++ {

    cadena += fmt.Sprintf("%x ", buf[i])

  }

 

 

  // Send a response back to person contacting us.

  conn.Write([]byte( "ok" ))

  fmt.Println("cadena: ", cadena, reflect.TypeOf(cadena) )

  fmt.Println( "\n" )

 

  // Close the connection when you're done with it.

  conn.Close()

    

}

 

 


On Sunday, July 17, 2016 at 2:05:22 PM UTC-5, Egon wrote:

On Sunday, 17 July 2016 21:42:26 UTC+3, EdgarAlejandro Vintimilla wrote:

Hi, I have a GPS that sends me data through a connection TCP

the data it sends me are in ASCII, and I have to convert it to HEX

for example in python I'm doing this 

 

    BUFFER_SIZE = 1024

    conn, addr = s.accept()

    data = conn.recv(BUFFER_SIZE)

    data.encode("hex")

    conn.close()

    print data

 

and it works.

but in GO, 

  buf := make([]byte, 1024)

  reqLen, err := conn.Read(buf)

 

Note, from here you are not using reqLen, you probably should do:

buf = buf[:reqLen], although if the conn is not fast enough you may not receive 
the full request.

 

  if err != nil {

    fmt.Println("Error: ", err.Error())

  }

 

  fmt.Println("buf: ", buf) 

  fmt.Println("buf str: ", string(buf))

 

this []byte to string conversion assumes that "buf" is encoded as UTF8, so if 
you have bytes that are larger than 0x7f you might get bizarre results. 
(Although I know you mentioned ASCII, it might also be Extended ASCII)

 

  var str string = ""

  for i:=0; i< len(buf); i++{

    str += strconv.FormatUint(uint64(buf[i]), 16)

  }

  fmt.Println("str: ", str) 

 

or if I use io, error2 :=ioutil.ReadAll(connection) i do not get the exact data 
that it sends me in any way

 

data, err := ioutil.ReadAll(conn)

if err != nil { panic(err) }

enc := hex.EncodeToString(data)

fmt.Println("hex:", enc)

 

 

Also you should be probably reading up to the message sequence not everything. 
Protocols usually define some ending character or sequence, or have a leading 
length of message. I suspect you should read up-to a line-feed instead of 
everything. And also that might be the reason that you get different results 
from Go and Python.

 

+ Egon

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to