How the PushTracker and SmartDrive connect to the App - PushTracker/EvalApp GitHub Wiki
This page covers how the PushTracker and SmartDrive function as Bluetooth central and Bluetooth peripheral devices, respectively, as well as how they communicate with each other and the app to handle controls, data, and over-the-air (OTA) firmware updates.
- How the PushTracker Communicates with the Phone
- How the SmartDrive Communicates with the Phone
- How the Eval App pages interact with the PushTracker
- How the Eval App pages interact with the SmartDrive
- OTA
- Bluetooth Service Descriptors
The PushTracker is a Bluetooth Central device - just like a phone or computer. This means that it does not advertise services like a peripheral does but instead scans for peripherals which are advertising certain services (with associated characteristics / descriptors). The two types of services that it searches for are
-
The App Service [
9358ac8f-6343-4a31-b4e0-4b13a2b45d86
] - this service has these characteristic UUIDs:58daaa15-f2b2-4cd9-b827-5807b267dae1, 68208ebf-f655-4a2d-98f4-20d7d860c471, // send all PT data (including OTA) to this 9272e309-cd33-4d83-a959-b54cc7a54d1f, 8489625f-6c73-4fc0-8bcc-735bb173a920, 5177fda8-1003-4254-aeb9-7f9edb3cc9cf
These characteristics should all have
-
properties
read, write, notify
, -
permissions
read, write
-
default value of
0
(UINT8
) -
WRITE_TYPE_DEFAULT
-
These descriptors:
2900 2902
where each descriptor should have:
-
permissions
read, write
- default value
[0x00, 0x00]
-
permissions
-
-
The SmartDrive Service [
0cd51666-e7cb-469b-8e4d-2742f1ba7723
]- this service has these characteristic UUIDs:e7add780-b042-4876-aae1-112855353cc1, // send SDBT OTA DATA e8add780-b042-4876-aae1-112855353cc1, e9add780-b042-4876-aae1-112855353cc1, // send smart drive packets (incl SDUC OTA) eaadd780-b042-4876-aae1-112855353cc1, ebadd780-b042-4876-aae1-112855353cc1 // send SDBT OTA Start (6) / Stop (3) commands
For a full description of the service please see SmartDrive Service Descriptor.
You can see an example of some SmartDrive connection management code in nodejs-bluetooth/SmartDrive.js - and even see a full OTA process at line 230
If the phone is advertising the App
service etc. mentioned above,
then the PushTracker will be able to find it when it scans for
available devices advertising a service with that UUID. When the user
requests the PushTracker to pair to the phone (from within the
PushTracker's settings menu) it will scan for the App and send a
pairing request to the first device that it finds. If the user
accepts the pairing request on the phone then the PushTracker will be
notified that the bonding was successful and will save the bonding
information on the PushTracker. From that point on the user can
simply press the right button to initiate a connection to the bonded
phone.
Note: on Android, the app has to listen for the bonding event so that after bonding succeeds it can delete the bonding information on the phone's side. This must be done because the PushTracker does not support encrypted connections - and Android will automatically encrypt connections to the PushTracker if the bonding information is saved on the phone (which it is by default).
Since the PushTracker is the Central / Master, the phone cannot initiate a connection to a PushTracker - and must advertise the App service and wait for the user to initiate a connection on the PushTracker. When the PushTracker connects, it will subscribe to all the characteristics of the App after which it will send
-
VersionInfo
that contain all firmware version for PT, SDUC and SDBT - the current day's
ErrorInfo
-
TotalDistance
that the SmartDrive driven - its current
Settings
- all
DailyInfo
data for days that have not been sent to a phone before (after which they will be deleted from the PushTracker) - the current day's
DailyInfo
While connected the App can send a SetTime
command to synchronize
the time on PushTracker. The App can also send a Wake
command to see
if the PushTracker is still connected - the PushTracker will respond
with a Ready
packet.
The app will be in one of these modes:
- Neither paired nor connected to a PushTracker
- Paired to a PushTracker but not connected to a PushTracker
- Paired and connected to a PushTracker
In all of these modes - the app will be advertising its services so that a PushTracker may find and pair or connect to the App.
The SmartDrive is a regular Bluetooth peripheral, meaning that all Bluetooth devices support communication with it and the app / phone controls the connections.
Note: The SmartDrive does not require pairing / bonding to communicate with the phone - the phone can simply initiate a connection to the SmartDrive.
Since the SmartDrive is a Bluetooth peripheral, the phone completely controls the connection to the SmartDrive. If the SmartDrive is not connected to any other devices (including PushTrackers), then it will advertise the SmartDrive services described above. Therefore, all the app needs to do is to scan for devices advertising the SmartDrive service and then choose one or more of those devices to connect to.
Once the app connects, the app should subscribe to all characteristics advertised by the SmartDrive service. Once it has subscribed, the SmartDrive will then send
- A
DeviceInfo
packet from the SmartDrive Bluetooth chip - this is sent once and lets the app know the version of the SmartDrive Bluetooth firmware - A
MotorInfo
packet five times a second which contains (among other things) the state of the motor and the version of the SmartDrive microcontroller firmware.
The app will never really do anything with the SmartDrive outside of performing OTA firmware updates. As such it will ever only be in one of these modes:
- Not connected to a SmartDrive
- Scanning for a SmartDrive
- Selecting which SmartDrive to connect to
- Connecting to a SmartDrive
- Connected to a SmartDrive
- Waiting for a smartdrive (which is the same as scanning - but involves looking for a specific MAC address as well)
The eval app is primarily concerned with:
- Pairing to a PushTracker: this may occur at any time from any page within the app - the pairing request is generated automatically by the PushTracker given that the app will always be advertising its services
- Making sure the PushTracker is up to date: this will happen on
every connection to the PushTracker - when the app receives the
VersionInfo
it will check the PT version against the app's knowledge of the most recent version and then pop up a dialog informing the user they should update their PT - if they accept it will take them to the OTA page. - Sending
Settings
to the PushTracker: this will happen during thetrial
andtraining
pages when the user is going to use the PT / SD so that the app can set the settings to be safe for new users. - Getting
TotalDistance
andDailyInfo
from the PushTracker: this will happen during thetrial
page - when the user starts and stops the trial. From this we'll have:- the time (on the phone) of start and stop
- the
TotalDistance
at start and stop (therefore the distance of the trial) - the number of pushes at start and stop (therefore the pushes of the trial)
The eval app is primarily concerned with:
- Making sure the SmartDrive Microcontroller (SDUC) and SmartDrive
Bluetooth (SDBT) are up to date - this check will happen on every
connection to the PushTracker - when the app receives the
VersionInfo
it will check the SDUC and SDBT version against the app's knowledge of the most recent version and then pop up a dialog informing the user they should update their SD - if they accept it will take them to the OTA page.
Since this is the only concern related to the SmartDrive - the app will only ever try to scan / connect to the SmartDrive from within the OTA page.
From within the OTA page, we will probably want a dialog that allows the user to explicitly tell the app that they want it to scan for a SmartDrive to update - this should then pop up a dialog which lists the found SmartDrives (by MAC address) and allows them to select one or more SmartDrives to attempt to update.
This section covers the steps necessary for all the over-the-air (OTA) firmware updates required for these three firmwares:
- PushTracker
- SmartDrive Bluetooth
- SmartDrive Microcontroller
Since the SmartDrive Bluetooth (SDBT) and SmartDrive Microcontroller (SDUC) share the same bluetooth connection (two characteristics write to / control the SDBT OTA and another writes to SDUC) those two firmwares should be sent sequentially to minimize the data loss. However, since the PushTracker is a separate connection - the PushTracker OTA can be performed in parallel with the SmartDrive OTA - helping to decrease the amount of time it takes to perform an OTA.
What this means is that the the next two sections
Should be performed in parallel whenever possible.
- PushTracker is connected to the App since App cannot initiate connection to PT
- App sends a packet with the format:
Type: Command SubType: StartOTA otaDevice: Comm::Packet::OTA::PushTracker
- App waits for packet with the format:
and periodically continues sending
Type: Command SubType: OTAReady otaDevice: Comm::Packet::OTA::PushTracker
StartOTA
packet as long as it hasn't receivedOTAReady
and there is a connection. - App chunks the
OTA Data
into 16 byte chunks and sends them sequentially into packets of the form:Type: OTA SubType: Comm::Packet::OTA::PushTracker bytes: <16 byte firmware chunk>
- Once app has sent all the bytes of the
OTA Data
, it sends a packet of the form:at which point the PushTracker will reset (which will terminate the bluetooth connection)Type: Command SubType: StopOTA otaDevice: Comm::Packet::OTA::PushTracker
- The app should display information to the user telling them to re-pair the PushTracker to the app
- When the PushTracker is re-paired, the app should tell the user to re-connect the PushTracker to the app
- When the PushTracker is re-connected, the app should check the
VersionInfo
from the PushTracker to see if the update succeeded and inform the user accordingly.
-
SmartDrive is on but not currently connected to the PushTracker or any other phone / app.
-
App scans for smartdrive based on UUID (and possibly based on specific MAC address) - if it finds one (or the correct one) it then subscribes to all its characteristics.
- the SmartDrive will send a
MotorInfo
packet with theSmartDrive
'sversion
- which can be sent through theversionCallback
in the comment above. - the SmartDriveBluetooth will send a
DeviceInfo
packet with theSmartDriveBluetooth
'sversion
- which can be sent through theversionCallback
in the comment above
- the SmartDrive will send a
-
App sends a packet with the format:
Type: Command SubType: StartOTA otaDevice: Comm::Packet::OTA::SmartDrive
Note: the smartdrive will reboot, terminating the connection - the app will need to handle the re-connection of the SmartDrive and then proceed with the next step.
-
App waits for packet with the format:
Type: Command SubType: OTAReady otaDevice: Comm::Packet::OTA::SmartDrive
and periodically continues sending
StartOTA
packet as long as it hasn't receivedOTAReady
and there is a connection. -
App chunks the
OTA Data
into 16 byte chunks and sends them sequentially into packets of the form:Type: OTA SubType: Comm::Packet::OTA::SmartDrive bytes: <16 byte firmware chunk>
-
Once the app has sent all the bytes of the
SmartDrive
OTA Data
, it then sends a command of6
to the SDBT OTA control characteristic (ebadd780-b042-4876-aae1-112855353cc1
) and then waits for packet with the format:Type: Command SubType: OTAReady otaDevice: Comm::Packet::OTA::SmartDriveBluetooth
-
App chunks the
OTA Data
into 16 byte chunks and sends them sequentially directly to the SDBT OTA Characteristic (e7add780-b042-4876-aae1-112855353cc1
) -
Once the app has sent all the bytes of the
OTA Data
, the App sends command3
to the SDBT OTA control characteristic (ebadd780-b042-4876-aae1-112855353cc1
) Note: this will reboot the bluetooth chip and therefore terminate the connection - the app will need to handle scanning, reconnecting, and resubscribing before proceeding with the next step. -
The app then sends a packet of the form:
Type: Command SubType: StopOTA otaDevice: Comm::Packet::OTA::SmartDrive
at which point the SmartDrive will reset (which will terminate / reset the bluetooth connection) - the app will need to scan again for the SmartDrive (with the same MAC Address) and try to connect / subscribe again to it before proceeding with the next step.
-
When the SmartDrive is re-connected, the app should check the
-
DeviceInfo
for theSmartDriveBluetooth
to see if the update succeeded and inform the user accordingly. -
MotorInfo::version
for theSmartDrive
's version to see if the update succeeded and inform the user accordingly.
-
<service uuid="0cd51666-e7cb-469b-8e4d-2742f1ba7723" advertise="true">
<description>SmartDrive Data service</description>
<characteristic uuid="e7add780-b042-4876-aae1-112855353cc1" id="ota_data_fromWB">
<description>Data</description>
<properties write="true" indicate="true" read="true" />
<value variable_length="true" length="20" type="user" />
</characteristic>
<characteristic uuid="e8add780-b042-4876-aae1-112855353cc1" id="xgatt_speed">
<description>Data</description>
<properties write="true" indicate="true" read="true"/>
<value variable_length="true" length="20" type="user" />
</characteristic>
<characteristic uuid="e9add780-b042-4876-aae1-112855353cc1" id="xgatt_data">
<description>Data</description>
<properties write="true" indicate="true" read="true" />
<value variable_length="true" length="20" type="user" />
</characteristic>
<characteristic uuid="eaadd780-b042-4876-aae1-112855353cc1" id="OTA_data_fromDG">
<description>Data</description>
<properties write_no_response="true" />
<value variable_length="true" length="20" type="user" />
</characteristic>
<characteristic uuid="ebadd780-b042-4876-aae1-112855353cc1" id="data_control">
<description>Data</description>
<properties write="true" indicate="true" read="true" />
<value variable_length="true" length="20" type="user" />
</characteristic>
</service>
NOTE: THIS SERVICE DESCRIPTOR IS NOT USED BY THE SMARTDRIVE OR THE APP
<service uuid="1d14d6ee-fd63-4fa1-bfa4-8f47b42119f0">
<description>Bluegiga OTA</description>
<characteristic uuid="f7bf3564-fb6d-4e53-88a4-5e37e0326063" id="ota_control">
<properties write="true" />
<value length="1" type="user" />
</characteristic>
<characteristic uuid="984227f3-34fc-4045-a5d0-2c581f81a153" id="ota_data">
<properties write_no_response="true" />
<value length="20" />
</characteristic>
</service>