1 /*
2  *  Copyright 2008-2024 NXP
3  *
4  *  SPDX-License-Identifier: BSD-3-Clause
5  */
6 /*
7  * Copyright (c) 2016 Intel Corporation.
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  */
11 
12 /*! \file wm_net.h
13  *  \brief Network Abstraction Layer
14  *
15  * This provides the calls related to the network layer.
16  *
17  *
18  */
19 
20 #ifndef _WM_NET_H_
21 #define _WM_NET_H_
22 
23 #include <string.h>
24 
25 #include <osa.h>
26 #include <wmtypes.h>
27 #include <wmerrno.h>
28 #include <zephyr/kernel.h>
29 #include <zephyr/net/ethernet.h>
30 #include <zephyr/net/net_pkt.h>
31 #include <zephyr/net/net_if.h>
32 #include <zephyr/net/wifi_mgmt.h>
33 
34 #if (CONFIG_POSIX_API)
35 #include <zephyr/posix/sys/socket.h>
36 #include <zephyr/posix/sys/select.h>
37 #include <zephyr/posix/arpa/inet.h>
38 #include <zephyr/posix/unistd.h>
39 #else
40 #include <zephyr/net/socket.h>
41 #endif
42 
43 #define NETIF_NAMESIZE       6
44 #define NETIF_MAX_HWADDR_LEN 6
45 
46 /* copy zephyr struct net if */
47 struct netif
48 {
49     /** The net_if_dev instance the net_if is related to */
50     struct net_if_dev *if_dev;
51 #if (CONFIG_NET_STATISTICS_PER_INTERFACE)
52     /** Network statistics related to this network interface */
53     struct net_stats stats;
54 #endif /* CONFIG_NET_STATISTICS_PER_INTERFACE */
55 
56     /** Network interface instance configuration */
57     struct net_if_config config;
58 
59 #if (CONFIG_NET_POWER_MANAGEMENT)
60     /** Keep track of packets pending in traffic queues. This is
61      * needed to avoid putting network device driver to sleep if
62      * there are packets waiting to be sent.
63      */
64     int tx_pending;
65 #endif
66 
67     struct k_mutex lock;
68     struct k_mutex tx_lock;
69 };
70 
71 /**
72  * Helper struct to hold private data used to operate your ethernet interface.
73  * Keeping the ethernet address of the MAC in this struct is not necessary
74  * as it is already kept in the struct netif.
75  * But this is only an example, anyway...
76  */
77 struct ethernetif
78 {
79     struct net_eth_addr ethaddr;
80     /* Interface to bss type identification that tells the FW wherether
81        the data is for STA for UAP */
82     uint8_t interface;
83     /* Add whatever per-interface state that is needed here. */
84 };
85 
86 struct interface
87 {
88     struct net_if *netif;
89     uint8_t mac_address[6];
90     struct net_addr ipaddr;
91     struct net_addr nmask;
92     struct net_addr gw;
93     struct ethernetif state;
94 #if (CONFIG_NET_STATISTICS_WIFI)
95     struct net_stats_wifi stats;
96 #endif
97     scan_result_cb_t scan_cb;
98     uint16_t max_bss_cnt;
99 };
100 
101 typedef struct interface interface_t;
102 
103 #define NET_SUCCESS WM_SUCCESS
104 #define NET_ERROR   (-WM_FAIL)
105 #define NET_ENOBUFS ENOBUFS
106 
107 #define NET_BLOCKING_OFF 1
108 #define NET_BLOCKING_ON  0
109 
110 /* Error Codes
111  * lwIP provides all standard errnos defined in arch.h, hence no need to
112  * redefine them here.
113  * */
114 
115 /* To be consistent with naming convention */
116 #define net_socket(domain, type, protocol)            socket(domain, type, protocol)
117 #define net_select(nfd, read, write, except, timeout) select(nfd, read, write, except, timeout)
118 #define net_bind(sock, addr, len)                     bind(sock, addr, len)
119 #define net_listen(sock, backlog)                     listen(sock, backlog)
120 #define net_close(c)                                  close((c))
121 #define net_accept(sock, addr, len)                   accept(sock, addr, len)
122 #define net_shutdown(c, b)                            shutdown(c, b)
123 #define net_connect(sock, addr, len)                  connect(sock, addr, len)
124 #define net_read(sock, data, len)                     read(sock, data, len)
125 #define net_write(sock, data, len)                    write(sock, data, len)
126 
127 /* directly map this to the zephyr internal functions */
128 #define inet_aton(cp, addr) inet_pton(AF_INET, cp, (char *)addr)
129 
130 enum net_address_types
131 {
132     /** static IP address */
133     NET_ADDR_TYPE_STATIC = 0,
134     /** Dynamic  IP address*/
135     NET_ADDR_TYPE_DHCP = 1,
136     /** Link level address */
137     NET_ADDR_TYPE_LLA = 2,
138 };
139 
140 /** This data structure represents an IPv4 address */
141 struct net_ipv4_config
142 {
143     /** Set to \ref ADDR_TYPE_DHCP to use DHCP to obtain the IP address or
144      *  \ref ADDR_TYPE_STATIC to use a static IP. In case of static IP
145      *  address ip, gw, netmask and dns members must be specified.  When
146      *  using DHCP, the ip, gw, netmask and dns are overwritten by the
147      *  values obtained from the DHCP server. They should be zeroed out if
148      *  not used. */
149     enum net_address_types addr_type;
150     /** The system's IP address in network order. */
151     unsigned address;
152     /** The system's default gateway in network order. */
153     unsigned gw;
154     /** The system's subnet mask in network order. */
155     unsigned netmask;
156     /** The system's primary dns server in network order. */
157     unsigned dns1;
158     /** The system's secondary dns server in network order. */
159     unsigned dns2;
160 };
161 
162 #if CONFIG_IPV6
163 /** This data structure represents an IPv6 address */
164 struct net_ipv6_config
165 {
166     /** The system's IPv6 address in network order. */
167     unsigned address[4];
168     /** The address type: linklocal, site-local or global. */
169     unsigned char addr_type;
170     /** The state of IPv6 address (Tentative, Preferred, etc). */
171     unsigned char addr_state;
172 };
173 #endif
174 
175 /** Network IP configuration.
176  *
177  *  This data structure represents the network IP configuration
178  *  for IPv4 as well as IPv6 addresses
179  */
180 struct net_ip_config
181 {
182 #if CONFIG_IPV6
183     /** The network IPv6 address configuration that should be
184      * associated with this interface. */
185     struct net_ipv6_config ipv6[CONFIG_MAX_IPV6_ADDRESSES];
186     /** The network IPv6 valid addresses count */
187     size_t ipv6_count;
188 #endif
189     /** The network IPv4 address configuration that should be
190      * associated with this interface. */
191     struct net_ipv4_config ipv4;
192 };
193 
194 /** Set hostname for network interface
195  *
196  * \param[in] hostname Hostname to be set.
197  *
198  * \note NULL is a valid value for hostname.
199  *
200  * \return WM_SUCESS
201  */
202 int net_dhcp_hostname_set(char *hostname);
203 
204 /** Deactivate the dhcp timer
205  *
206  */
207 void net_stop_dhcp_timer(void);
208 
209 /** Set socket blocking option as on or off
210  *
211  * \param[in] sock socket number to be set for blocking option.
212  * \param[in] state set blocking on or off
213  *
214  * \return WM_SUCESS otherwise standard LWIP error codes.
215  */
net_socket_blocking(int sock,int state)216 static inline int net_socket_blocking(int sock, int state)
217 {
218     /* TODO: implement */
219     return 0;
220 }
221 
222 /** Get error number from provided socket
223  *
224  * \param[in] sock socket number to get error number.
225  *
226  * \return error number.
227  */
net_get_sock_error(int sock)228 static inline int net_get_sock_error(int sock)
229 {
230     int ret = 0;
231 
232     return ret;
233 }
234 
235 /** Converts Internet host address from the IPv4 dotted-decimal notation into
236  * binary form (in network byte order)
237  *
238  * \param[in] cp IPv4 host address in dotted-decimal notation.
239  *
240  * \return IPv4 address in binary form
241  */
net_inet_aton(const char * cp)242 static inline uint32_t net_inet_aton(const char *cp)
243 {
244     struct in_addr addr;
245     addr.s_addr = 0;
246 
247     (void)net_addr_pton(AF_INET, cp, &addr);
248     return addr.s_addr;
249 }
250 
251 /** set MAC hardware address to lwip network interface
252  *
253  * \param[in] stamac sta MAC address.
254  * \param[in] uapmac uap MAC address.
255  *
256  */
257 void net_wlan_set_mac_address(unsigned char *stamac, unsigned char *uapmac);
258 
259 /** Skip a number of bytes at the start of a stack buffer
260  *
261  * \param[in] buf input stack buffer.
262  * \param[in] in_offset offset to skip.
263  *
264  * \return the payload pointer after skip a number of bytes
265  */
net_stack_buffer_skip(void * buf,uint16_t in_offset)266 static inline uint8_t *net_stack_buffer_skip(void *buf, uint16_t in_offset)
267 {
268     uint16_t offset_left = in_offset;
269     struct net_buf *frag = ((struct net_pkt *)buf)->frags;
270     while (frag && (frag->len <= offset_left))
271     {
272         offset_left = offset_left - frag->len;
273         frag        = frag->frags;
274     }
275     return (uint8_t *)(frag->data + offset_left);
276 }
277 
278 /** Free a buffer allocated from stack memory
279  *
280  * \param[in] buf stack buffer pointer.
281  *
282  */
net_stack_buffer_free(void * buf)283 static inline void net_stack_buffer_free(void *buf)
284 {
285     net_pkt_unref((struct net_pkt *)buf);
286 }
287 
288 /** Copy (part of) the contents of a packet buffer to an application supplied buffer
289  *
290  * \param[in] stack_buffer the stack buffer from which to copy data.
291  * \param[in] dst the destination buffer.
292  * \param[in] len length of data to copy.
293  * \param[in] offset offset into the stack buffer from where to begin copying
294  * \return copy status based on stack definition.
295  */
296 int net_stack_buffer_copy_partial(void *stack_buffer, void *dst, uint16_t len, uint16_t offset);
297 
298 /** Get the data payload inside the stack buffer.
299  *
300  * \param[in] buf input stack buffer.
301  *
302  * \return the payload pointer of the stack buffer.
303  */
net_stack_buffer_get_payload(void * buf)304 static inline void *net_stack_buffer_get_payload(void *buf)
305 {
306     return net_pkt_data((struct net_pkt *)buf);
307 }
308 
309 #if CONFIG_WIFI_PKT_FWD
310 /** Send packet from Wi-Fi driver
311  *
312  * \param[in] interface Wi-Fi interface.
313  * \param[in] stack_buffer net stack buffer pointer.
314  *
315  * \return WM_SUCCESS on success
316  * \return -WM_FAIL otherwise
317  */
318 int net_wifi_packet_send(uint8_t interface, void *stack_buffer);
319 
320 /** Generate TX net packet buffer
321  *
322  * \param[in] interface Wi-Fi interface.
323  * \param[in] payload source data payload pointer.
324  * \param[in] datalen data length.
325  *
326  * \return net packet
327  */
328 struct net_pkt *gen_tx_pkt_from_data(uint8_t interface, uint8_t *payload, uint16_t datalen);
329 #endif
330 
331 /** Converts Internet host address in network byte order to a string in IPv4
332  * dotted-decimal notation
333  *
334  * \param[in] addr IP address in network byte order.
335  * \param[out] cp buffer in which IPv4 dotted-decimal string is returned.
336  *
337  */
net_inet_ntoa(unsigned long addr,char * cp)338 static inline void net_inet_ntoa(unsigned long addr, char *cp)
339 {
340     struct in_addr saddr;
341 
342     saddr.s_addr = addr;
343     net_addr_ntop(AF_INET, &saddr, cp, NET_IPV4_ADDR_LEN);
344 }
345 
346 /** Check whether buffer is IPv4 or IPV6 packet type
347  *
348  * \param[in] buffer pointer to buffer where packet to be checked located.
349  *
350  * \return true if buffer packet type matches with IPv4 or IPv6, false otherwise.
351  *
352  */
net_is_ip_or_ipv6(const uint8_t * buffer)353 static inline bool net_is_ip_or_ipv6(const uint8_t *buffer)
354 {
355     if (((const struct net_eth_hdr *)(const void *)buffer)->type == htons(ETH_P_IP) ||
356         ((const struct net_eth_hdr *)(const void *)buffer)->type == htons(ETH_P_IPV6))
357     {
358         return true;
359     }
360 
361     return false;
362 }
363 
364 /** Get interface handle from socket descriptor
365  *
366  * Given a socket descriptor this API returns which interface it is bound with.
367  *
368  * \param[in] sock socket descriptor
369  *
370  * \return[out] interface handle
371  */
372 void *net_sock_to_interface(int sock);
373 
374 /** Initialize TCP/IP networking stack
375  *
376  * \return WM_SUCCESS on success
377  * \return -WM_FAIL otherwise
378  */
379 int net_wlan_init(void);
380 
381 /** DiInitialize TCP/IP networking stack
382  *
383  * \return WM_SUCCESS on success
384  * \return -WM_FAIL otherwise
385  */
386 int net_wlan_deinit(void);
387 
388 /** Get STA interface netif structure pointer
389  *
390  * \rerurn A pointer to STA interface netif structure
391  *
392  */
393 struct netif *net_get_sta_interface(void);
394 
395 #if UAP_SUPPORT
396 /** Get uAP interface netif structure pointer
397  *
398  * \rerurn A pointer to uAP interface netif structure
399  *
400  */
401 struct netif *net_get_uap_interface(void);
402 #endif
403 
404 /** Get interface name for given netif
405  *
406  * \param[out] pif_name Buffer to store interface name
407  * \param[in] iface Interface to get the name
408  *
409  * \return WM_SUCCESS on success
410  * \return -WM_FAIL otherwise
411  *
412  */
413 int net_get_if_name_netif(char *pif_name, struct netif *iface);
414 
415 /** Get client data index for storing private data in * netif.
416  *
417  * \return allocated client data index, -1 if error or
418  *         not supported.
419  */
420 int net_alloc_client_data_id();
421 
422 /** Get station interface handle
423  *
424  * Some APIs require the interface handle to be passed to them. The handle can
425  * be retrieved using this API.
426  *
427  * \return station interface handle
428  */
429 void *net_get_sta_handle(void);
430 #define net_get_mlan_handle() net_get_sta_handle()
431 
432 #if UAP_SUPPORT
433 /** Get micro-AP interface handle
434  *
435  * Some APIs require the interface handle to be passed to them. The handle can
436  * be retrieved using this API.
437  *
438  * \return micro-AP interface handle
439  */
440 void *net_get_uap_handle(void);
441 #endif
442 
443 /** Take interface up
444  *
445  * Change interface state to up. Use net_get_sta_handle(),
446  * net_get_uap_handle() to get interface handle.
447  *
448  * \param[in] intrfc_handle interface handle
449  *
450  * \return void
451  */
452 void net_interface_up(void *intrfc_handle);
453 
454 /** Take interface down
455  *
456  * Change interface state to down. Use net_get_sta_handle(),
457  * net_get_uap_handle() to get interface handle.
458  *
459  * \param[in] intrfc_handle interface handle
460  *
461  * \return void
462  */
463 void net_interface_down(void *intrfc_handle);
464 
465 /** Stop DHCP client on given interface
466  *
467  * Stop the DHCP client on given interface state. Use net_get_sta_handle(),
468  * net_get_uap_handle() to get interface handle.
469  *
470  * \param[in] intrfc_handle interface handle
471  *
472  * \return void
473  */
474 void net_interface_dhcp_stop(void *intrfc_handle);
475 
476 /** Cleanup DHCP client on given interface
477  *
478  * Cleanup the DHCP client on given interface state. Use net_get_sta_handle(),
479  * net_get_uap_handle() to get interface handle.
480  *
481  * \param[in] intrfc_handle interface handle
482  *
483  */
484 void net_interface_dhcp_cleanup(void *intrfc_handle);
485 
486 /** Configure IP address for interface
487  *
488  * \param[in] addr Address that needs to be configured.
489  * \param[in] intrfc_handle Handle for network interface to be configured.
490  *
491  * \return WM_SUCCESS on success or an error code.
492  */
493 int net_configure_address(struct net_ip_config *addr, void *intrfc_handle);
494 
495 /** Configure DNS server address
496  *
497  * \param[in] ip IP address of the DNS server to set
498  * \param[in] role Network wireless BSS Role
499  *
500  */
501 void net_configure_dns(struct net_ip_config *ip, unsigned int role);
502 
503 /** Get interface IP Address in \ref net_ip_config
504  *
505  * This function will get the IP address of a given interface. Use
506  * net_get_sta_handle(), net_get_uap_handle() to get
507  * interface handle.
508  *
509  * \param[out] addr \ref net_ip_config
510  * \param[in] intrfc_handle interface handle
511  *
512  * \return WM_SUCCESS on success or error code.
513  */
514 int net_get_if_addr(struct net_ip_config *addr, void *intrfc_handle);
515 
516 #if CONFIG_IPV6
517 /** Get interface IPv6 Addresses & their states in \ref net_ip_config
518  *
519  * This function will get the IPv6 addresses & address states of a given
520  * interface. Use net_get_sta_handle() to get interface handle.
521  *
522  * \param[out] addr \ref net_ip_config
523  * \param[in] intrfc_handle interface handle
524  *
525  * \return WM_SUCCESS on success or error code.
526  */
527 int net_get_if_ipv6_addr(struct net_ip_config *addr, void *intrfc_handle);
528 
529 /** Get list of preferred IPv6 Addresses of a given interface
530  * in \ref net_ip_config
531  *
532  * This function will get the list of IPv6 addresses whose address state
533  * is Preferred.
534  * Use net_get_sta_handle() to get interface handle.
535  *
536  * \param[out] addr \ref net_ip_config
537  * \param[in] intrfc_handle interface handle
538  *
539  * \return Number of IPv6 addresses whose address state is Preferred
540  */
541 int net_get_if_ipv6_pref_addr(struct net_ip_config *addr, void *intrfc_handle);
542 
543 /** Get the description of IPv6 address state
544  *
545  * This function will get the IPv6 address state description like -
546  * Invalid, Preferred, Deprecated
547  *
548  * \param[in] addr_state Address state
549  *
550  * \return IPv6 address state description
551  */
552 char *ipv6_addr_state_to_desc(unsigned char addr_state);
553 
554 /** Get the description of IPv6 address
555  *
556  * This function will get the IPv6 address type description like -
557  * Linklocal, Global, Sitelocal, Uniquelocal
558  *
559  * \param[in] ipv6_conf Pointer to IPv6 configuration of type \ref net_ipv6_config
560  *
561  * \return IPv6 address description
562  */
563 char *ipv6_addr_addr_to_desc(struct net_ipv6_config *ipv6_conf);
564 
565 /** Get the description of IPv6 address type
566  *
567  * This function will get the IPv6 address type description like -
568  * Linklocal, Global, Sitelocal, Uniquelocal
569  *
570  * \param[in] ipv6_conf Pointer to IPv6 configuration of type \ref net_ipv6_config
571  *
572  * \return IPv6 address type description
573  */
574 char *ipv6_addr_type_to_desc(struct net_ipv6_config *ipv6_conf);
575 #endif /* CONFIG_IPV6 */
576 
577 /** Get interface Name string containing name and number
578  *
579  * This function will get the string containing name and number for given interface.
580  * Use net_get_sta_handle(), net_get_uap_handle() to get
581  * interface handle.
582  *
583  * \param[out] if_name interface name pointer
584  * \param[in] intrfc_handle interface handle
585  *
586  * \return WM_SUCCESS on success or error code.
587  */
588 int net_get_if_name(char *if_name, void *intrfc_handle);
589 
590 /** Get interface IP Address
591  *
592  * This function will get the IP Address of a given interface. Use
593  * net_get_sta_handle(), net_get_uap_handle() to get
594  * interface handle.
595  *
596  * \param[out] ip ip address pointer
597  * \param[in] intrfc_handle interface handle
598  *
599  * \return WM_SUCCESS on success or error code.
600  */
601 int net_get_if_ip_addr(uint32_t *ip, void *intrfc_handle);
602 
603 /** Get interface IP Subnet-Mask
604  *
605  * This function will get the Subnet-Mask of a given interface. Use
606  * net_get_sta_handle(), net_get_uap_handle() to get
607  * interface handle.
608  *
609  * \param[in] mask Subnet Mask pointer
610  * \param[in] intrfc_handle interface
611  *
612  * \return WM_SUCCESS on success or error code.
613  */
614 int net_get_if_ip_mask(uint32_t *nm, void *intrfc_handle);
615 
616 /** Initialize the network stack
617  *
618  *  This function initializes the network stack. This function is
619  *  called by wlan_start().
620  *
621  *  Applications may optionally call this function directly:
622  *  if they wish to use the networking stack (loopback interface)
623  *  without the wlan functionality.
624  *  if they wish to initialize the networking stack even before wlan
625  *  comes up.
626  *
627  * \note This function may safely be called multiple times.
628  */
629 void net_ipv4stack_init(void);
630 
631 /** Display network statistics
632  */
633 void net_stat(void);
634 
635 #if CONFIG_WIFI_NM_WPA_SUPPLICANT
636 /** Get supplicant ready state
637  */
638 bool get_supp_ready_state(void);
639 #endif
640 
641 #if CONFIG_P2P
642 int netif_get_bss_type();
643 #endif
644 
645 #ifdef MGMT_RX
646 void rx_mgmt_register_callback(int (*rx_mgmt_cb_fn)(const enum wlan_bss_type bss_type,
647                                                     const wifi_mgmt_frame_t *frame,
648                                                     const size_t len));
649 
650 void rx_mgmt_deregister_callback(void);
651 #endif
652 
653 int nxp_wifi_internal_tx(const struct device *dev, struct net_pkt *pkt);
654 void nxp_wifi_internal_register_rx_cb(int (*rx_cb_fn)(struct net_if *iface, struct net_pkt *pkt));
655 const struct netif *net_if_get_binding(const char *ifname);
656 #endif /* _WM_NET_H_ */
657