source: asp3_tinet_ecnl_rx/trunk/bnep_bridge/src/if_btusb.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: 17.0 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
5 * Tomakomai National College of Technology, JAPAN
6 * Copyright (C) 2014-2017 by Cores Co., Ltd. Japan
7 *
8 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
9 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
10 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
11 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
12 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
13 * スコード中に含まれていること.
14 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
15 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
16 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
17 * の無保証規定を掲載すること.
18 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
19 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
20 * と.
21 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
22 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
23 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
24 * 報告すること.
25 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
26 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
27 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
28 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
29 * 免責すること.
30 *
31 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
33 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
34 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
35 * の責任を負わない.
36 *
37 * @(#) $Id$
38 */
39
40/*
41 * Copyright (c) 1995, David Greenman
42 * All rights reserved.
43 *
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
46 * are met:
47 * 1. Redistributions of source code must retain the above copyright
48 * notice unmodified, this list of conditions, and the following
49 * disclaimer.
50 * 2. Redistributions in binary form must reproduce the above copyright
51 * notice, this list of conditions and the following disclaimer in the
52 * documentation and/or other materials provided with the distribution.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
56 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE.
65 *
66 * $FreeBSD: src/sys/i386/isa/if_ed.c,v 1.148.2.4 1999/09/25 13:08:18 nyan Exp $
67 */
68
69#define __BTSTACK_FILE__ "if_btusb.c"
70
71#define CAST(type, val) ((type)(val))
72
73#include <kernel.h>
74#include <sil.h>
75#include <t_syslog.h>
76#include "kernel_cfg.h"
77#include "kernel/kernel_impl.h"
78#include "btstack/utils.h"
79#include "bt_main.h"
80#include "usb_hbth.h"
81//#include "hal_cpu.h"
82//#include "hal_tick.h"
83#include "hci.h"
84#include "debug.h"
85#include "main.h"
86#include "if_rx62n.h"
87#include "if_btusb.h"
88
89#include <string.h>
90
91#ifdef _MSC_VER
92#include <stdlib.h>
93#endif
94
95#ifndef TMO_IF_BTUSB_GET_NET_BUF
96#define TMO_IF_BTUSB_GET_NET_BUF ULONG_C(1000000) /* [us] */
97#endif
98
99static void (*btstack_network_send_packet_callback)(uint16_t bnep_cid, const uint8_t * packet, uint16_t size);
100
101int btstack_network_output_spos = 0;
102int btstack_network_output_rpos = 0;
103T_NET_BUF *btstack_network_output[NUM_IF_BTUSB_TXBUF];
104
105/*
106 * ネットワークインタフェースに依存するソフトウェア情報
107 */
108
109typedef struct t_btusb_softc {
110 uint16_t bnep_cid;
111 bd_addr_t bd_addr;
112 char bnep_name[10];
113} T_BTUSB_SOFTC;
114
115/*
116 * ネットワークインタフェースのソフトウェア情報
117 */
118
119/* ネットワークインタフェースに依存するソフトウェア情報 */
120
121T_BTUSB_SOFTC btusb_softc[MAX_PAN_CONNECTIONS];
122static int connection_count;
123
124
125/*
126 * 局所変数
127 */
128
129static void btusb_stop (T_BTUSB_SOFTC *sc);
130static void btusb_init_sub (T_IF_SOFTC *ic);
131
132#ifdef SUPPORT_INET6
133
134static uint32_t ds_crc (uint8_t *addr);
135static void ds_getmcaf (T_IF_SOFTC *ic, uint32_t *mcaf);
136
137/*
138 * ds_crc -- イーサネットアドレスの CRC を計算する。
139 */
140
141#define POLYNOMIAL 0x04c11db6
142
143static uint32_t
144ds_crc (uint8_t *addr)
145{
146 uint32_t crc = ULONG_C(0xffffffff);
147 int_t carry, len, bit;
148 uint8_t byte;
149
150 for (len = ETHER_ADDR_LEN; len -- > 0; ) {
151 byte = *addr ++;
152 for (bit = 8; bit -- > 0; ) {
153 carry = ((crc & ULONG_C(0x80000000)) ? 1 : 0) ^ (byte & UINT_C(0x01));
154 crc <<= 1;
155 byte >>= 1;
156 if (carry)
157 crc = (crc ^ POLYNOMIAL) | carry;
158 }
159 }
160 return crc;
161}
162
163#undef POLYNOMIAL
164
165/*
166 * ds_getmcaf -- マルチキャストアドレスのリストからマルチキャストアドレス
167 * フィルタを計算する。
168 */
169
170static void
171ds_getmcaf (T_IF_SOFTC *ic, uint32_t *mcaf)
172{
173 uint32_t count, index;
174 uint8_t *af = (uint8_t*)mcaf;
175
176 mcaf[0] = mcaf[1] = 0;
177
178 for (count = MAX_IF_MADDR_CNT; count -- > 0; ) {
179 index = ds_crc(ic->maddrs[count].lladdr) >> 26;
180 af[index >> 3] |= 1 << (index & 7);
181 }
182}
183
184/*
185 * btusb_setrcr -- 受信構成レジスタ (RCR) を設定する。
186 */
187
188static void
189btusb_setrcr (T_IF_SOFTC *ic)
190{
191}
192
193/*
194 * btusb_addmulti -- マルチキャストアドレスを追加する。
195 */
196
197ER
198btusb_addmulti (T_IF_SOFTC *ic)
199{
200 btusb_setrcr(ic);
201 return E_OK;
202}
203
204#endif /* of #ifdef SUPPORT_INET6 */
205
206T_BTUSB_SOFTC *get_softc(T_IF_SOFTC *ic, uint16_t bnep_cid)
207{
208 T_BTUSB_SOFTC *sc = if_softc.btusb;
209
210 for (int i = 0; i < MAX_PAN_CONNECTIONS; i++) {
211 if (sc->bnep_cid == bnep_cid)
212 return sc;
213 sc++;
214 }
215
216 return NULL;
217}
218
219void btstack_network_init(void (*send_packet_callback)(uint16_t bnep_cid, const uint8_t * packet, uint16_t size))
220{
221 btstack_network_send_packet_callback = send_packet_callback;
222}
223
224void btstack_network_up(uint16_t bnep_cid, bd_addr_t local_addr, bd_addr_t remote_addr)
225{
226 T_BTUSB_SOFTC *sc = get_softc(&if_softc, 0);
227
228 if (sc == NULL) {
229 log_info("btstack_network_up no space");
230 return;
231 }
232
233 sc->bnep_cid = bnep_cid;
234
235 /* MACアドレスを更新 */
236 memcpy(if_softc.ifaddr.lladdr, local_addr, sizeof(if_softc.ifaddr.lladdr));
237
238 memcpy(sc->bd_addr, remote_addr, sizeof(sc->bd_addr));
239
240 snprintf(sc->bnep_name, sizeof(sc->bnep_name), "BNEP%04x", bnep_cid);
241
242 connection_count++;
243 if (connection_count == 1)
244 ether_set_link_up(&if_softc);
245}
246
247const char * btstack_network_get_name(uint16_t bnep_cid)
248{
249 T_BTUSB_SOFTC *sc = get_softc(&if_softc, bnep_cid);
250
251 if (sc == NULL) {
252 return "???";
253 }
254
255 return sc->bnep_name;
256}
257
258int btstack_network_down(uint16_t bnep_cid)
259{
260 T_BTUSB_SOFTC *sc = get_softc(&if_softc, bnep_cid);
261
262 if (sc == NULL) {
263 log_info("btstack_network_down(bnep_cid=%d)", bnep_cid);
264 }
265
266 connection_count--;
267 if (connection_count == 0)
268 ether_set_link_down(&if_softc);
269
270 sc->bnep_cid = 0;
271
272 return 0;
273}
274
275/*
276 * btusb_stop -- ネットワークインタフェースを停止する。
277 *
278 * 注意: NIC 割り込み禁止状態で呼び出すこと。
279 */
280
281static void
282btusb_stop (T_BTUSB_SOFTC *sc)
283{
284}
285
286void btusb_bus_init() {}
287void btusb_inter_init() {}
288
289/*
290 * btusb_init_sub -- ネットワークインタフェースの初期化
291 *
292 * 注意: NIC 割り込み禁止状態で呼び出すこと。
293 */
294
295static void
296btusb_init_sub (T_IF_SOFTC *ic)
297{
298 /* ターゲット依存部の割込み初期化 */
299 btusb_inter_init();
300}
301
302/*
303 * btusb_reset -- ネットワークインタフェースをリセットする。
304 */
305
306void
307btusb_reset (T_IF_SOFTC *ic)
308{
309 T_BTUSB_SOFTC *sc = if_softc.btusb;
310
311 NET_COUNT_ETHER_NIC(net_count_ether_nic[NC_ETHER_NIC_RESETS], 1);
312
313 for (int i = 0; i < MAX_PAN_CONNECTIONS; i++) {
314 if (sc->bnep_cid != 0)
315 btusb_stop(sc);
316 sc++;
317 }
318
319 btusb_init_sub(ic);
320}
321
322/*
323 * btusb_watchdog -- ネットワークインタフェースのワッチドッグタイムアウト
324 */
325
326void
327btusb_watchdog (T_IF_SOFTC *ic)
328{
329 btusb_reset(ic);
330}
331
332/*
333 * btusb_probe -- ネットワークインタフェースの検出
334 */
335
336void
337btusb_probe (T_IF_SOFTC *ic)
338{
339 ic->btusb = btusb_softc;
340
341 /* ターゲット依存部のバスの初期化 */
342 btusb_bus_init();
343}
344
345/*
346 * btusb_init -- ネットワークインタフェースの初期化
347 */
348
349void
350btusb_init (T_IF_SOFTC *ic)
351{
352 /* btusb_init 本体を呼び出す。*/
353 btusb_init_sub(ic);
354}
355
356/*
357 * btstack_network_process_packet -- btstackからフレームの受信
358 */
359
360void
361btstack_network_process_packet(uint16_t bnep_cid, const uint8_t * packet, uint16_t size)
362{
363 T_BTUSB_SOFTC *sc = get_softc(&if_softc, bnep_cid);
364 T_NET_BUF *input = NULL;
365 uint16_t align;
366 uint8_t *dst;
367 ER error;
368
369 if (sc == NULL) {
370 log_info("btstack_network_process_packet(bnep_cid=%d)", bnep_cid);
371 return;
372 }
373
374 /*
375 * +-----------+--------+---------+---------+
376 * | Ehter HDR | IP HDR | TCP HDR | TCP SDU |
377 * +-----------+--------+---------+---------+
378 * 14 20 20 n
379 * <----------------- len ---------------->
380 * ^
381 * t_net_buf で 4 オクテット境界にアラインされている。
382 *
383 * tcp_input と udp_input では、擬似ヘッダと SDU でチェックサムを
384 * 計算するが、n が 4 オクテット境界になるように SDU の後ろに 0 を
385 * パッディングする。その分を考慮して net_buf を獲得しなければならない。
386 */
387 align = ((((size - sizeof(T_IF_HDR)) + 3) >> 2) << 2) + sizeof(T_IF_HDR);
388
389 if ((error = tget_net_buf(&input, align, TMO_IF_BTUSB_GET_NET_BUF)) == E_OK && input != NULL) {
390 dst = input->buf + IF_ETHER_NIC_HDR_ALIGN;
391 memcpy(dst, (void *)packet, size);
392
393 rx62n_start(&if_softc, input);
394
395 rel_net_buf(input);
396 }
397
398 /* BMEP側にも転送(マルチキャストと宛先MACアドレスがあるもの) */
399 if ((error = tget_net_buf(&input, align, TMO_IF_BTUSB_GET_NET_BUF)) == E_OK && input != NULL) {
400 dst = input->buf + IF_ETHER_NIC_HDR_ALIGN;
401 memcpy(dst, (void *)packet, size);
402
403 int rel = btusb_start(&if_softc, input);
404 if (rel) {
405 rel_net_buf(input);
406 }
407 }
408}
409
410/*
411 * btusb_start -- 送信フレームをバッファリングする。
412 */
413
414int
415btusb_start (T_IF_SOFTC *ic, T_NET_BUF *output)
416{
417 T_BTUSB_SOFTC *sc = ic->btusb;
418 T_ETHER_HDR *eth = GET_ETHER_HDR(output);
419 bool_t send = (btstack_network_output_spos == btstack_network_output_rpos)
420 && (btstack_network_output[btstack_network_output_rpos] == NULL);
421 bool_t enqueue = false;
422
423 if ((btstack_network_send_packet_callback == NULL)
424 || ((btstack_network_output_spos == btstack_network_output_rpos)
425 && (btstack_network_output[btstack_network_output_rpos] != NULL))) {
426 sig_sem(if_softc.semid_rxb_ready);
427 return 1;
428 }
429
430 output->conn_pos = 0;
431
432 if (send) {
433 while (output->conn_pos < MAX_PAN_CONNECTIONS) {
434 if ((sc->bnep_cid != 0)
435 && ((*eth->dhost & ETHER_MCAST_ADDR) || memcmp(eth->dhost, sc->bd_addr, sizeof(eth->dhost)) == 0)) {
436 enqueue = true;
437 break;
438 }
439 output->conn_pos++;
440 sc++;
441 }
442 }
443 else
444 enqueue = true;
445
446 if (enqueue) {
447 loc_cpu();
448
449 btstack_network_output[btstack_network_output_spos] = output;
450 btstack_network_output_spos++;
451 if (btstack_network_output_spos == NUM_IF_BTUSB_TXBUF)
452 btstack_network_output_spos = 0;
453
454 unl_cpu();
455 }
456 else {
457 sig_sem(if_softc.semid_rxb_ready);
458 return 1;
459 }
460
461 if (!send)
462 return 0;
463
464 btstack_network_send_packet_callback(sc->bnep_cid, output->buf, output->len);
465
466 return 0;
467}
468
469/*
470 * btstack_network_packet_sent -- バッファした送信フレームの送信が完了する。
471 */
472
473void
474btstack_network_packet_sent(uint16_t bnep_cid)
475{
476 T_NET_BUF *output = btstack_network_output[btstack_network_output_rpos];
477 T_BTUSB_SOFTC *sc;
478 T_ETHER_HDR *eth;
479
480 while (output != NULL) {
481 sc = &if_softc.btusb[output->conn_pos];
482 eth = GET_ETHER_HDR(output);
483
484 for (;;) {
485 output->conn_pos++;
486 sc++;
487 if (output->conn_pos >= MAX_PAN_CONNECTIONS)
488 break;
489 if ((sc->bnep_cid != 0)
490 && ((*eth->dhost & ETHER_MCAST_ADDR) || memcmp(eth->dhost, sc->bd_addr, sizeof(eth->dhost)) == 0)) {
491 btstack_network_send_packet_callback(sc->bnep_cid, output->buf, output->len);
492 return;
493 }
494 }
495
496 rel_net_buf(output);
497
498 loc_cpu();
499
500 btstack_network_output[btstack_network_output_rpos] = NULL;
501 btstack_network_output_rpos++;
502 if (btstack_network_output_rpos == NUM_IF_BTUSB_TXBUF)
503 btstack_network_output_rpos = 0;
504
505 output = btstack_network_output[btstack_network_output_rpos];
506
507 unl_cpu();
508
509 sig_sem(if_softc.semid_rxb_ready);
510 }
511}
512
513static void dummy_handler(void) {};
514static void(*tick_handler)(void) = &dummy_handler;
515void hal_tick_handler();
516
517void hal_tick_init(void)
518{
519 // timer_regist_userfunc(hal_tick_handler);
520}
521
522void hal_tick_set_handler(void(*handler)(void))
523{
524 if (handler == NULL) {
525 tick_handler = &dummy_handler;
526 return;
527 }
528 tick_handler = handler;
529}
530
531int hal_tick_get_tick_period_in_ms(void)
532{
533 return 1;
534}
535
536void hal_tick_handler()
537{
538 tick_handler();
539}
540
541uint32_t hal_time_ms(void)
542{
543 SYSTIM time;
544 get_tim(&time);
545 return time / 1000;
546}
547
548void hal_cpu_disable_irqs(void)
549{
550 loc_cpu();
551}
552
553void hal_cpu_enable_irqs(void)
554{
555 unl_cpu();
556}
557
558int btstack_sleep = 0;
559
560void hal_cpu_enable_irqs_and_sleep(void)
561{
562 unl_cpu();
563 btstack_sleep = 1;
564}
565
566//#define PACKET_DUMP
567static void usb_dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size);
568static void(*usb_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size) = usb_dummy_handler;
569
570void usb_bt_callback(uint8_t event_type, uint8_t *data, int size)
571{
572#ifdef PACKET_DUMP
573 int len = size;
574
575 switch (event_type) {
576 case HCI_EVENT_PACKET:
577 printf("EVT <= ");
578 break;
579 case HCI_ACL_DATA_PACKET:
580 printf("ACL <= ");
581 break;
582 default:
583 printf("??? <= ");
584 break;
585 }
586
587 if (len > 256)
588 len = 256;
589 printf_hexdump(data, len);
590#endif
591 usb_packet_handler(event_type, data, size);
592}
593
594static void usb_init(const void *transport_config)
595{
596
597}
598
599static int usb_open(void *transport_config)
600{
601 return 0;
602}
603
604static int usb_close(void *transport_config)
605{
606 return 0;
607}
608
609static int usb_send_packet(uint8_t packet_type, uint8_t *packet, int size)
610{
611 int r;
612#ifdef PACKET_DUMP
613 int len = size;
614 if (len > 256)
615 len = 256;
616#endif
617 switch (packet_type) {
618 case HCI_COMMAND_DATA_PACKET:
619#ifdef PACKET_DUMP
620 printf("CMD => ");
621 printf_hexdump(packet, len);
622#endif
623 r = bt_usb_hbth_control_write(packet, size);
624 if (r < 0 || r != size) {
625 log_error("Error submitting control transfer %d", r);
626 return -1;
627 }
628 return 0;
629 case HCI_ACL_DATA_PACKET:
630#ifdef PACKET_DUMP
631 printf("ACL => ");
632 printf_hexdump(packet, len);
633#endif
634 if (size >= 1024)
635 printf("HCI_ACL_DATA_PACKET size=%d\n", size);
636 r = bt_usb_hbth_bulk_write(packet, size);
637 if (r < 0) {
638 log_error("Error submitting data transfer, %d", r);
639 return -1;
640 }
641 return 0;
642 default:
643 return -1;
644 }
645}
646
647static void usb_register_packet_handler(void(*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size))
648{
649 log_info("registering packet handler.");
650 usb_packet_handler = handler;
651}
652
653static const char * usb_get_transport_name(void){
654 return "USB";
655}
656
657static void usb_dummy_handler(uint8_t packet_type, uint8_t *packet, uint16_t size)
658{
659}
660
661static int usb_acl_out_active = 0;
662static int usb_command_active = 0;
663
664static int usb_can_send_packet_now(uint8_t packet_type)
665{
666 switch (packet_type) {
667 case HCI_COMMAND_DATA_PACKET:
668 return !usb_command_active;
669 case HCI_ACL_DATA_PACKET:
670 return !usb_acl_out_active;
671 default:
672 return 0;
673 }
674}
675
676// single instance
677static const hci_transport_t hci_transport_usb =
678{
679 /*.open =*/ usb_open,
680 /*.close =*/ usb_close,
681 /*.send_packet =*/ usb_send_packet,
682 /*.register_packet_handler =*/ usb_register_packet_handler,
683 /*.get_transport_name =*/ usb_get_transport_name,
684 /*.set_baudrate =*/ NULL,
685 /*.can_send_packet_now =*/ NULL
686};
687
688// get usb singleton
689const hci_transport_t *hci_transport_usb_instance()
690{
691 return &hci_transport_usb;
692}
Note: See TracBrowser for help on using the repository browser.