BLE demo for mbed Ported RunningElectronics's SBDBT firmware for BLE. It can communicate with iOS
Dependencies: FatFileSystem mbed
Fork of BTstack by
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 }
Generated on Thu Jul 14 2022 15:03:48 by 1.7.2