Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 4:342b665fb826, committed 2018-02-09
- Comitter:
- kenjiArai
- Date:
- Fri Feb 09 22:31:19 2018 +0000
- Parent:
- 3:9236f8e65c80
- Child:
- 5:e90d7b6f83cb
- Commit message:
- Not set mac addr but use device name
Changed in this revision
--- a/main.cpp Sun Oct 22 09:45:44 2017 +0000
+++ b/main.cpp Fri Feb 09 22:31:19 2018 +0000
@@ -5,11 +5,12 @@
*
* Modified by Kenji Arai
* http://www.page.sannet.ne.jp/kenjia/index.html
- * http://mbed.org/users/kenjiArai/
+ * https://os.mbed.com/users/kenjiArai/
*
* Started: April 8th, 2016
* Revised: June 13th, 2016
* Revised: October 22nd, 2017 Run on mbed-OS-5.6.2
+ * Revised: Feburary 10th, 2018 Not set mac addr but use device name
*
* Original program (see original.cpp file):
* S130 potential unstability case [closed] by Fabien Comte
@@ -17,22 +18,27 @@
* s130-potential-unstability-case/
* GitHub Q&A by Fabien COMTE
* https://github.com/ARMmbed/ble/issues/69
+ * Reference program:
+ * BLE_Central_test by noboru koshinaka
+ * https://os.mbed.com/users/noboruk/code/BLE_Central_test/
* Tested Server Device:
* BLE_Uart_Server
- * https://developer.mbed.org/users/kenjiArai/code/BLE_Uart_Server/
+ * https://os.mbed.com/users/kenjiArai/code/BLE_Uart_Server/
*/
// Include --------------------------------------------------------------------
#include "mbed.h"
#include "BLE.h"
+#include "DiscoveredCharacteristic.h"
+#include "DiscoveredService.h"
#include "UARTService.h"
-#include "ble/DiscoveredCharacteristic.h"
-#include "ble/DiscoveredService.h"
#include "RingBuffer.h"
// Definition -----------------------------------------------------------------
-#define NUM_ONCE 20
-#define BFSIZE (NUM_ONCE+4)
+//#define USE_MAC // if you use mac address, please define it
+
+#define NUM_ONCE 20
+#define BFSIZE (NUM_ONCE+4)
//#define USE_DEBUG_MODE
#ifdef USE_DEBUG_MODE
@@ -44,7 +50,7 @@
#define SOFT_DEVICE_FATHER_HANDLE 3
// Object ---------------------------------------------------------------------
-BLE ble;
+BLE& ble_uart = BLE::Instance();
DigitalOut alivenessLED(LED1, 1);
DigitalOut connectedLED(D10, 0);
Serial pc(USBTX, USBRX, 115200);
@@ -54,12 +60,16 @@
Thread tsk;
// ROM / Constant data --------------------------------------------------------
+#ifdef USE_MAC
#warning "You need to modify below value based on your board."
const Gap::Address_t mac_board_0 = {0x50, 0x2b, 0xea, 0x14, 0x95, 0xd2};
const Gap::Address_t mac_board_1 = {0x59, 0x2c, 0xa8, 0x0e, 0xe2, 0xef};
const Gap::Address_t mac_board_2 = {0x0f, 0x72, 0xbf, 0x43, 0xbc, 0xd0};
const Gap::Address_t mac_board_3 = {0x83, 0xc9, 0x1a, 0x90, 0xdf, 0xd6};
const Gap::Address_t mac_board_4 = {0x43, 0xa4, 0x36, 0x11, 0x5b, 0xeb};
+#else
+const char PEER_NAME[] = "UART_PJL";
+#endif
// RAM ------------------------------------------------------------------------
Gap::Handle_t connectionHandle = 0xFFFF;
@@ -107,27 +117,28 @@
ticker.attach(periodicCallback, 1);
tsk.start(pc_ser_rx);
// clear terminal output
- for (int k = 0; k < 5; k++) { pc.printf("\r\n");}
+ for (int k = 0; k < 3; k++) {
+ pc.printf("\r\n");
+ }
// opening message
pc.printf("UART Communication / Client(Central) side\r\n");
- pc.printf(" need Sever module (run BLE_Uart_Sever program)\r\n");
+ pc.printf(" need Server module (run BLE_Uart_Server program)\r\n");
// Mixed role **************************************************************
- ble.init();
- ble.gap().onConnection(connectionCallback);
- ble.gap().onDisconnection(disconnectionCallback);
+ ble_uart.init();
+ ble_uart.gap().onConnection(connectionCallback);
+ ble_uart.gap().onDisconnection(disconnectionCallback);
// Client(Central) role ****************************************************
- ble.gattClient().onHVX(onReceivedDataFromDeviceCallback);
- ble.gap().setScanParams(500, 450);
- ble.gap().startScan(advertisementCallback);
+ ble_uart.gattClient().onHVX(onReceivedDataFromDeviceCallback);
+ ble_uart.gap().setScanParams(500, 450);
+ ble_uart.gap().startScan(advertisementCallback);
while(true) {
// allow notifications from Server(Peripheral)
if (foundUartRXCharacteristic &&
- !ble.gattClient().isServiceDiscoveryActive())
- {
+ !ble_uart.gattClient().isServiceDiscoveryActive()) {
// need to do the following only once
foundUartRXCharacteristic = false;
uint16_t value = BLE_HVX_NOTIFICATION;
- ble.gattClient().write(
+ ble_uart.gattClient().write(
GattClient::GATT_OP_WRITE_REQ,
connectionHandle,
uartRXCharacteristic.getValueHandle() + 1,
@@ -135,27 +146,27 @@
reinterpret_cast<const uint8_t *>(&value)
);
}
- if (received_uart_dat == true){
+ if (received_uart_dat == true) {
received_uart_dat = false;
- for(int i = 0; i < uart_bf_len; i++){
+ for(int i = 0; i < uart_bf_len; i++) {
//pc.printf("%c", uart_buffer[i]);
pc.putc(uart_buffer[i]);
}
}
- ble.waitForEvent();
+ ble_uart.waitForEvent();
}
}
void periodicCallback(void)
{
// Do blinky on alivenessLED to indicate system aliveness
- alivenessLED = !alivenessLED;
- if (connected2server){
+ alivenessLED = !alivenessLED;
+ if (connected2server) {
connectedLED = 1;
} else {
connectedLED = 0;
}
- if (rx_isr_busy == true){
+ if (rx_isr_busy == true) {
rx_isr_busy = false;
} else {
tsk.signal_set(0x01);
@@ -174,27 +185,27 @@
static uint8_t linebf_irq[BFSIZE];
static volatile uint8_t linebf_irq_len = 0;
- while(true){
+ while(true) {
Thread::signal_wait(0x01);
- if (ser_bf.check() == 0){
- if (linebf_irq_len != 0){
+ if (ser_bf.check() == 0) {
+ if (linebf_irq_len != 0) {
linebf_irq[linebf_irq_len] = 0;
adjust_line(linebf_irq);
linebf_irq_len = 0;
uartTXCharacteristic.write(NUM_ONCE, linebf_irq);
}
}
- while(ser_bf.check() != 0){
+ while(ser_bf.check() != 0) {
char c = ser_bf.read();
- if (c == '\b'){
+ if (c == '\b') {
linebf_irq_len--;
pc.putc(c);
pc.putc(' ');
pc.putc(c);
- } else if ((c >= ' ') || (c == '\r') || (c == '\n')){
+ } else if ((c >= ' ') || (c == '\r') || (c == '\n')) {
bool overflow = false;
if ((c == '\r') || (c == '\n')) {
- if (linebf_irq_len == NUM_ONCE - 1){// remain only 1 buffer
+ if (linebf_irq_len == NUM_ONCE - 1) { // remain only 1 buffer
overflow = true;
linebf_irq[linebf_irq_len++] = '\r';
pc.putc('\r');
@@ -208,11 +219,11 @@
linebf_irq[linebf_irq_len++] = c;
pc.putc(c);
}
- if (linebf_irq_len >= NUM_ONCE ){
+ if (linebf_irq_len >= NUM_ONCE ) {
linebf_irq[linebf_irq_len] = 0;
uartTXCharacteristic.write(linebf_irq_len, linebf_irq);
linebf_irq_len = 0;
- if (overflow == true){
+ if (overflow == true) {
overflow = false;
linebf_irq[linebf_irq_len++] = '\n';
pc.putc('\n');
@@ -227,11 +238,15 @@
{
uint8_t i, c;
- for (i = 0; i <NUM_ONCE; bf++, i++){
+ for (i = 0; i <NUM_ONCE; bf++, i++) {
c = *bf;
- if (c == 0){ break;}
+ if (c == 0) {
+ break;
+ }
}
- for (; i < NUM_ONCE; bf++, i++){ *bf = 0x11;}
+ for (; i < NUM_ONCE; bf++, i++) {
+ *bf = 0x11;
+ }
*(bf + 1) = 0;
}
@@ -242,26 +257,27 @@
params->handle,
(params->type == BLE_HVX_NOTIFICATION) ? "notification" : "indication"
);
- if (params->type == BLE_HVX_NOTIFICATION){
+ if (params->type == BLE_HVX_NOTIFICATION) {
if ((params->handle
- == uartRXCharacteristic.getValueHandle()) && (params->len > 0))
- {
+ == uartRXCharacteristic.getValueHandle()) && (params->len > 0)) {
uart_bf_len = params->len;
strcpy((char *)uart_buffer, (char *)params->data);
received_uart_dat = true;
- }
+ }
}
}
+#ifdef USE_MAC
+
bool mac_equals(const Gap::Address_t mac_1, const Gap::Address_t mac_2)
{
DBG("Address: ");
- for (int i = 0; i < 6; i++){
+ for (int i = 0; i < 6; i++) {
DBG("0x%02x ", mac_1[i]);
}
DBG("\r\n");
- for (int i = 0; i < 6; i++){
- if (mac_1[i] != mac_2[i]){
+ for (int i = 0; i < 6; i++) {
+ if (mac_1[i] != mac_2[i]) {
DBG("0x%02x != 0x%02x at %d\r\n", mac_1[i], mac_2[i], i);
return false;
} else {
@@ -273,11 +289,21 @@
int get_board_index(const Gap::Address_t mac)
{
- if (mac_equals(mac, mac_board_0)) { return 0;}
- if (mac_equals(mac, mac_board_1)) { return 1;}
- if (mac_equals(mac, mac_board_2)) { return 2;}
- if (mac_equals(mac, mac_board_3)) { return 3;}
- if (mac_equals(mac, mac_board_4)) { return 4;}
+ if (mac_equals(mac, mac_board_0)) {
+ return 0;
+ }
+ if (mac_equals(mac, mac_board_1)) {
+ return 1;
+ }
+ if (mac_equals(mac, mac_board_2)) {
+ return 2;
+ }
+ if (mac_equals(mac, mac_board_3)) {
+ return 3;
+ }
+ if (mac_equals(mac, mac_board_4)) {
+ return 4;
+ }
return -1;
}
@@ -286,26 +312,80 @@
{
// connections
int peer_board_index = get_board_index(params->peerAddr);
- if (peer_board_index != -1){
+ if (peer_board_index != -1) {
pc.printf("");
pc.printf(
"adv peerAddr [%02x %02x %02x %02x %02x %02x]\r\n",
params->peerAddr[5], params->peerAddr[4], params->peerAddr[3],
- params->peerAddr[2], params->peerAddr[1], params->peerAddr[0]
+ params->peerAddr[2], params->peerAddr[1], params->peerAddr[0]
);
pc.printf(
"rssi=%+4d, isScanResponse %u, AdvertisementType %u\r\n",
params->rssi, params->isScanResponse, params->type
);
- ble.gap().connect(
+ ble_uart.gap().connect(
params->peerAddr, Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL);
}
}
+#else
+
+// Client(Central) role ********************************************************
+void advertisementCallback(const Gap::AdvertisementCallbackParams_t *params)
+{
+ bool name_match = false;
+
+ // parse the advertising payload, looking for data type COMPLETE_LOCAL_NAME
+ // The advertising payload is a collection of key/value records where
+ // byte 0: length of the record excluding this byte
+ // byte 1: The key, it is the type of the data
+ // byte [2..N] The value. N is equal to byte0 - 1
+
+ for( uint8_t i = 0; i < params->advertisingDataLen; ++i) {
+ const uint8_t record_length = params->advertisingData[i];
+ if (record_length == 0) {
+ continue;
+ }
+ const uint8_t type = params->advertisingData[i + 1];
+ const uint8_t* value = params->advertisingData + i + 2;
+ const uint8_t value_length = record_length - 1;
+
+ if(type == GapAdvertisingData::COMPLETE_LOCAL_NAME) {
+ if ((value_length == sizeof(PEER_NAME))
+ && (memcmp(value, PEER_NAME, value_length) == 0)) {
+ pc.printf(
+ "\r\nadv peerAddr[%02x %02x %02x %02x %02x %02x] rssi %d, ",
+ params->peerAddr[5], params->peerAddr[4],
+ params->peerAddr[3], params->peerAddr[2],
+ params->peerAddr[1], params->peerAddr[0],
+ params->rssi
+ );
+ pc.printf(
+ "isScanResponse %u, AdvertisementType %u\r\n",
+ params->isScanResponse, params->type
+ );
+ name_match = true;
+ break;
+ }
+ }
+ i += record_length;
+ }
+ if( name_match != true ) {
+ return;
+ }
+
+ pc.printf("Found device name : %s\r\n",PEER_NAME);
+ // connections
+ ble_uart.gap().connect(params->peerAddr,
+ Gap::ADDR_TYPE_RANDOM_STATIC, NULL, NULL);
+}
+
+#endif
+
void serviceDiscoveryCallback(const DiscoveredService *service)
{
DBG("service found...\r\n");
- if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT){
+ if (service->getUUID().shortOrLong() == UUID::UUID_TYPE_SHORT) {
DBG(
"Service UUID-%x attrs[%u %u]\r\n",
service->getUUID().getShortUUID(),
@@ -319,7 +399,7 @@
DBG("%02x", longUUIDBytes[i]);
}
DBG(" attrs[%u %u]\r\n",
- service->getStartHandle(), service->getEndHandle());
+ service->getStartHandle(), service->getEndHandle());
}
}
@@ -333,14 +413,12 @@
(uint8_t)characteristicP->getProperties().broadcast()
);
if (characteristicP->getUUID().getShortUUID()
- == UARTServiceTXCharacteristicShortUUID)
- {
+ == UARTServiceTXCharacteristicShortUUID) {
DBG("Sevice TX 0x%04x\r\n", UARTServiceTXCharacteristicShortUUID);
uartTXCharacteristic = *characteristicP;
connection_tx = true;
} else if (characteristicP->getUUID().getShortUUID()
- == UARTServiceRXCharacteristicShortUUID)
- {
+ == UARTServiceRXCharacteristicShortUUID) {
DBG("Sevice RX 0x%04x\r\n", UARTServiceRXCharacteristicShortUUID);
uartRXCharacteristic = *characteristicP;
foundUartRXCharacteristic = true;
@@ -358,24 +436,24 @@
{
if (params->role == Gap::CENTRAL) {
pc.printf("connected as Client(Central) (handle = %d)\r\n\r",
- params->handle);
+ params->handle);
connected2server = true;
connectionHandle = params->handle;
- ble.gattClient().onServiceDiscoveryTermination(
- discoveryTerminationCallback);
- ble.gattClient().launchServiceDiscovery(
- params->handle,
- serviceDiscoveryCallback,
- characteristicDiscoveryCallback
+ ble_uart.gattClient().onServiceDiscoveryTermination(
+ discoveryTerminationCallback);
+ ble_uart.gattClient().launchServiceDiscovery(
+ params->handle,
+ serviceDiscoveryCallback,
+ characteristicDiscoveryCallback
);
}
pc.printf(
- "Client(Central/Myself) %02x:%02x:%02x:%02x:%02x:%02x\r\n",
+ "Client(Central/Myself) %02x:%02x:%02x:%02x:%02x:%02x\r\n",
params->ownAddr[5], params->ownAddr[4], params->ownAddr[3],
params->ownAddr[2], params->ownAddr[1], params->ownAddr[0]
);
pc.printf(
- "Connected Sever(peripheral) %02x:%02x:%02x:%02x:%02x:%02x\r\n",
+ "Connected Server(Peripheral) %02x:%02x:%02x:%02x:%02x:%02x\r\n",
params->peerAddr[5], params->peerAddr[4], params->peerAddr[3],
params->peerAddr[2], params->peerAddr[1], params->peerAddr[0]
);
@@ -390,8 +468,8 @@
connection_tx = false;
connection_rx = false;
if (params->handle == SOFT_DEVICE_FATHER_HANDLE) {
- ble.startAdvertising(); // restart advertising
+ ble_uart.startAdvertising(); // restart advertising
} else {
- ble.gap().startScan(advertisementCallback); // restart scan
+ ble_uart.gap().startScan(advertisementCallback);// restart scan
}
}
--- a/mbed-os.lib Sun Oct 22 09:45:44 2017 +0000 +++ b/mbed-os.lib Fri Feb 09 22:31:19 2018 +0000 @@ -1,1 +1,1 @@ -https://github.com/ARMmbed/mbed-os/#6e0d01cd13e8aca7bf4d697c3699ec9225386881 +https://github.com/ARMmbed/mbed-os/#caeaa49d68c67ee00275cece10cd88e0ed0f6ed3
--- a/original.cpp Sun Oct 22 09:45:44 2017 +0000 +++ b/original.cpp Fri Feb 09 22:31:19 2018 +0000 @@ -9,7 +9,7 @@ #include "UARTService.h" #include "ble/DiscoveredCharacteristic.h" #include "ble/DiscoveredService.h" -#include "UARTService.h" +#include "ble/service/UARTService.h" #define SOFT_DEVICE_FATHER_HANDLE 3