BTstack Bluetooth stack

Dependencies:   mbed USBHost

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers spp_demo.cpp Source File

spp_demo.cpp

00001 #if 0
00002 /*
00003  * spp_demo
00004  */
00005 #include "mbed.h"
00006 #include <btstack/hci_cmds.h>
00007 #include <btstack/run_loop.h>
00008 #include <btstack/sdp_util.h>
00009 #include "hci.h"
00010 #include "l2cap.h"
00011 #include "btstack_memory.h"
00012 #include "remote_device_db.h"
00013 #include "rfcomm.h"
00014 extern "C" {
00015 #include "sdp.h"
00016 }
00017 #include "config.h"
00018 #include "debug.h"
00019 #include "bd_addr.h"  // class bd_addr
00020 
00021 Serial pc(USBTX, USBRX);
00022 DigitalOut led1(LED1), led2(LED2), led3(LED3);
00023 
00024 #define HEARTBEAT_PERIOD_MS 500
00025 
00026 static uint8_t   rfcomm_channel_nr = 1;
00027 static uint16_t  rfcomm_channel_id = 0;
00028 static uint8_t   spp_service_buffer[128];
00029 
00030 // Bluetooth logic
00031 static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
00032     bd_addr_t event_addr;
00033     uint8_t   rfcomm_channel_nr;
00034     uint16_t  mtu;
00035     int err;
00036     switch (packet_type) {
00037         case HCI_EVENT_PACKET:
00038             switch (packet[0]) {
00039                     
00040                 case BTSTACK_EVENT_STATE:
00041                     // bt stack activated, get started - set local name
00042                     if (packet[2] == HCI_STATE_WORKING) {
00043                         hci_send_cmd(&hci_write_local_name, "mbed");
00044                     }
00045                     break;
00046                 
00047                 case HCI_EVENT_COMMAND_COMPLETE:
00048                     if (COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr)){
00049                         bt_flip_addr(event_addr, &packet[6]);
00050                         log_info("BD-ADDR: %s\n\r", bd_addr_to_str(event_addr));
00051                         break;
00052                     }
00053                     if (COMMAND_COMPLETE_EVENT(packet, hci_write_local_name)){
00054                         hci_discoverable_control(1);
00055                         break;
00056                     }
00057                     break;
00058 
00059                 case HCI_EVENT_LINK_KEY_REQUEST:
00060                     // deny link key request
00061                     log_info("Link key request\n\r");
00062                     bt_flip_addr(event_addr, &packet[2]);
00063                     hci_send_cmd(&hci_link_key_request_negative_reply, &event_addr);
00064                     break;
00065                     
00066                 case HCI_EVENT_PIN_CODE_REQUEST:
00067                     // inform about pin code request
00068                     log_info("Pin code request - using '0000'\n\r");
00069                     bt_flip_addr(event_addr, &packet[2]);
00070                     hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
00071                     break;
00072                 
00073                 case RFCOMM_EVENT_INCOMING_CONNECTION:
00074                     // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
00075                     bt_flip_addr(event_addr, &packet[2]); 
00076                     rfcomm_channel_nr = packet[8];
00077                     rfcomm_channel_id = READ_BT_16(packet, 9);
00078                     log_info("RFCOMM channel %u requested for %s\n\r", rfcomm_channel_nr, bd_addr_to_str(event_addr));
00079                     rfcomm_accept_connection_internal(rfcomm_channel_id);
00080                     break;
00081                     
00082                 case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
00083                     // data: event(8), len(8), status (8), address (48), server channel(8), rfcomm_cid(16), max frame size(16)
00084                     if (packet[2]) {
00085                         log_info("RFCOMM channel open failed, status %u\n\r", packet[2]);
00086                     } else {
00087                         rfcomm_channel_id = READ_BT_16(packet, 12);
00088                         mtu = READ_BT_16(packet, 14);
00089                         log_info("\n\rRFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n\r", rfcomm_channel_id, mtu);
00090                     }
00091                     break;
00092                     
00093                 case RFCOMM_EVENT_CHANNEL_CLOSED:
00094                     rfcomm_channel_id = 0;
00095                     break;
00096                 
00097                 default:
00098                     break;
00099             }
00100             break;
00101             
00102         case RFCOMM_DATA_PACKET:
00103             // loopback
00104             if (rfcomm_channel_id) {
00105                 err = rfcomm_send_internal(rfcomm_channel_id, packet, size);
00106                 if (err) {
00107                     log_info("rfcomm_send_internal -> error %d", err);
00108                 }
00109             }
00110             led3 = !led3;
00111             break;
00112         default:
00113             break;
00114     }
00115 }
00116 
00117 static void  heartbeat_handler(struct timer *ts){
00118     run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS);
00119     run_loop_add_timer(ts);
00120     led2 = !led2;
00121 } 
00122 
00123 // main
00124 int main(void)
00125 {
00126     pc.baud(921600);
00127     log_info("%s\n", __FILE__);
00128 
00129     // init LEDs
00130     led1 = led2 = led3 = 1;
00131     
00132     /// GET STARTED with BTstack ///
00133     btstack_memory_init();
00134     run_loop_init(RUN_LOOP_EMBEDDED);
00135     
00136     // init HCI
00137     hci_transport_t* transport = hci_transport_usb_instance();
00138     remote_device_db_t * remote_db = (remote_device_db_t *) &remote_device_db_memory;
00139     hci_init(transport, NULL, NULL, remote_db);
00140     
00141     // init L2CAP
00142     l2cap_init();
00143     l2cap_register_packet_handler(packet_handler);
00144     
00145     // init RFCOMM
00146     rfcomm_init();
00147     rfcomm_register_packet_handler(packet_handler);
00148     rfcomm_register_service_internal(NULL, rfcomm_channel_nr, 100);  // reserved channel, mtu=100
00149 
00150     // init SDP, create record for SPP and register with SDP
00151     sdp_init();
00152     memset(spp_service_buffer, 0, sizeof(spp_service_buffer));
00153     service_record_item_t * service_record_item = (service_record_item_t *) spp_service_buffer;
00154     sdp_create_spp_service( (uint8_t*) &service_record_item->service_record, 1, "loopback");
00155     log_info("SDP service buffer size: %u\n\r", (uint16_t) (sizeof(service_record_item_t) + de_get_len((uint8_t*) &service_record_item->service_record)));
00156     sdp_register_service_internal(NULL, service_record_item);
00157     
00158     // set one-shot timer
00159     timer_source_t heartbeat;
00160     heartbeat.process = &heartbeat_handler;
00161     run_loop_set_timer(&heartbeat, HEARTBEAT_PERIOD_MS);
00162     run_loop_add_timer(&heartbeat);
00163     
00164     log_info("SPP loopback demo...\n\r");
00165 
00166      // turn on!
00167     hci_power_control(HCI_POWER_ON);
00168 
00169     // go!
00170     run_loop_execute();    
00171 
00172     return 0;
00173 }
00174 #endif