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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BLE_demo.cpp Source File

BLE_demo.cpp

00001 /*
00002  * Copyright (C) 2011-2012 by Matthias Ringwald
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  * 4. This software may not be used in a commercial product
00017  *    without an explicit license granted by the copyright holder.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY MATTHIAS RINGWALD AND CONTRIBUTORS
00020  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00022  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
00023  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00024  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00025  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00026  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00027  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00028  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00029  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  *
00032  */
00033 
00034 /*  Change history
00035  2013/2/10: by todotani
00036   Modified tick event handler
00037   Modified LED control
00038   - LED 3 flush when connected
00039   - LED 2 OFF in case write attribute, ON in case read attribute
00040   - LED 1 OFF of after start of advertisement, then reflect write value to 0xFFF2
00041 2013/2/11: by todotani
00042   Changed serial pc.baud (115200 to 921600) to avoid imcomplete connection issue
00043   Disable btstack debug-log
00044 2013/2/20: by todotani
00045   Change tick timer interval 250ms to 1ms
00046   Change Attribute 0xFFF1 as read DigitalIn p5 of mbed
00047 */
00048 
00049 //*****************************************************************************
00050 //
00051 // att device demo
00052 //
00053 //*****************************************************************************
00054 
00055 // TODO: seperate BR/EDR from LE ACL buffers
00056 // TODO: move LE init into HCI
00057 // ..
00058 
00059 // NOTE: Supports only a single connection
00060 
00061 // mbed specific
00062 #include "mbed.h"
00063 Serial pc(USBTX, USBRX);
00064 DigitalOut led1(LED1), led2(LED2), led3(LED3);
00065 DigitalIn  sw1(p5);
00066 
00067 // from btstack ble_server.c
00068 #include "global.h"
00069 #include "debug.h"
00070 #include "btstack/btstack.h"
00071 #include "btstack/hci_cmds.h"
00072 #include "btstack/run_loop.h"
00073 #include "btstack/hal_tick.h"
00074 
00075 #include "hci.h"
00076 #include "l2cap.h"
00077 #include "btstack_memory.h"
00078 #include "remote_device_db.h"
00079 #include "config.h"
00080 
00081 #include "att.h"
00082 
00083 hci_transport_t * hci_transport_picusb_instance();
00084 
00085 static att_connection_t att_connection;
00086 static uint16_t         att_response_handle = 0;
00087 static uint16_t         att_response_size   = 0;
00088 static uint8_t          att_response_buffer[28];
00089 
00090 static uint8_t          switch_new_state   = 1;
00091 static uint8_t          switch_old_state   = 1;
00092 
00093 void hexdump2(void *data, int size)
00094 {
00095     int i;
00096     for (i=0; i<size; i++) {
00097         log_info("%02X ", ((uint8_t *)data)[i]);
00098     }
00099     log_info("\n");
00100 }
00101 
00102 static void att_try_respond(void)
00103 {
00104     if (!att_response_size) return;
00105     if (!att_response_handle) return;
00106     if (!hci_can_send_packet_now(HCI_ACL_DATA_PACKET)) return;
00107 
00108     // update state before sending packet
00109     uint16_t size = att_response_size;
00110     att_response_size = 0;
00111     l2cap_send_connectionless(att_response_handle, L2CAP_CID_ATTRIBUTE_PROTOCOL, att_response_buffer, size);
00112 }
00113 
00114 
00115 static void att_packet_handler(uint8_t packet_type, uint16_t handle, uint8_t *packet, uint16_t size)
00116 {
00117     if (packet_type != ATT_DATA_PACKET) return;
00118 
00119     att_response_handle = handle;
00120     att_response_size = att_handle_request(&att_connection, packet, size, att_response_buffer);
00121     att_try_respond();
00122 }
00123 
00124 
00125 // enable LE, setup ADV data
00126 static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
00127 {
00128     static bd_addr_t addr;
00129     // Data for advertisement and scan response
00130     const uint8_t adv_data[31]="\x02\x01\x05" "\x05\x09mbed" "\x03\x02\xf0\xff";
00131     switch (packet_type) {
00132 
00133         case HCI_EVENT_PACKET:
00134             switch (packet[0]) {
00135 
00136                 case BTSTACK_EVENT_STATE:
00137                     // bt stack activated, get started - set local name
00138                     if (packet[2] == HCI_STATE_WORKING) {
00139                         log_info("Working!\n");
00140                         hci_send_cmd(&hci_read_local_supported_features);
00141                     }
00142                     break;
00143 
00144                 case DAEMON_EVENT_HCI_PACKET_SENT:
00145                     att_try_respond();
00146                     break;
00147 
00148                 case HCI_EVENT_LE_META:
00149                     switch (packet[2]) {
00150                         case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
00151                             // reset connection MTU
00152                             att_connection.mtu = 23;
00153                             break;
00154                         default:
00155                             break;
00156                     }
00157                     break;
00158 
00159                 case BTSTACK_EVENT_NR_CONNECTIONS_CHANGED:
00160                     if (packet[2]) {
00161                         connection_status=1;
00162                         log_info("CONNECTED\n");
00163                     } else {
00164                         connection_status=0;
00165                         log_info("NOT CONNECTED\n");
00166                     }
00167                     break;
00168 
00169                 case HCI_EVENT_DISCONNECTION_COMPLETE:
00170                     att_response_handle =0;
00171                     att_response_size = 0;
00172 
00173                     // restart advertising
00174                     hci_send_cmd(&hci_le_set_advertise_enable, 1);
00175                     break;
00176 
00177                 case HCI_EVENT_COMMAND_COMPLETE:
00178                     if (COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr)) {
00179                         bt_flip_addr(addr, &packet[6]);
00180                         log_info("BD ADDR: %s\n", bd_addr_to_str(addr));
00181                         break;
00182                     }
00183                     if (COMMAND_COMPLETE_EVENT(packet, hci_read_local_supported_features)) {
00184                         log_info("Local supported features: %04lX%04lX\n", READ_BT_32(packet, 10), READ_BT_32(packet, 6));
00185                         hci_send_cmd(&hci_set_event_mask, 0xffffffff, 0x20001fff);
00186                         break;
00187                     }
00188                     if (COMMAND_COMPLETE_EVENT(packet, hci_set_event_mask)) {
00189                         hci_send_cmd(&hci_write_le_host_supported, 1, 1);
00190                         break;
00191                     }
00192                     if (COMMAND_COMPLETE_EVENT(packet, hci_write_le_host_supported)) {
00193                         hci_send_cmd(&hci_le_set_event_mask, 0xffffffff, 0xffffffff);
00194                         break;
00195                     }
00196                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_event_mask)) {
00197                         hci_send_cmd(&hci_le_read_buffer_size);
00198                         break;
00199                     }
00200                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_buffer_size)) {
00201                         log_info("LE buffer size: %u, count %u\n", READ_BT_16(packet,6), packet[8]);
00202                         hci_send_cmd(&hci_le_read_supported_states);
00203                         break;
00204                     }
00205                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_read_supported_states)) {
00206                         hci_send_cmd(&hci_le_set_advertising_parameters,  0x0400, 0x0800, 0, 0, 0, &addr, 0x07, 0);
00207                         break;
00208                     }
00209                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_parameters)) {
00210                         hci_send_cmd(&hci_le_set_advertising_data, sizeof(adv_data), adv_data);
00211                         break;
00212                     }
00213                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertising_data)) {
00214                         hci_send_cmd(&hci_le_set_scan_response_data, 10, adv_data);
00215                         break;
00216                     }
00217                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_scan_response_data)) {
00218                         hci_send_cmd(&hci_le_set_advertise_enable, 1);
00219                         break;
00220                     }
00221                     if (COMMAND_COMPLETE_EVENT(packet, hci_le_set_advertise_enable)) {
00222                         hci_discoverable_control(1);
00223                         log_info("startup_state=1\n");
00224                         startup_state=1;
00225                         led1 = 0;
00226                         break;
00227                     }
00228 
00229             }
00230     }
00231 }
00232 
00233 // test profile
00234 #include "profile.h"
00235 
00236 static uint8_t strbuf[80];
00237 static uint8_t  ledvalue;
00238 
00239 // read requests
00240 static uint16_t att_read_callback(uint16_t handle, uint16_t offset, uint8_t * buffer, uint16_t buffer_size)
00241 {
00242     uint16_t    ret=0,val;
00243 
00244     if(buffer) {
00245         log_info("READ Callback, handle %04x\n", handle);
00246         led2 = 1;
00247     }
00248     switch(handle) {
00249             // Correspond to Characteristics 0xFFF1
00250         case 0x000b:
00251             if(buffer && ret<=buffer_size) {
00252                 buffer[0] = sw1.read();
00253                 log_info("Read value: %u\n", buffer[0]);
00254             }
00255             ret = 1;
00256             break;
00257 
00258             // Correspond to Characteristics 0xFFF2
00259         case 0x000d:
00260             if(buffer && buffer_size) {
00261                 ledvalue = led1;
00262                 buffer[0] = ledvalue;
00263                 log_info("Read value: %u\n", buffer[0]);
00264             }
00265             ret=1;
00266             break;
00267 
00268             // Correspond to Characteristics 0x00001234-0000-1000-8000-00805F9B34FB
00269         case 0x000f:
00270             if(buffer && buffer_size>=2) {
00271                 val=timer_counter;
00272                 log_info("Read value: %u\n", val);
00273                 buffer[0]=val&0xff;
00274                 buffer[1]=val>>8;
00275             }
00276             ret=2;
00277             break;
00278     }
00279     return ret;
00280 }
00281 
00282 // write requests
00283 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)
00284 {
00285     log_info("WRITE Callback, handle %04x\n", handle);
00286     led2 = 0;
00287     switch(handle) {
00288             // Correspond to Characteristics 0xFFF1
00289         case 0x000b:
00290             log_info("No action\n");
00291             break;
00292 
00293             // Correspond to Characteristics 0xFFF2
00294         case 0x000d:
00295             log_info("New value: %u\n", buffer[0]);
00296             ledvalue = buffer[0];
00297             led1 = ledvalue;
00298             break;
00299     }
00300 }
00301 
00302 
00303 void hal_tick_event(void)
00304 {
00305     timer_counter++;
00306 
00307     if(connection_status) {
00308         if(timer_counter % 250 == 0) {
00309             led3 = !led3;
00310             //  Under testing
00311             //            switch_new_state = (uint8_t)sw1.read();
00312             //            if (switch_new_state != switch_old_state) {
00313             //                log_info("Fire notification\n");
00314             //                switch_old_state = switch_new_state;
00315             //                att_prepare_handle_value_notification(&att_connection, 0x000b, &switch_new_state, 1, att_response_buffer);
00316         }
00317     } else {
00318         led3 = 1;
00319     }
00320 }
00321 
00322 // main
00323 int main(void)
00324 {
00325     pc.baud(921600);
00326     //pc.baud(230400);
00327     log_info("%s\n", __FILE__);
00328 
00329     // init LEDs
00330     led1 = led2 = led3 = 1;
00331     ledvalue = led1;
00332 
00333     /// GET STARTED with BTstack ///
00334     btstack_memory_init();
00335     run_loop_init(RUN_LOOP_EMBEDDED);
00336     hal_tick_set_handler(&hal_tick_event);
00337 
00338     // init HCI
00339     // use BlueUSB
00340     hci_transport_t* transport = hci_transport_usb_instance();
00341     bt_control_t       * control   = NULL;
00342     hci_uart_config_t  * config    = NULL;
00343     remote_device_db_t * remote_db = (remote_device_db_t *) &remote_device_db_memory;
00344     hci_init(transport, config, control, remote_db);
00345 
00346     // use eHCILL
00347     // bt_control_cc256x_enable_ehcill(1);
00348 
00349     // set up l2cap_le
00350     l2cap_init();
00351     l2cap_register_fixed_channel(att_packet_handler, L2CAP_CID_ATTRIBUTE_PROTOCOL);
00352     l2cap_register_packet_handler(packet_handler);
00353 
00354     // set up ATT
00355     att_set_db(profile_data);
00356     att_set_write_callback(att_write_callback);
00357     att_set_read_callback(att_read_callback);
00358     att_dump_attributes();
00359     att_connection.mtu = 27;
00360 
00361     log_info("Run...\n\n");
00362 
00363     // turn on!
00364     hci_power_control(HCI_POWER_ON);
00365 
00366     // go!
00367     run_loop_execute();
00368 
00369     // happy compiler!
00370     return 0;
00371 }