bt_netdev.c 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424
  1. /****************************************************************************
  2. * wireless/bluetooth/bt_netdev.c
  3. * Network stack interface
  4. *
  5. * Licensed to the Apache Software Foundation (ASF) under one or more
  6. * contributor license agreements. See the NOTICE file distributed with
  7. * this work for additional information regarding copyright ownership. The
  8. * ASF licenses this file to you under the Apache License, Version 2.0 (the
  9. * "License"); you may not use this file except in compliance with the
  10. * License. You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  16. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  17. * License for the specific language governing permissions and limitations
  18. * under the License.
  19. *
  20. ****************************************************************************/
  21. /****************************************************************************
  22. * Included Files
  23. ****************************************************************************/
  24. #include <nuttx/config.h>
  25. #include <stdint.h>
  26. #include <stdbool.h>
  27. #include <time.h>
  28. #include <string.h>
  29. #include <errno.h>
  30. #include <assert.h>
  31. #include <debug.h>
  32. #include <arpa/inet.h>
  33. #include <nuttx/arch.h>
  34. #include <nuttx/irq.h>
  35. #include <nuttx/kmalloc.h>
  36. #include <nuttx/signal.h>
  37. #include <nuttx/wdog.h>
  38. #include <nuttx/wqueue.h>
  39. #include <nuttx/mm/iob.h>
  40. #include <nuttx/net/arp.h>
  41. #include <nuttx/net/netdev.h>
  42. #include <nuttx/net/radiodev.h>
  43. #include <nuttx/net/bluetooth.h>
  44. #include <nuttx/net/sixlowpan.h>
  45. #include <nuttx/wireless/bluetooth/bt_core.h>
  46. #include <netpacket/bluetooth.h>
  47. #include "bt_hcicore.h"
  48. #ifdef CONFIG_WIRELESS_BLUETOOTH_HOST
  49. #include "bt_l2cap.h"
  50. #include "bt_conn.h"
  51. #endif
  52. #include "bt_ioctl.h"
  53. #if defined(CONFIG_NET_6LOWPAN) || defined(CONFIG_NET_BLUETOOTH)
  54. /****************************************************************************
  55. * Pre-processor Definitions
  56. ****************************************************************************/
  57. /* If processing is not done at the interrupt level, then work queue support
  58. * is required.
  59. */
  60. #if !defined(CONFIG_SCHED_WORKQUEUE)
  61. # error Work queue support is required in this configuration (CONFIG_SCHED_WORKQUEUE)
  62. #endif
  63. /* Frame size */
  64. #if BLUETOOTH_MAX_FRAMELEN > CONFIG_IOB_BUFSIZE
  65. # error CONFIG_IOB_BUFSIZE to small for max Bluetooth frame
  66. #endif
  67. /* TX poll delay = 1 seconds.
  68. * CLK_TCK is the number of clock ticks per second
  69. */
  70. #define TXPOLL_WDDELAY (1*CLK_TCK)
  71. /****************************************************************************
  72. * Private Types
  73. ****************************************************************************/
  74. /* This is our private version of the MAC callback structure */
  75. struct btnet_callback_s
  76. {
  77. /* This holds the information visible to the MAC layer */
  78. FAR struct btnet_driver_s *bc_priv; /* Our priv data */
  79. };
  80. /* The btnet_driver_s encapsulates all state information for a single
  81. * Bluetooth device interface.
  82. */
  83. struct btnet_driver_s
  84. {
  85. /* This holds the information visible to the NuttX network */
  86. struct radio_driver_s bd_dev; /* Interface understood by the network */
  87. /* Cast compatible with struct btnet_driver_s */
  88. /* For internal use by this driver */
  89. sem_t bd_exclsem; /* Exclusive access to struct */
  90. bool bd_bifup; /* true:ifup false:ifdown */
  91. struct wdog_s bd_txpoll; /* TX poll timer */
  92. struct work_s bd_pollwork; /* Defer poll work to the work queue */
  93. #ifdef CONFIG_WIRELESS_BLUETOOTH_HOST
  94. struct bt_conn_cb_s bd_hcicb; /* HCI connection status callbacks */
  95. struct bt_l2cap_chan_s bd_l2capcb; /* L2CAP status callbacks */
  96. #else
  97. struct bt_hci_cb_s bd_hcicb; /* HCI RAW packet callbacks */
  98. #endif
  99. };
  100. /****************************************************************************
  101. * Private Function Prototypes
  102. ****************************************************************************/
  103. /* Utility functions ********************************************************/
  104. static int btnet_advertise(FAR struct net_driver_s *netdev);
  105. static inline void btnet_netmask(FAR struct net_driver_s *netdev);
  106. /* Bluetooth callback functions *********************************************/
  107. #ifdef CONFIG_WIRELESS_BLUETOOTH_HOST
  108. /* L2CAP callbacks */
  109. static void btnet_l2cap_connected(FAR struct bt_conn_s *conn,
  110. FAR void *context, uint16_t cid);
  111. static void btnet_l2cap_disconnected(FAR struct bt_conn_s *conn,
  112. FAR void *context, uint16_t cid);
  113. static void btnet_l2cap_encrypt_change(FAR struct bt_conn_s *conn,
  114. FAR void *context, uint16_t cid);
  115. static void btnet_l2cap_receive(FAR struct bt_conn_s *conn,
  116. FAR struct bt_buf_s *buf, FAR void *context, uint16_t cid);
  117. /* HCI callbacks */
  118. static void btnet_hci_connected(FAR struct bt_conn_s *conn,
  119. FAR void *context);
  120. static void btnet_hci_disconnected(FAR struct bt_conn_s *conn,
  121. FAR void *context);
  122. #else
  123. static void btnet_hci_received(FAR struct bt_buf_s *buf, FAR void *context);
  124. #endif
  125. /* Network interface support ************************************************/
  126. /* Common TX logic */
  127. static int btnet_txpoll_callback(FAR struct net_driver_s *netdev);
  128. static void btnet_txpoll_work(FAR void *arg);
  129. static void btnet_txpoll_expiry(wdparm_t arg);
  130. /* NuttX callback functions */
  131. static int btnet_ifup(FAR struct net_driver_s *netdev);
  132. static int btnet_ifdown(FAR struct net_driver_s *netdev);
  133. static void btnet_txavail_work(FAR void *arg);
  134. static int btnet_txavail(FAR struct net_driver_s *netdev);
  135. #ifdef CONFIG_NET_MCASTGROUP
  136. static int btnet_addmac(FAR struct net_driver_s *netdev,
  137. FAR const uint8_t *mac);
  138. static int btnet_rmmac(FAR struct net_driver_s *netdev,
  139. FAR const uint8_t *mac);
  140. #endif
  141. static int btnet_get_mhrlen(FAR struct radio_driver_s *netdev,
  142. FAR const void *meta);
  143. static int btnet_req_data(FAR struct radio_driver_s *netdev,
  144. FAR const void *meta, FAR struct iob_s *framelist);
  145. static int btnet_properties(FAR struct radio_driver_s *netdev,
  146. FAR struct radiodev_properties_s *properties);
  147. #ifdef CONFIG_WIRELESS_BLUETOOTH_HOST
  148. static int btnet_req_l2cap_data(FAR struct btnet_driver_s *priv,
  149. FAR struct bluetooth_frame_meta_s *meta,
  150. FAR struct iob_s *framelist);
  151. #endif
  152. static int btnet_req_hci_data(FAR struct btnet_driver_s *priv,
  153. FAR struct bluetooth_frame_meta_s *meta,
  154. FAR struct iob_s *framelist);
  155. /****************************************************************************
  156. * Private Data
  157. ****************************************************************************/
  158. #ifdef CONFIG_NET_6LOWPAN
  159. static struct sixlowpan_reassbuf_s g_iobuffer;
  160. #endif
  161. /****************************************************************************
  162. * Private Functions
  163. ****************************************************************************/
  164. /****************************************************************************
  165. * Name: btnet_advertise
  166. *
  167. * Description:
  168. * Advertise the MAC and IPv6 address for this node.
  169. *
  170. * Creates a MAC-based IP address from the 6-byte address address assigned
  171. * to the device.
  172. *
  173. * 128 112 96 80 64 48 32 16
  174. * ---- ---- ---- ---- ---- ---- ---- ----
  175. * fe80 0000 0000 0000 0200 xxxx xxxx xxxx
  176. *
  177. ****************************************************************************/
  178. static int btnet_advertise(FAR struct net_driver_s *netdev)
  179. {
  180. FAR uint8_t *addr;
  181. DEBUGASSERT(netdev != NULL && netdev->d_private != NULL);
  182. /* Get the 6-byte local address from the device.
  183. *
  184. * REVISIT: The use of the g_btdev global restricts the implementation to
  185. * a single Bluetooth device.
  186. */
  187. addr = g_btdev.bdaddr.val;
  188. /* Set the MAC address using 6-byte local address from the device. */
  189. BLUETOOTH_ADDRCOPY(netdev->d_mac.radio.nv_addr, addr);
  190. netdev->d_mac.radio.nv_addrlen = BLUETOOTH_ADDRSIZE;
  191. #ifdef CONFIG_NET_IPv6
  192. /* Set the IP address based on the 6-byte address */
  193. netdev->d_ipv6addr[0] = HTONS(0xfe80);
  194. netdev->d_ipv6addr[1] = 0;
  195. netdev->d_ipv6addr[2] = 0;
  196. netdev->d_ipv6addr[3] = 0;
  197. netdev->d_ipv6addr[4] = HTONS(0x0200);
  198. netdev->d_ipv6addr[5] = (uint16_t)addr[0] << 8 | (uint16_t)addr[1];
  199. netdev->d_ipv6addr[6] = (uint16_t)addr[2] << 8 | (uint16_t)addr[3];
  200. netdev->d_ipv6addr[7] = (uint16_t)addr[4] << 8 | (uint16_t)addr[5];
  201. #endif
  202. return OK;
  203. }
  204. /****************************************************************************
  205. * Name: btnet_netmask
  206. *
  207. * Description:
  208. * Create a netmask of a MAC-based IP address which is based on the 6-byte
  209. * Bluetooth address.
  210. *
  211. * 128 112 96 80 64 48 32 16
  212. * ---- ---- ---- ---- ---- ---- ---- ----
  213. * fe80 0000 0000 0000 xxxx xxxx xxxx xxxx
  214. *
  215. ****************************************************************************/
  216. static inline void btnet_netmask(FAR struct net_driver_s *netdev)
  217. {
  218. #ifdef CONFIG_NET_IPv6
  219. netdev->d_ipv6netmask[0] = 0xffff;
  220. netdev->d_ipv6netmask[1] = 0xffff;
  221. netdev->d_ipv6netmask[2] = 0xffff;
  222. netdev->d_ipv6netmask[3] = 0xffff;
  223. netdev->d_ipv6netmask[4] = 0;
  224. netdev->d_ipv6netmask[5] = 0;
  225. netdev->d_ipv6netmask[6] = 0;
  226. netdev->d_ipv6netmask[7] = 0;
  227. #endif
  228. }
  229. #ifdef CONFIG_WIRELESS_BLUETOOTH_HOST
  230. /****************************************************************************
  231. * Name: btnet_hci_connect/disconnect/encrypt_change
  232. *
  233. * Description:
  234. * There are callbacks that are involved by the core HCI layer when a
  235. * change is detected in the connection status or encryption.
  236. *
  237. * Input Parameters:
  238. * conn - The connection whose
  239. *
  240. * Returned Value:
  241. * None
  242. *
  243. * Assumptions:
  244. * No assumption should be made about the thread of execution that these
  245. * are called from
  246. *
  247. ****************************************************************************/
  248. static void btnet_l2cap_connected(FAR struct bt_conn_s *conn,
  249. FAR void *context, uint16_t cid)
  250. {
  251. wlinfo("Connected\n");
  252. #warning Missing logic
  253. }
  254. static void btnet_l2cap_disconnected(FAR struct bt_conn_s *conn,
  255. FAR void *context, uint16_t cid)
  256. {
  257. wlinfo("Disconnected\n");
  258. #warning Missing logic
  259. }
  260. static void btnet_l2cap_encrypt_change(FAR struct bt_conn_s *conn,
  261. FAR void *context, uint16_t cid)
  262. {
  263. wlinfo("Encryption change\n");
  264. #warning Missing logic
  265. }
  266. /****************************************************************************
  267. * Name: btnet_l2cap_receive
  268. *
  269. * Description:
  270. * Handle received frames forward by the Bluetooth L2CAP layer.
  271. *
  272. * Returned Value:
  273. * Zero (OK) is returned on success; a negated errno value is returned on
  274. * any failure. On success, the meta data and its contained iob will be
  275. * freed. The meta data will be intact if this function returns a
  276. * failure.
  277. *
  278. ****************************************************************************/
  279. static void btnet_l2cap_receive(FAR struct bt_conn_s *conn,
  280. FAR struct bt_buf_s *buf,
  281. FAR void *context, uint16_t cid)
  282. {
  283. FAR struct btnet_driver_s *priv;
  284. FAR struct iob_s *frame;
  285. struct bluetooth_frame_meta_s meta;
  286. int ret = -ENODEV;
  287. wlinfo("Received frame\n");
  288. DEBUGASSERT(conn != NULL && buf != NULL && buf->frame != NULL &&
  289. context != NULL && cid < UINT8_MAX);
  290. /* Detach the IOB frame from the buffer structure */
  291. frame = buf->frame;
  292. buf->frame = NULL;
  293. /* Ignore the frame if the network is not up */
  294. priv = (FAR struct btnet_driver_s *)context;
  295. if (!priv->bd_bifup)
  296. {
  297. wlwarn("WARNING: Dropped... Network is down\n");
  298. goto drop;
  299. }
  300. /* Make sure that the size/offset data matches the buffer structure data.
  301. * REVISIT: Wouldn't it be better to just have one copy rather than having
  302. * to synchronize?
  303. */
  304. frame->io_len = buf->len;
  305. frame->io_pktlen = buf->len;
  306. frame->io_offset = (unsigned int)
  307. ((uintptr_t)buf->data - (uintptr_t)frame->io_data);
  308. DEBUGASSERT(frame->io_len <= CONFIG_IOB_BUFSIZE);
  309. DEBUGASSERT(frame->io_offset < CONFIG_IOB_BUFSIZE);
  310. /* Construct the frame meta data.
  311. * REVISIT: Where do we get the channel number?
  312. */
  313. BLUETOOTH_ADDRCOPY(meta.bm_raddr.val, conn->src.val);
  314. meta.bm_channel = cid;
  315. /* Transfer the frame to the network logic */
  316. net_lock();
  317. #ifdef CONFIG_NET_BLUETOOTH
  318. /* Invoke the PF_BLUETOOTH tap first. If the frame matches
  319. * with a connected PF_BLUETOOTH socket, it will take the
  320. * frame and return success.
  321. */
  322. ret = bluetooth_input(&priv->bd_dev, frame, (FAR void *)&meta);
  323. #endif
  324. #ifdef CONFIG_NET_6LOWPAN
  325. if (ret < 0)
  326. {
  327. /* If the frame is not a 6LoWPAN frame, then thefirst byte at the
  328. * io_offset should be a valid IPHC header.
  329. */
  330. if ((iob->io_data[iob->io_offset] & SIXLOWPAN_DISPATCH_NALP_MASK) ==
  331. SIXLOWPAN_DISPATCH_NALP)
  332. {
  333. wlwarn("WARNING: Dropped... Not a 6LoWPAN frame: %02x\n",
  334. iob->io_data[iob->io_offset]);
  335. ret = -EINVAL;
  336. }
  337. else
  338. {
  339. /* Make sure the our single packet buffer is attached */
  340. priv->bd_dev.r_dev.d_buf = g_iobuffer.rb_buf;
  341. /* And give the packet to 6LoWPAN */
  342. ret = sixlowpan_input(&priv->bd_dev, iob, (FAR void *)meta);
  343. }
  344. }
  345. #endif
  346. drop:
  347. /* Handle errors */
  348. if (ret < 0)
  349. {
  350. iob_free(frame, IOBUSER_WIRELESS_BLUETOOTH);
  351. /* Increment statistics */
  352. NETDEV_RXDROPPED(&priv->bd_dev.r_dev);
  353. }
  354. else
  355. {
  356. /* Increment statistics */
  357. NETDEV_RXPACKETS(&priv->bd_dev.r_dev);
  358. NETDEV_RXIPV6(&priv->bd_dev.r_dev);
  359. }
  360. /* Release our reference on the buffer */
  361. bt_buf_release(buf);
  362. net_unlock();
  363. }
  364. /****************************************************************************
  365. * Name: btnet_hci_connect/disconnect
  366. *
  367. * Description:
  368. * There are callbacks that are involved by the core HCI layer when a
  369. * change is detected in the connection status.
  370. *
  371. * Input Parameters:
  372. * conn - The connection whose
  373. *
  374. * Returned Value:
  375. * None
  376. *
  377. * Assumptions:
  378. * No assumption should be made about the thread of execution that these
  379. * are called from
  380. *
  381. ****************************************************************************/
  382. static void btnet_hci_connected(FAR struct bt_conn_s *conn,
  383. FAR void *context)
  384. {
  385. wlinfo("Connected\n");
  386. #warning Missing logic
  387. }
  388. static void btnet_hci_disconnected(FAR struct bt_conn_s *conn,
  389. FAR void *context)
  390. {
  391. wlinfo("Disconnected\n");
  392. #warning Missing logic
  393. }
  394. #else
  395. /****************************************************************************
  396. * Name: btnet_hci_received
  397. *
  398. * Description:
  399. * This callback is called from the RX queue handling when an HCI
  400. * packet is received from controller.
  401. *
  402. * Input Parameters:
  403. * buf - The packet
  404. *
  405. * Returned Value:
  406. * None
  407. *
  408. * Assumptions:
  409. * No assumption should be made about the thread of execution that these
  410. * are called from
  411. *
  412. ****************************************************************************/
  413. static void btnet_hci_received(FAR struct bt_buf_s *buf, FAR void *context)
  414. {
  415. FAR struct btnet_driver_s *priv;
  416. FAR struct iob_s *frame;
  417. struct bluetooth_frame_meta_s meta;
  418. int ret = -ENODEV;
  419. wlinfo("Received frame\n");
  420. DEBUGASSERT(buf != NULL && buf->frame != NULL);
  421. /* Detach the IOB frame from the buffer structure */
  422. frame = buf->frame;
  423. buf->frame = NULL;
  424. /* Ignore the frame if the network is not up */
  425. priv = (FAR struct btnet_driver_s *)context;
  426. if (!priv->bd_bifup)
  427. {
  428. wlwarn("WARNING: Dropped... Network is down\n");
  429. goto drop;
  430. }
  431. /* Make sure that the size/offset data matches the buffer structure data. */
  432. DEBUGASSERT(frame->io_offset == BLUETOOTH_H4_HDRLEN);
  433. /* Rearrange IOB to consider H4 header */
  434. frame->io_len = buf->len + frame->io_offset;
  435. frame->io_pktlen = buf->len + frame->io_offset;
  436. frame->io_offset = 0;
  437. DEBUGASSERT(frame->io_len <= CONFIG_IOB_BUFSIZE);
  438. /* Write H4 header */
  439. switch (buf->type)
  440. {
  441. case BT_EVT:
  442. frame->io_data[0] = HCI_EVENT_PKT;
  443. break;
  444. case BT_ACL_IN:
  445. frame->io_data[0] = HCI_ACLDATA_PKT;
  446. break;
  447. default:
  448. wlerr("Bad HCI type: %i\n", buf->type);
  449. goto drop;
  450. break;
  451. }
  452. /* Construct the frame meta data.
  453. */
  454. meta.bm_channel = HCI_CHANNEL_RAW;
  455. meta.bm_proto = BTPROTO_HCI;
  456. /* Transfer the frame to the network logic */
  457. net_lock();
  458. #ifdef CONFIG_NET_BLUETOOTH
  459. /* Invoke the PF_BLUETOOTH tap first. If the frame matches
  460. * with a connected PF_BLUETOOTH socket, it will take the
  461. * frame and return success.
  462. */
  463. ret = bluetooth_input(&priv->bd_dev, frame, (FAR void *)&meta);
  464. #endif
  465. drop:
  466. /* Handle errors */
  467. if (ret < 0)
  468. {
  469. iob_free(frame, IOBUSER_WIRELESS_BLUETOOTH);
  470. /* Increment statistics */
  471. NETDEV_RXDROPPED(&priv->bd_dev.r_dev);
  472. }
  473. else
  474. {
  475. /* Increment statistics */
  476. NETDEV_RXPACKETS(&priv->bd_dev.r_dev);
  477. NETDEV_RXIPV6(&priv->bd_dev.r_dev);
  478. }
  479. /* Release our reference on the buffer */
  480. net_unlock();
  481. }
  482. #endif
  483. /****************************************************************************
  484. * Name: btnet_txpoll_callback
  485. *
  486. * Description:
  487. * The transmitter is available, check if the network has any outgoing
  488. * packets ready to send. This is a callback from devif_poll().
  489. * devif_poll() may be called:
  490. *
  491. * 1. When the preceding TX packet send is complete,
  492. * 2. When the preceding TX packet send timesout and the interface is reset
  493. * 3. During normal TX polling
  494. *
  495. * Input Parameters:
  496. * netdev - Reference to the NuttX driver state structure
  497. *
  498. * Returned Value:
  499. * OK on success; a negated errno on failure
  500. *
  501. * Assumptions:
  502. * The network is locked.
  503. *
  504. ****************************************************************************/
  505. static int btnet_txpoll_callback(FAR struct net_driver_s *netdev)
  506. {
  507. /* If zero is returned, the polling will continue until all connections
  508. * have been examined.
  509. */
  510. return 0;
  511. }
  512. /****************************************************************************
  513. * Name: btnet_txpoll_work
  514. *
  515. * Description:
  516. * Perform periodic polling from the worker thread
  517. *
  518. * Input Parameters:
  519. * arg - The argument passed when work_queue() as called.
  520. *
  521. * Returned Value:
  522. * OK on success
  523. *
  524. * Assumptions:
  525. * The network is locked.
  526. *
  527. ****************************************************************************/
  528. static void btnet_txpoll_work(FAR void *arg)
  529. {
  530. FAR struct btnet_driver_s *priv = (FAR struct btnet_driver_s *)arg;
  531. /* Lock the network and serialize driver operations if necessary.
  532. * NOTE: Serialization is only required in the case where the driver work
  533. * is performed on an LP worker thread and where more than one LP worker
  534. * thread has been configured.
  535. */
  536. net_lock();
  537. #ifdef CONFIG_NET_6LOWPAN
  538. /* Make sure the our single packet buffer is attached */
  539. priv->bd_dev.r_dev.d_buf = g_iobuffer.rb_buf;
  540. #endif
  541. /* Then perform the poll */
  542. devif_timer(&priv->bd_dev.r_dev, TXPOLL_WDDELAY, btnet_txpoll_callback);
  543. /* Setup the watchdog poll timer again */
  544. wd_start(&priv->bd_txpoll, TXPOLL_WDDELAY,
  545. btnet_txpoll_expiry, (wdparm_t)priv);
  546. net_unlock();
  547. }
  548. /****************************************************************************
  549. * Name: btnet_txpoll_expiry
  550. *
  551. * Description:
  552. * Periodic timer handler. Called from the timer interrupt handler.
  553. *
  554. * Input Parameters:
  555. * arg - The argument
  556. *
  557. * Returned Value:
  558. * None
  559. *
  560. * Assumptions:
  561. * Global interrupts are disabled by the watchdog logic.
  562. *
  563. ****************************************************************************/
  564. static void btnet_txpoll_expiry(wdparm_t arg)
  565. {
  566. FAR struct btnet_driver_s *priv = (FAR struct btnet_driver_s *)arg;
  567. /* Schedule to perform the interrupt processing on the worker thread. */
  568. work_queue(LPWORK, &priv->bd_pollwork, btnet_txpoll_work, priv, 0);
  569. }
  570. /****************************************************************************
  571. * Name: btnet_ifup
  572. *
  573. * Description:
  574. * NuttX Callback: Bring up the Bluetooth interface when an IP address
  575. * is provided
  576. *
  577. * Input Parameters:
  578. * netdev - Reference to the NuttX driver state structure
  579. *
  580. * Returned Value:
  581. * None
  582. *
  583. * Assumptions:
  584. *
  585. ****************************************************************************/
  586. static int btnet_ifup(FAR struct net_driver_s *netdev)
  587. {
  588. FAR struct btnet_driver_s *priv =
  589. (FAR struct btnet_driver_s *)netdev->d_private;
  590. int ret;
  591. /* Set the IP address based on the addressing assigned to the node */
  592. ret = btnet_advertise(netdev);
  593. if (ret >= 0)
  594. {
  595. #ifdef CONFIG_NET_IPv6
  596. wlinfo("Bringing up: IP %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
  597. netdev->d_ipv6addr[0], netdev->d_ipv6addr[1],
  598. netdev->d_ipv6addr[2], netdev->d_ipv6addr[3],
  599. netdev->d_ipv6addr[4], netdev->d_ipv6addr[5],
  600. netdev->d_ipv6addr[6], netdev->d_ipv6addr[7]);
  601. wlinfo(" ADDR %02x:%02x:%02x:%02x:%02x:%02x\n",
  602. netdev->d_mac.radio.nv_addr[0], netdev->d_mac.radio.nv_addr[1],
  603. netdev->d_mac.radio.nv_addr[2], netdev->d_mac.radio.nv_addr[3],
  604. netdev->d_mac.radio.nv_addr[4], netdev->d_mac.radio.nv_addr[5]);
  605. #else
  606. wlinfo("Bringing up: %02x:%02x:%02x:%02x:%02x:%02x\n",
  607. netdev->d_mac.radio.nv_addr[0], netdev->d_mac.radio.nv_addr[1],
  608. netdev->d_mac.radio.nv_addr[2], netdev->d_mac.radio.nv_addr[3],
  609. netdev->d_mac.radio.nv_addr[4], netdev->d_mac.radio.nv_addr[5]);
  610. #endif
  611. /* Set and activate a timer process */
  612. wd_start(&priv->bd_txpoll, TXPOLL_WDDELAY,
  613. btnet_txpoll_expiry, (wdparm_t)priv);
  614. /* The interface is now up */
  615. priv->bd_bifup = true;
  616. ret = OK;
  617. }
  618. return ret;
  619. }
  620. /****************************************************************************
  621. * Name: btnet_ifdown
  622. *
  623. * Description:
  624. * NuttX Callback: Stop the interface.
  625. *
  626. * Input Parameters:
  627. * netdev - Reference to the NuttX driver state structure
  628. *
  629. * Returned Value:
  630. * None
  631. *
  632. * Assumptions:
  633. *
  634. ****************************************************************************/
  635. static int btnet_ifdown(FAR struct net_driver_s *netdev)
  636. {
  637. FAR struct btnet_driver_s *priv =
  638. (FAR struct btnet_driver_s *)netdev->d_private;
  639. irqstate_t flags;
  640. /* Disable interruption */
  641. flags = spin_lock_irqsave(NULL);
  642. /* Cancel the TX poll timer and TX timeout timers */
  643. wd_cancel(&priv->bd_txpoll);
  644. /* Put the EMAC in its reset, non-operational state. This should be
  645. * a known configuration that will guarantee the btnet_ifup() always
  646. * successfully brings the interface back up.
  647. */
  648. /* Mark the device "down" */
  649. priv->bd_bifup = false;
  650. spin_unlock_irqrestore(NULL, flags);
  651. return OK;
  652. }
  653. /****************************************************************************
  654. * Name: btnet_txavail_work
  655. *
  656. * Description:
  657. * Perform an out-of-cycle poll on the worker thread.
  658. *
  659. * Input Parameters:
  660. * arg - Reference to the NuttX driver state structure (cast to void*)
  661. *
  662. * Returned Value:
  663. * None
  664. *
  665. * Assumptions:
  666. * Called on the higher priority worker thread.
  667. *
  668. ****************************************************************************/
  669. static void btnet_txavail_work(FAR void *arg)
  670. {
  671. FAR struct btnet_driver_s *priv = (FAR struct btnet_driver_s *)arg;
  672. wlinfo("ifup=%u\n", priv->bd_bifup);
  673. /* Lock the network and serialize driver operations if necessary.
  674. * NOTE: Serialization is only required in the case where the driver work
  675. * is performed on an LP worker thread and where more than one LP worker
  676. * thread has been configured.
  677. */
  678. net_lock();
  679. /* Ignore the notification if the interface is not yet up */
  680. if (priv->bd_bifup)
  681. {
  682. #ifdef CONFIG_NET_6LOWPAN
  683. /* Make sure the our single packet buffer is attached */
  684. priv->bd_dev.r_dev.d_buf = g_iobuffer.rb_buf;
  685. #endif
  686. /* Then poll the network for new XMIT data */
  687. devif_poll(&priv->bd_dev.r_dev, btnet_txpoll_callback);
  688. }
  689. net_unlock();
  690. }
  691. /****************************************************************************
  692. * Name: btnet_txavail
  693. *
  694. * Description:
  695. * Driver callback invoked when new TX data is available. This is a
  696. * stimulus perform an out-of-cycle poll and, thereby, reduce the TX
  697. * latency.
  698. *
  699. * Input Parameters:
  700. * netdev - Reference to the NuttX driver state structure
  701. *
  702. * Returned Value:
  703. * None
  704. *
  705. * Assumptions:
  706. * Called in normal user mode
  707. *
  708. ****************************************************************************/
  709. static int btnet_txavail(FAR struct net_driver_s *netdev)
  710. {
  711. FAR struct btnet_driver_s *priv =
  712. (FAR struct btnet_driver_s *)netdev->d_private;
  713. wlinfo("Available=%u\n", work_available(&priv->bd_pollwork));
  714. /* Is our single work structure available? It may not be if there are
  715. * pending interrupt actions and we will have to ignore the Tx
  716. * availability action.
  717. */
  718. if (work_available(&priv->bd_pollwork))
  719. {
  720. /* Schedule to serialize the poll on the worker thread. */
  721. work_queue(LPWORK, &priv->bd_pollwork, btnet_txavail_work, priv, 0);
  722. }
  723. return OK;
  724. }
  725. /****************************************************************************
  726. * Name: btnet_addmac
  727. *
  728. * Description:
  729. * NuttX Callback: Add the specified MAC address to the hardware multicast
  730. * address filtering
  731. *
  732. * Input Parameters:
  733. * netdev - Reference to the NuttX driver state structure
  734. * mac - The MAC address to be added
  735. *
  736. * Returned Value:
  737. * None
  738. *
  739. * Assumptions:
  740. *
  741. ****************************************************************************/
  742. #ifdef CONFIG_NET_MCASTGROUP
  743. static int btnet_addmac(FAR struct net_driver_s *netdev,
  744. FAR const uint8_t *mac)
  745. {
  746. /* Add the MAC address to the hardware multicast routing table.
  747. * Not used with Bluetooth.
  748. */
  749. return -ENOSYS;
  750. }
  751. #endif
  752. /****************************************************************************
  753. * Name: btnet_rmmac
  754. *
  755. * Description:
  756. * NuttX Callback: Remove the specified MAC address from the hardware
  757. * multicast address filtering
  758. *
  759. * Input Parameters:
  760. * netdev - Reference to the NuttX driver state structure
  761. * mac - The MAC address to be removed
  762. *
  763. * Returned Value:
  764. * None
  765. *
  766. * Assumptions:
  767. *
  768. ****************************************************************************/
  769. #ifdef CONFIG_NET_MCASTGROUP
  770. static int btnet_rmmac(FAR struct net_driver_s *netdev,
  771. FAR const uint8_t *mac)
  772. {
  773. /* Remove the MAC address from the hardware multicast routing table
  774. * Not used with Bluetooth.
  775. */
  776. return -ENOSYS;
  777. }
  778. #endif
  779. /****************************************************************************
  780. * Name: btnet_get_mhrlen
  781. *
  782. * Description:
  783. * Calculate the MAC header length given the frame meta-data.
  784. *
  785. * Input Parameters:
  786. * netdev - The networkd device that will mediate the MAC interface
  787. * meta - Obfuscated meta-data structure needed to create the radio
  788. * MAC header
  789. *
  790. * Returned Value:
  791. * A non-negative MAC header length is returned on success; a negated
  792. * errno value is returned on any failure.
  793. *
  794. ****************************************************************************/
  795. static int btnet_get_mhrlen(FAR struct radio_driver_s *netdev,
  796. FAR const void *meta)
  797. {
  798. const struct bluetooth_frame_meta_s *btmeta = meta;
  799. if (btmeta->bm_proto == BTPROTO_HCI)
  800. {
  801. /* the net device only requires the H4 header, the rest is already
  802. * part of the packet
  803. */
  804. return BLUETOOTH_H4_HDRLEN;
  805. }
  806. else if (btmeta->bm_proto == BTPROTO_L2CAP)
  807. {
  808. /* Report the complete header size, since H4 + ACL + L2CAP header
  809. * will not be part of the packet
  810. */
  811. /* TODO: correct? */
  812. return BLUETOOTH_MAX_HDRLEN;
  813. }
  814. return BLUETOOTH_MAX_HDRLEN;
  815. }
  816. /****************************************************************************
  817. * Name: btnet_req_data
  818. *
  819. * Description:
  820. * Requests the transfer of a list of frames to the MAC.
  821. *
  822. * Input Parameters:
  823. * netdev - The networkd device that will mediate the MAC interface
  824. * meta - Obfuscated metadata structure needed to create the radio
  825. * MAC header
  826. * framelist - Head of a list of frames to be transferred.
  827. *
  828. * Returned Value:
  829. * Zero (OK) returned on success; a negated errno value is returned on
  830. * any failure.
  831. *
  832. ****************************************************************************/
  833. static int btnet_req_data(FAR struct radio_driver_s *netdev,
  834. FAR const void *meta, FAR struct iob_s *framelist)
  835. {
  836. FAR struct btnet_driver_s *priv;
  837. FAR struct bluetooth_frame_meta_s *btmeta;
  838. priv = (FAR struct btnet_driver_s *)netdev;
  839. btmeta = (FAR struct bluetooth_frame_meta_s *)meta;
  840. wlinfo("Received framelist\n");
  841. DEBUGASSERT(priv != NULL && meta != NULL && framelist != NULL);
  842. if (btmeta->bm_proto == BTPROTO_HCI)
  843. {
  844. return btnet_req_hci_data(priv, btmeta, framelist);
  845. }
  846. #ifdef CONFIG_WIRELESS_BLUETOOTH_HOST
  847. else if (btmeta->bm_proto == BTPROTO_L2CAP)
  848. {
  849. return btnet_req_l2cap_data(priv, btmeta, framelist);
  850. }
  851. #endif
  852. else
  853. {
  854. return -EOPNOTSUPP;
  855. }
  856. return OK;
  857. }
  858. #ifdef CONFIG_WIRELESS_BLUETOOTH_HOST
  859. /****************************************************************************
  860. * Name: btnet_req_l2cap_data
  861. *
  862. * Description:
  863. * Requests the transfer of a list of L2CAP frames to the MAC.
  864. *
  865. * Input Parameters:
  866. * priv - Bluetooth network device
  867. * btmeta - Bluetooth frame metadata
  868. * framelist - Head of a list of L2CAP frames to be transferred.
  869. *
  870. * Returned Value:
  871. * Zero (OK) returned on success; a negated errno value is returned on
  872. * any failure.
  873. *
  874. ****************************************************************************/
  875. static int btnet_req_l2cap_data(FAR struct btnet_driver_s *priv,
  876. FAR struct bluetooth_frame_meta_s *btmeta,
  877. FAR struct iob_s *framelist)
  878. {
  879. FAR struct bt_conn_s *conn;
  880. bt_addr_le_t peer;
  881. FAR struct iob_s *iob;
  882. FAR struct bt_buf_s *buf;
  883. UNUSED(priv);
  884. /* Create a connection structure for this peer if one does not already
  885. * exist.
  886. *
  887. * Assumptions to REVISIT:
  888. *
  889. * 1. Role is Master (see bt_conn_create_le())
  890. * 2. Address type is BT_ADDR_LE_PUBLIC (vs. BT_ADDR_LE_RANDOM)
  891. */
  892. BLUETOOTH_ADDRCOPY(peer.val, btmeta->bm_raddr.val);
  893. peer.type = BT_ADDR_LE_PUBLIC;
  894. conn = bt_conn_create_le(&peer);
  895. if (conn == NULL)
  896. {
  897. /* bt_conn_create_le() can fail if (1) the connection exists, but is
  898. * in a bad state or (2) CONFIG_BLUETOOTH_MAX_CONN has been exceeded.
  899. * Assume the latter.
  900. */
  901. return -ENOMEM;
  902. }
  903. /* Add the incoming list of frames to the MAC's outgoing queue */
  904. for (iob = framelist; iob != NULL; iob = framelist)
  905. {
  906. /* Increment statistics */
  907. NETDEV_TXPACKETS(&priv->bd_dev.r_dev);
  908. /* Remove the IOB from the queue */
  909. framelist = iob->io_flink;
  910. iob->io_flink = NULL;
  911. DEBUGASSERT(iob->io_offset == BLUETOOTH_MAX_HDRLEN &&
  912. iob->io_len >= BLUETOOTH_MAX_HDRLEN);
  913. /* Allocate a buffer to contain the IOB */
  914. buf = bt_buf_alloc(BT_ACL_OUT, iob, BLUETOOTH_MAX_HDRLEN);
  915. if (buf == NULL)
  916. {
  917. wlerr("ERROR: Failed to allocate buffer container\n");
  918. return -ENOMEM;
  919. }
  920. /* Transfer the frame to the Bluetooth stack. */
  921. bt_l2cap_send(conn, (uint16_t)btmeta->bm_channel, buf);
  922. NETDEV_TXDONE(&priv->bd_dev.r_dev);
  923. }
  924. return OK;
  925. }
  926. #endif
  927. /****************************************************************************
  928. * Name: btnet_req_hci_data
  929. *
  930. * Description:
  931. * Requests the transfer of a list of HCI frames to the MAC.
  932. *
  933. * Input Parameters:
  934. * priv - Bluetooth network device
  935. * btmeta - Bluetooth frame metadata
  936. * framelist - Head of a list of HCI frames to be transferred.
  937. *
  938. * Returned Value:
  939. * Zero (OK) returned on success; a negated errno value is returned on
  940. * any failure.
  941. *
  942. ****************************************************************************/
  943. static int btnet_req_hci_data(FAR struct btnet_driver_s *priv,
  944. FAR struct bluetooth_frame_meta_s *meta,
  945. FAR struct iob_s *framelist)
  946. {
  947. FAR struct iob_s *iob;
  948. FAR struct bt_buf_s *buf;
  949. /* Add the incoming list of frames to the MAC's outgoing queue */
  950. for (iob = framelist; iob != NULL; iob = framelist)
  951. {
  952. /* Increment statistics */
  953. NETDEV_TXPACKETS(&priv->bd_dev.r_dev);
  954. /* Remove the IOB from the queue */
  955. framelist = iob->io_flink;
  956. iob->io_flink = NULL;
  957. DEBUGASSERT(iob->io_offset == BLUETOOTH_H4_HDRLEN &&
  958. iob->io_len >= BLUETOOTH_H4_HDRLEN);
  959. /* Allocate a buffer to contain the IOB */
  960. switch (iob->io_data[iob->io_offset])
  961. {
  962. case HCI_ACLDATA_PKT:
  963. iob->io_offset += 1;
  964. buf = bt_buf_alloc(BT_ACL_OUT, iob, 0);
  965. break;
  966. case HCI_COMMAND_PKT:
  967. iob->io_offset += 1;
  968. buf = bt_buf_alloc(BT_CMD, iob, 0);
  969. break;
  970. case HCI_EVENT_PKT:
  971. iob->io_offset += 1;
  972. buf = bt_buf_alloc(BT_EVT, iob, 0);
  973. break;
  974. default:
  975. return -EOPNOTSUPP;
  976. break;
  977. }
  978. if (buf == NULL)
  979. {
  980. wlerr("ERROR: Failed to allocate buffer container\n");
  981. return -ENOMEM;
  982. }
  983. bt_send(g_btdev.btdev, buf);
  984. bt_buf_release(buf);
  985. /* Transfer the frame to the Bluetooth stack. */
  986. NETDEV_TXDONE(&priv->bd_dev.r_dev);
  987. }
  988. return OK;
  989. }
  990. /****************************************************************************
  991. * Name: btnet_properties
  992. *
  993. * Description:
  994. * Different packet radios may have different properties. If there are
  995. * multiple packet radios, then those properties have to be queried at
  996. * run time. This information is provided to the 6LoWPAN network via the
  997. * following structure.
  998. *
  999. * Input Parameters:
  1000. * netdev - The network device to be queried
  1001. * properties - Location where radio properties will be returned.
  1002. *
  1003. * Returned Value:
  1004. * Zero (OK) returned on success; a negated errno value is returned on
  1005. * any failure.
  1006. *
  1007. ****************************************************************************/
  1008. static int btnet_properties(FAR struct radio_driver_s *netdev,
  1009. FAR struct radiodev_properties_s *properties)
  1010. {
  1011. DEBUGASSERT(netdev != NULL && properties != NULL);
  1012. memset(properties, 0, sizeof(struct radiodev_properties_s));
  1013. /* General */
  1014. properties->sp_addrlen = BLUETOOTH_ADDRSIZE; /* Length of an address */
  1015. properties->sp_framelen = BLUETOOTH_MAX_FRAMELEN; /* Fixed frame length */
  1016. /* Multicast, multicast, and star hub node addresses not supported */
  1017. return OK;
  1018. }
  1019. /****************************************************************************
  1020. * Public Functions
  1021. ****************************************************************************/
  1022. /****************************************************************************
  1023. * Name: bt_netdev_register
  1024. *
  1025. * Description:
  1026. * Register a network driver to access the Bluetooth layer using a 6LoWPAN
  1027. * IPv6 or AF_BLUETOOTH socket.
  1028. *
  1029. * Input Parameters:
  1030. * btdev - An instance of the low-level drivers interface structure.
  1031. *
  1032. * Returned Value:
  1033. * Zero (OK) is returned on success. Otherwise a negated errno value is
  1034. * returned to indicate the nature of the failure.
  1035. *
  1036. ****************************************************************************/
  1037. int bt_netdev_register(FAR const struct bt_driver_s *btdev)
  1038. {
  1039. FAR struct btnet_driver_s *priv;
  1040. FAR struct radio_driver_s *radio;
  1041. FAR struct net_driver_s *netdev;
  1042. #ifdef CONFIG_WIRELESS_BLUETOOTH_HOST
  1043. FAR struct bt_conn_cb_s *hcicb;
  1044. FAR struct bt_l2cap_chan_s *l2capcb;
  1045. #else
  1046. FAR struct bt_hci_cb_s *hcicb;
  1047. #endif
  1048. int ret;
  1049. /* Get the interface structure associated with this interface number. */
  1050. priv = (FAR struct btnet_driver_s *)
  1051. kmm_zalloc(sizeof(struct btnet_driver_s));
  1052. if (priv == NULL)
  1053. {
  1054. nerr("ERROR: Failed to allocate the device structure\n");
  1055. return -ENOMEM;
  1056. }
  1057. /* Initialize the driver structure */
  1058. radio = &priv->bd_dev;
  1059. netdev = &radio->r_dev;
  1060. netdev->d_ifup = btnet_ifup; /* I/F up (new IP address) callback */
  1061. netdev->d_ifdown = btnet_ifdown; /* I/F down callback */
  1062. netdev->d_txavail = btnet_txavail; /* New TX data callback */
  1063. #ifdef CONFIG_NET_MCASTGROUP
  1064. netdev->d_addmac = btnet_addmac; /* Add multicast MAC address */
  1065. netdev->d_rmmac = btnet_rmmac; /* Remove multicast MAC address */
  1066. #endif
  1067. #if defined(CONFIG_NETDEV_IOCTL) && defined(CONFIG_WIRELESS_BLUETOOTH_HOST)
  1068. netdev->d_ioctl = btnet_ioctl; /* Handle network IOCTL commands */
  1069. #endif
  1070. netdev->d_private = priv; /* Used to recover private state from netdev */
  1071. /* Connection status change callbacks */
  1072. #ifdef CONFIG_WIRELESS_BLUETOOTH_HOST
  1073. hcicb = &priv->bd_hcicb;
  1074. hcicb->context = priv;
  1075. hcicb->connected = btnet_hci_connected;
  1076. hcicb->disconnected = btnet_hci_disconnected;
  1077. bt_conn_cb_register(hcicb);
  1078. /* L2CAP status change callbacks */
  1079. l2capcb = &priv->bd_l2capcb;
  1080. l2capcb->context = priv;
  1081. l2capcb->connected = btnet_l2cap_connected;
  1082. l2capcb->disconnected = btnet_l2cap_disconnected;
  1083. l2capcb->encrypt_change = btnet_l2cap_encrypt_change;
  1084. l2capcb->receive = btnet_l2cap_receive;
  1085. bt_l2cap_chan_default(l2capcb);
  1086. #else
  1087. hcicb = &priv->bd_hcicb;
  1088. hcicb->context = priv;
  1089. hcicb->received = btnet_hci_received;
  1090. bt_hci_cb_register(hcicb);
  1091. #endif
  1092. /* Setup a locking semaphore for exclusive device driver access */
  1093. nxsem_init(&priv->bd_exclsem, 0, 1);
  1094. /* Set the network mask. */
  1095. btnet_netmask(netdev);
  1096. /* Initialize the Network frame-related callbacks */
  1097. radio->r_get_mhrlen = btnet_get_mhrlen; /* Get MAC header length */
  1098. radio->r_req_data = btnet_req_data; /* Enqueue frame for transmission */
  1099. radio->r_properties = btnet_properties; /* Return radio properties */
  1100. /* Associate the driver in with the Bluetooth stack.
  1101. *
  1102. * REVISIT: We will eventually need to remember which Bluetooth device
  1103. * we a serving. Not a problem now because only a single BLE device is
  1104. * supported.
  1105. */
  1106. ret = bt_driver_register(btdev);
  1107. if (ret < 0)
  1108. {
  1109. nerr("ERROR: bt_driver_register() failed: %d\n", ret);
  1110. goto errout;
  1111. }
  1112. /* Initialize the Bluetooth stack.
  1113. *
  1114. * REVISIT: This function should be called only once after all BLE
  1115. * drivers are registered. Not a problem now because only a single
  1116. * BLE device is supported.
  1117. */
  1118. ret = bt_initialize();
  1119. if (ret < 0)
  1120. {
  1121. nerr("ERROR: bt_initialize() failed: %d\n", ret);
  1122. goto errout;
  1123. }
  1124. /* Put the interface in the down state. */
  1125. btnet_ifdown(netdev);
  1126. #ifdef CONFIG_NET_6LOWPAN
  1127. /* Make sure the our single packet buffer is attached.
  1128. * We must do this before registering the device since, once the device is
  1129. * registered, a packet may be attempted to be forwarded and require the
  1130. * buffer.
  1131. */
  1132. priv->bd_dev.r_dev.d_buf = g_iobuffer.rb_buf;
  1133. #endif
  1134. /* Register the network device with the OS so that socket IOCTLs can be
  1135. * performed
  1136. */
  1137. ret = netdev_register(&priv->bd_dev.r_dev, NET_LL_BLUETOOTH);
  1138. if (ret >= 0)
  1139. {
  1140. return OK;
  1141. }
  1142. nerr("ERROR: netdev_register() failed: %d\n", ret);
  1143. errout:
  1144. /* Un-initialize semaphores */
  1145. nxsem_destroy(&priv->bd_exclsem);
  1146. /* Free memory and return the error */
  1147. kmm_free(priv);
  1148. return ret;
  1149. }
  1150. #endif /* CONFIG_NET && CONFIG_NET_skeleton */