1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  */
4 
5 #include <stdio.h>
6 #include <string.h>
7 
8 #include "k_api.h"
9 #include "ulog/ulog.h"
10 
11 #define TAG "netdev"
12 
13 #include <netdev_ipaddr.h>
14 #include <netdev.h>
15 
16 /* The list of network interface device */
17 struct netdev *netdev_list;
18 /* The default network interface device */
19 struct netdev *netdev_default;
20 
21 /**
22  * This function will register network interface device and
23  * add it to network interface device list.
24  *
25  * @param netdev the network interface device object
26  * @param name the network interface device name
27  * @param user_data user-specific data
28  *
29  * @return  0: registered successfully
30  *         -1: registered failed
31  */
netdev_register(struct netdev * netdev,const char * name,void * user_data)32 int netdev_register(struct netdev *netdev, const char *name, void *user_data)
33 {
34     uint16_t flags_mask;
35     int index;
36 
37     LOG("%s netdev %p name %s\r\n", __func__, netdev, name);
38 
39     ASSERT(netdev);
40 
41     /* clean network interface device */
42     flags_mask = NETDEV_FLAG_UP | NETDEV_FLAG_LINK_UP | NETDEV_FLAG_INTERNET_UP | NETDEV_FLAG_DHCP | NETDEV_FLAG_DHCPD;
43     netdev->flags &= ~flags_mask;
44 
45     ip_addr_set_zero(&(netdev->ip_addr));
46     ip_addr_set_zero(&(netdev->netmask));
47     ip_addr_set_zero(&(netdev->gw));
48     for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
49     {
50         ip_addr_set_zero(&(netdev->dns_servers[index]));
51     }
52     netdev->status_callback = NULL;
53     netdev->addr_callback = NULL;
54 
55     /* fill network interface device */
56     memset(netdev->name, 0, sizeof(netdev->name));
57     strncpy(netdev->name, name, sizeof(netdev->name)-1);
58     netdev->user_data = user_data;
59 
60     /* initialize current network interface device single list */
61     slist_init(&(netdev->list));
62 
63     CPSR_ALLOC();
64     RHINO_CPU_INTRPT_DISABLE();
65 
66     if (netdev_list == NULL)
67     {
68         LOGD(TAG, "%s netdev %s as the first node in list\r\n", __func__, netdev->name);
69         netdev_list = netdev;
70         //netdev_default = netdev;
71     }
72     else
73     {
74         /* tail insertion */
75         //slist_append(&(netdev_list->list), &(netdev->list));
76         LOGD(TAG, "%s netdev %s into list tail\r\n", __func__, netdev->name);
77         slist_add_tail(&(netdev->list), &(netdev_list->list));
78     }
79 
80     RHINO_CPU_INTRPT_ENABLE();
81 
82     return 0;
83 }
84 
85 /**
86  * This function will unregister network interface device and
87  * delete it from network interface device list.
88  *
89  * @param netdev the network interface device object
90  *
91  * @return  0: unregistered successfully
92  *         -1: unregistered failed
93  */
netdev_unregister(struct netdev * netdev)94 int netdev_unregister(struct netdev *netdev)
95 {
96     slist_t *node = NULL;
97     struct netdev *cur_netdev = NULL;
98 
99     ASSERT(netdev);
100 
101     if (netdev_list == NULL)
102     {
103         return -1;
104     }
105 
106     CPSR_ALLOC();
107     RHINO_CPU_INTRPT_DISABLE();
108 
109     slist_for_each_entry_safe(&(netdev_list->list), node, cur_netdev, struct netdev, list)
110     {
111         if (cur_netdev && (memcmp(cur_netdev, netdev, sizeof(struct netdev)) == 0))
112         {
113             slist_del(&(cur_netdev->list), &(netdev_list->list));
114             RHINO_CPU_INTRPT_ENABLE();
115 
116             return 0;
117         }
118     }
119 
120     RHINO_CPU_INTRPT_ENABLE();
121 
122     /* not find this network interface device in network interface device list */
123     return -1;
124 }
125 
126 /**
127  * This function will get the first network interface device
128  * with the flags in network interface device list.
129  *
130  * @param flags the network interface device flags
131  *
132  * @return != NULL: network interface device object
133  *            NULL: get failed
134  */
netdev_get_first_by_flags(uint16_t flags)135 struct netdev *netdev_get_first_by_flags(uint16_t flags)
136 {
137     slist_t *node = NULL;
138     struct netdev *netdev = NULL;
139 
140     if (netdev_list == NULL)
141     {
142         return NULL;
143     }
144 
145     CPSR_ALLOC();
146     RHINO_CPU_INTRPT_DISABLE();
147 
148     slist_for_each_entry_safe(&(netdev_list->list), node, netdev, struct netdev, list)
149     {
150         if (netdev && (netdev->flags & flags) != 0)
151         {
152             RHINO_CPU_INTRPT_ENABLE();
153             return netdev;
154         }
155     }
156 
157     RHINO_CPU_INTRPT_ENABLE();
158 
159     return NULL;
160 }
161 
162 /**
163  * This function will get the first network interface device
164  * in network interface device list by IP address.
165  *
166  * @param addr the network interface device IP address
167  *
168  * @return != NULL: network interface device object
169  *            NULL: get failed
170  */
netdev_get_by_ipaddr(ip_addr_t * ip_addr)171 struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr)
172 {
173     slist_t *node = NULL;
174     struct netdev *netdev = NULL;
175 
176     if (netdev_list == NULL)
177     {
178         return NULL;
179     }
180 
181     CPSR_ALLOC();
182     RHINO_CPU_INTRPT_DISABLE();
183 
184     slist_for_each_entry_safe(&(netdev_list->list), node, netdev, struct netdev, list)
185     {
186         if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr))
187         {
188            RHINO_CPU_INTRPT_ENABLE();
189            return netdev;
190         }
191     }
192 
193     RHINO_CPU_INTRPT_ENABLE();
194 
195     return NULL;
196 }
197 
198 /**
199  * This function will get network interface device
200  * in network interface device list by netdev name.
201  *
202  * @param name the network interface device name
203  *
204  * @return != NULL: network interface device object
205  *            NULL: get failed
206  */
netdev_get_by_name(const char * name)207 struct netdev *netdev_get_by_name(const char *name)
208 {
209     slist_t *node = NULL;
210     struct netdev *netdev = NULL;
211 
212     if (netdev_list == NULL)
213     {
214         return NULL;
215     }
216 
217     CPSR_ALLOC();
218     RHINO_CPU_INTRPT_DISABLE();
219 
220     slist_for_each_entry_safe(&(netdev_list->list), node, netdev, struct netdev, list)
221     {
222         if (netdev && (strncmp(netdev->name, name, strlen(netdev->name)) == 0))
223         {
224             RHINO_CPU_INTRPT_ENABLE();
225             return netdev;
226         }
227     }
228 
229     RHINO_CPU_INTRPT_ENABLE();
230 
231 
232     return NULL;
233 }
234 
235 #ifdef USING_SAL
236 /**
237  * This function will get the first network interface device
238  * in network interface device list by protocol family type.
239  *
240  * @param family the network interface device protocol family type
241  *
242  * @return != NULL: network interface device object
243  *            NULL: get failed
244  */
netdev_get_by_family(int family)245 struct netdev *netdev_get_by_family(int family)
246 {
247     slist_t *node = NULL;
248     struct netdev *netdev = NULL;
249     struct sal_proto_family *pf = NULL;
250 
251     if (netdev_list == NULL)
252     {
253         return NULL;
254     }
255 
256     CPSR_ALLOC();
257     RHINO_CPU_INTRPT_DISABLE();
258 
259     slist_for_each_entry_safe(&(netdev_list->list), node, netdev, struct netdev, list)
260     {
261         pf = (struct sal_proto_family *) netdev->sal_user_data;
262         if (pf && pf->skt_ops && pf->family == family && netdev_is_up(netdev))
263         {
264             RHINO_CPU_INTRPT_ENABLE();
265             return netdev;
266         }
267     }
268 
269     slist_for_each_entry_safe(&(netdev_list->list), node, netdev, struct netdev, list)
270     {
271         pf = (struct sal_proto_family *) netdev->sal_user_data;
272         if (pf && pf->skt_ops && pf->sec_family == family && netdev_is_up(netdev))
273         {
274             RHINO_CPU_INTRPT_ENABLE();
275             return netdev;
276         }
277     }
278 
279     RHINO_CPU_INTRPT_ENABLE();
280 
281     return NULL;
282 }
283 
284 /**
285  * This function will get the family type from network interface device
286  *
287  * @param netdev network interface device object
288  *
289  * @return the network interface device family type
290  */
netdev_family_get(struct netdev * netdev)291 int netdev_family_get(struct netdev *netdev)
292 {
293     ASSERT(netdev);
294 
295     return ((struct sal_proto_family *)netdev->sal_user_data)->family;
296 }
297 
298 #endif /* AOS_USING_SAL */
299 
300 /**
301  * This function will set default network interface device.
302  *
303  * @param netdev the network interface device to change
304  */
netdev_set_default(struct netdev * netdev)305 void netdev_set_default(struct netdev *netdev)
306 {
307     if (netdev)
308     {
309         netdev_default = netdev;
310         netdev->ops->set_default_netif(netdev);//add by li_zhihai@anyka.oa
311         LOGD("Setting default network interface device name(%s) successfully.", netdev->name);
312     }
313 }
314 
315 /**
316  * This function will enable network interface device .
317  *
318  * @param netdev the network interface device to change
319  *
320  * @return  0: set status successfully
321  *         -1: set status failed
322  */
netdev_set_up(struct netdev * netdev)323 int netdev_set_up(struct netdev *netdev)
324 {
325     if (!netdev->ops || !netdev->ops->set_up)
326     {
327         LOGE(TAG, "The network interface device(%s) not support to set status.", netdev->name);
328         return -1;
329     }
330 
331     /* network interface device status flags check */
332     if (netdev_is_up(netdev))
333     {
334         return 0;
335     }
336 
337     /* execute enable network interface device operations by network interface device driver */
338     return netdev->ops->set_up(netdev);
339 }
340 /**
341  * This function will disable network interface device.
342  *
343  * @param netdev the network interface device to change
344  *
345  * @return  0: set status successfully
346  *         -1: set sttaus failed
347  */
netdev_set_down(struct netdev * netdev)348 int netdev_set_down(struct netdev *netdev)
349 {
350     ASSERT(netdev);
351 
352     if (!netdev->ops || !netdev->ops->set_down)
353     {
354         LOGE(TAG, "The network interface device(%s) not support to set status.", netdev->name);
355         return -1;
356     }
357 
358     /* network interface device status flags check */
359     if (!netdev_is_up(netdev))
360     {
361         return 0;
362     }
363 
364     /* execute disable network interface device operations by network interface driver */
365     return netdev->ops->set_down(netdev);
366 }
367 
368 /**
369  * This function will control network interface device DHCP capability enable or disable.
370  *
371  * @param netdev the network interface device device to change
372  * @param is_enable the new DHCP status
373  *
374  * @return  0: set DHCP status successfully
375  *         -1: set DHCP status failed
376  */
netdev_dhcp_enabled(struct netdev * netdev,bool is_enabled)377 int netdev_dhcp_enabled(struct netdev *netdev, bool is_enabled)
378 {
379     ASSERT(netdev);
380 
381     if (!netdev->ops || !netdev->ops->set_dhcp)
382     {
383         LOGE(TAG, "The network interface device(%s) not support to set DHCP status.", netdev->name);
384         return -1;
385     }
386 
387     /* network interface device DHCP flags check */
388     if (netdev_is_dhcp_enabled(netdev) == is_enabled)
389     {
390         return 0;
391     }
392 
393     /* execute network interface device DHCP capability control operations */
394     return netdev->ops->set_dhcp(netdev, is_enabled);
395 }
396 
397 /**
398  * This function will control network interface device DHCP capability enable or disable.
399  *
400  * @param netdev the network interface device device to change
401  * @param is_enable the new DHCP status
402  *
403  * @return  0: set DHCP status successfully
404  *         -1: set DHCP status failed
405  */
netdev_dhcpd_enabled(struct netdev * netdev,bool is_enabled)406 int netdev_dhcpd_enabled(struct netdev *netdev, bool is_enabled)
407 {
408     ASSERT(netdev);
409 
410     if (!netdev->ops || !netdev->ops->set_dhcpd)
411     {
412         LOGE(TAG, "The network interface device(%s) not support to set DHCPD status.", netdev->name);
413         return -1;
414     }
415 
416     /* network interface device DHCP flags check */
417     if (netdev_is_dhcpd_enabled(netdev) == is_enabled)
418     {
419         return 0;
420     }
421 
422     if (is_enabled)
423     {
424         netdev->flags |= NETDEV_FLAG_DHCPD;
425     }
426     else
427     {
428         netdev->flags &= ~NETDEV_FLAG_DHCPD;
429     }
430 
431     /* execute network interface device DHCP capability control operations */
432     return netdev->ops->set_dhcpd(netdev, is_enabled);
433 }
434 
435 /**
436  * This function will set network interface device IP address.
437  *
438  * @param netdev the network interface device to change
439  * @param ipaddr the new IP address
440  *
441  * @return  0: set IP address successfully
442  *         -1: set IP address failed
443  */
netdev_set_ipaddr(struct netdev * netdev,const ip_addr_t * ip_addr)444 int netdev_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr)
445 {
446     ASSERT(netdev);
447     ASSERT(ip_addr);
448 
449     if (!netdev->ops || !netdev->ops->set_addr_info)
450     {
451         LOGE(TAG, "The network interface device(%s) not support to set IP address.", netdev->name);
452         return -1;
453     }
454 
455 //disabled by li_zhihai@any.oa
456 #if 0
457     if (netdev_is_dhcp_enabled(netdev))
458     {
459 
460         LOGE(TAG, "The network interface device(%s) DHCP capability is enable, not support set IP address.", netdev->name);
461         return -1;
462     }
463 #endif
464 
465      /* execute network interface device set IP address operations */
466     return netdev->ops->set_addr_info(netdev, (ip_addr_t *)ip_addr, NULL, NULL);
467 }
468 
469 /**
470  * This function will set network interface device netmask address.
471  *
472  * @param netdev the network interface device to change
473  * @param netmask the new netmask address
474  *
475  * @return  0: set netmask address successfully
476  *         -1: set netmask address failed
477  */
netdev_set_netmask(struct netdev * netdev,const ip_addr_t * netmask)478 int netdev_set_netmask(struct netdev *netdev, const ip_addr_t *netmask)
479 {
480     ASSERT(netdev);
481     ASSERT(netmask);
482 
483     if (!netdev->ops || !netdev->ops->set_addr_info)
484     {
485         LOGE(TAG, "The network interface device(%s) not support to set netmask address.", netdev->name);
486         return -1;
487     }
488 //disabled by li_zhihai@any.oa
489 #if 0
490     if (netdev_is_dhcp_enabled(netdev))
491     {
492        LOGE(TAG, "The network interface device(%s) DHCP capability is enable, not support set netmask address.", netdev->name);
493         return -1;
494     }
495 #endif
496     /* execute network interface device set netmask address operations */
497     return netdev->ops->set_addr_info(netdev, NULL, (ip_addr_t *)netmask, NULL);
498 }
499 
500 /**
501  * This function will set network interface device gateway address.
502  *
503  * @param netdev the network interface device to change
504  * @param gateway the new gateway address
505  *
506  * @return  0: set gateway address successfully
507  *         -1: set gateway address failed
508  */
netdev_set_gw(struct netdev * netdev,const ip_addr_t * gw)509 int netdev_set_gw(struct netdev *netdev, const ip_addr_t *gw)
510 {
511     ASSERT(netdev);
512     ASSERT(gw);
513 
514     if (!netdev->ops || !netdev->ops->set_addr_info)
515     {
516         LOGE(TAG, "The network interface device(%s) not support to set gateway address.", netdev->name);
517         return -1;
518     }
519 //disabled by li_zhihai@any.oa
520 #if 0
521     if (netdev_is_dhcp_enabled(netdev))
522     {
523         LOGE(TAG, "The network interface device(%s) DHCP capability is enable, not support set gateway address.", netdev->name);
524         return -1;
525     }
526 #endif
527     /* execute network interface device set gateway address operations */
528     return netdev->ops->set_addr_info(netdev, NULL, NULL, (ip_addr_t *)gw);
529 }
530 
531 /**
532  * This function will set network interface device DNS server address.
533  *
534  * @param netdev the network interface device to change
535  * @param dns_server the new DNS server address
536  *
537  * @return  0: set netmask address successfully
538  *         -1: set netmask address failed
539  */
netdev_set_dns_server(struct netdev * netdev,uint8_t dns_num,const ip_addr_t * dns_server)540 int netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server)
541 {
542     ASSERT(netdev);
543     ASSERT(dns_server);
544 
545     if (dns_num >= NETDEV_DNS_SERVERS_NUM)
546     {
547         LOGE(TAG, "The number of DNS servers(%d) set exceeds the maximum number(%d).", dns_num + 1, NETDEV_DNS_SERVERS_NUM);
548         return -1;
549     }
550 
551     if (!netdev->ops || !netdev->ops->set_dns_server)
552     {
553         LOGE(TAG, "The network interface device(%s) not support to set DNS server address.", netdev->name);
554         return -1;
555     }
556 
557     /* execute network interface device set DNS server address operations */
558     return netdev->ops->set_dns_server(netdev, dns_num, (ip_addr_t *)dns_server);
559 }
560 
561 /**
562  * This function will set callback to be called when the network interface device status has been changed.
563  *
564  * @param netdev the network interface device to change
565  * @param status_callback the callback be called when the status has been changed.
566  */
netdev_set_status_callback(struct netdev * netdev,netdev_callback_fn status_callback)567 void netdev_set_status_callback(struct netdev *netdev, netdev_callback_fn status_callback)
568 {
569     ASSERT(netdev);
570     ASSERT(status_callback);
571 
572     netdev->status_callback = status_callback;
573 }
574 
575 /**
576  * This function will set callback to be called when the network interface device address has been changed.
577  *
578  * @param netdev the network interface device to change
579  * @param addr_callback the callback be called when the address has been changed.
580  */
netdev_set_addr_callback(struct netdev * netdev,netdev_callback_fn addr_callback)581 void netdev_set_addr_callback(struct netdev *netdev, netdev_callback_fn addr_callback)
582 {
583     ASSERT(netdev);
584     ASSERT(addr_callback);
585 
586     netdev->addr_callback = addr_callback;
587 }
588 
589 
590 /**
591  * This function will set network interface device IP address.
592  * @NOTE it can only be called in the network interface device driver.
593  *
594  * @param netdev the network interface device to change
595  * @param ipaddr the new IP address
596  */
netdev_low_level_set_ipaddr(struct netdev * netdev,const ip_addr_t * ip_addr)597 void netdev_low_level_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr)
598 {
599     ASSERT(ip_addr);
600 
601     if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr) == 0)
602     {
603         ip_addr_copy(netdev->ip_addr, *ip_addr);
604 
605 #ifdef USING_SAL
606         /* set network interface device flags to internet up */
607         if (netdev_is_up(netdev) && netdev_is_link_up(netdev))
608         {
609             sal_check_netdev_internet_up(netdev);
610         }
611 #endif /* AOS_USING_SAL */
612 
613         /* execute IP address change callback function */
614         if (netdev->addr_callback)
615         {
616             netdev->addr_callback(netdev, NETDEV_CB_ADDR_IP);
617         }
618     }
619 }
620 
621 /**
622  * This function will set network interface device netmask address.
623  * @NOTE it can only be called in the network interface device driver.
624  *
625  * @param netdev the network interface device to change
626  * @param netmask the new netmask address
627  */
netdev_low_level_set_netmask(struct netdev * netdev,const ip_addr_t * netmask)628 void netdev_low_level_set_netmask(struct netdev *netdev, const ip_addr_t *netmask)
629 {
630     ASSERT(netmask);
631 
632     if (netdev && ip_addr_cmp(&(netdev->netmask), netmask) == 0)
633     {
634         ip_addr_copy(netdev->netmask, *netmask);
635 
636 #ifdef AOS_USING_SAL
637         /* set network interface device flags to internet up */
638         if (netdev_is_up(netdev) && netdev_is_link_up(netdev) &&
639                 !ip_addr_isany(&(netdev->ip_addr)))
640         {
641             sal_check_netdev_internet_up(netdev);
642         }
643 #endif /* AOS_USING_SAL */
644 
645         /* execute netmask address change callback function */
646         if (netdev->addr_callback)
647         {
648             netdev->addr_callback(netdev, NETDEV_CB_ADDR_NETMASK);
649         }
650     }
651 }
652 
653 /**
654  * This function will set network interface device gateway address.
655  * @NOTE it can only be called in the network interface device driver.
656  *
657  * @param netdev the network interface device to change
658  * @param gateway the new gateway address
659  */
netdev_low_level_set_gw(struct netdev * netdev,const ip_addr_t * gw)660 void netdev_low_level_set_gw(struct netdev *netdev, const ip_addr_t *gw)
661 {
662     ASSERT(gw);
663 
664     if (netdev && ip_addr_cmp(&(netdev->gw), gw) == 0)
665     {
666         ip_addr_copy(netdev->gw, *gw);
667 
668 #ifdef USING_SAL
669         /* set network interface device flags to internet up */
670         if (netdev_is_up(netdev) && netdev_is_link_up(netdev) &&
671                 !ip_addr_isany(&(netdev->ip_addr)))
672         {
673             sal_check_netdev_internet_up(netdev);
674         }
675 #endif /* AOS_USING_SAL */
676 
677         /* execute gateway address change callback function */
678         if (netdev->addr_callback)
679         {
680             netdev->addr_callback(netdev, NETDEV_CB_ADDR_GATEWAY);
681         }
682     }
683 }
684 
685 /**
686  * This function will set network interface device DNS server address.
687  * @NOTE it can only be called in the network interface device driver.
688  *
689  * @param netdev the network interface device to change
690  * @param dns_server the new DNS server address
691  *
692  */
netdev_low_level_set_dns_server(struct netdev * netdev,uint8_t dns_num,const ip_addr_t * dns_server)693 void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server)
694 {
695     int index;
696 
697     ASSERT(dns_server);
698 
699     /* check DNS servers is exist */
700     for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++)
701     {
702         if (ip_addr_cmp(&(netdev->dns_servers[index]), dns_server))
703         {
704             return;
705         }
706     }
707 
708     if (netdev && dns_num < NETDEV_DNS_SERVERS_NUM)
709     {
710         ip_addr_copy(netdev->dns_servers[dns_num], *dns_server);
711 
712         /* execute DNS servers address change callback function */
713         if (netdev->addr_callback)
714         {
715             netdev->addr_callback(netdev, NETDEV_CB_ADDR_DNS_SERVER);
716         }
717     }
718 }
719 
720 #ifdef NETDEV_USING_AUTO_DEFAULT
721 /* Change to the first link_up network interface device automatically */
netdev_auto_change_default(struct netdev * netdev)722 static void netdev_auto_change_default(struct netdev *netdev)
723 {
724     struct netdev *new_netdev = NULL;
725 
726     if (rt_memcmp(netdev, netdev_default, sizeof(struct netdev)) == 0)
727     {
728         new_netdev = netdev_get_first_by_flags(NETDEV_FLAG_LINK_UP);
729         if (new_netdev)
730         {
731             netdev_set_default(new_netdev);
732         }
733     }
734 }
735 #endif /* NETDEV_USING_AUTO_DEFAULT */
736 
737 /**
738  * This function will set network interface device status.
739  * @NOTE it can only be called in the network interface device driver.
740  *
741  * @param netdev the network interface device to change
742  * @param is_up the new status
743  */
netdev_low_level_set_status(struct netdev * netdev,bool is_up)744 void netdev_low_level_set_status(struct netdev *netdev, bool is_up)
745 {
746     if (netdev && netdev_is_up(netdev) != is_up)
747     {
748         if (is_up)
749         {
750             netdev->flags |= NETDEV_FLAG_UP;
751             if(netdev_default == NULL)
752             {
753                 netdev_default = netdev;
754                 netdev_set_default(netdev);
755             }
756         }
757         else
758         {
759             netdev->flags &= ~NETDEV_FLAG_UP;
760 
761 #ifdef NETDEV_USING_AUTO_DEFAULT
762             /* change to the first link_up network interface device automatically */
763             netdev_auto_change_default(netdev);
764 #endif /* NETDEV_USING_AUTO_DEFAULT */
765         }
766 
767         /* execute  network interface device status change callback function */
768         if (netdev->status_callback)
769         {
770             netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_UP : NETDEV_CB_STATUS_DOWN);
771         }
772     }
773 }
774 
775 /**
776  * This function will set network interface device active link status.
777  * @NOTE it can only be called in the network interface device driver.
778  *
779  * @param netdev the network interface device to change
780  * @param is_up the new link status
781  */
netdev_low_level_set_link_status(struct netdev * netdev,bool is_up)782 void netdev_low_level_set_link_status(struct netdev *netdev, bool is_up)
783 {
784     if (netdev && netdev_is_link_up(netdev) != is_up)
785     {
786         if (is_up)
787         {
788             netdev->flags |= NETDEV_FLAG_LINK_UP;
789 
790 #ifdef USING_SAL
791             /* set network interface device flags to internet up */
792             if (netdev_is_up(netdev) && !ip_addr_isany(&(netdev->ip_addr)))
793             {
794                 sal_check_netdev_internet_up(netdev);
795             }
796 #endif /* USING_SAL */
797         }
798         else
799         {
800             netdev->flags &= ~NETDEV_FLAG_LINK_UP;
801 
802             /* set network interface device flags to internet down */
803             netdev->flags &= ~NETDEV_FLAG_INTERNET_UP;
804 
805 #ifdef NETDEV_USING_AUTO_DEFAULT
806             /* change to the first link_up network interface device automatically */
807             netdev_auto_change_default(netdev);
808 #endif /* NETDEV_USING_AUTO_DEFAULT */
809         }
810 
811         /* execute link status change callback function */
812         if (netdev->status_callback)
813         {
814             netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_LINK_UP : NETDEV_CB_STATUS_LINK_DOWN);
815         }
816     }
817 }
818 
819 /**
820  * This function will set network interface device DHCP status.
821  * @NOTE it can only be called in the network interface device driver.
822  *
823  * @param netdev the network interface device to change
824  * @param is_up the new DHCP status
825  */
netdev_low_level_set_dhcp_status(struct netdev * netdev,bool is_enable)826 void netdev_low_level_set_dhcp_status(struct netdev *netdev, bool is_enable)
827 {
828     if (netdev && netdev_is_dhcp_enabled(netdev) != is_enable)
829     {
830         if (is_enable)
831         {
832             netdev->flags |= NETDEV_FLAG_DHCP;
833         }
834         else
835         {
836             netdev->flags &= ~NETDEV_FLAG_DHCP;
837         }
838 
839         /* execute DHCP status change callback function */
840         if (netdev->status_callback)
841         {
842             netdev->status_callback(netdev, is_enable ? NETDEV_CB_STATUS_DHCP_ENABLE : NETDEV_CB_STATUS_DHCP_DISABLE);
843         }
844     }
845 }
846 
847