mbed base bard check program for BlueTooth USB dongle module (3 switches, 6 leds, I2C LCD, A/D)
Fork of BTstack by
spp_counter.cpp@1:b657594559be, 2013-03-21 (annotated)
- Committer:
- va009039
- Date:
- Thu Mar 21 13:53:05 2013 +0000
- Revision:
- 1:b657594559be
- Parent:
- 0:1ed23ab1345f
replaced USBHost
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:1ed23ab1345f | 1 | #if 0 |
va009039 | 0:1ed23ab1345f | 2 | //***************************************************************************** |
va009039 | 0:1ed23ab1345f | 3 | // |
va009039 | 0:1ed23ab1345f | 4 | // spp_counter demo - it provides a SPP and sends a counter every second |
va009039 | 0:1ed23ab1345f | 5 | // |
va009039 | 0:1ed23ab1345f | 6 | // it doesn't use the LCD to get down to a minimal memory footpring |
va009039 | 0:1ed23ab1345f | 7 | // |
va009039 | 0:1ed23ab1345f | 8 | //***************************************************************************** |
va009039 | 0:1ed23ab1345f | 9 | #include "mbed.h" |
va009039 | 0:1ed23ab1345f | 10 | #include <btstack/hci_cmds.h> |
va009039 | 0:1ed23ab1345f | 11 | #include <btstack/run_loop.h> |
va009039 | 0:1ed23ab1345f | 12 | #include <btstack/sdp_util.h> |
va009039 | 0:1ed23ab1345f | 13 | |
va009039 | 0:1ed23ab1345f | 14 | #include "hci.h" |
va009039 | 0:1ed23ab1345f | 15 | #include "l2cap.h" |
va009039 | 0:1ed23ab1345f | 16 | #include "btstack_memory.h" |
va009039 | 0:1ed23ab1345f | 17 | #include "remote_device_db.h" |
va009039 | 0:1ed23ab1345f | 18 | #include "rfcomm.h" |
va009039 | 1:b657594559be | 19 | extern "C" { |
va009039 | 0:1ed23ab1345f | 20 | #include "sdp.h" |
va009039 | 1:b657594559be | 21 | } |
va009039 | 0:1ed23ab1345f | 22 | #include "config.h" |
va009039 | 0:1ed23ab1345f | 23 | #include "debug.h" |
va009039 | 0:1ed23ab1345f | 24 | #include "bd_addr.h" // class bd_addr |
va009039 | 0:1ed23ab1345f | 25 | |
va009039 | 0:1ed23ab1345f | 26 | Serial pc(USBTX, USBRX); |
va009039 | 0:1ed23ab1345f | 27 | DigitalOut led1(LED1), led2(LED2); |
va009039 | 0:1ed23ab1345f | 28 | |
va009039 | 0:1ed23ab1345f | 29 | #define HEARTBEAT_PERIOD_MS 1000 |
va009039 | 0:1ed23ab1345f | 30 | |
va009039 | 0:1ed23ab1345f | 31 | static uint8_t rfcomm_channel_nr = 1; |
va009039 | 0:1ed23ab1345f | 32 | static uint16_t rfcomm_channel_id = 0; |
va009039 | 0:1ed23ab1345f | 33 | static uint8_t spp_service_buffer[128]; |
va009039 | 0:1ed23ab1345f | 34 | |
va009039 | 0:1ed23ab1345f | 35 | // Bluetooth logic |
va009039 | 0:1ed23ab1345f | 36 | static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ |
va009039 | 0:1ed23ab1345f | 37 | bd_addr_t event_addr; |
va009039 | 0:1ed23ab1345f | 38 | uint8_t rfcomm_channel_nr; |
va009039 | 0:1ed23ab1345f | 39 | uint16_t mtu; |
va009039 | 0:1ed23ab1345f | 40 | |
va009039 | 0:1ed23ab1345f | 41 | switch (packet_type) { |
va009039 | 0:1ed23ab1345f | 42 | case HCI_EVENT_PACKET: |
va009039 | 0:1ed23ab1345f | 43 | switch (packet[0]) { |
va009039 | 0:1ed23ab1345f | 44 | |
va009039 | 0:1ed23ab1345f | 45 | case BTSTACK_EVENT_STATE: |
va009039 | 0:1ed23ab1345f | 46 | // bt stack activated, get started - set local name |
va009039 | 0:1ed23ab1345f | 47 | if (packet[2] == HCI_STATE_WORKING) { |
va009039 | 0:1ed23ab1345f | 48 | hci_send_cmd(&hci_write_local_name, "mbed-Demo"); |
va009039 | 0:1ed23ab1345f | 49 | } |
va009039 | 0:1ed23ab1345f | 50 | break; |
va009039 | 0:1ed23ab1345f | 51 | |
va009039 | 0:1ed23ab1345f | 52 | case HCI_EVENT_COMMAND_COMPLETE: |
va009039 | 0:1ed23ab1345f | 53 | if (COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr)){ |
va009039 | 0:1ed23ab1345f | 54 | bt_flip_addr(event_addr, &packet[6]); |
va009039 | 0:1ed23ab1345f | 55 | log_info("BD-ADDR: %s\n\r", bd_addr_to_str(event_addr)); |
va009039 | 0:1ed23ab1345f | 56 | break; |
va009039 | 0:1ed23ab1345f | 57 | } |
va009039 | 0:1ed23ab1345f | 58 | if (COMMAND_COMPLETE_EVENT(packet, hci_write_local_name)){ |
va009039 | 0:1ed23ab1345f | 59 | hci_discoverable_control(1); |
va009039 | 0:1ed23ab1345f | 60 | break; |
va009039 | 0:1ed23ab1345f | 61 | } |
va009039 | 0:1ed23ab1345f | 62 | break; |
va009039 | 0:1ed23ab1345f | 63 | |
va009039 | 0:1ed23ab1345f | 64 | case HCI_EVENT_LINK_KEY_REQUEST: |
va009039 | 0:1ed23ab1345f | 65 | // deny link key request |
va009039 | 0:1ed23ab1345f | 66 | log_info("Link key request\n\r"); |
va009039 | 0:1ed23ab1345f | 67 | bt_flip_addr(event_addr, &packet[2]); |
va009039 | 0:1ed23ab1345f | 68 | hci_send_cmd(&hci_link_key_request_negative_reply, &event_addr); |
va009039 | 0:1ed23ab1345f | 69 | break; |
va009039 | 0:1ed23ab1345f | 70 | |
va009039 | 0:1ed23ab1345f | 71 | case HCI_EVENT_PIN_CODE_REQUEST: |
va009039 | 0:1ed23ab1345f | 72 | // inform about pin code request |
va009039 | 0:1ed23ab1345f | 73 | log_info("Pin code request - using '0000'\n\r"); |
va009039 | 0:1ed23ab1345f | 74 | bt_flip_addr(event_addr, &packet[2]); |
va009039 | 0:1ed23ab1345f | 75 | hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000"); |
va009039 | 0:1ed23ab1345f | 76 | break; |
va009039 | 0:1ed23ab1345f | 77 | |
va009039 | 0:1ed23ab1345f | 78 | case RFCOMM_EVENT_INCOMING_CONNECTION: |
va009039 | 0:1ed23ab1345f | 79 | // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) |
va009039 | 0:1ed23ab1345f | 80 | bt_flip_addr(event_addr, &packet[2]); |
va009039 | 0:1ed23ab1345f | 81 | rfcomm_channel_nr = packet[8]; |
va009039 | 0:1ed23ab1345f | 82 | rfcomm_channel_id = READ_BT_16(packet, 9); |
va009039 | 0:1ed23ab1345f | 83 | log_info("RFCOMM channel %u requested for %s\n\r", rfcomm_channel_nr, bd_addr_to_str(event_addr)); |
va009039 | 0:1ed23ab1345f | 84 | rfcomm_accept_connection_internal(rfcomm_channel_id); |
va009039 | 0:1ed23ab1345f | 85 | break; |
va009039 | 0:1ed23ab1345f | 86 | |
va009039 | 0:1ed23ab1345f | 87 | case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE: |
va009039 | 0:1ed23ab1345f | 88 | // data: event(8), len(8), status (8), address (48), server channel(8), rfcomm_cid(16), max frame size(16) |
va009039 | 0:1ed23ab1345f | 89 | if (packet[2]) { |
va009039 | 0:1ed23ab1345f | 90 | log_info("RFCOMM channel open failed, status %u\n\r", packet[2]); |
va009039 | 0:1ed23ab1345f | 91 | } else { |
va009039 | 0:1ed23ab1345f | 92 | rfcomm_channel_id = READ_BT_16(packet, 12); |
va009039 | 0:1ed23ab1345f | 93 | mtu = READ_BT_16(packet, 14); |
va009039 | 0:1ed23ab1345f | 94 | log_info("\n\rRFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u\n\r", rfcomm_channel_id, mtu); |
va009039 | 0:1ed23ab1345f | 95 | } |
va009039 | 0:1ed23ab1345f | 96 | break; |
va009039 | 0:1ed23ab1345f | 97 | |
va009039 | 0:1ed23ab1345f | 98 | case RFCOMM_EVENT_CHANNEL_CLOSED: |
va009039 | 0:1ed23ab1345f | 99 | rfcomm_channel_id = 0; |
va009039 | 0:1ed23ab1345f | 100 | break; |
va009039 | 0:1ed23ab1345f | 101 | |
va009039 | 0:1ed23ab1345f | 102 | default: |
va009039 | 0:1ed23ab1345f | 103 | break; |
va009039 | 0:1ed23ab1345f | 104 | } |
va009039 | 0:1ed23ab1345f | 105 | break; |
va009039 | 0:1ed23ab1345f | 106 | |
va009039 | 0:1ed23ab1345f | 107 | default: |
va009039 | 0:1ed23ab1345f | 108 | break; |
va009039 | 0:1ed23ab1345f | 109 | } |
va009039 | 0:1ed23ab1345f | 110 | } |
va009039 | 0:1ed23ab1345f | 111 | |
va009039 | 0:1ed23ab1345f | 112 | static void heartbeat_handler(struct timer *ts){ |
va009039 | 0:1ed23ab1345f | 113 | |
va009039 | 0:1ed23ab1345f | 114 | if (rfcomm_channel_id){ |
va009039 | 0:1ed23ab1345f | 115 | static int counter = 0; |
va009039 | 0:1ed23ab1345f | 116 | char lineBuffer[32]; |
va009039 | 0:1ed23ab1345f | 117 | snprintf(lineBuffer, sizeof(lineBuffer), "counter %04u\n\r", ++counter); |
va009039 | 0:1ed23ab1345f | 118 | log_info("%s\n", lineBuffer); |
va009039 | 0:1ed23ab1345f | 119 | int err = rfcomm_send_internal(rfcomm_channel_id, (uint8_t*) lineBuffer, strlen(lineBuffer)); |
va009039 | 0:1ed23ab1345f | 120 | if (err) { |
va009039 | 0:1ed23ab1345f | 121 | log_info("rfcomm_send_internal -> error %d", err); |
va009039 | 0:1ed23ab1345f | 122 | } |
va009039 | 0:1ed23ab1345f | 123 | } |
va009039 | 0:1ed23ab1345f | 124 | |
va009039 | 0:1ed23ab1345f | 125 | run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS); |
va009039 | 0:1ed23ab1345f | 126 | run_loop_add_timer(ts); |
va009039 | 0:1ed23ab1345f | 127 | led2 = !led2; |
va009039 | 0:1ed23ab1345f | 128 | } |
va009039 | 0:1ed23ab1345f | 129 | |
va009039 | 0:1ed23ab1345f | 130 | // main |
va009039 | 0:1ed23ab1345f | 131 | int main(void) |
va009039 | 0:1ed23ab1345f | 132 | { |
va009039 | 0:1ed23ab1345f | 133 | pc.baud(921600); |
va009039 | 0:1ed23ab1345f | 134 | log_info("%s\n", __FILE__); |
va009039 | 0:1ed23ab1345f | 135 | |
va009039 | 0:1ed23ab1345f | 136 | |
va009039 | 0:1ed23ab1345f | 137 | // init LEDs |
va009039 | 0:1ed23ab1345f | 138 | led1 = led2 = 1; |
va009039 | 0:1ed23ab1345f | 139 | |
va009039 | 0:1ed23ab1345f | 140 | /// GET STARTED with BTstack /// |
va009039 | 0:1ed23ab1345f | 141 | btstack_memory_init(); |
va009039 | 0:1ed23ab1345f | 142 | run_loop_init(RUN_LOOP_EMBEDDED); |
va009039 | 0:1ed23ab1345f | 143 | |
va009039 | 0:1ed23ab1345f | 144 | // init HCI |
va009039 | 0:1ed23ab1345f | 145 | hci_transport_t * transport = hci_transport_usb_instance(); |
va009039 | 0:1ed23ab1345f | 146 | remote_device_db_t * remote_db = (remote_device_db_t *) &remote_device_db_memory; |
va009039 | 0:1ed23ab1345f | 147 | hci_init(transport, NULL, NULL, remote_db); |
va009039 | 0:1ed23ab1345f | 148 | |
va009039 | 0:1ed23ab1345f | 149 | // init L2CAP |
va009039 | 0:1ed23ab1345f | 150 | l2cap_init(); |
va009039 | 0:1ed23ab1345f | 151 | l2cap_register_packet_handler(packet_handler); |
va009039 | 0:1ed23ab1345f | 152 | |
va009039 | 0:1ed23ab1345f | 153 | // init RFCOMM |
va009039 | 0:1ed23ab1345f | 154 | rfcomm_init(); |
va009039 | 0:1ed23ab1345f | 155 | rfcomm_register_packet_handler(packet_handler); |
va009039 | 0:1ed23ab1345f | 156 | rfcomm_register_service_internal(NULL, rfcomm_channel_nr, 100); // reserved channel, mtu=100 |
va009039 | 0:1ed23ab1345f | 157 | |
va009039 | 0:1ed23ab1345f | 158 | // init SDP, create record for SPP and register with SDP |
va009039 | 0:1ed23ab1345f | 159 | sdp_init(); |
va009039 | 0:1ed23ab1345f | 160 | memset(spp_service_buffer, 0, sizeof(spp_service_buffer)); |
va009039 | 0:1ed23ab1345f | 161 | service_record_item_t * service_record_item = (service_record_item_t *) spp_service_buffer; |
va009039 | 0:1ed23ab1345f | 162 | sdp_create_spp_service( (uint8_t*) &service_record_item->service_record, 1, "SPP Counter"); |
va009039 | 0:1ed23ab1345f | 163 | 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))); |
va009039 | 0:1ed23ab1345f | 164 | sdp_register_service_internal(NULL, service_record_item); |
va009039 | 0:1ed23ab1345f | 165 | |
va009039 | 0:1ed23ab1345f | 166 | // set one-shot timer |
va009039 | 0:1ed23ab1345f | 167 | timer_source_t heartbeat; |
va009039 | 0:1ed23ab1345f | 168 | heartbeat.process = &heartbeat_handler; |
va009039 | 0:1ed23ab1345f | 169 | run_loop_set_timer(&heartbeat, HEARTBEAT_PERIOD_MS); |
va009039 | 0:1ed23ab1345f | 170 | run_loop_add_timer(&heartbeat); |
va009039 | 0:1ed23ab1345f | 171 | |
va009039 | 0:1ed23ab1345f | 172 | log_info("Run...\n\r"); |
va009039 | 0:1ed23ab1345f | 173 | |
va009039 | 0:1ed23ab1345f | 174 | // turn on! |
va009039 | 0:1ed23ab1345f | 175 | hci_power_control(HCI_POWER_ON); |
va009039 | 0:1ed23ab1345f | 176 | |
va009039 | 0:1ed23ab1345f | 177 | // go! |
va009039 | 0:1ed23ab1345f | 178 | run_loop_execute(); |
va009039 | 0:1ed23ab1345f | 179 | |
va009039 | 0:1ed23ab1345f | 180 | // happy compiler! |
va009039 | 0:1ed23ab1345f | 181 | return 0; |
va009039 | 0:1ed23ab1345f | 182 | } |
va009039 | 0:1ed23ab1345f | 183 | |
va009039 | 0:1ed23ab1345f | 184 | #endif |