BLE demo for mbed Ported RunningElectronics's SBDBT firmware for BLE. It can communicate with iOS

Dependencies:   FatFileSystem mbed

Fork of BTstack by Norimasa Okamoto

Revision:
6:cf06ba884429
Parent:
5:5fb56e13a1f9
--- a/BLE_demo.cpp	Mon Feb 11 14:10:57 2013 +0000
+++ b/BLE_demo.cpp	Wed Feb 20 14:18:38 2013 +0000
@@ -14,7 +14,7 @@
  *    contributors may be used to endorse or promote products derived
  *    from this software without specific prior written permission.
  * 4. This software may not be used in a commercial product
- *    without an explicit license granted by the copyright holder. 
+ *    without an explicit license granted by the copyright holder.
  *
  * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -32,7 +32,7 @@
  */
 
 /*  Change history
- 2013/2/10: by todotani 
+ 2013/2/10: by todotani
   Modified tick event handler
   Modified LED control
   - LED 3 flush when connected
@@ -41,6 +41,9 @@
 2013/2/11: by todotani
   Changed serial pc.baud (115200 to 921600) to avoid imcomplete connection issue
   Disable btstack debug-log
+2013/2/20: by todotani
+  Change tick timer interval 250ms to 1ms
+  Change Attribute 0xFFF1 as read DigitalIn p5 of mbed
 */
 
 //*****************************************************************************
@@ -59,6 +62,7 @@
 #include "mbed.h"
 Serial pc(USBTX, USBRX);
 DigitalOut led1(LED1), led2(LED2), led3(LED3);
+DigitalIn  sw1(p5);
 
 // from btstack ble_server.c
 #include "global.h"
@@ -83,19 +87,24 @@
 static uint16_t         att_response_size   = 0;
 static uint8_t          att_response_buffer[28];
 
-void hexdump2(void *data, int size){
+static uint8_t          switch_new_state   = 1;
+static uint8_t          switch_old_state   = 1;
+
+void hexdump2(void *data, int size)
+{
     int i;
-    for (i=0; i<size;i++){
+    for (i=0; i<size; i++) {
         log_info("%02X ", ((uint8_t *)data)[i]);
     }
     log_info("\n");
 }
 
-static void att_try_respond(void){
+static void att_try_respond(void)
+{
     if (!att_response_size) return;
     if (!att_response_handle) return;
     if (!hci_can_send_packet_now(HCI_ACL_DATA_PACKET)) return;
-    
+
     // update state before sending packet
     uint16_t size = att_response_size;
     att_response_size = 0;
@@ -103,9 +112,10 @@
 }
 
 
-static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size){
+static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size)
+{
     if (packet_type != ATT_DATA_PACKET) return;
-    
+
     att_response_handle = handle;
     att_response_size = att_handle_request(&att_connection, packet, size, att_response_buffer);
     att_try_respond();
@@ -113,28 +123,28 @@
 
 
 // enable LE, setup ADV data
-static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
+static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
+{
     static bd_addr_t addr;
-    //uint8_t adv_data[] = { 02, 01, 05, 03, 02, 0xf0, 0xff }; 
     // Data for advertisement and scan response
-    const uint8_t adv_data[31]="\x02\x01\x05" "\x06\x09SBDBT" "\x03\x02\xf0\xff";
+    const uint8_t adv_data[31]="\x02\x01\x05" "\x05\x09mbed" "\x03\x02\xf0\xff";
     switch (packet_type) {
-            
+
         case HCI_EVENT_PACKET:
             switch (packet[0]) {
-                
+
                 case BTSTACK_EVENT_STATE:
                     // bt stack activated, get started - set local name
                     if (packet[2] == HCI_STATE_WORKING) {
-                       log_info("Working!\n");
+                        log_info("Working!\n");
                         hci_send_cmd(&hci_read_local_supported_features);
                     }
                     break;
-                
+
                 case DAEMON_EVENT_HCI_PACKET_SENT:
                     att_try_respond();
                     break;
-                    
+
                 case HCI_EVENT_LE_META:
                     switch (packet[2]) {
                         case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
@@ -155,67 +165,67 @@
                         log_info("NOT CONNECTED\n");
                     }
                     break;
-                    
+
                 case HCI_EVENT_DISCONNECTION_COMPLETE:
                     att_response_handle =0;
                     att_response_size = 0;
-                    
+
                     // restart advertising
                     hci_send_cmd(&hci_le_set_advertise_enable, 1);
                     break;
-                    
+
                 case HCI_EVENT_COMMAND_COMPLETE:
-                    if (COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr)){
+                    if (COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr)) {
                         bt_flip_addr(addr, &packet[6]);
                         log_info("BD ADDR: %s\n", bd_addr_to_str(addr));
                         break;
                     }
-                    if (COMMAND_COMPLETE_EVENT(packet, hci_read_local_supported_features)){
+                    if (COMMAND_COMPLETE_EVENT(packet, hci_read_local_supported_features)) {
                         log_info("Local supported features: %04lX%04lX\n", READ_BT_32(packet, 10), READ_BT_32(packet, 6));
                         hci_send_cmd(&hci_set_event_mask, 0xffffffff, 0x20001fff);
                         break;
                     }
-                    if (COMMAND_COMPLETE_EVENT(packet, hci_set_event_mask)){
+                    if (COMMAND_COMPLETE_EVENT(packet, hci_set_event_mask)) {
                         hci_send_cmd(&hci_write_le_host_supported, 1, 1);
                         break;
                     }
-                    if (COMMAND_COMPLETE_EVENT(packet, hci_write_le_host_supported)){
+                    if (COMMAND_COMPLETE_EVENT(packet, hci_write_le_host_supported)) {
                         hci_send_cmd(&hci_le_set_event_mask, 0xffffffff, 0xffffffff);
                         break;
                     }
-                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_event_mask)){
+                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_event_mask)) {
                         hci_send_cmd(&hci_le_read_buffer_size);
                         break;
                     }
-                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_buffer_size)){
+                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_buffer_size)) {
                         log_info("LE buffer size: %u, count %u\n", READ_BT_16(packet,6), packet[8]);
-                       hci_send_cmd(&hci_le_read_supported_states);
-                       break;
+                        hci_send_cmd(&hci_le_read_supported_states);
+                        break;
                     }
-                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_supported_states)){
-                       hci_send_cmd(&hci_le_set_advertising_parameters,  0x0400, 0x0800, 0, 0, 0, &addr, 0x07, 0);
-                       break;
+                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_supported_states)) {
+                        hci_send_cmd(&hci_le_set_advertising_parameters,  0x0400, 0x0800, 0, 0, 0, &addr, 0x07, 0);
+                        break;
                     }
-                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_parameters)){
-                       hci_send_cmd(&hci_le_set_advertising_data, sizeof(adv_data), adv_data);
-                       break;
+                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_parameters)) {
+                        hci_send_cmd(&hci_le_set_advertising_data, sizeof(adv_data), adv_data);
+                        break;
                     }
-                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_data)){
-                       hci_send_cmd(&hci_le_set_scan_response_data, 10, adv_data);
-                       break;
+                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_data)) {
+                        hci_send_cmd(&hci_le_set_scan_response_data, 10, adv_data);
+                        break;
                     }
-                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_scan_response_data)){
-                       hci_send_cmd(&hci_le_set_advertise_enable, 1);
-                       break;
+                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_scan_response_data)) {
+                        hci_send_cmd(&hci_le_set_advertise_enable, 1);
+                        break;
                     }
-                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertise_enable)){
+                    if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertise_enable)) {
                         hci_discoverable_control(1);
                         log_info("startup_state=1\n");
                         startup_state=1;
                         led1 = 0;
                         break;
                     }
-                    
+
             }
     }
 }
@@ -227,35 +237,37 @@
 static uint8_t  ledvalue;
 
 // read requests
-static uint16_t att_read_callback(uint16_t handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size){
+static uint16_t att_read_callback(uint16_t handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size)
+{
     uint16_t    ret=0,val;
 
-    if(buffer){
+    if(buffer) {
         log_info("READ Callback, handle %04x\n", handle);
         led2 = 1;
     }
-    switch(handle){
-        // Correspond to Characteristics 0xFFF1
-       case 0x000b:
-            ret=strlen((char*)strbuf);
-            if(buffer && ret<=buffer_size){
-                log_info("Read text: %s\n", strbuf);
-                memcpy(buffer,strbuf,ret);
+    switch(handle) {
+            // Correspond to Characteristics 0xFFF1
+        case 0x000b:
+            if(buffer && ret<=buffer_size) {
+                buffer[0] = sw1.read();
+                log_info("Read value: %u\n", buffer[0]);
             }
+            ret = 1;
             break;
 
-        // Correspond to Characteristics 0xFFF2
+            // Correspond to Characteristics 0xFFF2
         case 0x000d:
-            if(buffer && buffer_size){
+            if(buffer && buffer_size) {
+                ledvalue = led1;
+                buffer[0] = ledvalue;
                 log_info("Read value: %u\n", buffer[0]);
-                buffer[0]=ledvalue;
             }
             ret=1;
             break;
 
-        // Correspond to Characteristics 0x00001234-0000-1000-8000-00805F9B34FB
+            // Correspond to Characteristics 0x00001234-0000-1000-8000-00805F9B34FB
         case 0x000f:
-            if(buffer && buffer_size>=2){
+            if(buffer && buffer_size>=2) {
                 val=timer_counter;
                 log_info("Read value: %u\n", val);
                 buffer[0]=val&0xff;
@@ -268,28 +280,21 @@
 }
 
 // write requests
-static void att_write_callback(uint16_t handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size, signature_t * signature){
+static void att_write_callback(uint16_t handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size, signature_t * signature)
+{
     log_info("WRITE Callback, handle %04x\n", handle);
     led2 = 0;
-    switch(handle){
-        // Correspond to Characteristics 0xFFF1
+    switch(handle) {
+            // Correspond to Characteristics 0xFFF1
         case 0x000b:
-            buffer[buffer_size]=0;
-            if(sizeof(strbuf)>buffer_size){
-                strcpy((char*)strbuf,(char*)buffer);
-            }
-            log_info("New text: %s\n", buffer);
+            log_info("No action\n");
             break;
-        
-        // Correspond to Characteristics 0xFFF2
+
+            // Correspond to Characteristics 0xFFF2
         case 0x000d:
             log_info("New value: %u\n", buffer[0]);
-            ledvalue=buffer[0];
-            if (buffer[0]){
-                led1 = 1;
-            } else {
-                led1 = 0;
-            }
+            ledvalue = buffer[0];
+            led1 = ledvalue;
             break;
     }
 }
@@ -299,9 +304,17 @@
 {
     timer_counter++;
 
-    if(connection_status){
-        led3 = !led3;
-    }else{
+    if(connection_status) {
+        if(timer_counter % 250 == 0) {
+            led3 = !led3;
+            //  Under testing
+            //            switch_new_state = (uint8_t)sw1.read();
+            //            if (switch_new_state != switch_old_state) {
+            //                log_info("Fire notification\n");
+            //                switch_old_state = switch_new_state;
+            //                att_prepare_handle_value_notification(&att_connection, 0x000b, &switch_new_state, 1, att_response_buffer);
+        }
+    } else {
         led3 = 1;
     }
 }
@@ -310,16 +323,18 @@
 int main(void)
 {
     pc.baud(921600);
+    //pc.baud(230400);
     log_info("%s\n", __FILE__);
 
     // init LEDs
     led1 = led2 = led3 = 1;
-    
-   /// GET STARTED with BTstack ///
+    ledvalue = led1;
+
+    /// GET STARTED with BTstack ///
     btstack_memory_init();
     run_loop_init(RUN_LOOP_EMBEDDED);
     hal_tick_set_handler(&hal_tick_event);
-    
+
     // init HCI
     // use BlueUSB
     hci_transport_t* transport = hci_transport_usb_instance();
@@ -327,30 +342,30 @@
     hci_uart_config_t  * config    = NULL;
     remote_device_db_t * remote_db = (remote_device_db_t *) &remote_device_db_memory;
     hci_init(transport, config, control, remote_db);
-    
+
     // use eHCILL
     // bt_control_cc256x_enable_ehcill(1);
-    
+
     // set up l2cap_le
     l2cap_init();
     l2cap_register_fixed_channel(att_packet_handler, L2CAP_CID_ATTRIBUTE_PROTOCOL);
     l2cap_register_packet_handler(packet_handler);
-    
+
     // set up ATT
     att_set_db(profile_data);
     att_set_write_callback(att_write_callback);
     att_set_read_callback(att_read_callback);
     att_dump_attributes();
     att_connection.mtu = 27;
-    
-    log_info("Run...\n\r");
+
+    log_info("Run...\n\n");
 
     // turn on!
     hci_power_control(HCI_POWER_ON);
 
     // go!
-    run_loop_execute(); 
-    
+    run_loop_execute();
+
     // happy compiler!
     return 0;
 }