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.

Table of Contents

How the PushTracker Communicates with the Phone


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]
  • 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

Pairing

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).

Connecting

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.

Modes of Communication

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.

How the SmartDrive Communicates with the Phone


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.

Connecting

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.

Modes of Communication

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)

How the Eval App pages interact with the PushTracker


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 the trial and training 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 and DailyInfo from the PushTracker: this will happen during the trial 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)

How the Eval App pages interact with the SmartDrive


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.

OTA


This section covers the steps necessary for all the over-the-air (OTA) firmware updates required for these three firmwares:

  1. PushTracker
  2. SmartDrive Bluetooth
  3. 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.

OTA Process for PushTracker

  1. PushTracker is connected to the App since App cannot initiate connection to PT
  2. App sends a packet with the format:
    Type: Command
    SubType: StartOTA
    otaDevice: Comm::Packet::OTA::PushTracker
    
  3. App waits for packet with the format:
    Type: Command
    SubType: OTAReady
    otaDevice: Comm::Packet::OTA::PushTracker
    
    and periodically continues sending StartOTA packet as long as it hasn't received OTAReady and there is a connection.
  4. 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>
    
  5. Once app has sent all the bytes of the OTA Data, it sends a packet of the form:
    Type: Command
    SubType: StopOTA
    otaDevice: Comm::Packet::OTA::PushTracker
    
    at which point the PushTracker will reset (which will terminate the bluetooth connection)
  6. The app should display information to the user telling them to re-pair the PushTracker to the app
  7. When the PushTracker is re-paired, the app should tell the user to re-connect the PushTracker to the app
  8. 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.

Combined OTA Process for SmartDrive and SmartDrive Bluetooth


  1. SmartDrive is on but not currently connected to the PushTracker or any other phone / app.

  2. 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 the SmartDrive's version - which can be sent through the versionCallback in the comment above.
    • the SmartDriveBluetooth will send a DeviceInfo packet with the SmartDriveBluetooth's version - which can be sent through the versionCallback in the comment above
  3. 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.

  4. 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 received OTAReady and there is a connection.

  5. 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>
    
  6. Once the app has sent all the bytes of the SmartDrive OTA Data, it then sends a command of 6 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
    
  7. App chunks the OTA Data into 16 byte chunks and sends them sequentially directly to the SDBT OTA Characteristic (e7add780-b042-4876-aae1-112855353cc1)

  8. Once the app has sent all the bytes of the OTA Data, the App sends command 3 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.

  9. 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.

  10. When the SmartDrive is re-connected, the app should check the

    • DeviceInfo for the SmartDriveBluetooth to see if the update succeeded and inform the user accordingly.
    • MotorInfo::version for the SmartDrive's version to see if the update succeeded and inform the user accordingly.

Bluetooth Service Descriptors


SmartDrive Service Descriptor

<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>

PushTracker Service Descriptor

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>
⚠️ **GitHub.com Fallback** ⚠️