1

I have just bought a GPS Tracker, it can send SMS to cellphone just fine. It also supports reporting to a server via GPRS.

I have setup the device to contact my own server on port 8123, it's a FreeBSD server and i have checked that i recieve packets on that port.

I successfully have setup a listener server written in PHP, and i can receive data from the device. But how do i convert the partial HEX data to something usefull (ASCII)?

Example data string:

$$^@T^@E Y'^WÿU210104.000,A,5534.4079,N,01146.2510,E,0.00,,170411,,*10|1.0|72|0000á

Unfortunately i don't know how i can copy-paste the HEX parts

Now how do i get the ID part out? I have tried echo hexdec(mb_substr($data, 4, 7));

The data is following this protocol

From the document:

Command format of GPRS packets are as follows:

From server to tracker:
@@\r\n 

From tracker to server: 
$$\r\n

Note: 
Do NOT input ‘’ when writing a command. 
All multi-byte data complies with the following sequence: High byte prior to low byte. 
The size of a GPRS packet (including data) is about 100 bytes

Item        Specification
@@          2 bytes. It means the header of packet from server to tracker. 
            It is in ASCII code (Hex code: 0x40)

$$          2 bytes. It is the header of packet from tracker to server.
            It is in ASCII code (Hex code: 0x24)

L           2 bytes. It means the length of the whole packet including 
            the header and ending character and it is in hex code

ID          7 bytes, ID must be digit and not over 14 digits, the unused byte 
            will be stuffed by ‘f’ or ‘0xff’. It is in the format of hex code.
            For example, if ID is 13612345678, then it will be shown as 
            follows: 0x13, 0x61, 0x23, 0x45, 0x67, 0x8f, 0xff.
            If all 7 bytes are 0xff, it is a broadcasting command. ID is in hex code

command     2 bytes. The command code is in hex code. Please refer to the 
            command list below.

data        Min 0 byte and max 100 bytes. See Annex 1 for description of ‘data’.

checksum    2 bytes. It indicates CRC-CCITT (default is 0xffff) checksum of
            all data (not including CRC itself and the ending character).
            It is in hex code. 
            For example: 24 24 00 11 13 61 23 45 67 8f ff 50 00 05 d8 0d 0a
            0x05d8 = CRC-CCITT (24 24 00 11 13 61 23 45 67 8f ff 50 00)

\r\n        2 bytes. It is the ending character and in hex code 
            (0x0d,0x0a in hex code)

Update

With the answer from Anomie, i was able to piece this together

$arr = unpack('H4length/H14id/H4cmd/H4crc/H4end', mb_substr($data, 2, 11) . mb_substr($data, -4));

var_dump($arr);

This will out put something like

array(5) {
  ["length"]=>
  string(4) "0054"
  ["id"]=>
  string(14) "004512345678ff"
  ["cmd"]=>
  string(4) "9955"
  ["crc"]=>
  string(4) "c97e"
  ["end"]=>
  string(4) "0d0a"
}
Phliplip
  • 3,582
  • 2
  • 25
  • 42
  • You need to have a listener on :8123 that knows how to intepret the data and logs into into the MySQL database. For that, you'll need our collegues over at Stack Overflow. However I suggest you get more details, such as the format and protocol of the messages (Raw TCP, HTTP, SOAP, XML, etc) – Mark Henderson Apr 12 '11 at 10:00
  • Ok, just thought there maybe was some server software that could handle this :) – Phliplip Apr 12 '11 at 10:39
  • without knowing specifics about the device, there's no way we can know. – Mark Henderson Apr 12 '11 at 10:46
  • I have updated the OP with some more info about the format of the data that is transmitted to the server. – Phliplip Apr 17 '11 at 21:33

3 Answers3

2

It sounds like you are needing to convert binary data to integers or strings. The most straightforward way is to use unpack.

For example, to extract the length you already know you can use

$length_bin = substr($string, 2, 2);

To convert it to an integer, you can use something like

$length = unpack('v', $length_bin); $length = $length[1];

The 'v' code will work for the length and the checksum; if you have a number stored as 4 bytes use 'V', and for the ID you can use 'H*' to get it as a string of hex digits. Other codes are listed in the documentation.


A somewhat less straightforward way is to do the bit manipulation manually, after using unpack with C* to get an array of all the byte values. For example,

$bytes = unpack('C*', $length_bin);
$length = ($bytes[0] << 8) | $bytes[1];
Anomie
  • 92,546
  • 13
  • 126
  • 145
  • Thank you very much! I have looked at unpack, but didn't know how to utilize it. Now i got it - Again, thanks! – Phliplip Apr 26 '11 at 19:14
  • Could you possibly help me with the CRC check? – Phliplip Apr 26 '11 at 19:17
  • @Phliplip: What do you need help with for the CRC check? – Anomie Apr 27 '11 at 01:11
  • Something to get me going, i have tried various snippets from PHP.net. Unfortunately i haven't been able to get the same result as the CRC checkvalue in the packet. – Phliplip Apr 27 '11 at 05:11
  • @Phliplip: The PHP code listed in [this question](http://stackoverflow.com/questions/5139480/crc-ccitt-0xffff-function) matches the CRC in the sample in the documentation you pasted. – Anomie Apr 27 '11 at 10:41
  • @Anomie: Thanks, i have allready tried with that code, i will try again. Thank you for your kind help :) – Phliplip Apr 27 '11 at 10:55
0

You need to know the format of the messages you are going to receive from the device. You can get this info from the manufacturer. Then, depending on that, you have to create a proper listener in the server side.

I've been working with several devices like that and normally you have to create a process in the server listening to the port with a Socket (or similar). You may have an authentication process also to differentiate between devices (you can have more than one). After that, you simply get the data from the device, you parse it and you store it. Depending on the device you can also send requests or configurations.

Hope this helps

ACdev
  • 62
  • 2
  • It should be Raw TCP, the device is a PST-T100 branded as 'GO Everywhere / GPS personal tracker'. The device will send TrackerID (configurable) in the data. Do you know of any ready made software that do this? Or does it have to be custom piece of software that listens on that port? – Phliplip Apr 12 '11 at 10:38
  • I don't know what you want to do, but if you are just testing you can write your own listener quickly. For eaxample in Java you can copy [this](http://www.kieser.net/linux/java_server.html) and run it on your computer. Take care to open ports if you are behind a firewall. – ACdev Apr 12 '11 at 12:23
  • I have updated the OP with some more info about the format of the data that is transmitted to the server. – Phliplip Apr 17 '11 at 21:33
0

*Edit 26 April:* I have changed the question a bit, thus this seems out of place. Initial question was more on how to read the data from TCP.

I found some great articles on writing a TCP/socket server in PHP (/me slaps PHP around a bit with a large trout)

http://devzone.zend.com/article/1086 http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/

Can't wait to get this going :)

Phliplip
  • 3,582
  • 2
  • 25
  • 42