@@ -342,6 +342,7 @@ class phpFITFileAnalysis
342342 263 => 'favero_electronics ' ,
343343 264 => 'dynovelo ' ,
344344 265 => 'Strava ' ,
345+ 267 => 'Bryton ' ,
345346 5759 => 'actigraphcorp '
346347 ],
347348 'pwr_zone_calc ' => [0 => 'custom ' , 1 => 'percent_ftp ' ],
@@ -392,6 +393,7 @@ class phpFITFileAnalysis
392393 1482 => 'Forerunner 10 ' , // 'fr10',
393394 1497 => 'Edge 800 ' , // 'edge800_korea',
394395 1499 => 'swim ' ,
396+ 1505 => 'Rider 310 ' ,
395397 1537 => 'Forerunner 910XT ' , // 'fr910xt_china',
396398 1551 => 'Fenix ' , // fenix
397399 1555 => 'edge200_taiwan ' ,
@@ -833,7 +835,7 @@ class phpFITFileAnalysis
833835 ]
834836 ],
835837
836- 20 => [
838+ 20 => [
837839 'mesg_name ' => 'record ' , 'field_defns ' => [
838840 0 => ['field_name ' => 'position_lat ' , 'scale ' => 1 , 'offset ' => 0 , 'units ' => 'semicircles ' ],
839841 1 => ['field_name ' => 'position_long ' , 'scale ' => 1 , 'offset ' => 0 , 'units ' => 'semicircles ' ],
@@ -1115,29 +1117,40 @@ private function readDataRecords()
11151117 $ message_type = 0 ;
11161118 $ developer_data_flag = 0 ;
11171119 $ local_mesg_type = 0 ;
1120+ $ previousTS = 0 ;
1121+
11181122
11191123 while ($ this ->file_header ['header_size ' ] + $ this ->file_header ['data_size ' ] > $ this ->file_pointer ) {
11201124 $ record_header_byte = ord (substr ($ this ->file_contents , $ this ->file_pointer , 1 ));
11211125 $ this ->file_pointer ++;
11221126
1127+ $ compressedTimestamp = false ;
1128+ $ tsOffset = 0 ;
11231129 /**
11241130 * D00001275 Flexible & Interoperable Data Transfer (FIT) Protocol Rev 2.2.pdf
11251131 * Table 4-1. Normal Header Bit Field Description
11261132 */
11271133 if (($ record_header_byte >> 7 ) & 1 ) { // Check that it's a normal header
1128- throw new \Exception ('phpFITFileAnalysis->readDataRecords(): this class can only handle normal headers! ' );
1134+ // Header with compressed timestamp
1135+ $ message_type = 0 ; //always 0: DATA_MESSAGE
1136+ $ developer_data_flag = 0 ; // always 0: DATA_MESSAGE
1137+ $ local_mesg_type = ($ record_header_byte >> 5 ) & 3 ; // bindec('0011') == 3
1138+ $ tsOffset = $ record_header_byte & 31 ;
1139+ $ compressedTimestamp = true ;
1140+ }
1141+ else {
1142+ //Normal header
1143+ $ message_type = ($ record_header_byte >> 6 ) & 1 ; // 1: DEFINITION_MESSAGE; 0: DATA_MESSAGE
1144+ $ developer_data_flag = ($ record_header_byte >> 5 ) & 1 ; // 1: DEFINITION_MESSAGE; 0: DATA_MESSAGE
1145+ $ local_mesg_type = $ record_header_byte & 15 ; // bindec('1111') == 15
11291146 }
1130- $ message_type = ($ record_header_byte >> 6 ) & 1 ; // 1: DEFINITION_MESSAGE; 0: DATA_MESSAGE
1131- $ developer_data_flag = ($ record_header_byte >> 5 ) & 1 ; // 1: DEFINITION_MESSAGE; 0: DATA_MESSAGE
1132- $ local_mesg_type = $ record_header_byte & 15 ; // bindec('1111') == 15
11331147
11341148 switch ($ message_type ) {
11351149 case DEFINITION_MESSAGE :
11361150 /**
11371151 * D00001275 Flexible & Interoperable Data Transfer (FIT) Protocol Rev 1.7.pdf
11381152 * Table 4-1. Normal Header Bit Field Description
11391153 */
1140-
11411154 $ this ->file_pointer ++; // Reserved - IGNORED
11421155 $ architecture = ord (substr ($ this ->file_contents , $ this ->file_pointer , 1 )); // Architecture
11431156 $ this ->file_pointer ++;
@@ -1146,7 +1159,7 @@ private function readDataRecords()
11461159
11471160 $ global_mesg_num = ($ architecture === 0 ) ? unpack ('v1tmp ' , substr ($ this ->file_contents , $ this ->file_pointer , 2 ))['tmp ' ] : unpack ('n1tmp ' , substr ($ this ->file_contents , $ this ->file_pointer , 2 ))['tmp ' ];
11481161 $ this ->file_pointer += 2 ;
1149-
1162+
11501163 $ num_fields = ord (substr ($ this ->file_contents , $ this ->file_pointer , 1 ));
11511164 $ this ->file_pointer ++;
11521165
@@ -1241,12 +1254,30 @@ private function readDataRecords()
12411254 // Process the temporary array and load values into the public data messages array
12421255 if (!empty ($ tmp_record_array )) {
12431256 $ timestamp = isset ($ this ->data_mesgs ['record ' ]['timestamp ' ]) ? max ($ this ->data_mesgs ['record ' ]['timestamp ' ]) + 1 : 0 ;
1244-
1245- if (isset ($ tmp_record_array ['timestamp ' ])) {
1246- if ($ tmp_record_array ['timestamp ' ] > 0 ) {
1247- $ timestamp = $ tmp_record_array ['timestamp ' ];
1257+ if ($ compressedTimestamp ) {
1258+ if ($ previousTS === 0 ) {
1259+ // This should not happen! Throw exception?
1260+ } else {
1261+ $ previousTS -= FIT_UNIX_TS_DIFF ; // back to FIT timestamps epoch
1262+ $ fiveLsb = $ previousTS & 0x1F ;
1263+ if ($ tsOffset >= $ fiveLsb ) {
1264+ // No rollover
1265+ $ timestamp = $ previousTS - $ fiveLsb + $ tsOffset ;
1266+ } else {
1267+ // Rollover
1268+ $ timestamp = $ previousTS - $ fiveLsb + $ tsOffset + 32 ;
1269+ }
1270+ $ timestamp += FIT_UNIX_TS_DIFF ; // back to Unix timestamps epoch
1271+ $ previousTS += FIT_UNIX_TS_DIFF ;
1272+ }
1273+ } else {
1274+ if (isset ($ tmp_record_array ['timestamp ' ])) {
1275+ if ($ tmp_record_array ['timestamp ' ] > 0 ) {
1276+ $ timestamp = $ tmp_record_array ['timestamp ' ];
1277+ $ previousTS = $ timestamp ;
1278+ }
1279+ unset($ tmp_record_array ['timestamp ' ]);
12481280 }
1249- unset($ tmp_record_array ['timestamp ' ]);
12501281 }
12511282
12521283 $ this ->data_mesgs ['record ' ]['timestamp ' ][] = $ timestamp ;
0 commit comments