kopia lustrzana https://github.com/meshtastic/firmware
				
				
				
			BLE is now secured to require pairing with PIN
							rodzic
							
								
									0c0d4025f1
								
							
						
					
					
						commit
						593a6e6f83
					
				
							
								
								
									
										4
									
								
								TODO.md
								
								
								
								
							
							
						
						
									
										4
									
								
								TODO.md
								
								
								
								
							| 
						 | 
				
			
			@ -2,11 +2,12 @@
 | 
			
		|||
 | 
			
		||||
* have node info screen show real info (including distance and heading)
 | 
			
		||||
* very occasionally send our position and user packet (if for nothing else so that other nodes update last_seen)
 | 
			
		||||
* save our node db on entry to sleep
 | 
			
		||||
* make a screen for bluetooth not yet configured
 | 
			
		||||
 | 
			
		||||
# Medium priority
 | 
			
		||||
 | 
			
		||||
* only BLE advertise for a short time after the screen is on and button pressed - to save power and prevent people for sniffing for our BT app.
 | 
			
		||||
* use https://platformio.org/lib/show/1260/OneButton
 | 
			
		||||
* make an about to sleep screen
 | 
			
		||||
* make a no bluetooth configured yet screen
 | 
			
		||||
* don't send location packets if we haven't moved
 | 
			
		||||
| 
						 | 
				
			
			@ -107,3 +108,4 @@ until the phone pulls those packets.  Ever so often power on bluetooth just so w
 | 
			
		|||
* switch to my gui layout manager
 | 
			
		||||
* make basic gui. different screens: debug, one page for each user in the user db, last received text message
 | 
			
		||||
* make button press cycle between screens
 | 
			
		||||
* save our node db on entry to sleep
 | 
			
		||||
| 
						 | 
				
			
			@ -5,19 +5,21 @@
 | 
			
		|||
#include <Arduino.h>
 | 
			
		||||
#include <Update.h>
 | 
			
		||||
#include "configuration.h"
 | 
			
		||||
#include "screen.h"
 | 
			
		||||
 | 
			
		||||
static BLECharacteristic SWVersionCharacteristic(BLEUUID((uint16_t) ESP_GATT_UUID_SW_VERSION_STR), BLECharacteristic::PROPERTY_READ);
 | 
			
		||||
static BLECharacteristic ManufacturerCharacteristic(BLEUUID((uint16_t) ESP_GATT_UUID_MANU_NAME), BLECharacteristic::PROPERTY_READ);
 | 
			
		||||
static BLECharacteristic HardwareVersionCharacteristic(BLEUUID((uint16_t) ESP_GATT_UUID_HW_VERSION_STR), BLECharacteristic::PROPERTY_READ);
 | 
			
		||||
static BLECharacteristic SWVersionCharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_SW_VERSION_STR), BLECharacteristic::PROPERTY_READ);
 | 
			
		||||
static BLECharacteristic ManufacturerCharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_MANU_NAME), BLECharacteristic::PROPERTY_READ);
 | 
			
		||||
static BLECharacteristic HardwareVersionCharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_HW_VERSION_STR), BLECharacteristic::PROPERTY_READ);
 | 
			
		||||
//static BLECharacteristic SerialNumberCharacteristic(BLEUUID((uint16_t) ESP_GATT_UUID_SERIAL_NUMBER_STR), BLECharacteristic::PROPERTY_READ);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create standard device info service
 | 
			
		||||
 **/
 | 
			
		||||
BLEService *createDeviceInfomationService(BLEServer* server, std::string hwVendor, std::string swVersion) {
 | 
			
		||||
    BLEService *deviceInfoService = server->createService(BLEUUID((uint16_t) ESP_GATT_UUID_DEVICE_INFO_SVC));
 | 
			
		||||
BLEService *createDeviceInfomationService(BLEServer *server, std::string hwVendor, std::string swVersion)
 | 
			
		||||
{
 | 
			
		||||
  BLEService *deviceInfoService = server->createService(BLEUUID((uint16_t)ESP_GATT_UUID_DEVICE_INFO_SVC));
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
  /*
 | 
			
		||||
	 * Mandatory characteristic for device info service?
 | 
			
		||||
	 
 | 
			
		||||
	BLECharacteristic *m_pnpCharacteristic = m_deviceInfoService->createCharacteristic(ESP_GATT_UUID_PNP_ID, BLECharacteristic::PROPERTY_READ);
 | 
			
		||||
| 
						 | 
				
			
			@ -26,128 +28,196 @@ BLEService *createDeviceInfomationService(BLEServer* server, std::string hwVendo
 | 
			
		|||
	uint8_t pnp[] = { sig, (uint8_t) (vid >> 8), (uint8_t) vid, (uint8_t) (pid >> 8), (uint8_t) pid, (uint8_t) (version >> 8), (uint8_t) version };
 | 
			
		||||
	m_pnpCharacteristic->setValue(pnp, sizeof(pnp));
 | 
			
		||||
    */
 | 
			
		||||
    SWVersionCharacteristic.setValue(swVersion);
 | 
			
		||||
    deviceInfoService->addCharacteristic(&SWVersionCharacteristic);
 | 
			
		||||
    ManufacturerCharacteristic.setValue(hwVendor);
 | 
			
		||||
    deviceInfoService->addCharacteristic(&ManufacturerCharacteristic);
 | 
			
		||||
    HardwareVersionCharacteristic.setValue("1.0");
 | 
			
		||||
    deviceInfoService->addCharacteristic(&HardwareVersionCharacteristic); 
 | 
			
		||||
    //SerialNumberCharacteristic.setValue("FIXME");
 | 
			
		||||
    //deviceInfoService->addCharacteristic(&SerialNumberCharacteristic); 
 | 
			
		||||
  SWVersionCharacteristic.setValue(swVersion);
 | 
			
		||||
  deviceInfoService->addCharacteristic(&SWVersionCharacteristic);
 | 
			
		||||
  ManufacturerCharacteristic.setValue(hwVendor);
 | 
			
		||||
  deviceInfoService->addCharacteristic(&ManufacturerCharacteristic);
 | 
			
		||||
  HardwareVersionCharacteristic.setValue("1.0");
 | 
			
		||||
  deviceInfoService->addCharacteristic(&HardwareVersionCharacteristic);
 | 
			
		||||
  //SerialNumberCharacteristic.setValue("FIXME");
 | 
			
		||||
  //deviceInfoService->addCharacteristic(&SerialNumberCharacteristic);
 | 
			
		||||
 | 
			
		||||
    // m_manufacturerCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t) 0x2a29, BLECharacteristic::PROPERTY_READ);
 | 
			
		||||
	// m_manufacturerCharacteristic->setValue(name);
 | 
			
		||||
  // m_manufacturerCharacteristic = m_deviceInfoService->createCharacteristic((uint16_t) 0x2a29, BLECharacteristic::PROPERTY_READ);
 | 
			
		||||
  // m_manufacturerCharacteristic->setValue(name);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /* add these later?
 | 
			
		||||
  /* add these later?
 | 
			
		||||
    ESP_GATT_UUID_SYSTEM_ID
 | 
			
		||||
    */
 | 
			
		||||
 | 
			
		||||
   // caller must call service->start();
 | 
			
		||||
   return deviceInfoService;
 | 
			
		||||
  // caller must call service->start();
 | 
			
		||||
  return deviceInfoService;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool _BLEClientConnected = false;
 | 
			
		||||
 | 
			
		||||
class MyServerCallbacks : public BLEServerCallbacks {
 | 
			
		||||
    void onConnect(BLEServer* pServer) {
 | 
			
		||||
      _BLEClientConnected = true;
 | 
			
		||||
    };
 | 
			
		||||
class MyServerCallbacks : public BLEServerCallbacks
 | 
			
		||||
{
 | 
			
		||||
  void onConnect(BLEServer *pServer)
 | 
			
		||||
  {
 | 
			
		||||
    _BLEClientConnected = true;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
    void onDisconnect(BLEServer* pServer) {
 | 
			
		||||
      _BLEClientConnected = false;
 | 
			
		||||
    }
 | 
			
		||||
  void onDisconnect(BLEServer *pServer)
 | 
			
		||||
  {
 | 
			
		||||
    _BLEClientConnected = false;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Help routine to add a description to any BLECharacteristic and add it to the service
 | 
			
		||||
void addWithDesc(BLEService *service, BLECharacteristic *c, const char *description) {
 | 
			
		||||
  BLEDescriptor *desc = new BLEDescriptor(BLEUUID((uint16_t) ESP_GATT_UUID_CHAR_DESCRIPTION), strlen(description) + 1);
 | 
			
		||||
// We default to require an encrypted BOND for all these these characterstics
 | 
			
		||||
void addWithDesc(BLEService *service, BLECharacteristic *c, const char *description)
 | 
			
		||||
{
 | 
			
		||||
  c->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
 | 
			
		||||
 | 
			
		||||
  BLEDescriptor *desc = new BLEDescriptor(BLEUUID((uint16_t)ESP_GATT_UUID_CHAR_DESCRIPTION), strlen(description) + 1);
 | 
			
		||||
  assert(desc);
 | 
			
		||||
  desc->setAccessPermissions(ESP_GATT_PERM_READ_ENCRYPTED | ESP_GATT_PERM_WRITE_ENCRYPTED);
 | 
			
		||||
  desc->setValue(description);
 | 
			
		||||
  c->addDescriptor(desc);
 | 
			
		||||
  service->addCharacteristic(c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BLECharacteristic BatteryLevelCharacteristic(BLEUUID((uint16_t) ESP_GATT_UUID_BATTERY_LEVEL), BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
 | 
			
		||||
static BLECharacteristic BatteryLevelCharacteristic(BLEUUID((uint16_t)ESP_GATT_UUID_BATTERY_LEVEL), BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create a battery level service
 | 
			
		||||
 */
 | 
			
		||||
BLEService *createBatteryService(BLEServer* server) {
 | 
			
		||||
    // Create the BLE Service
 | 
			
		||||
    BLEService *pBattery = server->createService(BLEUUID((uint16_t)0x180F));
 | 
			
		||||
BLEService *createBatteryService(BLEServer *server)
 | 
			
		||||
{
 | 
			
		||||
  // Create the BLE Service
 | 
			
		||||
  BLEService *pBattery = server->createService(BLEUUID((uint16_t)0x180F));
 | 
			
		||||
 | 
			
		||||
    addWithDesc(pBattery, &BatteryLevelCharacteristic, "Percentage 0 - 100");
 | 
			
		||||
    BatteryLevelCharacteristic.addDescriptor(new BLE2902()); // Needed so clients can request notification
 | 
			
		||||
  addWithDesc(pBattery, &BatteryLevelCharacteristic, "Percentage 0 - 100");
 | 
			
		||||
  BatteryLevelCharacteristic.addDescriptor(new BLE2902()); // Needed so clients can request notification
 | 
			
		||||
 | 
			
		||||
    // I don't think we need to advertise this
 | 
			
		||||
    // server->getAdvertising()->addServiceUUID(pBattery->getUUID());
 | 
			
		||||
    pBattery->start();
 | 
			
		||||
  // I don't think we need to advertise this
 | 
			
		||||
  // server->getAdvertising()->addServiceUUID(pBattery->getUUID());
 | 
			
		||||
  pBattery->start();
 | 
			
		||||
 | 
			
		||||
    return pBattery;
 | 
			
		||||
  return pBattery;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Update the battery level we are currently telling clients.
 | 
			
		||||
 * level should be a pct between 0 and 100
 | 
			
		||||
 */
 | 
			
		||||
void updateBatteryLevel(uint8_t level) {
 | 
			
		||||
      // Pretend to update battery levels - fixme do elsewhere
 | 
			
		||||
    BatteryLevelCharacteristic.setValue(&level, 1);
 | 
			
		||||
    BatteryLevelCharacteristic.notify();
 | 
			
		||||
void updateBatteryLevel(uint8_t level)
 | 
			
		||||
{
 | 
			
		||||
  // Pretend to update battery levels - fixme do elsewhere
 | 
			
		||||
  BatteryLevelCharacteristic.setValue(&level, 1);
 | 
			
		||||
  BatteryLevelCharacteristic.notify();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dumpCharacteristic(BLECharacteristic *c)
 | 
			
		||||
{
 | 
			
		||||
  std::string value = c->getValue();
 | 
			
		||||
 | 
			
		||||
void dumpCharacteristic(BLECharacteristic *c) {
 | 
			
		||||
      std::string value = c->getValue();
 | 
			
		||||
  if (value.length() > 0)
 | 
			
		||||
  {
 | 
			
		||||
    DEBUG_MSG("New value: ");
 | 
			
		||||
    for (int i = 0; i < value.length(); i++)
 | 
			
		||||
      DEBUG_MSG("%c", value[i]);
 | 
			
		||||
 | 
			
		||||
      if (value.length() > 0) {
 | 
			
		||||
        DEBUG_MSG("New value: ");
 | 
			
		||||
        for (int i = 0; i < value.length(); i++)
 | 
			
		||||
          DEBUG_MSG("%c", value[i]);
 | 
			
		||||
 | 
			
		||||
        DEBUG_MSG("\n");
 | 
			
		||||
      }
 | 
			
		||||
    DEBUG_MSG("\n");
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** converting endianness pull out a 32 bit value */
 | 
			
		||||
uint32_t getValue32(BLECharacteristic *c, uint32_t defaultValue) {
 | 
			
		||||
    std::string value = c->getValue();
 | 
			
		||||
    uint32_t r = defaultValue;
 | 
			
		||||
uint32_t getValue32(BLECharacteristic *c, uint32_t defaultValue)
 | 
			
		||||
{
 | 
			
		||||
  std::string value = c->getValue();
 | 
			
		||||
  uint32_t r = defaultValue;
 | 
			
		||||
 | 
			
		||||
    if(value.length() == 4) 
 | 
			
		||||
        r = value[0] | (value[1] << 8UL) | (value[2] << 16UL) | (value[3] << 24UL);
 | 
			
		||||
    
 | 
			
		||||
    return r;
 | 
			
		||||
  if (value.length() == 4)
 | 
			
		||||
    r = value[0] | (value[1] << 8UL) | (value[2] << 16UL) | (value[3] << 24UL);
 | 
			
		||||
 | 
			
		||||
  return r;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class MySecurity : public BLESecurityCallbacks
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
BLEServer *initBLE(std::string deviceName, std::string hwVendor, std::string swVersion) {
 | 
			
		||||
    BLEDevice::init(deviceName);
 | 
			
		||||
    // Create the BLE Server
 | 
			
		||||
    BLEServer *pServer = BLEDevice::createServer();
 | 
			
		||||
    pServer->setCallbacks(new MyServerCallbacks());
 | 
			
		||||
  bool onConfirmPIN(uint32_t pin)
 | 
			
		||||
  {
 | 
			
		||||
    Serial.printf("onConfirmPIN %u\n", pin);
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    BLEService *pDevInfo = createDeviceInfomationService(pServer, hwVendor, swVersion);
 | 
			
		||||
  uint32_t onPassKeyRequest()
 | 
			
		||||
  {
 | 
			
		||||
    Serial.println("onPassKeyRequest");
 | 
			
		||||
    return 123511; // not used
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    // We now let users create the battery service only if they really want (not all devices have a battery)
 | 
			
		||||
    // BLEService *pBattery = createBatteryService(pServer);
 | 
			
		||||
  void onPassKeyNotify(uint32_t pass_key)
 | 
			
		||||
  {
 | 
			
		||||
    Serial.printf("onPassKeyNotify %u\n", pass_key);
 | 
			
		||||
    screen_start_bluetooth(pass_key);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    BLEService *pUpdate = createUpdateService(pServer); // We need to advertise this so our android ble scan operation can see it
 | 
			
		||||
    pServer->getAdvertising()->addServiceUUID(pUpdate->getUUID());
 | 
			
		||||
  bool onSecurityRequest()
 | 
			
		||||
  {
 | 
			
		||||
    Serial.println("onSecurityRequest");
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    // start all our services (do this after creating all of them)
 | 
			
		||||
    pDevInfo->start();
 | 
			
		||||
    pUpdate->start();
 | 
			
		||||
  void onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl)
 | 
			
		||||
  {
 | 
			
		||||
    if (cmpl.success)
 | 
			
		||||
    {
 | 
			
		||||
      uint16_t length;
 | 
			
		||||
      esp_ble_gap_get_whitelist_size(&length);
 | 
			
		||||
      Serial.printf(" onAuthenticationComplete -> success size: %d\n", length);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      Serial.printf("onAuthenticationComplete -> fail %d\n", cmpl.fail_reason);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Start advertising
 | 
			
		||||
    pServer->getAdvertising()->start();
 | 
			
		||||
    // Remove our custom screen
 | 
			
		||||
    screen_set_frames();
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
    return pServer;
 | 
			
		||||
BLEServer *initBLE(std::string deviceName, std::string hwVendor, std::string swVersion)
 | 
			
		||||
{
 | 
			
		||||
  BLEDevice::init(deviceName);
 | 
			
		||||
  BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT);
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
   * Required in authentication process to provide displaying and/or input passkey or yes/no butttons confirmation
 | 
			
		||||
   */
 | 
			
		||||
  BLEDevice::setSecurityCallbacks(new MySecurity());
 | 
			
		||||
 | 
			
		||||
  // Create the BLE Server
 | 
			
		||||
  BLEServer *pServer = BLEDevice::createServer();
 | 
			
		||||
  pServer->setCallbacks(new MyServerCallbacks());
 | 
			
		||||
 | 
			
		||||
  BLEService *pDevInfo = createDeviceInfomationService(pServer, hwVendor, swVersion);
 | 
			
		||||
 | 
			
		||||
  // We now let users create the battery service only if they really want (not all devices have a battery)
 | 
			
		||||
  // BLEService *pBattery = createBatteryService(pServer);
 | 
			
		||||
 | 
			
		||||
  BLEService *pUpdate = createUpdateService(pServer); // We need to advertise this so our android ble scan operation can see it
 | 
			
		||||
  pServer->getAdvertising()->addServiceUUID(pUpdate->getUUID());
 | 
			
		||||
 | 
			
		||||
  // start all our services (do this after creating all of them)
 | 
			
		||||
  pDevInfo->start();
 | 
			
		||||
  pUpdate->start();
 | 
			
		||||
 | 
			
		||||
  // Start advertising
 | 
			
		||||
  pServer->getAdvertising()->start();
 | 
			
		||||
 | 
			
		||||
  BLESecurity *pSecurity = new BLESecurity();
 | 
			
		||||
  pSecurity->setCapability(ESP_IO_CAP_OUT);
 | 
			
		||||
  pSecurity->setAuthenticationMode(ESP_LE_AUTH_REQ_SC_BOND);
 | 
			
		||||
  pSecurity->setInitEncryptionKey(ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK);
 | 
			
		||||
 | 
			
		||||
  return pServer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Called from loop
 | 
			
		||||
void loopBLE() {
 | 
			
		||||
    bluetoothRebootCheck();
 | 
			
		||||
void loopBLE()
 | 
			
		||||
{
 | 
			
		||||
  bluetoothRebootCheck();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,6 +61,7 @@ lib_deps =
 | 
			
		|||
  ESP8266_SSD1306
 | 
			
		||||
  AXP202X_Library
 | 
			
		||||
  SPI
 | 
			
		||||
  OneButton
 | 
			
		||||
  CRC32 ; explicitly needed because dependency is missing in the ble ota update lib
 | 
			
		||||
  Wire ; explicitly needed here because the AXP202 library forgets to add it
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,6 +31,7 @@
 | 
			
		|||
#include "MeshService.h"
 | 
			
		||||
#include "GPS.h"
 | 
			
		||||
#include "screen.h"
 | 
			
		||||
#include "NodeDB.h"
 | 
			
		||||
 | 
			
		||||
#ifdef T_BEAM_V10
 | 
			
		||||
#include "axp20x.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -66,6 +67,8 @@ void doDeepSleep(uint64_t msecToWake)
 | 
			
		|||
  // Put radio in sleep mode (will still draw power but only 0.2uA)
 | 
			
		||||
  service.radio.sleep();
 | 
			
		||||
 | 
			
		||||
  nodeDB.saveToDisk();
 | 
			
		||||
 | 
			
		||||
#ifdef RESET_OLED
 | 
			
		||||
  digitalWrite(RESET_OLED, 1); // put the display in reset before killing its power
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,6 +66,26 @@ void drawBootScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x,
 | 
			
		|||
    ui.disableIndicator();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char btPIN[16] = "888888";
 | 
			
		||||
 | 
			
		||||
void drawFrameBluetooth(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
 | 
			
		||||
{
 | 
			
		||||
    // Demonstrates the 3 included default sizes. The fonts come from SSD1306Fonts.h file
 | 
			
		||||
    // Besides the default fonts there will be a program to convert TrueType fonts into this format
 | 
			
		||||
    display->setTextAlignment(TEXT_ALIGN_CENTER);
 | 
			
		||||
    display->setFont(ArialMT_Plain_16);
 | 
			
		||||
    display->drawString(64 + x, 2 + y, "Bluetooth");
 | 
			
		||||
 | 
			
		||||
    display->setFont(ArialMT_Plain_10);
 | 
			
		||||
    display->drawString(64 + x, SCREEN_HEIGHT - FONT_HEIGHT + y, "Enter this code");
 | 
			
		||||
 | 
			
		||||
    display->setTextAlignment(TEXT_ALIGN_CENTER);
 | 
			
		||||
    display->setFont(ArialMT_Plain_24);
 | 
			
		||||
    display->drawString(64 + x, 22 + y, btPIN);
 | 
			
		||||
 | 
			
		||||
    ui.disableIndicator();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void drawFrame2(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
 | 
			
		||||
{
 | 
			
		||||
    // Demonstrates the 3 included default sizes. The fonts come from SSD1306Fonts.h file
 | 
			
		||||
| 
						 | 
				
			
			@ -209,12 +229,13 @@ OverlayCallback overlays[] = {/* msOverlay */};
 | 
			
		|||
const int frameCount = sizeof(frames) / sizeof(frames[0]);
 | 
			
		||||
const int overlaysCount = sizeof(overlays) / sizeof(overlays[0]);
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
void _screen_header()
 | 
			
		||||
{
 | 
			
		||||
    if (!disp)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
 | 
			
		||||
    // Message count
 | 
			
		||||
    //snprintf(buffer, sizeof(buffer), "#%03d", ttn_get_count() % 1000);
 | 
			
		||||
    //display->setTextAlignment(TEXT_ALIGN_LEFT);
 | 
			
		||||
| 
						 | 
				
			
			@ -229,8 +250,8 @@ void _screen_header()
 | 
			
		|||
    char buffer[10];
 | 
			
		||||
    display->drawString(display->getWidth() - SATELLITE_IMAGE_WIDTH - 4, 2, itoa(gps.satellites.value(), buffer, 10));
 | 
			
		||||
    display->drawXbm(display->getWidth() - SATELLITE_IMAGE_WIDTH, 0, SATELLITE_IMAGE_WIDTH, SATELLITE_IMAGE_HEIGHT, SATELLITE_IMAGE);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void screen_off()
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -259,10 +280,7 @@ static void screen_print(const char *text, uint8_t x, uint8_t y, uint8_t alignme
 | 
			
		|||
    dispdev.drawString(x, y, text);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void screen_print(const char *text, uint8_t x, uint8_t y)
 | 
			
		||||
{
 | 
			
		||||
    screen_print(text, x, y, TEXT_ALIGN_LEFT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void screen_print(const char *text)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -317,6 +335,8 @@ void screen_setup()
 | 
			
		|||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool showingBluetooth;
 | 
			
		||||
 | 
			
		||||
uint32_t screen_loop()
 | 
			
		||||
{
 | 
			
		||||
    if (!disp)
 | 
			
		||||
| 
						 | 
				
			
			@ -356,19 +376,43 @@ uint32_t screen_loop()
 | 
			
		|||
    ui.update();
 | 
			
		||||
 | 
			
		||||
    // Once we finish showing the bootscreen, remove it from the loop
 | 
			
		||||
    if (showingBootScreen && ui.getUiState()->currentFrame == 1)
 | 
			
		||||
    if (showingBootScreen && !showingBluetooth && ui.getUiState()->currentFrame == 1)
 | 
			
		||||
    {
 | 
			
		||||
        showingBootScreen = false;
 | 
			
		||||
        ui.setFrames(nonBootFrames, frameCount - 1); 
 | 
			
		||||
        screen_set_frames();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // If we are scrolling do 30fps, otherwise just 1 fps (to save CPU)
 | 
			
		||||
    return (ui.getUiState()->frameState == IN_TRANSITION ? 10 : 500);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Show the bluetooth PIN screen
 | 
			
		||||
void screen_start_bluetooth(uint32_t pin) {
 | 
			
		||||
    static FrameCallback btFrames[] = { drawFrameBluetooth };
 | 
			
		||||
 | 
			
		||||
    snprintf(btPIN, sizeof(btPIN), "%06d", pin);
 | 
			
		||||
 | 
			
		||||
    DEBUG_MSG("showing bluetooth screen\n");
 | 
			
		||||
    showingBluetooth = true;
 | 
			
		||||
 | 
			
		||||
    //screen_on(); // make sure the screen is not asleep - FIXME, this causes crap to draw on the screen
 | 
			
		||||
    ui.disableAutoTransition();  // we now require presses
 | 
			
		||||
    ui.setFrames(btFrames, 1); // Just show the bluetooth frame
 | 
			
		||||
    // we rely on our main loop to show this screen (because we are invoked deep inside of bluetooth callbacks)
 | 
			
		||||
    // ui.update(); // manually draw once, because I'm not sure if loop is getting called
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// restore our regular frame list
 | 
			
		||||
void screen_set_frames() {
 | 
			
		||||
    DEBUG_MSG("showing standard frames\n");
 | 
			
		||||
    ui.setFrames(nonBootFrames, frameCount - 1); 
 | 
			
		||||
    showingBluetooth = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// handle press of the button
 | 
			
		||||
void screen_press() {
 | 
			
		||||
    //screen_start_bluetooth(123456);
 | 
			
		||||
 | 
			
		||||
    // Once the user presses a button, stop auto scrolling between screens
 | 
			
		||||
    ui.disableAutoTransition();  // we now require presses
 | 
			
		||||
    ui.nextFrame();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,4 +5,10 @@ void screen_print(const char * text);
 | 
			
		|||
/// @return how many msecs can we sleep before we want service again
 | 
			
		||||
uint32_t screen_loop();
 | 
			
		||||
 | 
			
		||||
void screen_setup(), screen_on(), screen_off(), screen_press();
 | 
			
		||||
void screen_setup(), screen_on(), screen_off(), screen_press();
 | 
			
		||||
 | 
			
		||||
// Show the bluetooth PIN screen
 | 
			
		||||
void screen_start_bluetooth(uint32_t pin); 
 | 
			
		||||
 | 
			
		||||
// restore our regular frame list
 | 
			
		||||
void screen_set_frames();
 | 
			
		||||
		Ładowanie…
	
		Reference in New Issue