21

The Mara-Naboisho Lion Project has asked for our help decoding and plotting the positions of lions fitted with GPS collars.

They receive SMSes from the collars:

Collar07854_100806210058.SMS

074952494449554d0000000000000000000000000000000000000000000000040f33303030333430313232393738393000000000000000000000000000000000f10a0806100028008c13ef348a0039d0fe000de871004cc92b5ca92d6213ef26640039d108000de86b004cc92d5ca92d5d13ef18620039d101000de865004cc92c5ca92d5813ef0a930039d0fc000de864004cc9311c682d5413eefc170039d045000de7d4004cc95b7c692c5013eeee280039d0ff000de85f004cc92a7c692d6fffffffffffffffffffffffffffffffffffffffffff

Collar07854_100807060011.SMS

074952494449554d0000000000000000000000000000000000000000000000040f33303030333430313232393738393000000000000000000000000000000000f10a0807020038008c13efb2eb0039d0ed000de853004cc92e3cea2d8813efa5060039d0fb000de860004cc9291c6a2d8413ef96fd0039d0fc000de85e004cc92d5c6a2d7f13ef88e00039d0f6000de85a004cc92b5c6a2d7b13ef7ad80039d0fa000de85a004cc9327c6a2d77ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

These are presumably SMS PDUs, although simple online decoders don't seem to make much sense of them. There's the ASCII text "IRIDIUM" in them, presumably being the SMSC or sender or something string, as IRIDIUM is a satellite telephone system and presumably the bearer when the collars send up their positions.

UPDATE: They have some KML files that correspond to these collars; I've uploaded the KML here and here. The collars are probably made by Vectronic-Aerospace.

What format is it, and how do we decode it?

(This is a giving code project; perhaps you want to help them, or look at other issues there?)

Will
  • 73,905
  • 40
  • 169
  • 246

6 Answers6

13

I've been able to translate the lat/lon positions! After looking at the website from the collar developers I've seen they are using x/y/z ECEF coordinates.

The first line of the first message:

13ef 348a 0039 d0fe 000d e871 004c c92b 5ca9 2d62

Is translated as:

0039 d0fe = X = 3789054
000d e871 = Y = 911473
004c c92b = Z = 5032235

This translates into:

Lat: 52.43067054630929
Lon: 13.525755535406619
Height: 88.99500464554876

This results into a location in Germany... which sounds wrong for a Kenya reserve, but in fact it is the street of the company which makes these collars: check their website

The code to translate the coordinates has been found online:

public static double[] xyz2LLH(double x, double y, double z)
{
    double[] llh = new double[3];
    double da = 0.0; // datum parameter
    double df = 0.0; // datum parameter
    double a = 6378137 - da;
    double f = 1 / 298.2572235630 - df;
    double b = (1 - f) * a;
    double e2 = 2 * f - f * f;
    double E2 = (a * a - b * b) / (b * b);
    double p = Math.sqrt(x * x + y * y);
    llh[0] = Math.atan2(y, x);
    double theta = Math.atan((z * a) / (p * b));
    llh[1] = Math.atan((z + E2 * b * Math.pow(Math.sin(theta), 3)) / (p - e2 * a * Math.pow(Math.cos(theta), 3)));
    double N = a / Math.sqrt(1 - e2 * Math.sin(llh[1]) * Math.sin(llh[1]));
    llh[2] = p / Math.cos(llh[1]) - N;
    llh[0] = Math.toDegrees(llh[0]);
    llh[1] = Math.toDegrees(llh[1]);
    return llh;
}

So the only code left to decypher is the last bit: 5ca9 2d62.

Another clue from the website suggests these bytes hold the main voltage/backup voltage and temperature.

Roy van Rijn
  • 840
  • 7
  • 17
  • From git https://github.com/giving/giving.github.com/issues/11 it says that the collars also send the "air temperature". maybe those last two numbers are temperature? (hm.. seems like the numbers are too big...) – Nir Levy Sep 19 '12 at 14:17
  • Also the same place say that they are tracking the speed as well, so it might be another hint.. but again the numbers are too high.. – Nir Levy Sep 19 '12 at 14:37
6

Expansion on Roy's remark:

perhaps the '13' is not part of the headers? Then the headers would be:

  SMS 1: 10a0806100028008c
  SMS 2: 10a0807020038008c

And then the messages would be:

  Message #1
  13ef 348a 0039 d0fe 000d e871 004c c92b 5ca9 2d62
  13ef 2664 0039 d108 000d e86b 004c c92d 5ca9 2d5d
  13ef 1862 0039 d101 000d e865 004c c92c 5ca9 2d58
  13ef 0a93 0039 d0fc 000d e864 004c c931 1c68 2d54
  13ee fc17 0039 d045 000d e7d4 004c c95b 7c69 2c50
  13ee ee28 0039 d0ff 000d e85f 004c c92a 7c69 2d6f
  ffff ffff ffff ffff ffff ffff ffff ffff ffff ffff
  ff

  Message #2
  13ef b2eb 0039 d0ed 000d e853 004c c92e 3cea 2d88
  13ef a506 0039 d0fb 000d e860 004c c929 1c6a 2d84
  13ef 96fd 0039 d0fc 000d e85e 004c c92d 5c6a 2d7f
  13ef 88e0 0039 d0f6 000d e85a 004c c92b 5c6a 2d7b
  13ef 7ad8 0039 d0fa 000d e85a 004c c932 7c6a 2d77
  ffff ffff ffff ffff ffff ffff ffff ffff ffff ffff
  ffff ffff ffff ffff ffff ffff ffff ffff ffff ffff
  ff

It does seem like a log , with the message for Aug 06 (guessing) has 6 entries and the second from Aug 07 having 7. What would a collar record? I'm guessing longitude,latitude and timestamp?

Chances are high that the first eight digits represent the timestamp. They are incremental from bottom to top.

Eg. 13ef348a = 334443658. 334443658 seconds = 10 years, 8 months, 6 days, 23:00:58 (since 1970) . This matches the date in the title of the first sms: Collar07854_ 100806 210058 . It even matches the timestamp minus 2 hrs in the title.

A question for the poster: how often are these texts received per day? what year are they from (I was guessing 2010) ?

dstibbe
  • 1,589
  • 18
  • 33
  • That is great! It works out for both messages indeed. So it seems the current date/time in the SMS is 10 years, 8 months, 6 and 7 days. Are these collars old? Or does the time start at 01-01-2000 or something? And what do the next 3x 8 bytes mean? :-) Would is be possible to get more information on the collars and when the data was recorded (and where!?) Because if we know where (give or take) the lat/lon was recorded it would help us match it! – Roy van Rijn Sep 11 '12 at 06:53
2

It doesn't seem to be a normal PDU. It is also 8-bit information, not 7 bit (like most PDU's).

There also seems to be patterns, if you take away the first header they have in common:

    074952494449554d0000000000000000000000000000000000000000000000040f33303030333430313232393738393000000000000000000000000000000000f10a

Next there seems to be another 16 byte header/timestamp/id:

    SMS 1: 0806100028008c13
    SMS 2: 0807020038008c13

And format it a bit, the pattern becomes clearer:

    Message #1:
    ef348a0039d0fe000de871004cc92b5ca92d6213
    ef26640039d108000de86b004cc92d5ca92d5d13
    ef18620039d101000de865004cc92c5ca92d5813
    ef0a930039d0fc000de864004cc9311c682d5413
    eefc170039d045000de7d4004cc95b7c692c5013
    eeee280039d0ff000de85f004cc92a7c692d6fff
    ffffffffffffffffffffffffffffffffffffffff

    Message #2:
    efb2eb0039d0ed000de853004cc92e3cea2d8813
    efa5060039d0fb000de860004cc9291c6a2d8413
    ef96fd0039d0fc000de85e004cc92d5c6a2d7f13
    ef88e00039d0f6000de85a004cc92b5c6a2d7b13
    ef7ad80039d0fa000de85a004cc9327c6a2d77ff
    ffffffffffffffffffffffffffffffffffffffff
    ffffffffffffffffffffffffffffffffffffffff
Roy van Rijn
  • 840
  • 7
  • 17
  • So the data seems to be 20 bytes long? But I still don't have a clue what it is... the first message seems to have 6 'values' and the second just 5 'values' with room for 7...? – Roy van Rijn Sep 10 '12 at 13:22
2

I want to contribute a little bit to dstibbe's answer, but I cannot comment yet..

The last byte of the 'header' (8c) is the length of the message (140) when you start to count at 0.

Jasper
  • 478
  • 6
  • 19
1

Why don't you just ask the people from the German company? Either call them or send them an email. I am quite sure they will provide you with the answer.

Furthermore, according to the product sheet on the website, the collars can be set to record in different modes. You have to find out from the lion project how the collars have been programmed.

Kao
  • 2,242
  • 3
  • 22
  • 31
Martin B
  • 11
  • 2
0

This looks like a good reference:

http://www.dreamfabric.com/sms/

The trick could be to decode the message at the end.

I managed to extract the IRIDIUM but didn't go any further.

A quick perl script for that:

my $text=".....";
my $str;
while( $text ) {
  $str .= chr( hex(substr $text, 0, 2) );
  if( length($text) > 2 ) {
    $text8 = substr($text, 2);
  } else {
    $text8 = '';
  }
}
print $str;
zaf
  • 22,776
  • 12
  • 65
  • 95