Skip to content
This repository was archived by the owner on May 8, 2025. It is now read-only.

Commit 5665620

Browse files
Merge pull request #41 from rafaelnajera/compressed-ts
Implemented compress TSs, added Bryton vendor code, added Rider 310 device
2 parents 8333529 + c4cf676 commit 5665620

File tree

2 files changed

+44
-12
lines changed

2 files changed

+44
-12
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,4 @@ $RECYCLE.BIN/
4545
Network Trash Folder
4646
Temporary Items
4747
.apdisk
48+
/nbproject

src/phpFITFileAnalysis.php

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)