BTstack Bluetooth stack

Dependencies:   mbed USBHost

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers spp_counter.cpp Source File

spp_counter.cpp

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