Experimental BLE project showing how IO can be made with an App over BLE. Pointer to matching App will be added when ready, initially this works with: - Android App [nRF-Master Control Panel], supports Write,Read,Notify - Android Project [BluetoothLeGatt]

Dependencies:   BLE_API mbed nRF51822

This is an experimental project for BLE (Bluetooth LE == Bluetooth Low Energy == Bluetooth Smart).

  • It supports general IO over BLE with Read/Notify/Write support.
  • It is compatible with FOTA using Android App "nRF Master Control Panel" (20150126)
  • IO supported by:
    • Custom Android App is in the WIKI under: Android-App, developed from Android Sample "BluetoothLeGatt"
    • Android App: nRF-MCP (Master Control Panel)
    • iOS App LightBlue.
    • General HRM, HTM, Battery and similar apps should be able to access the matching services.
  • It includes combinations of code from other projects, alternative code included can be tried by moving comments (, //)
  • 20150126 bleIO r25: It compiles for both "Nordic nRF51822" and "Nordic nRF51822 FOTA" platforms
  • 20150126 The matching bleIO App (in wiki) doesn't support FOTA yet, use Android App "nRF Master Control Panel"

Feedback and ideas greatly appreciated!!!

Revision:
6:5b6fb35b4450
Parent:
5:d36bbb315e31
Child:
7:1097d012b01a
--- a/main.cpp	Sun Dec 14 01:06:16 2014 +0000
+++ b/main.cpp	Sun Dec 14 20:22:06 2014 +0000
@@ -4,6 +4,7 @@
 //    - http://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_HeartRate/
 //    - https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_LoopbackUART/
 //    - https://developer.mbed.org/users/takafuminaka/code/BLE_HTM_by_InTempSensr/
+//    - https://developer.mbed.org/users/garimagupta002/notebook/ble-uart-lcd-demo/  (Advertise UUID16+UUID128)
 //    - miscellaneous adopted from more samples...
 // Reference:
 //    - http://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/
@@ -57,15 +58,17 @@
 
 //==========Debug Console==========
 #if ENABLE_SerialUSB_DEBUG_CONSOLE
-    Serial  debug_serial(USBTX, USBRX); //PR: DebugSerialOverMbedUSB 9600-8N1N
+    //Restart TeraTerm just before Pressing Reset on mbed, Default:9600-8N1(No Flow Control)
+    //Using default baud rate to avoid issues with DEBUG in a constructor being at wrong baud rate before main()
+    Serial  debug_serial(USBTX, USBRX); //PR: DebugSerialOverMbedUSB
     #define DEBUG(...) { debug_serial.printf(__VA_ARGS__); }
 #else
-    #define DEBUG(...)            //Do Nothing
+    #define DEBUG(...) //Do Nothing, DEBUG() lines are ignored
 #endif 
 
 //========== This Section is to Create Debug output showing variable prep before main() ==========
 bool u8_prep_dummy(void) {
-    DEBUG("\n\nBLE: ____Prep Memory____\n");
+    DEBUG("\n\nBLE: ____Prep Memory____\n"); //May comment this out if none of the following Objects/Classes call initiator functions with debug
     return true;
 }
 const bool bPrep = u8_prep_dummy();
@@ -83,42 +86,57 @@
 BLEDevice   ble;
 const static char     pcDeviceName[]    = "blePRv04"; //PR: Why can App nRF-MCP modify this even though flagged as Const, maybe only temporary mod till App restarts?
 
-//UUID List by Advertised 16bit UUID list (PartA)
+//==========UUID==========
+//UUID16 List - Advertising these required by App nRF-Toolbox:HRM&HTM 
+// Keep list short so advertizing not too long.
 static const uint16_t uuid16_list[]     = { //Service List (Pre-defined standard 16bit services)
     // *Order here doesn't affect order in nRF-MCP Discovery of Services
     //BLE_UUID_GAP  UUID_GENERIC_ACCESS                 //0x1800    //Included by Default, DeviceName, Appearance, PreferredConnectionParam
     //BLE_UUID_GATT UUID_GENERIC ATTRIBUTE              //0x1801    //Included by Default, ServiceChanged, 
     GattService::UUID_HEALTH_THERMOMETER_SERVICE,       //0x1809    //HTM (Might need to be first for nRF App)
-    GattService::UUID_DEVICE_INFORMATION_SERVICE,       //0x180A    //sManufacturer, sModelNumber, sSerialNumber, sHWver, sFWver, sSWver
     GattService::UUID_HEART_RATE_SERVICE,               //0x180D    //HRM, BodyLocation, ControlPoint
-    GattService::UUID_BATTERY_SERVICE,                  //0x180F    //BatteryLevel
-//    GattService::UUID_HEALTH_THERMOMETER_SERVICE,       //0x1809    //HTM
+    //GattService::UUID_DEVICE_INFORMATION_SERVICE,       //0x180A    //sManufacturer, sModelNumber, sSerialNumber, sHWver, sFWver, sSWver
+    //GattService::UUID_BATTERY_SERVICE,                  //0x180F    //BatteryLevel
+
     //x GattService::UUID_DFU,                          //0x1530 - See UARTServiceShortUUID in BLE_API:DFUService.cpp  //
     //x GattService::UARTService,                       //0x0001~0x0003 - See DFUServiceShortUUID  in BLE_API:UARTService.cpp //
     //GattService::UUID_ALERT_NOTIFICATION_SERVICE,     = 0x1811,
     //GattService::UUID_CURRENT_TIME_SERVICE,           = 0x1805,
     //GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE, = 0x1812,
-    //GattService::UUID_IMMEDIATE_ALERT_SERVICE,       = 0x1802,
+    //GattService::UUID_IMMEDIATE_ALERT_SERVICE,        = 0x1802,
     //GattService::UUID_LINK_LOSS_SERVICE,              = 0x1803,
     //GattService::UUID_PHONE_ALERT_STATUS_SERVICE,     = 0x180E,
     //GattService::UUID_REFERENCE_TIME_UPDATE_SERVICE,  = 0x1806,
     //GattService::UUID_SCAN_PARAMETERS_SERVICE,        = 0x1813,
 };
 
+//UUID128 List(Only a single UUID128 can fit in advertising)  
+uint8_t puUUID128_Bluetooth_Base_Rev[16] = {0xFB,0x34,0x9B,0x5F,0x80,0, 0,0x80, 0,0x10, 0,0, 0x00,0x00, 0,0};//0000****-0000-1000-8000 00805F9B34FB, Base for UUID16
+uint8_t puUUID128_BatteryService[16]     = {0xFB,0x34,0x9B,0x5F,0x80,0, 0,0x80, 0,0x10, 0,0, 0x0F,0x18, 0,0};//0000****-0000-1000-8000 00805F9B34FB, ***=0x180F
 
 
-//build a 128bit UUID table  
-//   0000****-0000-1000-8000 00805F9B34FB == Base for 16bit IDs
-//static const 
+/*    //Adopted from sample code in header of BLE_API:UUID.cpp
+//    // Create a UUID16 (0x180F)
+//    uint8_t shortID[16] = { 0, 0, 0x0F, 0x18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+//    UUID ble_uuid = UUID(shortID);  // Will have: ble_uuid.type  = UUID_TYPE_SHORT, ble_uuid.value = 0x180F
+//    // Create a UUID128
+//    uint8_t longID[16] = { 0x00,0x11,0x22,0x33, 0x44,0x55,0x66,0x77, 0x88,0x99,0xAA,0xBB, 0xCC,0xDD,0xEE,0xFF };
+//    UUID custom_uuid = UUID(longID);// Will have: custom_uuid.type=UUID_TYPE_LONG, custom_uuid.value=0x3322, custom_uuid.base=00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
+*/
 
-// The Nordic UART Service
+/* // The Nordic UART Service
 //static const uint8_t uart_base_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
 //static const uint8_t uart_tx_uuid[]   = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
 //static const uint8_t uart_rx_uuid[]   = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
-//static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};
-//const uint8_t  UARTServiceUUID[LENGTH_OF_LONG_UUID] = {          0x6E, 0x40, (uint8_t)(UARTServiceShortUUID >> 8), (uint8_t)(UARTServiceShortUUID & 0xFF), 0xB5, 0xA3, 0xF3, 0x93, 0xE0, 0xA9, 0xE5, 0x0E, 0x24, 0xDC,                                   0xCA,                                 0x9E,};
-//const uint8_t  UARTServiceUUID_reversed[LENGTH_OF_LONG_UUID] = { 0x9E, 0xCA, 0xDC,                                                                         0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, (uint8_t)(UARTServiceShortUUID & 0xFF), (uint8_t)(UARTServiceShortUUID >> 8), 0x40, 0x6E };
+//static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};// = flip uart_base_uuid[]
+//const uint16_t UUID16_UART_Serv = 0x0001;
+//const uint16_t UUID16_UART_Tx = 0x0002;
+//const uint16_t UUID16_UART_Rx = 0x0003;
+//const uint8_t  UUID128_UART_Serv[LENGTH_OF_LONG_UUID]={0x6E,0x40,(uint8_t)(UUID16_UART_Serv>>8),(uint8_t)(UUID16_UART_Serv&0xFF),0xB5,0xA3,0xF3,0x93,0xE0,0xA9,0xE5,0x0E,0x24,0xDC,0xCA,0x9E};
+//const uint8_t  UUID128_UART_Rev[LENGTH_OF_LONG_UUID]={0x9E,0xCA,0xDC,0x24,0x0E,0xE5,0xA9,0xE0,0x93,0xF3,0xA3,0xB5,(uint8_t)(UUID16_UART_Serv&0xFF),(uint8_t)(UUID16_UART_Serv>>8),0x40,0x6E};//Use with: INCOMPLETE_LIST_128BIT_SERVICE_IDS
+*/
  
+//UUID Info:
 // 20141213 From https://developer.bluetooth.org/community/lists/community%20discussion/flat.aspx?rootfolder=/community/lists/community+discussion/16+bit+uuid+vs.+128+uuid&folderctid=0x01200200e2f0e56e3d53004dba96bdf0c357551f
 // 16bit UUID reserved 128bit base = 32 hex digits: 0000****-0000-1000-8000 00805F9B34FB (Careful to use unsigned to avoid negatives and overflows)
 // 32bit UUID reserved 128bit base = 32 hex digits: ********-0000-1000-8000 00805F9B34FB (Careful to use unsigned to avoid negatives and overflows)
@@ -134,37 +152,26 @@
         Note: All attribute types are effectively compared as 128-bit UUIDs, even if a 16-bit UUID is provided in this request or defined for an attribute. (See Section 3.2.1.) 
         A suggestive alternative will be to use a notification method, (see 3.4.7.1), where you don't need the 128 bit UUID or the indication method (see 3.4.7.2) 
  */
-//========== Prep UUID list (before main()) ==========
-// Adopted 2014Dec from PUCK and http://developer.mbed.org/users/Bobty/code/BLE_ScoringDevice/
 
-//TODO: Unfinished new code style from http://developer.mbed.org/users/Bobty/code/BLE_ScoringDevice/
-
-//const UUID IR_SERVICE_UUID = stringToUUID("hello           ");
-//const UUID COMMAND_UUID    = stringToUUID("hello command   ");
-
-//UUID List by Advertised 128bit UUID list (PartA, ToDo:)
-// Gatt characteristic and service UUIDs - Readable to UUID
-const UUID stringToUUID(const char* str) {
-    uint8_t array[16] = {0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55, 0x55,0x55,0x55,0x55};//Prefill 'U' so fully specified even short string
-    for(int i = 0; i < strlen(str); i++) { //Don't convert unspecified bytes past end of string
-        array[i] = str[i];    
-    }
-    
-    DEBUG("UUID: Prep[%16s] --> [%02x %02x %02x %02x  %02x %02x %02x %02x  %02x %02x %02x %02x  %02x %02x %02x %02x] %c\n", 
-        str, array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7], 
-             array[8], array[9], array[10],array[11],array[12],array[13],array[14],array[15], array[15] );       
-       
-    return UUID(array);//TODO: Check if this array is safe or stack temporary??
+//========== UUID128 from readable strings based on URL (processed before main()) ==========
+// UUID for released product may need to be properly generated, but for testing this can be convenient
+// Adopted 20141214 from Nordic PUCK
+uint8_t* puStrToUUID128(const char* pStr) {
+    static uint8_t pUUID[LENGTH_OF_LONG_UUID];  //Call only once before using
+    for(int i = 0; i < LENGTH_OF_LONG_UUID; i++) { 
+        if( i < strlen(pStr) ){ pUUID[LENGTH_OF_LONG_UUID-i-1] = pStr[i];}
+        else { pUUID[LENGTH_OF_LONG_UUID-i-1] =' '; } //Pad end with space character (Or your choice of character such as 'u' or 'x' or NULL)
+    }  
+    // (UUID128 byte order to match that displayed by App nRF-MCP)
+    DEBUG("UUID: Prep[%-16s] --> [%02x %02x %02x %02x  %02x %02x %02x %02x  %02x %02x %02x %02x  %02x %02x %02x %02x]\n", 
+        pStr, pUUID[15],pUUID[14],pUUID[13],pUUID[12], pUUID[11],pUUID[10],pUUID[ 9],pUUID[ 8], 
+              pUUID[ 7],pUUID[ 6],pUUID[ 5],pUUID[ 4], pUUID[ 3],pUUID[ 2],pUUID[ 1],pUUID[ 0] );       
+    return pUUID; //Pointer to prepared UUID128
 }
-//const UUID SCORING_GATT_SERVICE =               stringToUUID("nod.score1.serv ");
-//const UUID THRESHOLD_GATT_CHARACTERISTIC =      stringToUUID("nod.score1.thres");
-//const UUID DIVISOR_GATT_CHARACTERISTIC =        stringToUUID("nod.score1.div  ");
-//const UUID INTERVAL_US_GATT_CHARACTERISTIC =    stringToUUID("nod.score1.intus");
-// Strings to hex UUID                                         "0123456789ABCDEF"
-const UUID UUID_GATT_SERVICE_A                  = stringToUUID("com.test.servA");
-const UUID UUID_GATT_CHARACTERISTIC_A1          = stringToUUID("com.test.charA1");
-const UUID UUID_GATT_CHARACTERISTIC_A2          = stringToUUID("com.test.charA2");
-const UUID UUID_GATT_CHARACTERISTIC_SHORT       = stringToUUID("com.short");
+// Strings to UUID128, test url: www.none.com: "0123456789ABCDEF"  (16chars=32HexDigits=32nibbles) 
+//const char pc_com_none_servA[]  = "com.none.servA";// Provide a short URL you own (in reverse to match Android naming style)
+//const char pc_com_none_charA1[] = "com.none.charA1";
+//const char pc_com_none_charA2[] = "com.none.charA2";
 
 //==========Functions:Timer==========
 static volatile bool  b_Ticker1 = false;//Volatile, don't optimize, changes under interrupt control
@@ -261,7 +268,9 @@
 {
     f_led1level = 1; pwm_led1 = f_led1level;//Start LED1=OnMax
     f_led2level = 1; pwm_led2 = f_led2level;//Start LED2=OnMax
-    DEBUG("\nBLE: ___%s___\n", pcDeviceName); //Restart TeraTerm just before Pressing Reset on mbed
+
+    //Restart TeraTerm just before Pressing Reset on mbed, 9600-8N1(No Flow Control)
+    DEBUG("\nBLE: ___%s___\n", pcDeviceName); 
     DEBUG("BLE: Connect App for Data: nRF-MCP, nRF-Toolbox:HRM, etc.\n");
 
     Ticker ticker1;                             //PR: Timer Object(Structure)
@@ -281,35 +290,52 @@
 //ble_error_t  updateCharacteristicValue (uint16_t handle, const uint8_t *value, uint16_t size, bool localOnly=false) 
 
 //UUID List by Services that are setup
-    //BLE2: Setup Services
+    //BLE2: Setup Services (with their initial values and options)
     DEBUG("BLE: Setup Services\n");
     // *Order here affects order in nRF-MCP Discovery of Services
-    HealthThermometerService    htmService(ble, 30.0, HealthThermometerService::LOCATION_EAR); 
-    BatteryService              battService(ble, 11);//Declare the service for BLE:BATTERY
+    HealthThermometerService    htmService(ble, 33.3, HealthThermometerService::LOCATION_EAR); 
+    BatteryService              battService(ble, 10);
     HeartRateService            hrmService(ble, (uint8_t)111, HeartRateService::LOCATION_FINGER);
     DeviceInformationService    deviceInfo(ble, "Maker", pcDeviceName, "sn1234", "hw00", "fw00", "sw00");//(BLEDevice), pcManufacturer, pcModelNumber, pcSerialNumber, pcHWver, pcFWver, pcSWver
-
-    LinkLossService             linkLoss(ble, Callback_BLE_onLinkLoss, LinkLossService::HIGH_ALERT); //TODO: How to support this?
+    LinkLossService             linkLoss(ble, Callback_BLE_onLinkLoss, LinkLossService::HIGH_ALERT); //New20141213, TBD
 
     //BLE3: Setup advertising
+    // Note the Advertising payload is limited to 31bytes, so careful don't overflow this. Multiple UUID16's or a single UUID128 are possible in advertising.
+    // If there isn't enough space, then the accumulatepayload won't add that block to the advertising, it won't add a partial block.
     DEBUG("BLE: Setup Advertising\n");
-    ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000)); //PR: Advertise 1sec (1Hz)
-    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); //PR: TODO
-    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); //PR: BLE Only, Options(LE_GENERAL_DISCOVERABLE/LE_LIMITED_DISCOVERABLE)
-
-//UUID List Advertised (PartB)
-    /* 16bit */ ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); //PR: Might need to change for Custom Services/Characteristics
-    ///* 128bit*/ ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
+    ble.clearAdvertisingPayload(); //Prep
+    ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000));    //PR: Advertise 1sec (1Hz)
+    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);       //PR: TODO: To Study
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); //PR: BLE Only (Option:LE_LIMITED_DISCOVERABLE)
+    // Does "LE_GENERAL_DISCOVERABLE" affect whether UUID needs to be advertised to discover services?
+    //ble.accumulateAdvertisingPayload(GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS, (const uint8_t *)UUID128_UART_Rev, sizeof(UUID128_UART_Rev)); //Single UUID128
+    //ble.accumulateAdvertisingPayload(GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS, (const uint8_t *)puUUID128_BatteryService, sizeof(puUUID128_BatteryService)); //Single UUID128
+    //ble.accumulateAdvertisingPayload(GapAdvertisingData::INCOMPLETE_LIST_128BIT_SERVICE_IDS, puStrToUUID128( pc_com_none_servA), LENGTH_OF_LONG_UUID); //Single UUID128
+    //ble.accumulateAdvertisingPayload(GapAdvertisingData::INCOMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // Multiple UUID16
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // Multiple UUID16
+    //ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);//PR: Add Appearance::HeartRate (HRM Connects without this)
+    //ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER);      //PR: Add Appearance::Thermometer (HTM Connects without this, though float format still needs change)
+    // Add LocalName last so if Advertising too long will easily see as Name won't be available for the device.
+    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)pcDeviceName, sizeof(pcDeviceName)-1);//PR: LocalName (No NULL) 
+    ble.startAdvertising();
 
-    ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR);//PR: Add Heart Rate
-    ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER);  //PR: Add Thermometer
-    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)pcDeviceName, sizeof(pcDeviceName));//PR: Product?
-    //Thermometer: ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
-    //Thermometer: ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
+    // Raw Advertizing max length 31bytes:             0x01020304050607080910111213141516171819202122232425262728293031
+    // Example Raw Advertising caught by App nRF-MCP:  0x020106070309180A180D180909626C655052763034
+    // = Len02 Type01 Value06                                   (Flags: BREDR_NOT_SUPPORTED, LE_GENERAL_DISCOVERABLE)
+    // = Len07 Type03 Values: 0918 0A18 0D18                    (ListUUID16: 1809 180A 180D )
+    // = Len09 Type09 Values: 62 6C 65 50 52 76 30 34           (LocalName = "blePRv04")
 
-    //Linkloss: ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); //Linkloss
-    //Linkloss: ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000)); //Linkloss /* 1second. */
-    ble.startAdvertising();
+    // Example Raw Advertising caught by App nRF-MCP:  0x02010611069ECADC240EE5A9E093F3A3B50100406E090209180A180D180F18 (==Max Length)
+    // = Len02 Type01 Value06                                   (Flags: BREDR_NOT_SUPPORTED, LE_GENERAL_DISCOVERABLE)
+    // = Len11 Type06 Value9ECADC240EE5A9E093F3A3B5_0100_406E   (UUID128: NordicUART=0x0001)
+    // = Len09 Type02 Values:0918 0A18 0D18 0F18                (UUID16: 1809 180A 180D 180F)
+    // = LocalName field wasn't appended as insufficient space, so Device won't be named when scanning.
+
+    // Example Raw Advertising caught by App nRF-MCP:  0x0201061106FB349B5F80000080001000000F180000070209180A180D18
+    // = Len02 Type01 Value06                                   (Flags: BREDR_NOT_SUPPORTED, LE_GENERAL_DISCOVERABLE)
+    // = Len11 Type06 ValueFB349B5F8000008000100000_0F18_0000   (UUID128: BluetoothBattery=0x180F)
+    // = Len07 Type02 Value 0918 0A18 0D18                      (UUID16: 1809 180A 180D )
+    // = LocalName field wasn't appended as insufficient space, so Device won't be named when scanning.
 
     DEBUG("BLE: Main Loop\n");
     uint32_t u32_wakeevents=0, u32_wakelast=0; // Counter&Register for tracking Wake Events (to see monitor their Frequency)
@@ -322,6 +348,8 @@
             float   update_htm(void); //prototype
             uint8_t update_hrm(void); //prototype
             uint8_t update_batt(void);//prototype
+            //TBD: Maybe save power by not Tx unless enabled by App?
+            // The Services are discovered if they were setup/started (They don't need update to be discovered)
             htmService.updateTemperature( update_htm() );
             hrmService.updateHeartRate( update_hrm() );
             battService.updateBatteryLevel( update_batt() );
@@ -388,4 +416,4 @@
     DEBUG("[BATT:%d%%]", u8_BattPercent);
     return(u8_BattPercent);
 }
-//========== end ==========
\ No newline at end of file
+//========== end ==========