source: asp3_tinet_ecnl_rx/trunk/asp3_dcre/tinet/netdev/if_btusb/bt_main.c@ 374

Last change on this file since 374 was 374, checked in by coas-nagasima, 5 years ago

mbed関連を更新
シリアルドライバをmbedのHALを使うよう変更
ファイルディスクリプタの処理を更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 20.3 KB
Line 
1/*
2 * Copyright (C) 2014 BlueKitchen GmbH
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the copyright holders nor the names of
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 * 4. Any redistribution, use, or modification is done solely for
17 * personal benefit and not for any commercial purpose or for
18 * monetary gain.
19 *
20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24 * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * Please inquire about commercial licensing options at
34 * contact@bluekitchen-gmbh.com
35 *
36 */
37
38#include "btstack-config.h"
39
40#include <stdint.h>
41
42#include <btstack/hci_cmds.h>
43#include <btstack/run_loop.h>
44#include <btstack/sdp_util.h>
45
46#include <kernel.h>
47#include "kernel_cfg.h"
48#include "target_syssvc.h"
49
50#include "debug.h"
51#include "hci.h"
52#include "btstack_memory.h"
53#include "hci_dump.h"
54#include "l2cap.h"
55#include "sdp_parser.h"
56#include "sdp_client.h"
57#include "sdp_query_util.h"
58#include "sdp.h"
59#include "pan.h"
60#include "bt_main.h"
61#include "usb_hbth.h"
62
63//#define PACKET_DUMP
64
65// エラー返却用定数(-1:0xffff固定)
66#define FAILED_RFCOMM_ID_NOT_SET 0xffff
67
68#define RFCOMM_SERVER_CHANNEL 1
69static uint16_t rfcomm_channel_id = FAILED_RFCOMM_ID_NOT_SET;
70
71static int record_id = -1;
72static uint16_t bnep_l2cap_psm = 0;
73static uint32_t bnep_remote_uuid = 0;
74static uint16_t bnep_version = 0;
75static uint16_t bnep_cid = 0;
76static bool_t bnep_do_connect = false;
77
78static uint16_t sdp_bnep_l2cap_psm = 0;
79static uint16_t sdp_bnep_version = 0;
80static uint32_t sdp_bnep_remote_uuid = 0;
81
82uint8_t attribute_value[1000];
83const unsigned int attribute_value_buffer_size = sizeof(attribute_value);
84
85extern bd_addr_t remote_addr;
86
87uint8_t spp_service_buffer[120];
88uint8_t bnep_service_buffer[256];
89
90char bt_localname[] = TARGET_NAME"0000";
91
92volatile int bt_bnep_mode = 0;
93
94enum bt_state_t {
95 BT_STATE_DORMANT,
96 BT_STATE_POWER_ON,
97 BT_STATE_BNEP_QUERY,
98 BT_STATE_BNEP_WAIT,
99 BT_STATE_BNEP_QUERY_WAIT,
100 BT_STATE_CONNECTING,
101 BT_STATE_CONNECTED,
102};
103
104enum bt_state_t bt_state = BT_STATE_DORMANT;
105int bt_timer;
106
107// outgoing network packet
108const uint8_t * network_buffer;
109uint16_t network_buffer_len;
110uint16_t network_buffer_cid;
111
112/*************** PANU client routines *********************/
113
114char * get_string_from_data_element(uint8_t * element) {
115 de_size_t de_size = de_get_size_type(element);
116 int pos = de_get_header_size(element);
117 int len = 0;
118 switch (de_size) {
119 case DE_SIZE_VAR_8:
120 len = element[1];
121 break;
122 case DE_SIZE_VAR_16:
123 len = big_endian_read_16(element, 1);
124 break;
125 default:
126 break;
127 }
128 char * str = (char*)malloc(len + 1);
129 memcpy(str, &element[pos], len);
130 str[len] = '\0';
131 return str;
132}
133
134/* @section SDP parser callback
135*
136* @text The SDP parsers retrieves the BNEP PAN UUID as explained in
137* Section [on SDP BNEP Query example](#sec:sdpbnepqueryExample}.
138*/
139static void handle_sdp_client_record_complete(void)
140{
141 log_info("SDP BNEP Record complete");
142
143 // accept first entry or if we foudn a NAP and only have a PANU yet
144 if ((bnep_remote_uuid == 0) || (sdp_bnep_remote_uuid == BLUETOOTH_SERVICE_CLASS_NAP && bnep_remote_uuid == BLUETOOTH_SERVICE_CLASS_PANU)) {
145 bnep_l2cap_psm = sdp_bnep_l2cap_psm;
146 bnep_remote_uuid = sdp_bnep_remote_uuid;
147 bnep_version = sdp_bnep_version;
148 }
149}
150
151/* SDP parser callback */
152static void handle_sdp_client_query_result(sdp_query_event_t *event)
153{
154 sdp_query_attribute_value_event_t *value_event;
155 sdp_query_complete_event_t *complete_event;
156 des_iterator_t des_list_it;
157 des_iterator_t prot_it;
158 char *str;
159
160 switch (event->type) {
161 case SDP_EVENT_QUERY_ATTRIBUTE_VALUE:
162 value_event = (sdp_query_attribute_value_event_t*)event;
163
164 // Handle new SDP record
165 if (value_event->record_id != record_id) {
166 handle_sdp_client_record_complete();
167 // next record started
168 record_id = value_event->record_id;
169 log_info("SDP Record: Nr: %d", record_id);
170 }
171
172 if (value_event->attribute_length <= attribute_value_buffer_size) {
173 attribute_value[value_event->data_offset] = value_event->data;
174
175 if ((uint16_t)(value_event->data_offset + 1) == value_event->attribute_length) {
176 //printf("SDP Attribute Data:");
177 //printf_hexdump(attribute_value, value_event->attribute_length);
178
179 switch (value_event->attribute_id) {
180 case BLUETOOTH_ATTRIBUTE_SERVICE_CLASS_ID_LIST:
181 if (de_get_element_type(attribute_value) != DE_DES) break;
182 for (des_iterator_init(&des_list_it, attribute_value); des_iterator_has_more(&des_list_it); des_iterator_next(&des_list_it)) {
183 uint8_t * element = des_iterator_get_element(&des_list_it);
184 if (de_get_element_type(element) != DE_UUID) continue;
185 uint32_t uuid = de_get_uuid32(element);
186 switch (uuid) {
187 case BLUETOOTH_SERVICE_CLASS_PANU:
188 case BLUETOOTH_SERVICE_CLASS_NAP:
189 case BLUETOOTH_SERVICE_CLASS_GN:
190 log_info("SDP Attribute 0x%04x: BNEP PAN protocol UUID: %04x", value_event->attribute_id, uuid);
191 sdp_bnep_remote_uuid = uuid;
192 break;
193 default:
194 log_info("SDP Attribute 0x%04x: UUID: %04x", value_event->attribute_id, uuid);
195 break;
196 }
197 }
198 break;
199 // 0x0100 "Service Name"
200 case 0x0100:
201 // 0x0101 "Service Description"
202 case 0x0101:
203 str = get_string_from_data_element(attribute_value);
204 log_info("SDP Attribute: 0x%04x: %s", value_event->attribute_id, str);
205 free(str);
206 break;
207 case BLUETOOTH_ATTRIBUTE_PROTOCOL_DESCRIPTOR_LIST: {
208 log_info("SDP Attribute: 0x%04x", value_event->attribute_id);
209
210 for (des_iterator_init(&des_list_it, attribute_value); des_iterator_has_more(&des_list_it); des_iterator_next(&des_list_it)) {
211 uint8_t *des_element;
212 uint8_t *element;
213 uint32_t uuid;
214
215 if (des_iterator_get_type(&des_list_it) != DE_DES) continue;
216
217 des_element = des_iterator_get_element(&des_list_it);
218 des_iterator_init(&prot_it, des_element);
219 element = des_iterator_get_element(&prot_it);
220
221 if (de_get_element_type(element) != DE_UUID) continue;
222
223 uuid = de_get_uuid32(element);
224 switch (uuid) {
225 case BLUETOOTH_PROTOCOL_L2CAP:
226 if (!des_iterator_has_more(&prot_it)) continue;
227 des_iterator_next(&prot_it);
228 de_element_get_uint16(des_iterator_get_element(&prot_it), &sdp_bnep_l2cap_psm);
229 break;
230 case BLUETOOTH_PROTOCOL_BNEP:
231 if (!des_iterator_has_more(&prot_it)) continue;
232 des_iterator_next(&prot_it);
233 de_element_get_uint16(des_iterator_get_element(&prot_it), &sdp_bnep_version);
234 break;
235 default:
236 log_info("uuid 0x%04x", uuid);
237 break;
238 }
239 }
240 log_info("Summary: uuid 0x%04x, l2cap_psm 0x%04x, bnep_version 0x%04x", sdp_bnep_remote_uuid, sdp_bnep_l2cap_psm, sdp_bnep_version);
241 break;
242 }
243 default:
244 break;
245 }
246 }
247 }
248 else {
249 log_error("SDP attribute value buffer size exceeded: available %d, required %d", attribute_value_buffer_size, value_event->attribute_length);
250 }
251 break;
252
253 case SDP_EVENT_QUERY_COMPLETE:
254 handle_sdp_client_record_complete();
255 complete_event = (sdp_query_complete_event_t*)event;
256 log_error("General query done with status %d, bnep psm %04x.", complete_event->status, bnep_l2cap_psm);
257 if (bnep_l2cap_psm) {
258 bnep_do_connect = complete_event->status == 0;
259 }
260 else {
261 bnep_do_connect = false;
262 log_error("No BNEP service found");
263 }
264 if (!bnep_do_connect) {
265 // 20秒後 BNEP Query 開始
266 bt_state = BT_STATE_BNEP_QUERY_WAIT;
267 bt_timer = 20 * 1000;
268 }
269 break;
270 }
271}
272
273static void packet_handler(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)
274{
275 uint8_t event;
276 bd_addr_t event_addr;
277 uint8_t rfcomm_channel_nr;
278 uint16_t uuid_source;
279 uint16_t uuid_dest;
280 uint16_t mtu;
281
282 switch (packet_type) {
283 case HCI_EVENT_PACKET:
284 event = packet[0];
285 switch (event) {
286 case BTSTACK_EVENT_STATE:
287 /* BT Stack activated, get started */
288 if (packet[2] == HCI_STATE_WORKING) {
289 hci_send_cmd(&hci_write_local_name, bt_localname);
290 if (bt_bnep_mode == 0) {
291 // 即時 BNEP Query 開始
292 bt_state = BT_STATE_BNEP_QUERY_WAIT;
293 bt_timer = 0;
294 }
295 else {
296 bt_state = BT_STATE_BNEP_WAIT;
297 bt_timer = -1;
298 }
299 }
300 break;
301
302 case BTSTACK_EVENT_NR_CONNECTIONS_CHANGED:
303 if ((packet[2] == 0) && bnep_do_connect) {
304 bnep_do_connect = false;
305 /* Create BNEP connection */
306 bnep_connect(NULL, &remote_addr, bnep_l2cap_psm, bnep_remote_uuid);
307 }
308 break;
309
310 case HCI_EVENT_COMMAND_COMPLETE:
311 if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_read_bd_addr)) {
312 reverse_bd_addr(&packet[6], event_addr);
313 log_info("BD-ADDR: %s", bd_addr_to_str(event_addr));
314
315 snprintf(bt_localname, sizeof(bt_localname), TARGET_NAME"%04x", ((event_addr[4] << 8) | event_addr[5]));
316 gap_set_local_name(bt_localname);
317 break;
318 }
319 if (HCI_EVENT_IS_COMMAND_COMPLETE(packet, hci_write_local_name)) {
320 gap_discoverable_control(1);
321 break;
322 }
323 break;
324
325 case HCI_EVENT_LINK_KEY_REQUEST:
326 // deny link key request
327 log_info("Link key request");
328 reverse_bd_addr(&packet[2], event_addr);
329 hci_send_cmd(&hci_link_key_request_negative_reply, &event_addr);
330 break;
331
332 case HCI_EVENT_PIN_CODE_REQUEST:
333 // inform about pin code request
334 log_info("Pin code request - using '0000'");
335 reverse_bd_addr(&packet[2], event_addr);
336 hci_send_cmd(&hci_pin_code_request_reply, &event_addr, 4, "0000");
337 break;
338
339 case HCI_EVENT_USER_CONFIRMATION_REQUEST:
340 // inform about user confirmation request
341 log_info("HCI User Confirmation Request with numeric value '%06u'", little_endian_read_32(packet, 8));
342 log_info("HCI User Confirmation Auto accept");
343 break;
344
345 case RFCOMM_EVENT_INCOMING_CONNECTION:
346 // data: event (8), len(8), address(48), channel (8), rfcomm_cid (16)
347 reverse_bd_addr(&packet[2], event_addr);
348 rfcomm_channel_nr = packet[8];
349 rfcomm_channel_id = little_endian_read_16(packet, 9);
350 log_info("RFCOMM channel %u requested for %s", rfcomm_channel_nr, bd_addr_to_str(event_addr));
351 rfcomm_accept_connection_internal(rfcomm_channel_id);
352 break;
353
354 case RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE:
355 // data: event(8), len(8), status (8), address (48), server channel(8), rfcomm_cid(16), max frame size(16)
356 if (packet[2]) {
357 log_info("RFCOMM channel open failed, status %u", packet[2]);
358 }
359 else {
360 rfcomm_channel_id = little_endian_read_16(packet, 12);
361 mtu = little_endian_read_16(packet, 14);
362 log_info("RFCOMM channel open succeeded. New RFCOMM Channel ID %u, max frame size %u", rfcomm_channel_id, mtu);
363 }
364 break;
365
366 case RFCOMM_EVENT_CHANNEL_CLOSED:
367 log_info("RFCOMM channel closed");
368 rfcomm_channel_id = 0;
369 break;
370
371 case BNEP_EVENT_OPEN_CHANNEL_COMPLETE:
372 if (packet[2]) {
373 log_info("BNEP channel open failed, status %02x", packet[2]);
374
375 // 30秒後 BNEP Query 開始
376 bt_state = BT_STATE_BNEP_QUERY_WAIT;
377 bt_timer = 30 * 1000;
378 }
379 else {
380 // data: event(8), len(8), status (8), bnep source uuid (16), bnep destination uuid (16), remote_address (48)
381 bnep_cid = little_endian_read_16(packet, 3);
382 uuid_source = little_endian_read_16(packet, 5);
383 uuid_dest = little_endian_read_16(packet, 7);
384 mtu = little_endian_read_16(packet, 9);
385 //reverse_bd_addr(&packet[11], remote_addr);
386 memcpy(&remote_addr, &packet[11], sizeof(bd_addr_t));
387 log_info("BNEP connection open succeeded to %s source UUID 0x%04x dest UUID: 0x%04x, max frame size %u", bd_addr_to_str(event_addr), uuid_source, uuid_dest, mtu);
388 /* Setup network interface */
389 btstack_network_up(bnep_cid, (uint8_t *)hci_local_bd_addr(), (uint8_t *)remote_addr);
390 log_info("Network Interface %s activated", btstack_network_get_name(bnep_cid));
391
392 bt_state = BT_STATE_CONNECTED;
393 bt_timer = -1;
394 }
395 break;
396
397 case BNEP_EVENT_CHANNEL_TIMEOUT:
398 log_info("BNEP channel timeout! Channel will be closed");
399 break;
400
401 case BNEP_EVENT_CHANNEL_CLOSED:
402 bnep_cid = little_endian_read_16(packet, 2);
403 bt_channel_closed(bnep_cid);
404
405 // 30秒後 BNEP Query 開始
406 bt_state = BT_STATE_BNEP_QUERY_WAIT;
407 bt_timer = 30 * 1000;
408 break;
409
410 case BNEP_EVENT_READY_TO_SEND:
411 bnep_cid = little_endian_read_16(packet, 2);
412 bt_send_packet(bnep_cid);
413 break;
414
415 default:
416 break;
417 }
418 break;
419
420 case RFCOMM_DATA_PACKET:
421 // loopback
422 if (rfcomm_channel_id) {
423 int err = rfcomm_send_internal(rfcomm_channel_id, packet, size);
424 if (err) {
425 log_error("rfcomm_send_internal -> error %d", err);
426 }
427 }
428 break;
429
430 case BNEP_DATA_PACKET:
431 bt_recv_packet(channel, packet, size);
432 break;
433
434 default:
435 break;
436 }
437}
438
439/*
440 * @section Network packet handler
441 *
442 * @text A pointer to the network packet is stored and a BNEP_EVENT_CAN_SEND_NOW requested
443 */
444
445 /* LISTING_START(networkPacketHandler): Network Packet Handler */
446static void network_send_packet_callback(uint16_t bnep_cid, const uint8_t * packet, uint16_t size) {
447 if ((bnep_cid == 0) || (network_buffer_len > 0)) {
448#ifdef PACKET_DUMP
449 int len = size;
450 printf("DROP %04x %d ", bnep_cid, size);
451 if (len > 128)
452 len = 128;
453 printf_hexdump(packet, len);
454#endif
455 if (network_buffer_len > 0) {
456 network_buffer_len = 0;
457 btstack_network_packet_sent(network_buffer_cid);
458 }
459 }
460
461 network_buffer_cid = bnep_cid;
462 network_buffer = packet;
463 network_buffer_len = size;
464}
465
466void bt_init(void)
467{
468 const hci_transport_t *transport;
469 bt_control_t * control;
470 hci_uart_config_t * config;
471 remote_device_db_t * remote_db;
472 service_record_item_t *spp_service_record_item;
473 service_record_item_t *bnep_service_record_item;
474
475 btstack_network_init(&network_send_packet_callback);
476
477 //hci_dump_open("", HCI_DUMP_PACKETLOGGER);
478
479 // start with BTstack init - especially configure HCI Transport
480 btstack_memory_init();
481 run_loop_init(RUN_LOOP_EMBEDDED);
482
483 /* Initialize HCI */
484 transport = hci_transport_usb_instance();
485 control = NULL;
486 config = NULL;
487 remote_db = (remote_device_db_t *)&remote_device_db_memory;
488 hci_init(transport, config, control, remote_db);
489 hci_set_class_of_device(0x820300/*0x820810*/);
490
491 /* Initialize L2CAP */
492 l2cap_init();
493 l2cap_register_packet_handler(packet_handler);
494
495 /* Initialise SDP, create record for SPP and register with SDP */
496 sdp_init();
497
498 /* Initialize RFCOMM */
499 rfcomm_init();
500 rfcomm_register_packet_handler(packet_handler);
501 rfcomm_register_service_internal(NULL, RFCOMM_SERVER_CHANNEL, 0xffff); // reserved channel, mtu=100
502
503 /* Initialise BNEP */
504 bnep_init();
505 bnep_register_packet_handler(packet_handler);
506 if (bt_bnep_mode == 0) {
507 bnep_register_service(NULL, BLUETOOTH_SERVICE_CLASS_PANU, BNEP_MTU_MIN); /* Minimum L2CAP MTU for bnep is 1691 bytes */
508 }
509 else {
510 bnep_register_service(NULL, BLUETOOTH_SERVICE_CLASS_NAP, BNEP_MTU_MIN); /* Minimum L2CAP MTU for bnep is 1691 bytes */
511 }
512
513 memset(spp_service_buffer, 0, sizeof(spp_service_buffer));
514 memset(bnep_service_buffer, 0, sizeof(bnep_service_buffer));
515
516 // サービス定義
517 spp_service_record_item = (service_record_item_t *)spp_service_buffer;
518 bnep_service_record_item = (service_record_item_t *)bnep_service_buffer;
519
520 sdp_create_spp_service((uint8_t*)&spp_service_record_item->service_record, 1, "RX SPP");
521 de_dump_data_element((uint8_t*)spp_service_record_item->service_record);
522 log_info("SSP SDP service buffer size: %u", (uint16_t)(sizeof(service_record_item_t) + de_get_len((uint8_t*)spp_service_record_item->service_record)));
523 sdp_register_service_internal(NULL, spp_service_record_item);
524
525 if (bt_bnep_mode == 0) {
526 pan_create_panu_service((uint8_t*)&bnep_service_record_item->service_record, "RX PANU", "RX PANU", BNEP_SECURITY_NONE);
527 de_dump_data_element((uint8_t*)bnep_service_record_item->service_record);
528 log_info("PANU SDP service buffer size: %u", (uint16_t)(sizeof(service_record_item_t) + de_get_len((uint8_t*)bnep_service_record_item->service_record)));
529 }
530 else {
531 pan_create_nap_service((uint8_t*)&bnep_service_record_item->service_record, "RX NAP", "RX NAP", BNEP_SECURITY_NONE,
532 PAN_NET_ACCESS_TYPE_100MB_ETHERNET, 0x0001312D0/*10Mb/sec*/, NULL, NULL);
533 de_dump_data_element((uint8_t*)bnep_service_record_item->service_record);
534 log_info("NAP SDP service buffer size: %u", (uint16_t)(sizeof(service_record_item_t) + de_get_len((uint8_t*)bnep_service_record_item->service_record)));
535 }
536 sdp_register_service_internal(NULL, bnep_service_record_item);
537
538 // Secure Simple Pairing configuration -> just works
539 hci_ssp_set_enable(1);
540 hci_ssp_set_io_capability(SSP_IO_CAPABILITY_NO_INPUT_NO_OUTPUT);
541 hci_ssp_set_auto_accept(1);
542
543 /* Turn on the device */
544 hci_power_control(HCI_POWER_ON);
545
546 /* Initialise SDP */
547 sdp_parser_init();
548 sdp_parser_register_callback(handle_sdp_client_query_result);
549
550 bt_state = BT_STATE_POWER_ON;
551 bt_timer = -1;
552}
553
554void bt_process(void)
555{
556 if (bt_state != BT_STATE_DORMANT) {
557 run_loop_execute();
558 bt_send_packet(0xffff);
559 }
560
561 if (bt_timer != 0)
562 return;
563
564 switch (bt_state) {
565 case BT_STATE_BNEP_QUERY_WAIT:
566 /* Send a general query for BNEP Protocol ID */
567 log_info("Start SDP BNEP query.");
568 sdp_general_query_for_uuid(remote_addr, BLUETOOTH_PROTOCOL_BNEP);
569
570 bt_state = BT_STATE_BNEP_QUERY;
571 bt_timer = -1;
572 break;
573 default:
574 bt_timer = -1;
575 break;
576 }
577}
578
579int bt_can_send_packet(void)
580{
581 return network_buffer_len == 0;
582}
583
584void bt_send_packet(uint16_t bnep_cid)
585{
586 if (network_buffer_len > 0) {
587 if (network_buffer_cid == 0) {
588 network_buffer_len = 0;
589 btstack_network_packet_sent(network_buffer_cid);
590 return;
591 }
592 /* Check for parked network packets and send it out now */
593 if (bnep_can_send_packet_now(network_buffer_cid)) {
594 uint16_t len = network_buffer_len;
595#ifdef PACKET_DUMP
596 printf("ETH %u => ", len);
597 if (len > 128)
598 len = 128;
599 printf_hexdump(network_buffer, len);
600#endif
601 // この関数はbnep_sendから再帰呼び出しされるので、
602 // bnep_sendを呼び出すより前に送信パケットなし状態にします。
603 network_buffer_len = 0;
604 bnep_send(network_buffer_cid, (uint8_t*)network_buffer, len);
605 btstack_network_packet_sent(network_buffer_cid);
606 }
607 }
608}
609
610void bt_recv_packet(uint16_t bnep_cid, const uint8_t * packet, uint16_t size)
611{
612#ifdef PACKET_DUMP
613 int len = size;
614 printf("ETH %d <= ", size);
615 if (len > 128)
616 len = 128;
617 printf_hexdump(packet, len);
618#endif
619 btstack_network_process_packet(bnep_cid, packet, size);
620}
621
622void bt_channel_closed(uint16_t bnep_cid)
623{
624 log_info("BNEP channel closed");
625 btstack_network_down(bnep_cid);
626 if ((network_buffer_len > 0) && (network_buffer_cid == bnep_cid)) {
627 network_buffer_len = 0;
628 btstack_network_packet_sent(network_buffer_cid);
629 }
630}
631
632void bt_terminate(void)
633{
634 hci_close();
635
636 bt_state = BT_STATE_DORMANT;
637 bt_timer = -1;
638}
639
640void bt_task_on_start(struct task_if_t *task, ID tskid)
641{
642}
643
644void bt_task_on_end(struct task_if_t *task)
645{
646}
647
648int bt_task_get_timer(struct task_if_t *task)
649{
650 return bt_timer;
651}
652
653void bt_task_progress(struct task_if_t *task, int elapse)
654{
655 if (bt_timer == -1)
656 return;
657
658 bt_timer -= elapse;
659 if (bt_timer < 0)
660 bt_timer = 0;
661}
662
663void bt_task_process(struct task_if_t *task, enum task_event_t event)
664{
665 extern void hal_tick_handler();
666
667 switch (event & ~TASK_EVENT_TICK) {
668 case TASK_EVENT_START:
669 bt_init();
670 break;
671 case TASK_EVENT_TERMINATE:
672 bt_terminate();
673 break;
674 case TASK_EVENT_WAKEUP:
675 case TASK_EVENT_TIMEOUT:
676 if (event & TASK_EVENT_TICK)
677 hal_tick_handler();
678 bt_process();
679 break;
680 }
681}
682
683struct task_if_t bt_task = {
684 bt_task_on_start,
685 bt_task_on_end,
686 bt_task_get_timer,
687 bt_task_progress,
688 bt_task_process,
689};
Note: See TracBrowser for help on using the repository browser.