1 /* 2 * Copyright (C) 2017 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 * [email protected] 35 * 36 */ 37 38 #define BTSTACK_FILE__ "bnep_lwip_lwip.c" 39 40 /* 41 * bnep_lwip_lwip_.c 42 */ 43 44 #include "lwip/netif.h" 45 #include "lwip/sys.h" 46 #include "lwip/arch.h" 47 #include "lwip/api.h" 48 #include "lwip/netifapi.h" 49 #include "lwip/tcpip.h" 50 #include "lwip/ip.h" 51 #include "lwip/dhcp.h" 52 #include "lwip/sockets.h" 53 #include "netif/etharp.h" 54 #include "lwip/prot/dhcp.h" 55 56 #include "bnep_lwip.h" 57 58 #include "btstack_config.h" 59 #include "btstack_debug.h" 60 #include "btstack_util.h" 61 #include "btstack_event.h" 62 #include "classic/bnep.h" 63 64 #if NO_SYS 65 #include "btstack_ring_buffer.h" 66 #include "btstack_run_loop.h" 67 #include "lwip/timeouts.h" 68 #else 69 #include "btstack_run_loop_freertos.h" 70 #endif 71 72 /* Short name used for netif in lwIP */ 73 #define IFNAME0 'b' 74 #define IFNAME1 't' 75 76 #define LWIP_TIMER_INTERVAL_MS 25 77 78 static void bnep_lwip_outgoing_process(void * arg); 79 80 // lwip data 81 static struct netif btstack_netif; 82 83 // outgoing queue 84 #if NO_SYS 85 static uint8_t bnep_lwip_outgoing_queue_storage[ (TCP_SND_QUEUELEN+1) * sizeof(struct pbuf *)]; 86 static btstack_ring_buffer_t bnep_lwip_outgoing_queue; 87 #else 88 static QueueHandle_t bnep_lwip_outgoing_queue; 89 #endif 90 91 92 // bnep data 93 static uint16_t bnep_cid; 94 static btstack_timer_source_t bnep_lwip_timer; 95 static btstack_packet_handler_t client_handler; 96 97 // next packet only modified from btstack context 98 static struct pbuf * bnep_lwip_outgoing_next_packet; 99 100 // temp buffer to unchain buffer 101 static uint8_t btstack_network_outgoing_buffer[HCI_ACL_PAYLOAD_SIZE]; 102 103 /// lwIP functions 104 105 /** 106 * This function should do the actual transmission of the packet. The packet is 107 * contained in the pbuf that is passed to the function. This pbuf 108 * might be chained. 109 * 110 * @param netif the lwip network interface structure 111 * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) 112 * @return ERR_OK if the packet could be sent 113 * an err_t value if the packet couldn't be sent 114 * 115 * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to 116 * strange results. You might consider waiting for space in the DMA queue 117 * to become availale since the stack doesn't retry to send a packet 118 * dropped because of memory failure (except for the TCP timers). 119 */ 120 static err_t low_level_output( struct netif *netif, struct pbuf *p ){ 121 UNUSED(netif); 122 123 log_info("low_level_output: queue %p, len %u, total len %u", p, p->len, p->tot_len); 124 125 126 // bnep up? 127 if (bnep_cid == 0) return ERR_OK; 128 129 // inc refcount 130 pbuf_ref( p ); 131 132 #if NO_SYS 133 // queue up 134 void * pointer = (void * ) p; 135 btstack_ring_buffer_write(&bnep_lwip_outgoing_queue, (uint8_t *) &pointer, sizeof(struct pbuf *)); 136 137 // trigger (might be new packet) 138 bnep_lwip_outgoing_process(NULL); 139 140 #else 141 // queue up 142 xQueueSendToBack(bnep_lwip_outgoing_queue, &p, portMAX_DELAY); 143 144 // trigger (might be new packet) 145 btstack_run_loop_freertos_execute_code_on_main_thread(&bnep_lwip_outgoing_process, NULL); 146 #endif 147 148 return (err_t) ERR_OK; 149 } 150 151 /** 152 * Should be called at the beginning of the program to set up the 153 * network interface. It calls the function low_level_init() to do the 154 * actual setup of the hardware. 155 * 156 * This function should be passed as a parameter to netif_add(). 157 * 158 * @param netif the lwip network interface structure for this ethernetif 159 * @return ERR_OK if the loopif is initialized 160 * ERR_MEM if private data couldn't be allocated 161 * any other err_t on error 162 */ 163 164 static err_t bnep_lwip_netif_init(struct netif *netif){ 165 166 // interface short name 167 netif->name[0] = IFNAME0; 168 netif->name[1] = IFNAME1; 169 170 // mtu 171 netif->mtu = 1600; 172 173 /* device capabilities */ 174 netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP; 175 176 /* We directly use etharp_output() here to save a function call. 177 * You can instead declare your own function an call etharp_output() 178 * from it if you have to do some checks before sending (e.g. if link 179 * is available...) 180 */ 181 netif->output = etharp_output; 182 #if LWIP_IPV6 183 netif->output_ip6 = ethip6_output; 184 #endif 185 netif->linkoutput = low_level_output; 186 187 return ERR_OK; 188 } 189 190 static int bnep_lwip_netif_up(bd_addr_t network_address){ 191 log_info("bnep_lwip_netif_up start addr %s", bd_addr_to_str(network_address)); 192 193 // set mac address 194 btstack_netif.hwaddr_len = 6; 195 memcpy(btstack_netif.hwaddr, network_address, 6); 196 197 // link is up 198 btstack_netif.flags |= NETIF_FLAG_LINK_UP; 199 200 // if up 201 netif_set_up(&btstack_netif); 202 203 return 0; 204 } 205 206 /** 207 * @brief Bring up network interfacd 208 * @param network_address 209 * @return 0 if ok 210 */ 211 static int bnep_lwip_netif_down(void){ 212 log_info("bnep_lwip_netif_down"); 213 214 // link is down 215 btstack_netif.flags &= ~NETIF_FLAG_LINK_UP; 216 217 netif_set_down(&btstack_netif); 218 return 0; 219 } 220 221 /** 222 * @brief Forward packet to TCP/IP stack 223 * @param packet 224 * @param size 225 */ 226 static void bnep_lwip_netif_process_packet(const uint8_t * packet, uint16_t size){ 227 228 /* We allocate a pbuf chain of pbufs from the pool. */ 229 struct pbuf * p = pbuf_alloc(PBUF_RAW, size, PBUF_POOL); 230 log_debug("bnep_lwip_netif_process_packet, pbuf_alloc = %p", p); 231 232 if (!p) return; 233 234 /* store packet in pbuf chain */ 235 struct pbuf * q = p; 236 while (q != NULL && size){ 237 memcpy(q->payload, packet, q->len); 238 packet += q->len; 239 size -= q->len; 240 q = q->next; 241 } 242 243 if (size != 0){ 244 log_error("failed to copy data into pbuf"); 245 pbuf_free(p); 246 return; 247 } 248 249 /* pass all packets to ethernet_input, which decides what packets it supports */ 250 if (btstack_netif.input(p, &btstack_netif) != ERR_OK){ 251 log_error("bnep_lwip_netif_process_packet: IP input error\n"); 252 pbuf_free(p); 253 p = NULL; 254 } 255 } 256 257 258 259 // BNEP Functions & Handler 260 261 static void bnep_lwip_outgoing_process(void * arg){ 262 UNUSED(arg); 263 264 // previous packet not sent yet 265 if (bnep_lwip_outgoing_next_packet) return; 266 267 // get new pbuf to send 268 #if NO_SYS 269 uint32_t bytes_read = 0; 270 void * pointer = NULL; 271 btstack_ring_buffer_read(&bnep_lwip_outgoing_queue, (uint8_t *) &pointer, sizeof(struct pbuf *), &bytes_read); 272 (void) bytes_read; 273 bnep_lwip_outgoing_next_packet = pointer; 274 #else 275 xQueueReceive(bnep_lwip_outgoing_queue, &bnep_lwip_outgoing_next_packet, portMAX_DELAY); 276 #endif 277 278 log_info("bnep_lwip_outgoing_process send %p", bnep_lwip_outgoing_next_packet); 279 280 // request can send now 281 bnep_request_can_send_now_event(bnep_cid); 282 } 283 284 static void bnep_lwip_timeout_handler(btstack_timer_source_t * ts){ 285 286 // process lwIP timers 287 sys_check_timeouts(); 288 289 // check if link is still up 290 if ((btstack_netif.flags & NETIF_FLAG_LINK_UP) == 0) return; 291 292 // restart timer 293 btstack_run_loop_set_timer(ts, LWIP_TIMER_INTERVAL_MS); 294 btstack_run_loop_add_timer(ts); 295 } 296 297 static void bnep_lwip_send_packet(void){ 298 if (bnep_lwip_outgoing_next_packet == NULL){ 299 log_error("CAN SEND NOW, but now packet queued"); 300 } 301 302 // flatten into our buffer 303 uint32_t len = btstack_min(sizeof(btstack_network_outgoing_buffer), bnep_lwip_outgoing_next_packet->tot_len); 304 pbuf_copy_partial(bnep_lwip_outgoing_next_packet, btstack_network_outgoing_buffer, len, 0); 305 bnep_send(bnep_cid, (uint8_t*) btstack_network_outgoing_buffer, len); 306 } 307 308 static void bnep_lwip_outgoing_packet_processed(void){ 309 #if NO_SYS 310 // release buffer / decrease refcount 311 pbuf_free(bnep_lwip_outgoing_next_packet); 312 #else 313 // release buffer / decrease refcount 314 pbuf_free_callback(bnep_lwip_outgoing_next_packet); 315 #endif 316 // mark as done 317 bnep_lwip_outgoing_next_packet = NULL; 318 } 319 320 static int bnep_lwip_outgoing_packets_empty(void){ 321 #if NO_SYS 322 return btstack_ring_buffer_empty(&bnep_lwip_outgoing_queue); 323 #else 324 return uxQueueMessagesWaiting(bnep_lwip_outgoing_queue) == 0; 325 #endif 326 } 327 328 static void bnep_lwip_trigger_outgoing_process(void){ 329 #if NO_SYS 330 bnep_lwip_outgoing_process(NULL); 331 #else 332 btstack_run_loop_freertos_execute_code_on_main_thread(&bnep_lwip_outgoing_process, NULL); 333 #endif 334 } 335 336 static void bnep_lwip_packet_sent(void){ 337 log_debug("bnep_lwip_packet_sent: %p", bnep_lwip_outgoing_next_packet); 338 339 // release current packet 340 bnep_lwip_outgoing_packet_processed(); 341 342 // more ? 343 if (bnep_lwip_outgoing_packets_empty()) return; 344 bnep_lwip_trigger_outgoing_process(); 345 } 346 347 static void bnep_lwip_discard_packets(void){ 348 // discard current packet 349 if (bnep_lwip_outgoing_next_packet){ 350 bnep_lwip_outgoing_packet_processed(); 351 } 352 353 // reset queue 354 #if NO_SYS 355 btstack_ring_buffer_init(&bnep_lwip_outgoing_queue, bnep_lwip_outgoing_queue_storage, sizeof(bnep_lwip_outgoing_queue_storage)); 356 #else 357 xQueueReset(bnep_lwip_outgoing_queue); 358 #endif 359 } 360 361 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size) 362 { 363 /* LISTING_PAUSE */ 364 UNUSED(channel); 365 366 bd_addr_t local_addr; 367 368 switch (packet_type) { 369 case HCI_EVENT_PACKET: 370 switch (hci_event_packet_get_type(packet)) { 371 372 /* @text BNEP_EVENT_CHANNEL_OPENED is received after a BNEP connection was established or 373 * or when the connection fails. The status field returns the error code. 374 * 375 * The TAP network interface is then configured. A data source is set up and registered with the 376 * run loop to receive Ethernet packets from the TAP interface. 377 * 378 * The event contains both the source and destination UUIDs, as well as the MTU for this connection and 379 * the BNEP Channel ID, which is used for sending Ethernet packets over BNEP. 380 */ 381 case BNEP_EVENT_CHANNEL_OPENED: 382 if (bnep_event_channel_opened_get_status(packet) != 0) break; 383 384 bnep_cid = bnep_event_channel_opened_get_bnep_cid(packet); 385 386 /* Setup network interface */ 387 gap_local_bd_addr(local_addr); 388 bnep_lwip_netif_up(local_addr); 389 390 #if NO_SYS 391 // start timer 392 btstack_run_loop_set_timer_handler(&bnep_lwip_timer, bnep_lwip_timeout_handler); 393 btstack_run_loop_set_timer(&bnep_lwip_timer, LWIP_TIMER_INTERVAL_MS); 394 btstack_run_loop_add_timer(&bnep_lwip_timer); 395 #endif 396 break; 397 398 /* @text BNEP_EVENT_CHANNEL_CLOSED is received when the connection gets closed. 399 */ 400 case BNEP_EVENT_CHANNEL_CLOSED: 401 bnep_cid = 0; 402 bnep_lwip_discard_packets(); 403 404 // Mark Link as Down 405 bnep_lwip_netif_down(); 406 break; 407 408 /* @text BNEP_EVENT_CAN_SEND_NOW indicates that a new packet can be send. This triggers the send of a 409 * stored network packet. The tap datas source can be enabled again 410 */ 411 case BNEP_EVENT_CAN_SEND_NOW: 412 bnep_lwip_send_packet(); 413 bnep_lwip_packet_sent(); 414 break; 415 416 default: 417 break; 418 } 419 break; 420 421 /* @text Ethernet packets from the remote device are received in the packet handler with type BNEP_DATA_PACKET. 422 * It is forwarded to the TAP interface. 423 */ 424 case BNEP_DATA_PACKET: 425 if (bnep_cid == 0) break; 426 // Write out the ethernet frame to the network interface 427 bnep_lwip_netif_process_packet(packet, size); 428 break; 429 430 default: 431 break; 432 } 433 434 // forward to app 435 if (!client_handler) return; 436 (*client_handler)(packet_type, channel, packet, size); 437 } 438 439 /// API 440 441 /** 442 * @brief Initialize network interface 443 * @param send_packet_callback 444 */ 445 void bnep_lwip_init(void){ 446 447 // set up outgoing queue 448 #if NO_SYS 449 btstack_ring_buffer_init(&bnep_lwip_outgoing_queue, bnep_lwip_outgoing_queue_storage, sizeof(bnep_lwip_outgoing_queue_storage)); 450 #else 451 bnep_lwip_outgoing_queue = xQueueCreate(TCP_SND_QUEUELEN, sizeof(struct pbuf *)); 452 if (bnep_lwip_outgoing_queue == NULL){ 453 log_error("cannot allocate outgoing queue"); 454 return; 455 } 456 #endif 457 458 ip4_addr_t fsl_netif0_ipaddr, fsl_netif0_netmask, fsl_netif0_gw; 459 460 #if 0 461 // when using DHCP Client, no address 462 IP4_ADDR(&fsl_netif0_ipaddr, 0U, 0U, 0U, 0U); 463 IP4_ADDR(&fsl_netif0_netmask, 0U, 0U, 0U, 0U); 464 #else 465 // when playing DHCP Server, set address 466 IP4_ADDR(&fsl_netif0_ipaddr, 192U, 168U, 7U, 1U); 467 IP4_ADDR(&fsl_netif0_netmask, 255U, 255U, 255U, 0U); 468 #endif 469 IP4_ADDR(&fsl_netif0_gw, 0U, 0U, 0U, 0U); 470 471 // input function differs for sys vs nosys 472 netif_input_fn input_function; 473 #if NO_SYS 474 input_function = ethernet_input; 475 #else 476 input_function = tcpip_input; 477 #endif 478 479 netif_add(&btstack_netif, &fsl_netif0_ipaddr, &fsl_netif0_netmask, &fsl_netif0_gw, NULL, bnep_lwip_netif_init, input_function); 480 netif_set_default(&btstack_netif); 481 } 482 483 /** 484 * @brief Register packet handler for BNEP events 485 */ 486 void bnep_lwip_register_packet_handler(btstack_packet_handler_t handler){ 487 client_handler = handler; 488 } 489 490 /** 491 * @brief Register BNEP service 492 * @brief Same as benp_register_service, but bnep lwip adapter handles all events 493 * @param service_uuid 494 * @Param max_frame_size 495 */ 496 uint8_t bnep_lwip_register_service(uint16_t service_uuid, uint16_t max_frame_size){ 497 return bnep_register_service(packet_handler, service_uuid, max_frame_size); 498 } 499