Skip to content

Commit

Permalink
Merge pull request #166 from geeksville/usb
Browse files Browse the repository at this point in the history
Changes to support USB
  • Loading branch information
geeksville authored Jun 9, 2020
2 parents 185fe85 + 846fc14 commit e650033
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 166 deletions.
2 changes: 1 addition & 1 deletion bin/version.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@


export VERSION=0.6.8
export VERSION=0.7.4
6 changes: 6 additions & 0 deletions docs/software/power.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ From lower to higher power consumption.
onEntry: setBluetoothOn(true), screen.setOn(true)
onExit: screen.setOn(false)

- serial API usage (SERIAL) - Screen is on, device doesn't sleep, bluetooth off
onEntry: setBluetooth off, screen on
onExit:

## Behavior

### events that increase CPU activity
Expand All @@ -51,9 +55,11 @@ From lower to higher power consumption.
- While in DARK/ON: If we receive EVENT_BLUETOOTH_PAIR we transition to ON and start our screen_on_secs timeout
- While in NB/DARK/ON: If we receive EVENT_NODEDB_UPDATED we transition to ON (so the new screen can be shown)
- While in DARK: While the phone talks to us over BLE (EVENT_CONTACT_FROM_PHONE) reset any sleep timers and stay in DARK (needed for bluetooth sw update and nice user experience if the user is reading/replying to texts)
- while in LS/NB/DARK: if SERIAL_CONNECTED, go to serial

### events that decrease cpu activity

- While in SERIAL: if SERIAL_DISCONNECTED, go to NB
- While in ON: If PRESS event occurs, reset screen_on_secs timer and tell the screen to handle the pess
- While in ON: If it has been more than screen_on_secs since a press, lower to DARK
- While in DARK: If time since last contact by our phone exceeds phone_timeout_secs (15 minutes), we transition down into NB mode
Expand Down
17 changes: 16 additions & 1 deletion src/PowerFSM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ static void darkEnter()
screen.setOn(false);
}

static void serialEnter()
{
setBluetoothEnable(false);
screen.setOn(true);
}

static void onEnter()
{
screen.setOn(true);
Expand Down Expand Up @@ -133,6 +139,7 @@ State stateSDS(sdsEnter, NULL, NULL, "SDS");
State stateLS(lsEnter, lsIdle, lsExit, "LS");
State stateNB(nbEnter, NULL, NULL, "NB");
State stateDARK(darkEnter, NULL, NULL, "DARK");
State stateSERIAL(serialEnter, NULL, NULL, "SERIAL");
State stateBOOT(bootEnter, NULL, NULL, "BOOT");
State stateON(onEnter, NULL, NULL, "ON");
Fsm powerFSM(&stateBOOT);
Expand All @@ -148,7 +155,7 @@ void PowerFSM_setup()

powerFSM.add_transition(&stateNB, &stateNB, EVENT_RECEIVED_PACKET, NULL, "Received packet, resetting win wake");

// Handle press events
// Handle press events - note: we ignore button presses when in API mode
powerFSM.add_transition(&stateLS, &stateON, EVENT_PRESS, NULL, "Press");
powerFSM.add_transition(&stateNB, &stateON, EVENT_PRESS, NULL, "Press");
powerFSM.add_transition(&stateDARK, &stateON, EVENT_PRESS, NULL, "Press");
Expand All @@ -160,6 +167,7 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateNB, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateDARK, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateON, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");
powerFSM.add_transition(&stateSERIAL, &stateSDS, EVENT_LOW_BATTERY, NULL, "LowBat");

powerFSM.add_transition(&stateDARK, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
powerFSM.add_transition(&stateON, &stateON, EVENT_BLUETOOTH_PAIR, NULL, "Bluetooth pairing");
Expand All @@ -173,6 +181,13 @@ void PowerFSM_setup()
powerFSM.add_transition(&stateDARK, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text");
powerFSM.add_transition(&stateON, &stateON, EVENT_RECEIVED_TEXT_MSG, NULL, "Received text"); // restarts the sleep timer

powerFSM.add_transition(&stateLS, &stateSERIAL, EVENT_SERIAL_CONNECTED, NULL, "serial API");
powerFSM.add_transition(&stateNB, &stateSERIAL, EVENT_SERIAL_CONNECTED, NULL, "serial API");
powerFSM.add_transition(&stateDARK, &stateSERIAL, EVENT_SERIAL_CONNECTED, NULL, "serial API");
powerFSM.add_transition(&stateON, &stateSERIAL, EVENT_SERIAL_CONNECTED, NULL, "serial API");

powerFSM.add_transition(&stateSERIAL, &stateNB, EVENT_SERIAL_DISCONNECTED, NULL, "serial disconnect");

powerFSM.add_transition(&stateDARK, &stateDARK, EVENT_CONTACT_FROM_PHONE, NULL, "Contact from phone");

powerFSM.add_transition(&stateNB, &stateDARK, EVENT_PACKET_FOR_PHONE, NULL, "Packet for phone");
Expand Down
2 changes: 2 additions & 0 deletions src/PowerFSM.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#define EVENT_NODEDB_UPDATED 8 // NodeDB has a big enough change that we think you should turn on the screen
#define EVENT_CONTACT_FROM_PHONE 9 // the phone just talked to us over bluetooth
#define EVENT_LOW_BATTERY 10 // Battery is critically low, go to sleep
#define EVENT_SERIAL_CONNECTED 11
#define EVENT_SERIAL_DISCONNECTED 12

extern Fsm powerFSM;

Expand Down
18 changes: 13 additions & 5 deletions src/SerialConsole.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "SerialConsole.h"
#include "PowerFSM.h"
#include "configuration.h"
#include <Arduino.h>

Expand Down Expand Up @@ -26,12 +27,19 @@ void SerialConsole::init()
*/
void SerialConsole::handleToRadio(const uint8_t *buf, size_t len)
{
// Note: for the time being we could _allow_ debug printing to keep going out the console
// I _think_ this is okay because we currently only print debug msgs from loop() and we are only
// dispatching serial protobuf msgs from loop() as well. When things are more threaded in the future this
// will need to change.
// setDestination(&noopPrint);
// Turn off debug serial printing once the API is activated, because other threads could print and corrupt packets
setDestination(&noopPrint);
canWrite = true;

StreamAPI::handleToRadio(buf, len);
}

/// Hookable to find out when connection changes
void SerialConsole::onConnectionChanged(bool connected)
{
if (connected) { // To prevent user confusion, turn off bluetooth while using the serial port api
powerFSM.trigger(EVENT_SERIAL_CONNECTED);
} else {
powerFSM.trigger(EVENT_SERIAL_DISCONNECTED);
}
}
4 changes: 4 additions & 0 deletions src/SerialConsole.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class SerialConsole : public StreamAPI, public RedirectablePrint
RedirectablePrint::write('\r');
return RedirectablePrint::write(c);
}

protected:
/// Hookable to find out when connection changes
virtual void onConnectionChanged(bool connected);
};

extern SerialConsole console;
6 changes: 0 additions & 6 deletions src/esp32/BluetoothSoftwareUpdate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ class TotalSizeCharacteristic : public CallbackCharacteristic

void onWrite(BLECharacteristic *c)
{
BLEKeepAliveCallbacks::onWrite(c);

LockGuard g(updateLock);
// Check if there is enough to OTA Update
uint32_t len = getValue32(c, 0);
Expand Down Expand Up @@ -67,8 +65,6 @@ class DataCharacteristic : public CallbackCharacteristic

void onWrite(BLECharacteristic *c)
{
BLEKeepAliveCallbacks::onWrite(c);

LockGuard g(updateLock);
std::string value = c->getValue();
uint32_t len = value.length();
Expand All @@ -92,8 +88,6 @@ class CRC32Characteristic : public CallbackCharacteristic

void onWrite(BLECharacteristic *c)
{
BLEKeepAliveCallbacks::onWrite(c);

LockGuard g(updateLock);
uint32_t expectedCRC = getValue32(c, 0);
uint32_t actualCRC = crc.finalize();
Expand Down
29 changes: 4 additions & 25 deletions src/esp32/CallbackCharacteristic.h
Original file line number Diff line number Diff line change
@@ -1,33 +1,12 @@
#pragma once
#include "PowerFSM.h" // FIXME - someday I want to make this OTA thing a separate lb at at that point it can't touch this
#include "BLECharacteristic.h"

/**
* This mixin just lets the power management state machine know the phone is still talking to us
*/
class BLEKeepAliveCallbacks : public BLECharacteristicCallbacks
{
public:
void onRead(BLECharacteristic *c)
{
powerFSM.trigger(EVENT_CONTACT_FROM_PHONE);
}

void onWrite(BLECharacteristic *c)
{
powerFSM.trigger(EVENT_CONTACT_FROM_PHONE);
}
};
#include "PowerFSM.h" // FIXME - someday I want to make this OTA thing a separate lb at at that point it can't touch this

/**
* A characterstic with a set of overridable callbacks
*/
class CallbackCharacteristic : public BLECharacteristic, public BLEKeepAliveCallbacks
class CallbackCharacteristic : public BLECharacteristic, public BLECharacteristicCallbacks
{
public:
CallbackCharacteristic(const char *uuid, uint32_t btprops)
: BLECharacteristic(uuid, btprops)
{
setCallbacks(this);
}
public:
CallbackCharacteristic(const char *uuid, uint32_t btprops) : BLECharacteristic(uuid, btprops) { setCallbacks(this); }
};
130 changes: 2 additions & 128 deletions src/esp32/MeshBluetoothService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ static CallbackCharacteristic *meshFromNumCharacteristic;

BLEService *meshService;

// If defined we will also support the old API
#define SUPPORT_OLD_BLE_API

class BluetoothPhoneAPI : public PhoneAPI
{
/**
Expand Down Expand Up @@ -58,17 +55,12 @@ class ProtobufCharacteristic : public CallbackCharacteristic

void onRead(BLECharacteristic *c)
{
BLEKeepAliveCallbacks::onRead(c);
size_t numbytes = pb_encode_to_bytes(trBytes, sizeof(trBytes), fields, my_struct);
DEBUG_MSG("pbread from %s returns %d bytes\n", c->getUUID().toString().c_str(), numbytes);
c->setValue(trBytes, numbytes);
}

void onWrite(BLECharacteristic *c)
{
BLEKeepAliveCallbacks::onWrite(c);
writeToDest(c, my_struct);
}
void onWrite(BLECharacteristic *c) { writeToDest(c, my_struct); }

protected:
/// like onWrite, but we provide an different destination to write to, for use by subclasses that
Expand All @@ -83,120 +75,13 @@ class ProtobufCharacteristic : public CallbackCharacteristic
}
};

#ifdef SUPPORT_OLD_BLE_API
class NodeInfoCharacteristic : public BLECharacteristic, public BLEKeepAliveCallbacks
{
public:
NodeInfoCharacteristic()
: BLECharacteristic("d31e02e0-c8ab-4d3f-9cc9-0b8466bdabe8",
BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ)
{
setCallbacks(this);
}

void onRead(BLECharacteristic *c)
{
BLEKeepAliveCallbacks::onRead(c);

const NodeInfo *info = nodeDB.readNextInfo();

if (info) {
DEBUG_MSG("Sending nodeinfo: num=0x%x, lastseen=%u, id=%s, name=%s\n", info->num, info->position.time, info->user.id,
info->user.long_name);
size_t numbytes = pb_encode_to_bytes(trBytes, sizeof(trBytes), NodeInfo_fields, info);
c->setValue(trBytes, numbytes);
} else {
c->setValue(trBytes, 0); // Send an empty response
DEBUG_MSG("Done sending nodeinfos\n");
}
}

void onWrite(BLECharacteristic *c)
{
BLEKeepAliveCallbacks::onWrite(c);
DEBUG_MSG("Reset nodeinfo read pointer\n");
nodeDB.resetReadPointer();
}
};

// wrap our protobuf version with something that forces the service to reload the config
class RadioCharacteristic : public ProtobufCharacteristic
{
public:
RadioCharacteristic()
: ProtobufCharacteristic("b56786c8-839a-44a1-b98e-a1724c4a0262",
BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ, RadioConfig_fields,
&radioConfig)
{
}

void onRead(BLECharacteristic *c)
{
DEBUG_MSG("Reading radio config, sdsecs %u\n", radioConfig.preferences.sds_secs);
ProtobufCharacteristic::onRead(c);
}

void onWrite(BLECharacteristic *c)
{
DEBUG_MSG("Writing radio config\n");
ProtobufCharacteristic::onWrite(c);
bluetoothPhoneAPI->handleSetRadio(radioConfig);
}
};

// wrap our protobuf version with something that forces the service to reload the owner
class OwnerCharacteristic : public ProtobufCharacteristic
{
public:
OwnerCharacteristic()
: ProtobufCharacteristic("6ff1d8b6-e2de-41e3-8c0b-8fa384f64eb6",
BLECharacteristic::PROPERTY_WRITE | BLECharacteristic::PROPERTY_READ, User_fields, &owner)
{
}

void onWrite(BLECharacteristic *c)
{
BLEKeepAliveCallbacks::onWrite(
c); // NOTE: We do not call the standard ProtobufCharacteristic superclass, because we want custom write behavior

static User o; // if the phone doesn't set ID we are careful to keep ours, we also always keep our macaddr
if (writeToDest(c, &o)) {
bluetoothPhoneAPI->handleSetOwner(o);
}
}
};

class MyNodeInfoCharacteristic : public ProtobufCharacteristic
{
public:
MyNodeInfoCharacteristic()
: ProtobufCharacteristic("ea9f3f82-8dc4-4733-9452-1f6da28892a2", BLECharacteristic::PROPERTY_READ, MyNodeInfo_fields,
&myNodeInfo)
{
}

void onRead(BLECharacteristic *c)
{
// update gps connection state
myNodeInfo.has_gps = gps->isConnected;

ProtobufCharacteristic::onRead(c);

myNodeInfo.error_code = 0; // The phone just read us, so throw it away
myNodeInfo.error_address = 0;
}
};

#endif

class ToRadioCharacteristic : public CallbackCharacteristic
{
public:
ToRadioCharacteristic() : CallbackCharacteristic("f75c76d2-129e-4dad-a1dd-7866124401e7", BLECharacteristic::PROPERTY_WRITE) {}

void onWrite(BLECharacteristic *c)
{
BLEKeepAliveCallbacks::onWrite(c);
DEBUG_MSG("Got on write\n");

bluetoothPhoneAPI->handleToRadio(c->getData(), c->getValue().length());
Expand All @@ -212,7 +97,6 @@ class FromRadioCharacteristic : public CallbackCharacteristic

void onRead(BLECharacteristic *c)
{
BLEKeepAliveCallbacks::onRead(c);
size_t numBytes = bluetoothPhoneAPI->getFromRadio(trBytes);

// Someone is going to read our value as soon as this callback returns. So fill it with the next message in the queue
Expand All @@ -236,11 +120,7 @@ class FromNumCharacteristic : public CallbackCharacteristic
// observe(&service.fromNumChanged);
}

void onRead(BLECharacteristic *c)
{
BLEKeepAliveCallbacks::onRead(c);
DEBUG_MSG("FIXME implement fromnum read\n");
}
void onRead(BLECharacteristic *c) { DEBUG_MSG("FIXME implement fromnum read\n"); }
};

/*
Expand All @@ -263,12 +143,6 @@ BLEService *createMeshBluetoothService(BLEServer *server)
addWithDesc(service, meshFromNumCharacteristic, "fromRadio");
addWithDesc(service, new ToRadioCharacteristic, "toRadio");
addWithDesc(service, new FromRadioCharacteristic, "fromNum");
#ifdef SUPPORT_OLD_BLE_API
addWithDesc(service, new MyNodeInfoCharacteristic, "myNode");
addWithDesc(service, new RadioCharacteristic, "radio");
addWithDesc(service, new OwnerCharacteristic, "owner");
addWithDesc(service, new NodeInfoCharacteristic, "nodeinfo");
#endif

meshFromNumCharacteristic->addDescriptor(addBLEDescriptor(new BLE2902())); // Needed so clients can request notification

Expand Down
Loading

0 comments on commit e650033

Please sign in to comment.