Example for BLE HID scanner
Fork of BLE_HIDScanner_DELTA by
Revision 2:9f46fa6237dd, committed 2017-03-27
- Comitter:
- silviaChen
- Date:
- Mon Mar 27 09:58:38 2017 +0000
- Parent:
- 1:8bca989a70be
- Child:
- 3:9d6e0ddf3fbe
- Commit message:
- update mbed-os so both NNN50 and NQ620 (as well as NQ624 module) platform are supported; Add config in mbed_app.json to fix NQ620 use internal RC issue ; remove the unused shield folder; support both iOS and Android
Changed in this revision
--- a/BLE_API.lib Tue Feb 07 02:51:56 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#65474dc93927
--- a/HIDService.h Tue Feb 07 02:51:56 2017 +0000
+++ b/HIDService.h Mon Mar 27 09:58:38 2017 +0000
@@ -2,6 +2,9 @@
#define __BLE_HID_SERVICE_H__
#include "BLE.h"
+
+#define BLE_UUID_DESCRIPTOR_REPORT_REFERENCE 0x2908
+
/**
* @class Human Interface Device Service
* @brief BLE Human Interface Device Service. This service displays the Glucose measurement value represented as a 16bit Float format.<br>
@@ -9,19 +12,31 @@
* @Email: marco.missyou@gmail.com
*/
+typedef struct {
+ uint8_t ID;
+ uint8_t type;
+} report_reference_t;
+
+enum ReportType {
+ INPUT_REPORT = 0x1,
+ OUTPUT_REPORT = 0x2,
+ FEATURE_REPORT = 0x3,
+};
+
extern const uint8_t KeyboardReportMap[76];
class HIDService {
public:
- HIDService(BLEDevice &_ble, const uint8_t* key = &KeyboardReportMap[0]):
+ HIDService(BLE &_ble, const uint8_t* key = &KeyboardReportMap[0]):
ble(_ble),
protocol_modeValue(1), // Report Protocol Mode(1), Boot Protocol Mode(0)
KeyboardMap(key),
Protocol_Mode(GattCharacteristic::UUID_PROTOCOL_MODE_CHAR, &protocol_modeValue, 1, 1, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
- ReportMap(GattCharacteristic::UUID_REPORT_MAP_CHAR, KeyboardMap.getPointer(), 76, sizeof(KeyboardMap), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ |GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY),
- Report(GattCharacteristic::UUID_REPORT_CHAR, reportValue.getPointer(), 8, 8, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+ ReportMap(GattCharacteristic::UUID_REPORT_MAP_CHAR, KeyboardMap.getPointer(), 76, sizeof(KeyboardMap), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
+ Report(GattCharacteristic::UUID_REPORT_CHAR, reportValue.getPointer(), 8, 8, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE, inputReportDescriptors(), 1),
HID_Information(GattCharacteristic::UUID_HID_INFORMATION_CHAR, hidInformation.getPointer(), 4, 4, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ),
- HID_Control_Point(GattCharacteristic::UUID_HID_CONTROL_POINT_CHAR, &hidcontrolPointer, 1, 1, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE)
+ HID_Control_Point(GattCharacteristic::UUID_HID_CONTROL_POINT_CHAR, &hidcontrolPointer, 1, 1, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE),
+ inputReportReferenceDescriptor(BLE_UUID_DESCRIPTOR_REPORT_REFERENCE,(uint8_t *)&inputReportReferenceData, 2, 2)
{
static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */
if (serviceAdded) {
@@ -73,6 +88,16 @@
return KeyboardMap;
}
};
+
+ GattAttribute** HIDService::inputReportDescriptors() {
+ inputReportReferenceData.ID = 0;
+ inputReportReferenceData.type = INPUT_REPORT;
+
+ static GattAttribute *descs[] = {
+ &inputReportReferenceDescriptor,
+ };
+ return descs;
+ }
private:
struct ReportStructure {
@@ -114,7 +139,7 @@
};
private:
- BLEDevice &ble;
+ BLE &ble;
uint8_t protocol_modeValue;
ReportStructure reportValue;
uint8_t hidcontrolPointer;
@@ -128,5 +153,7 @@
// ReadOnlyGattCharacteristic Boot_Mouse_Input_Report;
GattCharacteristic HID_Information;
GattCharacteristic HID_Control_Point;
+ GattAttribute inputReportReferenceDescriptor;
+ report_reference_t inputReportReferenceData;
};
#endif /* #ifndef __BLE_GLUCOSE_SERVICE_H__*/
\ No newline at end of file
--- a/main.cpp Tue Feb 07 02:51:56 2017 +0000
+++ b/main.cpp Mon Mar 27 09:58:38 2017 +0000
@@ -21,17 +21,28 @@
#include "HIDService.h"
//DigitalOut led1(LED1);
-Serial uart(USBTX, USBRX);
+Serial uart(USBTX, USBRX, 115200);
+BLE deltaBLE;
HIDService *hidService;
unsigned char keyData;
const static char DEVICE_NAME[] = "HID_Keyboard";
static const uint16_t uuid16_list[] = {GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE,
+ GattService::UUID_BATTERY_SERVICE,
GattService::UUID_DEVICE_INFORMATION_SERVICE};
static volatile bool triggerSensorPolling = false;
bool isConnectionSecured = false;
+bool isSecuritySetup = false;
+static uint8_t key_press_scan_buff[50];
+static uint8_t modifyKey[50];
+char msg[25] = "";
+int index_b = 0;
+int index_w = 0;
+unsigned char uart_buf[64];
+unsigned int i = 0;
DeviceInformationService *deviceInfo;
+BatteryService *batteryService;
void passkeyDisplayCallback(Gap::Handle_t handle, const SecurityManager::Passkey_t passkey)
{
@@ -41,12 +52,18 @@
}
uart.printf("\r\n");
}
+
+void securitySetupInitiatedCallback(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps)
+{
+ uart.printf("securitySetupInitiatedCallback\r\n");
+ isSecuritySetup = true;
+}
void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status)
{
if (status == SecurityManager::SEC_STATUS_SUCCESS) {
uart.printf("Security success\r\n", status);
- isConnectionSecured = true;
+ //isConnectionSecured = true;
} else {
uart.printf("Security failed\r\n", status);
}
@@ -55,7 +72,15 @@
void linkSecuredCallback(Gap::Handle_t handle, SecurityManager::SecurityMode_t securityMode)
{
uart.printf("linkSecuredCallback\r\n");
+ if (!isSecuritySetup) {
+ isConnectionSecured = true;
+ }
+}
+
+void securityContextStoredCallback(Gap::Handle_t handle) {
+ uart.printf("securityContextStoredCallback\r\n");
isConnectionSecured = true;
+ isSecuritySetup = false;
}
void onConnectionCallback(const Gap::ConnectionCallbackParams_t *params)
@@ -67,7 +92,7 @@
{
uart.printf("Disconnected\r\n");
isConnectionSecured = false;
- BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); // restart advertising
+ deltaBLE.gap().startAdvertising(); // restart advertising
}
void onTimeoutCallback(Gap::TimeoutSource_t source)
@@ -94,77 +119,18 @@
/* Note that the periodicCallback() executes in interrupt context, so it is safer to do
* heavy-weight sensor polling from the main thread. */
- triggerSensorPolling = true;
+ //triggerSensorPolling = true;
}
-void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
-{
- BLE &ble = params->ble;
- ble_error_t error = params->error;
-
- if (error != BLE_ERROR_NONE) {
- return;
- }
-
- bool enableBonding = true;
- bool requireMITM = false;
-
- //const uint8_t passkeyValue[6] = {0x00,0x00,0x00,0x00,0x00,0x00};
- ble.securityManager().init(enableBonding, requireMITM, SecurityManager::IO_CAPS_NONE);
- ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback);
- ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback);
- ble.securityManager().onLinkSecured(linkSecuredCallback);
- ble.gap().onDisconnection(disconnectionCallback);
- ble.gap().onConnection(onConnectionCallback);
- ble.gap().onTimeout(onTimeoutCallback);
- //ble.gattServer().onDataRead(onDataReadCallback);
-
- /* Setup primary service. */
- hidService = new HIDService(ble);
-
- /* Setup auxiliary service. */
- deviceInfo = new DeviceInformationService(ble, "DELTA", "NQ620", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
-
- /* Setup advertising. */
- ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
- ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
- ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD);
- ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
- ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
- ble.gap().setAdvertisingInterval(50); /* 50ms */
- ble.gap().startAdvertising();
- uart.printf("Start advertising\r\n");
-}
-
-static uint8_t key_press_scan_buff[50];
-static uint8_t modifyKey[50];
-char msg[25] = "";
-int index_b = 0;
-int index_w = 0;
-
-int main(void)
-{
- //led1 = 1;
- // Ticker ticker;
-// ticker.attach(periodicCallback, 0.1); // blink LED every second
-
- uart.baud(115200);
- uart.printf("Srarting HID Service\r\n");
-
- BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
- ble.init(bleInitComplete);
-
- /* SpinWait for initialization to complete. This is necessary because the
- * BLE object is used in the main loop below. */
- while (ble.hasInitialized() == false) { /* spin loop */ }
-
- // infinite loop
- while (1) {
+void CLI_execute() {
+// if (i>=2)
+// if (uart_buf[i-2] == 0x0D && uart_buf[i-1] == 0x0A){//detecting CR LF
+ if (uart.readable()) return;//retrun if it is not the end of packet
+
if (isConnectionSecured) {
- if (uart.readable() == 1) {
- keyData = uart.getc();
- uart.putc(keyData);
- msg[index_w++] = keyData;
+ for (int j=0; j<i; j++) {
+ keyData = uart_buf[j];
+
if(keyData <= 0x39 && keyData >= 0x30){ //number
if(keyData == 0x30){
modifyKey[index_b] = 0x00;
@@ -192,31 +158,110 @@
key_press_scan_buff[index_b] = 0x2c;
index_b++;
key_press_scan_buff[index_b] = 0x73;
+ } else if (keyData == 0x08) { //backspace
+ modifyKey[index_b] = 0x00;
+ key_press_scan_buff[index_b] = 0x2a;
+ index_b++;
+ key_press_scan_buff[index_b] = 0x73;
+ } else if (keyData == 0x0d) { //return
+ modifyKey[index_b] = 0x00;
+ key_press_scan_buff[index_b] = 0x28;
+ index_b++;
+ key_press_scan_buff[index_b] = 0x73;
} else {
modifyKey[index_b] = 0x00;
//key_press_scan_buff[index_b] = 0x73; //this is dummy data.
//msg[index_w+1] = '\0';
}
index_b++;
- if(keyData == 0x0a && ble.getGapState().connected){
- for(int i = 0; i < index_b ; i++){
- uart.printf("m[%x] k[%x] ", modifyKey[i], key_press_scan_buff[i]);
- hidService->updateReport(modifyKey[i], key_press_scan_buff[i]);
- ble.waitForEvent();
- wait(0.03);
- }
+ }
+
+ i=0;
- index_b = 0;
- index_w = 0;
- memset(modifyKey, 0, 50);
- memset(msg, 0, 25);
- memset(key_press_scan_buff, 0, 50);
- }
+ for(int i = 0; i < index_b ; i++){
+ uart.printf("m[%x] k[%x] ", modifyKey[i], key_press_scan_buff[i]);
+ hidService->updateReport(modifyKey[i], key_press_scan_buff[i]);
+ //BLE::Instance(BLE::DEFAULT_INSTANCE).waitForEvent();
+ //wait(0.03);
}
- } else {
- ble.waitForEvent(); // low power wait for event
- wait(1);
+
+ index_b = 0;
+ index_w = 0;
+ memset(modifyKey, 0, 50);
+ memset(msg, 0, 25);
+ memset(key_press_scan_buff, 0, 50);
+
}
+// }
+}
+
+void uart_interrupt() {
+ uart.printf("uart_interrupt\r\n");
+ uart_buf[i++] = uart.getc();
+ CLI_execute();
+}
+
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
+{
+ BLE &ble = params->ble;
+ ble_error_t error = params->error;
+
+ if (error != BLE_ERROR_NONE) {
+ return;
+ }
+
+ bool enableBonding = true;
+ bool requireMITM = false;
+
+ //uint8_t pKey[6] = {'1', '1', '1', '1', '1', '1'}; //set the passkey
+ ble.securityManager().init(enableBonding, requireMITM, SecurityManager::IO_CAPS_NONE);
+ ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback);
+ ble.securityManager().onSecuritySetupInitiated(securitySetupInitiatedCallback);
+ ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback);
+ ble.securityManager().onLinkSecured(linkSecuredCallback);
+ ble.securityManager().onSecurityContextStored(securityContextStoredCallback);
+ ble.gap().onDisconnection(disconnectionCallback);
+ ble.gap().onConnection(onConnectionCallback);
+ ble.gap().onTimeout(onTimeoutCallback);
+ //ble.gattServer().onDataRead(onDataReadCallback);
+
+ /* Setup primary service. */
+ hidService = new HIDService(ble);
+
+ /* Setup auxiliary service. */
+ batteryService = new BatteryService(ble, 100);
+ deviceInfo = new DeviceInformationService(ble, "DELTA", "NQ620", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
+
+ /* Setup advertising. */
+ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
+ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD);
+ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
+ ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+ ble.gap().setAdvertisingInterval(50); /* 50ms */
+ ble.gap().startAdvertising();
+ uart.printf("Start advertising\r\n");
+}
+
+int main(void)
+{
+ //led1 = 1;
+ //Ticker ticker;
+ //ticker.attach(periodicCallback, 1); // blink LED every second
+
+ uart.attach(&uart_interrupt);
+ uart.printf("Srarting HID Service\r\n");
+
+ BLE &deltaBLE = BLE::Instance(BLE::DEFAULT_INSTANCE);
+ deltaBLE.init(bleInitComplete);
+
+ /* SpinWait for initialization to complete. This is necessary because the
+ * BLE object is used in the main loop below. */
+ while (deltaBLE.hasInitialized() == false) { /* spin loop */ }
+
+ // infinite loop
+ while (1) {
+ deltaBLE.waitForEvent();
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-os.lib Mon Mar 27 09:58:38 2017 +0000 @@ -0,0 +1,1 @@ +https://github.com/ARMmbed/mbed-os/#f4864dc6429e1ff5474111d4e0f6bee36a759b1c
--- a/mbed.bld Tue Feb 07 02:51:56 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/25aea2a3f4e3 \ No newline at end of file
--- a/mbed_app.json Tue Feb 07 02:51:56 2017 +0000
+++ b/mbed_app.json Mon Mar 27 09:58:38 2017 +0000
@@ -1,13 +1,12 @@
{
- "target_overrides": {
- "K64F": {
- "target.features_add": ["BLE"],
- "target.extra_labels_add": ["ST_BLUENRG"],
- "target.macros_add": ["IDB0XA1_D13_PATCH"]
+ "config": {
+ "lf_clock_rc_calib_timer_interval": {
+ "value": 16,
+ "macro_name": "MBED_CONF_NORDIC_NRF_LF_CLOCK_CALIB_TIMER_INTERVAL"
},
- "NUCLEO_F401RE": {
- "target.features_add": ["BLE"],
- "target.extra_labels_add": ["ST_BLUENRG"]
+ "lf_clock_rc_calib_mode_config": {
+ "value": 0,
+ "macro_name": "MBED_CONF_NORDIC_NRF_LF_CLOCK_CALIB_MODE_CONFIG"
}
}
}
\ No newline at end of file
--- a/nRF51822.lib Tue Feb 07 02:51:56 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#c90ae1400bf2
--- a/shields/TARGET_ST_BLUENRG.lib Tue Feb 07 02:51:56 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://developer.mbed.org/teams/ST/code/X_NUCLEO_IDB0XA1/#fa98703ece8e
