1 /* 2 * Copyright (c) 2006-2018, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2018-08-14 tyx the first version 9 */ 10 11 #include <rthw.h> 12 #include <rtthread.h> 13 #include <wlan_dev.h> 14 #include <wlan_prot.h> 15 #include <wlan_workqueue.h> 16 17 #ifdef RT_USING_LWIP 18 #include <netif/ethernetif.h> 19 #include <lwip/netifapi.h> 20 #ifdef LWIP_USING_DHCPD 21 #include <dhcp_server.h> 22 #endif 23 24 #define DBG_ENABLE 25 #ifdef RT_WLAN_LWIP_DEBUG 26 #define DBG_LEVEL DBG_LOG 27 #else 28 #define DBG_LEVEL DBG_INFO 29 #endif 30 #define DBG_SECTION_NAME "WLAN.lwip" 31 #define DBG_COLOR 32 #include <rtdbg.h> 33 34 #ifndef IPADDR_STRLEN_MAX 35 #define IPADDR_STRLEN_MAX (32) 36 #endif 37 38 struct lwip_prot_des 39 { 40 struct rt_wlan_prot prot; 41 struct eth_device eth; 42 rt_int8_t connected_flag; 43 struct rt_timer timer; 44 struct rt_work work; 45 }; 46 47 static void netif_is_ready(struct rt_work *work, void *parameter) 48 { 49 ip_addr_t ip_addr_zero = { 0 }; 50 struct rt_wlan_device *wlan = parameter; 51 struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)wlan->prot; 52 struct eth_device *eth_dev = &lwip_prot->eth; 53 rt_base_t level; 54 struct rt_wlan_buff buff; 55 rt_uint32_t ip_addr[4]; 56 char str[IPADDR_STRLEN_MAX]; 57 58 rt_timer_stop(&lwip_prot->timer); 59 if (ip_addr_cmp(&(eth_dev->netif->ip_addr), &ip_addr_zero) != 0) 60 { 61 rt_timer_start(&lwip_prot->timer); 62 goto exit; 63 } 64 rt_memset(&ip_addr, 0, sizeof(ip_addr)); 65 #if LWIP_IPV4 && LWIP_IPV6 66 if (eth_dev->netif->ip_addr.type == IPADDR_TYPE_V4) 67 { 68 ip_addr[0] = ip4_addr_get_u32(ð_dev->netif->ip_addr.u_addr.ip4); 69 buff.data = &ip_addr[0]; 70 buff.len = sizeof(ip_addr[0]); 71 } 72 else if (eth_dev->netif->ip_addr.type == IPADDR_TYPE_V6) 73 { 74 *(ip6_addr_t *)(&ip_addr[0]) = eth_dev->netif->ip_addr.u_addr.ip6; 75 buff.data = ip_addr; 76 buff.len = sizeof(ip_addr); 77 } 78 else 79 { 80 LOG_W("F:%s L:%d ip addr type not support", __FUNCTION__, __LINE__); 81 } 82 #else 83 #if LWIP_IPV4 84 ip_addr[0] = ip4_addr_get_u32(ð_dev->netif->ip_addr); 85 buff.data = &ip_addr[0]; 86 buff.len = sizeof(ip_addr[0]); 87 #else 88 *(ip_addr_t *)(&ip_addr[0]) = eth_dev->netif->ip_addr; 89 buff.data = ip_addr; 90 buff.len = sizeof(ip_addr); 91 #endif 92 #endif 93 if (rt_wlan_prot_ready(wlan, &buff) != 0) 94 { 95 rt_timer_start(&lwip_prot->timer); 96 goto exit; 97 } 98 rt_memset(str, 0, IPADDR_STRLEN_MAX); 99 rt_enter_critical(); 100 rt_memcpy(str, ipaddr_ntoa(&(eth_dev->netif->ip_addr)), IPADDR_STRLEN_MAX); 101 rt_exit_critical(); 102 LOG_I("Got IP address : %s", str); 103 exit: 104 level = rt_hw_interrupt_disable(); 105 rt_memset(work, 0, sizeof(struct rt_work)); 106 rt_hw_interrupt_enable(level); 107 } 108 109 static void timer_callback(void *parameter) 110 { 111 struct rt_workqueue *workqueue; 112 struct rt_wlan_device *wlan = parameter; 113 struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)wlan->prot; 114 struct rt_work *work = &lwip_prot->work; 115 rt_base_t level; 116 117 workqueue = rt_wlan_get_workqueue(); 118 if (workqueue != RT_NULL) 119 { 120 level = rt_hw_interrupt_disable(); 121 rt_work_init(work, netif_is_ready, parameter); 122 rt_hw_interrupt_enable(level); 123 if (rt_workqueue_dowork(workqueue, work) != RT_EOK) 124 { 125 level = rt_hw_interrupt_disable(); 126 rt_memset(work, 0, sizeof(struct rt_work)); 127 rt_hw_interrupt_enable(level); 128 } 129 } 130 } 131 132 static void netif_set_connected(void *parameter) 133 { 134 struct rt_wlan_device *wlan = parameter; 135 struct lwip_prot_des *lwip_prot = wlan->prot; 136 struct eth_device *eth_dev = &lwip_prot->eth; 137 138 if (lwip_prot->connected_flag) 139 { 140 if (wlan->mode == RT_WLAN_STATION) 141 { 142 LOG_D("F:%s L:%d dhcp start run", __FUNCTION__, __LINE__); 143 netifapi_netif_common(eth_dev->netif, netif_set_link_up, NULL); 144 #ifdef RT_LWIP_DHCP 145 dhcp_start(eth_dev->netif); 146 #endif 147 rt_timer_start(&lwip_prot->timer); 148 } 149 else if (wlan->mode == RT_WLAN_AP) 150 { 151 LOG_D("F:%s L:%d dhcpd start run", __FUNCTION__, __LINE__); 152 153 netifapi_netif_common(eth_dev->netif, netif_set_link_up, NULL); 154 #ifdef LWIP_USING_DHCPD 155 { 156 char netif_name[8]; 157 int i; 158 159 rt_memset(netif_name, 0, sizeof(netif_name)); 160 for (i = 0; i < sizeof(eth_dev->netif->name); i++) 161 { 162 netif_name[i] = eth_dev->netif->name[i]; 163 } 164 dhcpd_start(netif_name); 165 } 166 #endif 167 } 168 } 169 else 170 { 171 if (wlan->mode == RT_WLAN_STATION) 172 { 173 LOG_D("F:%s L:%d dhcp stop run", __FUNCTION__, __LINE__); 174 netifapi_netif_common(eth_dev->netif, netif_set_link_down, NULL); 175 #ifdef RT_LWIP_DHCP 176 { 177 ip_addr_t ip_addr = { 0 }; 178 dhcp_stop(eth_dev->netif); 179 netif_set_addr(eth_dev->netif, &ip_addr, &ip_addr, &ip_addr); 180 } 181 #endif 182 rt_timer_stop(&lwip_prot->timer); 183 } 184 else if (wlan->mode == RT_WLAN_AP) 185 { 186 LOG_D("F:%s L:%d dhcpd stop run", __FUNCTION__, __LINE__); 187 netifapi_netif_common(eth_dev->netif, netif_set_link_down, NULL); 188 } 189 } 190 } 191 192 static void rt_wlan_lwip_event_handle(struct rt_wlan_prot *port, struct rt_wlan_device *wlan, int event) 193 { 194 struct lwip_prot_des *lwip_prot = (struct lwip_prot_des *)wlan->prot; 195 rt_bool_t flag_old; 196 197 flag_old = lwip_prot->connected_flag; 198 199 switch (event) 200 { 201 case RT_WLAN_PROT_EVT_CONNECT: 202 { 203 LOG_D("event: CONNECT"); 204 lwip_prot->connected_flag = RT_TRUE; 205 break; 206 } 207 case RT_WLAN_PROT_EVT_DISCONNECT: 208 { 209 LOG_D("event: DISCONNECT"); 210 lwip_prot->connected_flag = RT_FALSE; 211 break; 212 } 213 case RT_WLAN_PROT_EVT_AP_START: 214 { 215 LOG_D("event: AP_START"); 216 lwip_prot->connected_flag = RT_TRUE; 217 break; 218 } 219 case RT_WLAN_PROT_EVT_AP_STOP: 220 { 221 LOG_D("event: AP_STOP"); 222 lwip_prot->connected_flag = RT_FALSE; 223 break; 224 } 225 case RT_WLAN_PROT_EVT_AP_ASSOCIATED: 226 { 227 LOG_D("event: ASSOCIATED"); 228 break; 229 } 230 case RT_WLAN_PROT_EVT_AP_DISASSOCIATED: 231 { 232 LOG_D("event: DISASSOCIATED"); 233 break; 234 } 235 default : 236 { 237 LOG_D("event: UNKNOWN"); 238 break; 239 } 240 } 241 if (flag_old != lwip_prot->connected_flag) 242 { 243 rt_wlan_workqueue_dowork(netif_set_connected, wlan); 244 // netif_set_connected(wlan); 245 } 246 } 247 248 static rt_err_t rt_wlan_lwip_protocol_control(rt_device_t device, int cmd, void *args) 249 { 250 struct eth_device *eth_dev = (struct eth_device *)device; 251 struct rt_wlan_device *wlan; 252 rt_err_t err = RT_EOK; 253 254 RT_ASSERT(eth_dev != RT_NULL); 255 256 LOG_D("F:%s L:%d device:0x%08x user_data:0x%08x", __FUNCTION__, __LINE__, eth_dev, eth_dev->parent.user_data); 257 258 switch (cmd) 259 { 260 case NIOCTL_GADDR: 261 /* get MAC address */ 262 wlan = eth_dev->parent.user_data; 263 err = rt_device_control((rt_device_t)wlan, RT_WLAN_CMD_GET_MAC, args); 264 break; 265 default : 266 break; 267 } 268 return err; 269 } 270 271 static rt_err_t rt_wlan_lwip_protocol_recv(struct rt_wlan_device *wlan, void *buff, int len) 272 { 273 struct eth_device *eth_dev = &((struct lwip_prot_des *)wlan->prot)->eth; 274 struct pbuf *p = RT_NULL; 275 276 LOG_D("F:%s L:%d run", __FUNCTION__, __LINE__); 277 278 if (eth_dev == RT_NULL) 279 { 280 return -RT_ERROR; 281 } 282 #ifdef RT_WLAN_PROT_LWIP_PBUF_FORCE 283 { 284 p = buff; 285 if ((eth_dev->netif->input(p, eth_dev->netif)) != ERR_OK) 286 { 287 return -RT_ERROR; 288 } 289 return RT_EOK; 290 } 291 #else 292 { 293 int count = 0; 294 295 while (p == RT_NULL) 296 { 297 p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); 298 if (p != RT_NULL) 299 break; 300 301 p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM); 302 if (p != RT_NULL) 303 break; 304 305 LOG_D("F:%s L:%d wait for pbuf_alloc!", __FUNCTION__, __LINE__); 306 rt_thread_delay(1); 307 count++; 308 309 //wait for 10ms or give up!! 310 if (count >= 10) 311 { 312 LOG_W("F:%s L:%d pbuf allocate fail!!!", __FUNCTION__, __LINE__); 313 return -RT_ENOMEM; 314 } 315 } 316 /*copy data dat -> pbuf*/ 317 pbuf_take(p, buff, len); 318 if ((eth_dev->netif->input(p, eth_dev->netif)) != ERR_OK) 319 { 320 LOG_D("F:%s L:%d IP input error", __FUNCTION__, __LINE__); 321 pbuf_free(p); 322 p = RT_NULL; 323 } 324 LOG_D("F:%s L:%d netif iput success! len:%d", __FUNCTION__, __LINE__, len); 325 return RT_EOK; 326 } 327 #endif 328 } 329 330 static rt_err_t rt_wlan_lwip_protocol_send(rt_device_t device, struct pbuf *p) 331 { 332 struct rt_wlan_device *wlan = ((struct eth_device *)device)->parent.user_data; 333 334 LOG_D("F:%s L:%d run", __FUNCTION__, __LINE__); 335 336 if (wlan == RT_NULL) 337 { 338 return RT_EOK; 339 } 340 341 #ifdef RT_WLAN_PROT_LWIP_PBUF_FORCE 342 { 343 rt_wlan_prot_transfer_dev(wlan, p, p->tot_len); 344 return RT_EOK; 345 } 346 #else 347 { 348 rt_uint8_t *frame; 349 350 /* sending data directly */ 351 if (p->len == p->tot_len) 352 { 353 frame = (rt_uint8_t *)p->payload; 354 rt_wlan_prot_transfer_dev(wlan, frame, p->tot_len); 355 LOG_D("F:%s L:%d run len:%d", __FUNCTION__, __LINE__, p->tot_len); 356 return RT_EOK; 357 } 358 frame = rt_malloc(p->tot_len); 359 if (frame == RT_NULL) 360 { 361 LOG_E("F:%s L:%d malloc out_buf fail\n", __FUNCTION__, __LINE__); 362 return -RT_ENOMEM; 363 } 364 /*copy pbuf -> data dat*/ 365 pbuf_copy_partial(p, frame, p->tot_len, 0); 366 /* send data */ 367 rt_wlan_prot_transfer_dev(wlan, frame, p->tot_len); 368 LOG_D("F:%s L:%d run len:%d", __FUNCTION__, __LINE__, p->tot_len); 369 rt_free(frame); 370 return RT_EOK; 371 } 372 #endif 373 } 374 375 #ifdef RT_USING_DEVICE_OPS 376 const static struct rt_device_ops wlan_lwip_ops = 377 { 378 RT_NULL, 379 RT_NULL, 380 RT_NULL, 381 RT_NULL, 382 RT_NULL, 383 rt_wlan_lwip_protocol_control 384 }; 385 #endif 386 387 static struct rt_wlan_prot *rt_wlan_lwip_protocol_register(struct rt_wlan_prot *prot, struct rt_wlan_device *wlan) 388 { 389 struct eth_device *eth = RT_NULL; 390 static rt_uint8_t id = 0; 391 char eth_name[4], timer_name[16]; 392 rt_device_t device = RT_NULL; 393 struct lwip_prot_des *lwip_prot; 394 395 if (wlan == RT_NULL || prot == RT_NULL) 396 return RT_NULL;; 397 398 LOG_D("F:%s L:%d is run wlan:0x%08x", __FUNCTION__, __LINE__, wlan); 399 400 do 401 { 402 /* find ETH device name */ 403 eth_name[0] = 'w'; 404 eth_name[1] = '0' + id++; 405 eth_name[2] = '\0'; 406 device = rt_device_find(eth_name); 407 } 408 while (device); 409 410 if (id > 9) 411 { 412 LOG_E("F:%s L:%d not find Empty name", __FUNCTION__, __LINE__, eth_name); 413 return RT_NULL; 414 } 415 416 if (rt_device_open((rt_device_t)wlan, RT_DEVICE_OFLAG_RDWR) != RT_EOK) 417 { 418 LOG_E("F:%s L:%d open wlan failed", __FUNCTION__, __LINE__); 419 return RT_NULL; 420 } 421 422 lwip_prot = rt_malloc(sizeof(struct lwip_prot_des)); 423 if (lwip_prot == RT_NULL) 424 { 425 LOG_E("F:%s L:%d malloc mem failed", __FUNCTION__, __LINE__); 426 rt_device_close((rt_device_t)wlan); 427 return RT_NULL; 428 } 429 rt_memset(lwip_prot, 0, sizeof(struct lwip_prot_des)); 430 431 eth = &lwip_prot->eth; 432 433 #ifdef RT_USING_DEVICE_OPS 434 eth->parent.ops = &wlan_lwip_ops; 435 #else 436 eth->parent.init = RT_NULL; 437 eth->parent.open = RT_NULL; 438 eth->parent.close = RT_NULL; 439 eth->parent.read = RT_NULL; 440 eth->parent.write = RT_NULL; 441 eth->parent.control = rt_wlan_lwip_protocol_control; 442 #endif 443 444 eth->parent.user_data = wlan; 445 eth->eth_rx = RT_NULL; 446 eth->eth_tx = rt_wlan_lwip_protocol_send; 447 448 /* register ETH device */ 449 if (eth_device_init(eth, eth_name) != RT_EOK) 450 { 451 LOG_E("eth device init failed"); 452 rt_device_close((rt_device_t)wlan); 453 rt_free(lwip_prot); 454 return RT_NULL; 455 } 456 rt_memcpy(&lwip_prot->prot, prot, sizeof(struct rt_wlan_prot)); 457 if (wlan->mode == RT_WLAN_STATION) 458 { 459 rt_sprintf(timer_name, "timer_%s", eth_name); 460 rt_timer_init(&lwip_prot->timer, timer_name, timer_callback, wlan, rt_tick_from_millisecond(1000), 461 RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT); 462 } 463 netif_set_up(eth->netif); 464 LOG_I("eth device init ok name:%s", eth_name); 465 466 return &lwip_prot->prot; 467 } 468 469 static void rt_wlan_lwip_protocol_unregister(struct rt_wlan_prot *prot, struct rt_wlan_device *wlan) 470 { 471 /*TODO*/ 472 LOG_D("F:%s L:%d is run wlan:0x%08x", __FUNCTION__, __LINE__, wlan); 473 } 474 475 static struct rt_wlan_prot_ops ops = 476 { 477 rt_wlan_lwip_protocol_recv, 478 rt_wlan_lwip_protocol_register, 479 rt_wlan_lwip_protocol_unregister 480 }; 481 482 int rt_wlan_lwip_init(void) 483 { 484 static struct rt_wlan_prot prot; 485 rt_wlan_prot_event_t event; 486 487 rt_memset(&prot, 0, sizeof(prot)); 488 rt_strncpy(&prot.name[0], RT_WLAN_PROT_LWIP, RT_WLAN_PROT_NAME_LEN); 489 prot.ops = &ops; 490 491 if (rt_wlan_prot_regisetr(&prot) != RT_EOK) 492 { 493 LOG_E("F:%s L:%d protocol regisetr failed", __FUNCTION__, __LINE__); 494 return -1; 495 } 496 497 for (event = RT_WLAN_PROT_EVT_INIT_DONE; event < RT_WLAN_PROT_EVT_MAX; event++) 498 { 499 rt_wlan_prot_event_register(&prot, event, rt_wlan_lwip_event_handle); 500 } 501 502 return 0; 503 } 504 INIT_PREV_EXPORT(rt_wlan_lwip_init); 505 506 #endif 507