BLE HF2 log service (#1549)
* basic hf2 service * service to send hf2 log messages * use common console.log * updated shims * adding config * adding simulator * fix hf2 logging * hide console blocks
This commit is contained in:
		
							
								
								
									
										50
									
								
								libs/bluetooth/BLEHF2Service.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								libs/bluetooth/BLEHF2Service.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
#include "MicroBitConfig.h"
 | 
			
		||||
#include "ble/UUID.h"
 | 
			
		||||
#include "BLEHF2Service.h"
 | 
			
		||||
#include "MicroBitEvent.h"
 | 
			
		||||
 | 
			
		||||
BLEHF2Service::BLEHF2Service(BLEDevice &_ble) :
 | 
			
		||||
        ble(_ble)
 | 
			
		||||
{
 | 
			
		||||
    GattCharacteristic  txCharacteristic(BLEHF2TxCharacteristicUUID, (uint8_t *)&txCharacteristicMessage, 0,
 | 
			
		||||
    sizeof(txCharacteristicMessage), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
 | 
			
		||||
 | 
			
		||||
    // Initialise our characteristic values.
 | 
			
		||||
    memset(&txCharacteristicMessage, 0, sizeof(txCharacteristicMessage));
 | 
			
		||||
 | 
			
		||||
    // Set default security requirements
 | 
			
		||||
    txCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
 | 
			
		||||
 | 
			
		||||
    // setup GATT table
 | 
			
		||||
    GattCharacteristic *characteristics[] = {&txCharacteristic};
 | 
			
		||||
    GattService service(BLEHF2ServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
 | 
			
		||||
    ble.addService(service);
 | 
			
		||||
 | 
			
		||||
    // retreive handles
 | 
			
		||||
    txCharacteristicHandle = txCharacteristic.getValueHandle();
 | 
			
		||||
 | 
			
		||||
    // initialize data
 | 
			
		||||
    ble.gattServer().write(txCharacteristicHandle,(uint8_t *)&txCharacteristicMessage, sizeof(txCharacteristicMessage));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BLEHF2Service::sendSerial(const char *data, int len, bool isError) {
 | 
			
		||||
    if (ble.getGapState().connected)
 | 
			
		||||
    {
 | 
			
		||||
        int32_t sent = 0;
 | 
			
		||||
        while(sent < len) {
 | 
			
		||||
            int32_t n = min(BLEHF2_DATA_LENGTH, len - sent);
 | 
			
		||||
            txCharacteristicMessage.command = (isError ? BLEHF2_FLAG_SERIAL_OUT : BLEHF2_FLAG_SERIAL_ERR) | n;
 | 
			
		||||
            memcpy(&txCharacteristicMessage.data, data + sent, n);
 | 
			
		||||
            ble.gattServer().notify(txCharacteristicHandle,(uint8_t *)&txCharacteristicMessage, sizeof(txCharacteristicMessage));
 | 
			
		||||
            sent += n;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const uint8_t  BLEHF2ServiceUUID[] = {
 | 
			
		||||
    0xb1,0x12,0xf5,0xe6,0x26,0x79,0x30,0xda,0xa2,0x6e,0x02,0x73,0xb6,0x04,0x38,0x49
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const uint8_t  BLEHF2TxCharacteristicUUID[] = {
 | 
			
		||||
    0xb1,0x12,0xf5,0xe6,0x26,0x79,0x30,0xda,0xa2,0x6e,0x02,0x73,0xb6,0x04,0x38,0x4a
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										54
									
								
								libs/bluetooth/BLEHF2Service.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								libs/bluetooth/BLEHF2Service.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
#ifndef BLE_HF2_SERVICE_H
 | 
			
		||||
#define BLE_HF2_SERVICE_H
 | 
			
		||||
 | 
			
		||||
#include "MicroBitConfig.h"
 | 
			
		||||
#include "ble/BLE.h"
 | 
			
		||||
#include "MicroBitThermometer.h"
 | 
			
		||||
#include "EventModel.h"
 | 
			
		||||
#include "pxt.h"
 | 
			
		||||
 | 
			
		||||
#define HF2_ID 9501
 | 
			
		||||
 | 
			
		||||
#define BLEHF2_FLAG_SERIAL_OUT 0x80
 | 
			
		||||
#define BLEHF2_FLAG_SERIAL_ERR 0xC0
 | 
			
		||||
#define BLEHF2_DATA_LENGTH 19
 | 
			
		||||
 | 
			
		||||
// UUIDs for our service and characteristics
 | 
			
		||||
extern const uint8_t  BLEHF2ServiceUUID[];
 | 
			
		||||
extern const uint8_t  BLEHF2TxCharacteristicUUID[];
 | 
			
		||||
 | 
			
		||||
struct BLEHF2Packet {
 | 
			
		||||
  uint8_t command;
 | 
			
		||||
  uint8_t data[BLEHF2_DATA_LENGTH];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class BLEHF2Service
 | 
			
		||||
{
 | 
			
		||||
    public:
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
      * Constructor.
 | 
			
		||||
      * Create a representation of the TemperatureService
 | 
			
		||||
      * @param _ble The instance of a BLE device that we're running on.
 | 
			
		||||
      */
 | 
			
		||||
    BLEHF2Service(BLEDevice &_ble);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Sends text
 | 
			
		||||
    */
 | 
			
		||||
    void sendSerial(const char *data, int len, bool isError); 
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
 | 
			
		||||
    // Bluetooth stack we're running on.
 | 
			
		||||
    BLEDevice &ble;
 | 
			
		||||
 | 
			
		||||
    // memory for buffers.
 | 
			
		||||
    BLEHF2Packet txCharacteristicMessage;
 | 
			
		||||
 | 
			
		||||
    // Handles to access each characteristic when they are held by Soft Device.
 | 
			
		||||
    GattAttribute::Handle_t txCharacteristicHandle;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
#include "pxt.h"
 | 
			
		||||
#include "MESEvents.h"
 | 
			
		||||
#include "MicroBitUARTService.h"
 | 
			
		||||
#include "BLEHF2Service.h"
 | 
			
		||||
 | 
			
		||||
using namespace pxt;
 | 
			
		||||
 | 
			
		||||
@@ -10,6 +11,14 @@ using namespace pxt;
 | 
			
		||||
//% color=#0082FB weight=96 icon="\uf294"
 | 
			
		||||
namespace bluetooth {
 | 
			
		||||
    MicroBitUARTService *uart = NULL;
 | 
			
		||||
    BLEHF2Service* pHF2 = NULL;
 | 
			
		||||
 | 
			
		||||
    //%
 | 
			
		||||
    void __log(String msg) {
 | 
			
		||||
        if (NULL == pHF2)
 | 
			
		||||
            pHF2 = new BLEHF2Service(*uBit.ble);
 | 
			
		||||
        pHF2->sendSerial(msg->data, msg->length, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    *  Starts the Bluetooth accelerometer service
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,18 @@
 | 
			
		||||
/// <reference no-default-lib="true"/>
 | 
			
		||||
/**
 | 
			
		||||
 * Support for additional Bluetooth services.
 | 
			
		||||
 */
 | 
			
		||||
//% color=#007EF4 weight=96 icon="\uf294"
 | 
			
		||||
namespace bluetooth {
 | 
			
		||||
    /**
 | 
			
		||||
     * Internal use
 | 
			
		||||
     */
 | 
			
		||||
    //% shim=bluetooth::__log
 | 
			
		||||
    export function __log(msg: string) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    console.addListener(function (msg) { __log(msg) });
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    *  Writes to the Bluetooth UART service buffer. From there the data is transmitted over Bluetooth to a connected device.
 | 
			
		||||
    */
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,9 @@
 | 
			
		||||
        "enums.d.ts",
 | 
			
		||||
        "shims.d.ts",
 | 
			
		||||
        "bluetooth.ts",
 | 
			
		||||
        "bluetooth.cpp"
 | 
			
		||||
        "bluetooth.cpp",
 | 
			
		||||
        "BLEHF2Service.h",
 | 
			
		||||
        "BLEHF2Service.cpp"
 | 
			
		||||
    ],
 | 
			
		||||
    "icon": "./static/packages/bluetooth/icon.png",
 | 
			
		||||
    "public": true,
 | 
			
		||||
 
 | 
			
		||||
@@ -205,6 +205,12 @@
 | 
			
		||||
  "basic.showString": "Display text on the display, one character at a time. If the string fits on the screen (i.e. is one letter), does not scroll.",
 | 
			
		||||
  "basic.showString|param|interval": "how fast to shift characters; eg: 150, 100, 200, -100",
 | 
			
		||||
  "basic.showString|param|text": "the text to scroll on the screen, eg: \"Hello!\"",
 | 
			
		||||
  "console": "Reading and writing data to the console output.",
 | 
			
		||||
  "console.addListener": "Adds a listener for the log messages",
 | 
			
		||||
  "console.log": "Write a line of text to the console output.",
 | 
			
		||||
  "console.logValue": "Write a name:value pair as a line of text to the console output.",
 | 
			
		||||
  "console.logValue|param|name": "name of the value stream, eg: \"x\"",
 | 
			
		||||
  "console.logValue|param|value": "to write",
 | 
			
		||||
  "control": "Runtime and event utilities.",
 | 
			
		||||
  "control.assert": "If the condition is false, display msg on serial console, and panic with code 098.",
 | 
			
		||||
  "control.createBuffer": "Create a new zero-initialized buffer.",
 | 
			
		||||
 
 | 
			
		||||
@@ -240,6 +240,7 @@
 | 
			
		||||
  "basic.showNumber|block": "show|number %number",
 | 
			
		||||
  "basic.showString|block": "show|string %text",
 | 
			
		||||
  "basic|block": "basic",
 | 
			
		||||
  "console|block": "console",
 | 
			
		||||
  "control.deviceName|block": "device name",
 | 
			
		||||
  "control.deviceSerialNumber|block": "device serial number",
 | 
			
		||||
  "control.eventSourceId|block": "%id",
 | 
			
		||||
 
 | 
			
		||||
@@ -228,8 +228,9 @@ void debuglog(const char *format, ...)
 | 
			
		||||
    va_end(arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void sendSerial(const char *data, int len) {
 | 
			
		||||
    logwriten(data, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace pxt
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								libs/core/console.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								libs/core/console.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
/// <reference no-default-lib="true"/>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reading and writing data to the console output.
 | 
			
		||||
 */
 | 
			
		||||
//% weight=12 color=#002050 icon="\uf120"
 | 
			
		||||
//% advanced=true
 | 
			
		||||
namespace console {
 | 
			
		||||
    type Listener = (text: string) => void;
 | 
			
		||||
 | 
			
		||||
    //% whenUsed
 | 
			
		||||
    let listeners: Listener[] = undefined;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Write a line of text to the console output.
 | 
			
		||||
     * @param value to send
 | 
			
		||||
     */
 | 
			
		||||
    //% weight=90
 | 
			
		||||
    //% help=console/log blockGap=8
 | 
			
		||||
    //% text.shadowOptions.toString=true
 | 
			
		||||
    export function log(text: string): void {
 | 
			
		||||
        // pad text on the 32byte boundar
 | 
			
		||||
        text += "\r\n";
 | 
			
		||||
        control.__log(text);
 | 
			
		||||
        // send to listeners
 | 
			
		||||
        if (listeners)
 | 
			
		||||
            for (let i = 0; i < listeners.length; ++i)
 | 
			
		||||
                listeners[i](text);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Write a name:value pair as a line of text to the console output.
 | 
			
		||||
     * @param name name of the value stream, eg: "x"
 | 
			
		||||
     * @param value to write
 | 
			
		||||
     */
 | 
			
		||||
    //% weight=88 blockGap=8
 | 
			
		||||
    //% help=console/log-value
 | 
			
		||||
    export function logValue(name: string, value: number): void {
 | 
			
		||||
        log(name ? `${name}: ${value}` : `${value}`)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds a listener for the log messages
 | 
			
		||||
     * @param listener
 | 
			
		||||
     */
 | 
			
		||||
    //%
 | 
			
		||||
    export function addListener(listener: (text: string) => void) {
 | 
			
		||||
        if (!listener) return;
 | 
			
		||||
        if (!listener)
 | 
			
		||||
            listeners = [];
 | 
			
		||||
        listeners.push(listener);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -311,4 +311,13 @@ namespace control {
 | 
			
		||||
    void __midiSend(Buffer buffer) {
 | 
			
		||||
        // this is a stub to support the simulator
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    *
 | 
			
		||||
    */
 | 
			
		||||
    //%
 | 
			
		||||
    void __log(String text) {
 | 
			
		||||
        if (NULL == text) return;
 | 
			
		||||
        pxt::sendSerial(text->data, text->length);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,3 @@
 | 
			
		||||
namespace console {
 | 
			
		||||
    export function log(msg: string) {
 | 
			
		||||
        serial.writeString(msg);
 | 
			
		||||
        serial.writeString("\r\n");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace Math {
 | 
			
		||||
    /**
 | 
			
		||||
     * Generates a `true` or `false` value randomly, just like flipping a coin.
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,7 @@
 | 
			
		||||
        "gestures.jres",
 | 
			
		||||
        "control.ts",
 | 
			
		||||
        "control.cpp",
 | 
			
		||||
        "console.ts",
 | 
			
		||||
        "game.ts",
 | 
			
		||||
        "led.cpp",
 | 
			
		||||
        "led.ts",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								libs/core/shims.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								libs/core/shims.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -440,6 +440,12 @@ declare namespace control {
 | 
			
		||||
     */
 | 
			
		||||
    //% part=midioutput blockHidden=1 shim=control::__midiSend
 | 
			
		||||
    function __midiSend(buffer: Buffer): void;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    //% shim=control::__log
 | 
			
		||||
    function __log(text: string): void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,12 @@ namespace pxsim {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace pxsim.control {
 | 
			
		||||
    export function __log(s: string) {
 | 
			
		||||
        board().writeSerial(s + "\r\n");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace pxsim.serial {
 | 
			
		||||
    export function writeString(s: string) {
 | 
			
		||||
        board().writeSerial(s);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user