ban4jp -
/
BTstack_test
https://mbed.org/forum/ja/topic/4890/
Fork of BTstack by
spp_flowcontrol.cpp@3:316daabf0d24, 2014-05-09 (annotated)
- Committer:
- ban4jp
- Date:
- Fri May 09 15:54:35 2014 +0000
- Revision:
- 3:316daabf0d24
- Parent:
- 0:1ed23ab1345f
??????????????????????
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 | #include "hci.h" |
va009039 | 0:1ed23ab1345f | 14 | #include "l2cap.h" |
va009039 | 0:1ed23ab1345f | 15 | #include "btstack_memory.h" |
va009039 | 0:1ed23ab1345f | 16 | #include "remote_device_db.h" |
va009039 | 0:1ed23ab1345f | 17 | #include "rfcomm.h" |
va009039 | 0:1ed23ab1345f | 18 | #include "sdp.h" |
va009039 | 0:1ed23ab1345f | 19 | #include "config.h" |
va009039 | 0:1ed23ab1345f | 20 | #include "debug.h" |
va009039 | 0:1ed23ab1345f | 21 | #include "bd_addr.h" // class bd_addr |
va009039 | 0:1ed23ab1345f | 22 | |
va009039 | 0:1ed23ab1345f | 23 | Serial pc(USBTX, USBRX); |
va009039 | 0:1ed23ab1345f | 24 | DigitalOut led1(LED1), led2(LED2); |
va009039 | 0:1ed23ab1345f | 25 | |
va009039 | 0:1ed23ab1345f | 26 | #define HEARTBEAT_PERIOD_MS 500 |
va009039 | 0:1ed23ab1345f | 27 | |
va009039 | 0:1ed23ab1345f | 28 | static uint8_t rfcomm_channel_nr = 1; |
va009039 | 0:1ed23ab1345f | 29 | static uint16_t rfcomm_channel_id = 0; |
va009039 | 0:1ed23ab1345f | 30 | static uint8_t rfcomm_send_credit = 0; |
va009039 | 0:1ed23ab1345f | 31 | static uint8_t spp_service_buffer[128]; |
va009039 | 0:1ed23ab1345f | 32 | |
va009039 | 0:1ed23ab1345f | 33 | // Bluetooth logic |
va009039 | 0:1ed23ab1345f | 34 | static void packet_handler (void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){ |
va009039 | 0:1ed23ab1345f | 35 | bd_addr_t event_addr; |
va009039 | 0:1ed23ab1345f | 36 | uint8_t rfcomm_channel_nr; |
va009039 | 0:1ed23ab1345f | 37 | uint16_t mtu; |
va009039 | 0:1ed23ab1345f | 38 | |
va009039 | 0:1ed23ab1345f | 39 | switch (packet_type) { |
va009039 | 0:1ed23ab1345f | 40 | case HCI_EVENT_PACKET: |
va009039 | 0:1ed23ab1345f | 41 | switch (packet[0]) { |
va009039 | 0:1ed23ab1345f | 42 | |
va009039 | 0:1ed23ab1345f | 43 | case BTSTACK_EVENT_STATE: |
va009039 | 0:1ed23ab1345f | 44 | // bt stack activated, get started - set local name |
va009039 | 0:1ed23ab1345f | 45 | if (packet[2] == HCI_STATE_WORKING) { |
va009039 | 0:1ed23ab1345f | 46 | hci_send_cmd(&hci_write_local_name, "mbed-Demo"); |
va009039 | 0:1ed23ab1345f | 47 | } |
va009039 | 0:1ed23ab1345f | 48 | break; |
va009039 | 0:1ed23ab1345f | 49 | |
va009039 | 0:1ed23ab1345f | 50 | case HCI_EVENT_COMMAND_COMPLETE: |
va009039 | 0:1ed23ab1345f | 51 | if (COMMAND_COMPLETE_EVENT(packet, hci_read_bd_addr)){ |
va009039 | 0:1ed23ab1345f | 52 | bt_flip_addr(event_addr, &packet[6]); |
va009039 | 0:1ed23ab1345f | 53 | log_info("BD-ADDR: %s\n\r", bd_addr_to_str(event_addr)); |
va009039 | 0:1ed23ab1345f | 54 | break; |
va009039 | 0:1ed23ab1345f | 55 | } |
va009039 | 0:1ed23ab1345f | 56 | if (COMMAND_COMPLETE_EVENT(packet, hci_write_local_name)){ |
va009039 | 0:1ed23ab1345f | 57 | hci_discoverable_control(1); |
va009039 | 0:1ed23ab1345f | 58 | break; |
va009039 | 0:1ed23ab1345f | 59 | } |
va009039 | 0:1ed23ab1345f | 60 | break; |
va009039 | 0:1ed23ab1345f | 61 | |
va009039 | 0:1ed23ab1345f | 62 | case HCI_EVENT_LINK_KEY_REQUEST: |
va009039 | 0:1ed23ab1345f | 63 | // deny link key request |
va009039 | 0:1ed23ab1345f | 64 | log_info("Link key request\n\r"); |
va009039 | 0:1ed23ab1345f | 65 | bt_flip_addr(event_addr, &packet[2]); |
va009039 | 0:1ed23ab1345f | 66 | hci_send_cmd(&hci_link_key_request_negative_reply, &event_addr); |
va009039 | 0:1ed23ab1345f | 67 | break; |
va009039 | 0:1ed23ab1345f | 68 | |
va009039 | 0:1ed23ab1345f | 69 | case HCI_EVENT_PIN_CODE_REQUEST: |
va009039 | 0:1ed23ab1345f | 70 | // inform about pin code request |
va009039 | 0:1ed23ab1345f | 71 | log_info("Pin code request - using '0000'\n\r"); |
va009039 | 0:1ed23ab1345f | 72 | bt_flip_addr(event_addr, &packet[2]); |
va009039 | 0:1ed23ab1345f | 73 | hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000"); |
va009039 | 0:1ed23ab1345f | 74 | break; |
va009039 | 0:1ed23ab1345f | 75 | |
va009039 | 0:1ed23ab1345f | 76 | case RFCOMM_EVENT_INCOMING_CONNECTION: |
va009039 | 0:1ed23ab1345f | 77 | // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16) |
va009039 | 0:1ed23ab1345f | 78 | bt_flip_addr(event_addr, &packet[2]); |
va009039 | 0:1ed23ab1345f | 79 | rfcomm_channel_nr = packet[8]; |
va009039 | 0:1ed23ab1345f | 80 | rfcomm_channel_id = READ_BT_16(packet, 9); |
va009039 | 0:1ed23ab1345f | 81 | log_info("RFCOMM channel %u requested for %s\n\r", rfcomm_channel_nr, bd_addr_to_str(event_addr)); |
va009039 | 0:1ed23ab1345f | 82 | rfcomm_accept_connection_internal(rfcomm_channel_id); |
va009039 | 0:1ed23ab1345f | 83 | break; |
va009039 | 0:1ed23ab1345f | 84 | |
va009039 | 0:1ed23ab1345f | 85 | case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE: |
va009039 | 0:1ed23ab1345f | 86 | // data: event(8), len(8), status (8), address (48), server channel(8), rfcomm_cid(16), max frame size(16) |
va009039 | 0:1ed23ab1345f | 87 | if (packet[2]) { |
va009039 | 0:1ed23ab1345f | 88 | log_info("RFCOMM channel open failed, status %u\n\r", packet[2]); |
va009039 | 0:1ed23ab1345f | 89 | } else { |
va009039 | 0:1ed23ab1345f | 90 | rfcomm_channel_id = READ_BT_16(packet, 12); |
va009039 | 0:1ed23ab1345f | 91 | mtu = READ_BT_16(packet, 14); |
va009039 | 0:1ed23ab1345f | 92 | 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 | 93 | } |
va009039 | 0:1ed23ab1345f | 94 | break; |
va009039 | 0:1ed23ab1345f | 95 | |
va009039 | 0:1ed23ab1345f | 96 | case RFCOMM_EVENT_CHANNEL_CLOSED: |
va009039 | 0:1ed23ab1345f | 97 | rfcomm_channel_id = 0; |
va009039 | 0:1ed23ab1345f | 98 | break; |
va009039 | 0:1ed23ab1345f | 99 | |
va009039 | 0:1ed23ab1345f | 100 | default: |
va009039 | 0:1ed23ab1345f | 101 | break; |
va009039 | 0:1ed23ab1345f | 102 | } |
va009039 | 0:1ed23ab1345f | 103 | break; |
va009039 | 0:1ed23ab1345f | 104 | |
va009039 | 0:1ed23ab1345f | 105 | case RFCOMM_DATA_PACKET: |
va009039 | 0:1ed23ab1345f | 106 | // hack: truncate data (we know that the packet is at least on byte bigger |
va009039 | 0:1ed23ab1345f | 107 | packet[size] = 0; |
va009039 | 0:1ed23ab1345f | 108 | puts( (const char *) packet); |
va009039 | 0:1ed23ab1345f | 109 | rfcomm_send_credit = 1; |
va009039 | 0:1ed23ab1345f | 110 | default: |
va009039 | 0:1ed23ab1345f | 111 | break; |
va009039 | 0:1ed23ab1345f | 112 | } |
va009039 | 0:1ed23ab1345f | 113 | } |
va009039 | 0:1ed23ab1345f | 114 | |
va009039 | 0:1ed23ab1345f | 115 | static void heartbeat_handler(struct timer *ts){ |
va009039 | 0:1ed23ab1345f | 116 | if (rfcomm_send_credit){ |
va009039 | 0:1ed23ab1345f | 117 | rfcomm_grant_credits(rfcomm_channel_id, 1); |
va009039 | 0:1ed23ab1345f | 118 | rfcomm_send_credit = 0; |
va009039 | 0:1ed23ab1345f | 119 | } |
va009039 | 0:1ed23ab1345f | 120 | run_loop_set_timer(ts, HEARTBEAT_PERIOD_MS); |
va009039 | 0:1ed23ab1345f | 121 | run_loop_add_timer(ts); |
va009039 | 0:1ed23ab1345f | 122 | led2 = !led2; |
va009039 | 0:1ed23ab1345f | 123 | } |
va009039 | 0:1ed23ab1345f | 124 | |
va009039 | 0:1ed23ab1345f | 125 | // main |
va009039 | 0:1ed23ab1345f | 126 | int main(void) |
va009039 | 0:1ed23ab1345f | 127 | { |
va009039 | 0:1ed23ab1345f | 128 | pc.baud(921600); |
va009039 | 0:1ed23ab1345f | 129 | log_info("%s\n", __FILE__); |
va009039 | 0:1ed23ab1345f | 130 | |
va009039 | 0:1ed23ab1345f | 131 | // init LEDs |
va009039 | 0:1ed23ab1345f | 132 | led1 = led2 = 1; |
va009039 | 0:1ed23ab1345f | 133 | |
va009039 | 0:1ed23ab1345f | 134 | /// GET STARTED with BTstack /// |
va009039 | 0:1ed23ab1345f | 135 | btstack_memory_init(); |
va009039 | 0:1ed23ab1345f | 136 | run_loop_init(RUN_LOOP_EMBEDDED); |
va009039 | 0:1ed23ab1345f | 137 | |
va009039 | 0:1ed23ab1345f | 138 | // init HCI |
va009039 | 0:1ed23ab1345f | 139 | hci_transport_t* transport = hci_transport_usb_instance(); |
va009039 | 0:1ed23ab1345f | 140 | remote_device_db_t * remote_db = (remote_device_db_t *) &remote_device_db_memory; |
va009039 | 0:1ed23ab1345f | 141 | hci_init(transport, NULL, NULL, remote_db); |
va009039 | 0:1ed23ab1345f | 142 | |
va009039 | 0:1ed23ab1345f | 143 | // init L2CAP |
va009039 | 0:1ed23ab1345f | 144 | l2cap_init(); |
va009039 | 0:1ed23ab1345f | 145 | l2cap_register_packet_handler(packet_handler); |
va009039 | 0:1ed23ab1345f | 146 | |
va009039 | 0:1ed23ab1345f | 147 | // init RFCOMM |
va009039 | 0:1ed23ab1345f | 148 | rfcomm_init(); |
va009039 | 0:1ed23ab1345f | 149 | rfcomm_register_packet_handler(packet_handler); |
va009039 | 0:1ed23ab1345f | 150 | rfcomm_register_service_with_initial_credits_internal(NULL, rfcomm_channel_nr, 100, 1); // reserved channel, mtu=100, 1 credit |
va009039 | 0:1ed23ab1345f | 151 | |
va009039 | 0:1ed23ab1345f | 152 | // init SDP, create record for SPP and register with SDP |
va009039 | 0:1ed23ab1345f | 153 | sdp_init(); |
va009039 | 0:1ed23ab1345f | 154 | memset(spp_service_buffer, 0, sizeof(spp_service_buffer)); |
va009039 | 0:1ed23ab1345f | 155 | service_record_item_t * service_record_item = (service_record_item_t *) spp_service_buffer; |
va009039 | 0:1ed23ab1345f | 156 | sdp_create_spp_service( (uint8_t*) &service_record_item->service_record, 1, "SPP Counter"); |
va009039 | 0:1ed23ab1345f | 157 | 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))); |
va009039 | 0:1ed23ab1345f | 158 | sdp_register_service_internal(NULL, service_record_item); |
va009039 | 0:1ed23ab1345f | 159 | |
va009039 | 0:1ed23ab1345f | 160 | // set one-shot timer |
va009039 | 0:1ed23ab1345f | 161 | timer_source_t heartbeat; |
va009039 | 0:1ed23ab1345f | 162 | heartbeat.process = &heartbeat_handler; |
va009039 | 0:1ed23ab1345f | 163 | run_loop_set_timer(&heartbeat, HEARTBEAT_PERIOD_MS); |
va009039 | 0:1ed23ab1345f | 164 | run_loop_add_timer(&heartbeat); |
va009039 | 0:1ed23ab1345f | 165 | |
va009039 | 0:1ed23ab1345f | 166 | |
va009039 | 0:1ed23ab1345f | 167 | log_info("SPP FlowControl Demo: simulates processing on received data...\n\r"); |
va009039 | 0:1ed23ab1345f | 168 | |
va009039 | 0:1ed23ab1345f | 169 | // turn on! |
va009039 | 0:1ed23ab1345f | 170 | hci_power_control(HCI_POWER_ON); |
va009039 | 0:1ed23ab1345f | 171 | |
va009039 | 0:1ed23ab1345f | 172 | // go! |
va009039 | 0:1ed23ab1345f | 173 | run_loop_execute(); |
va009039 | 0:1ed23ab1345f | 174 | |
va009039 | 0:1ed23ab1345f | 175 | // happy compiler! |
va009039 | 0:1ed23ab1345f | 176 | return 0; |
va009039 | 0:1ed23ab1345f | 177 | } |
va009039 | 0:1ed23ab1345f | 178 | #endif |