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 /** Converts Internet host address in network byte order to a string in IPv4
310  * dotted-decimal notation
311  *
312  * \param[in] addr IP address in network byte order.
313  * \param[out] cp buffer in which IPv4 dotted-decimal string is returned.
314  *
315  */
net_inet_ntoa(unsigned long addr,char * cp)316 static inline void net_inet_ntoa(unsigned long addr, char *cp)
317 {
318     struct in_addr saddr;
319 
320     saddr.s_addr = addr;
321     net_addr_ntop(AF_INET, &saddr, cp, NET_IPV4_ADDR_LEN);
322 }
323 
324 /** Check whether buffer is IPv4 or IPV6 packet type
325  *
326  * \param[in] buffer pointer to buffer where packet to be checked located.
327  *
328  * \return true if buffer packet type matches with IPv4 or IPv6, false otherwise.
329  *
330  */
net_is_ip_or_ipv6(const uint8_t * buffer)331 static inline bool net_is_ip_or_ipv6(const uint8_t *buffer)
332 {
333     if (((const struct net_eth_hdr *)(const void *)buffer)->type == htons(ETH_P_IP) ||
334         ((const struct net_eth_hdr *)(const void *)buffer)->type == htons(ETH_P_IPV6))
335     {
336         return true;
337     }
338 
339     return false;
340 }
341 
342 /** Get interface handle from socket descriptor
343  *
344  * Given a socket descriptor this API returns which interface it is bound with.
345  *
346  * \param[in] sock socket descriptor
347  *
348  * \return[out] interface handle
349  */
350 void *net_sock_to_interface(int sock);
351 
352 /** Initialize TCP/IP networking stack
353  *
354  * \return WM_SUCCESS on success
355  * \return -WM_FAIL otherwise
356  */
357 int net_wlan_init(void);
358 
359 /** DiInitialize TCP/IP networking stack
360  *
361  * \return WM_SUCCESS on success
362  * \return -WM_FAIL otherwise
363  */
364 int net_wlan_deinit(void);
365 
366 /** Get STA interface netif structure pointer
367  *
368  * \rerurn A pointer to STA interface netif structure
369  *
370  */
371 struct netif *net_get_sta_interface(void);
372 
373 /** Get uAP interface netif structure pointer
374  *
375  * \rerurn A pointer to uAP interface netif structure
376  *
377  */
378 struct netif *net_get_uap_interface(void);
379 
380 /** Get interface name for given netif
381  *
382  * \param[out] pif_name Buffer to store interface name
383  * \param[in] iface Interface to get the name
384  *
385  * \return WM_SUCCESS on success
386  * \return -WM_FAIL otherwise
387  *
388  */
389 int net_get_if_name_netif(char *pif_name, struct netif *iface);
390 
391 /** Get client data index for storing private data in * netif.
392  *
393  * \return allocated client data index, -1 if error or
394  *         not supported.
395  */
396 int net_alloc_client_data_id();
397 
398 /** Get station interface handle
399  *
400  * Some APIs require the interface handle to be passed to them. The handle can
401  * be retrieved using this API.
402  *
403  * \return station interface handle
404  */
405 void *net_get_sta_handle(void);
406 #define net_get_mlan_handle() net_get_sta_handle()
407 
408 /** Get micro-AP interface handle
409  *
410  * Some APIs require the interface handle to be passed to them. The handle can
411  * be retrieved using this API.
412  *
413  * \return micro-AP interface handle
414  */
415 void *net_get_uap_handle(void);
416 
417 /** Take interface up
418  *
419  * Change interface state to up. Use net_get_sta_handle(),
420  * net_get_uap_handle() to get interface handle.
421  *
422  * \param[in] intrfc_handle interface handle
423  *
424  * \return void
425  */
426 void net_interface_up(void *intrfc_handle);
427 
428 /** Take interface down
429  *
430  * Change interface state to down. Use net_get_sta_handle(),
431  * net_get_uap_handle() to get interface handle.
432  *
433  * \param[in] intrfc_handle interface handle
434  *
435  * \return void
436  */
437 void net_interface_down(void *intrfc_handle);
438 
439 /** Stop DHCP client on given interface
440  *
441  * Stop the DHCP client on given interface state. Use net_get_sta_handle(),
442  * net_get_uap_handle() to get interface handle.
443  *
444  * \param[in] intrfc_handle interface handle
445  *
446  * \return void
447  */
448 void net_interface_dhcp_stop(void *intrfc_handle);
449 
450 /** Cleanup DHCP client on given interface
451  *
452  * Cleanup the DHCP client on given interface state. Use net_get_sta_handle(),
453  * net_get_uap_handle() to get interface handle.
454  *
455  * \param[in] intrfc_handle interface handle
456  *
457  */
458 void net_interface_dhcp_cleanup(void *intrfc_handle);
459 
460 /** Configure IP address for interface
461  *
462  * \param[in] addr Address that needs to be configured.
463  * \param[in] intrfc_handle Handle for network interface to be configured.
464  *
465  * \return WM_SUCCESS on success or an error code.
466  */
467 int net_configure_address(struct net_ip_config *addr, void *intrfc_handle);
468 
469 /** Configure DNS server address
470  *
471  * \param[in] ip IP address of the DNS server to set
472  * \param[in] role Network wireless BSS Role
473  *
474  */
475 void net_configure_dns(struct net_ip_config *ip, unsigned int role);
476 
477 /** Get interface IP Address in \ref net_ip_config
478  *
479  * This function will get the IP address of a given interface. Use
480  * net_get_sta_handle(), net_get_uap_handle() to get
481  * interface handle.
482  *
483  * \param[out] addr \ref net_ip_config
484  * \param[in] intrfc_handle interface handle
485  *
486  * \return WM_SUCCESS on success or error code.
487  */
488 int net_get_if_addr(struct net_ip_config *addr, void *intrfc_handle);
489 
490 #if CONFIG_IPV6
491 /** Get interface IPv6 Addresses & their states in \ref net_ip_config
492  *
493  * This function will get the IPv6 addresses & address states of a given
494  * interface. Use net_get_sta_handle() to get interface handle.
495  *
496  * \param[out] addr \ref net_ip_config
497  * \param[in] intrfc_handle interface handle
498  *
499  * \return WM_SUCCESS on success or error code.
500  */
501 int net_get_if_ipv6_addr(struct net_ip_config *addr, void *intrfc_handle);
502 
503 /** Get list of preferred IPv6 Addresses of a given interface
504  * in \ref net_ip_config
505  *
506  * This function will get the list of IPv6 addresses whose address state
507  * is Preferred.
508  * Use net_get_sta_handle() to get interface handle.
509  *
510  * \param[out] addr \ref net_ip_config
511  * \param[in] intrfc_handle interface handle
512  *
513  * \return Number of IPv6 addresses whose address state is Preferred
514  */
515 int net_get_if_ipv6_pref_addr(struct net_ip_config *addr, void *intrfc_handle);
516 
517 /** Get the description of IPv6 address state
518  *
519  * This function will get the IPv6 address state description like -
520  * Invalid, Preferred, Deprecated
521  *
522  * \param[in] addr_state Address state
523  *
524  * \return IPv6 address state description
525  */
526 char *ipv6_addr_state_to_desc(unsigned char addr_state);
527 
528 /** Get the description of IPv6 address
529  *
530  * This function will get the IPv6 address type description like -
531  * Linklocal, Global, Sitelocal, Uniquelocal
532  *
533  * \param[in] ipv6_conf Pointer to IPv6 configuration of type \ref net_ipv6_config
534  *
535  * \return IPv6 address description
536  */
537 char *ipv6_addr_addr_to_desc(struct net_ipv6_config *ipv6_conf);
538 
539 /** Get the description of IPv6 address type
540  *
541  * This function will get the IPv6 address type description like -
542  * Linklocal, Global, Sitelocal, Uniquelocal
543  *
544  * \param[in] ipv6_conf Pointer to IPv6 configuration of type \ref net_ipv6_config
545  *
546  * \return IPv6 address type description
547  */
548 char *ipv6_addr_type_to_desc(struct net_ipv6_config *ipv6_conf);
549 #endif /* CONFIG_IPV6 */
550 
551 /** Get interface Name string containing name and number
552  *
553  * This function will get the string containing name and number for given interface.
554  * Use net_get_sta_handle(), net_get_uap_handle() to get
555  * interface handle.
556  *
557  * \param[out] if_name interface name pointer
558  * \param[in] intrfc_handle interface handle
559  *
560  * \return WM_SUCCESS on success or error code.
561  */
562 int net_get_if_name(char *if_name, void *intrfc_handle);
563 
564 /** Get interface IP Address
565  *
566  * This function will get the IP Address of a given interface. Use
567  * net_get_sta_handle(), net_get_uap_handle() to get
568  * interface handle.
569  *
570  * \param[out] ip ip address pointer
571  * \param[in] intrfc_handle interface handle
572  *
573  * \return WM_SUCCESS on success or error code.
574  */
575 int net_get_if_ip_addr(uint32_t *ip, void *intrfc_handle);
576 
577 /** Get interface IP Subnet-Mask
578  *
579  * This function will get the Subnet-Mask of a given interface. Use
580  * net_get_sta_handle(), net_get_uap_handle() to get
581  * interface handle.
582  *
583  * \param[in] mask Subnet Mask pointer
584  * \param[in] intrfc_handle interface
585  *
586  * \return WM_SUCCESS on success or error code.
587  */
588 int net_get_if_ip_mask(uint32_t *nm, void *intrfc_handle);
589 
590 /** Initialize the network stack
591  *
592  *  This function initializes the network stack. This function is
593  *  called by wlan_start().
594  *
595  *  Applications may optionally call this function directly:
596  *  if they wish to use the networking stack (loopback interface)
597  *  without the wlan functionality.
598  *  if they wish to initialize the networking stack even before wlan
599  *  comes up.
600  *
601  * \note This function may safely be called multiple times.
602  */
603 void net_ipv4stack_init(void);
604 
605 /** Display network statistics
606  */
607 void net_stat(void);
608 
609 #if CONFIG_WIFI_NM_WPA_SUPPLICANT
610 /** Get supplicant ready state
611  */
612 bool get_supp_ready_state(void);
613 #endif
614 
615 #if CONFIG_P2P
616 int netif_get_bss_type();
617 #endif
618 
619 #ifdef MGMT_RX
620 void rx_mgmt_register_callback(int (*rx_mgmt_cb_fn)(const enum wlan_bss_type bss_type,
621                                                     const wifi_mgmt_frame_t *frame,
622                                                     const size_t len));
623 
624 void rx_mgmt_deregister_callback(void);
625 #endif
626 
627 int nxp_wifi_internal_tx(const struct device *dev, struct net_pkt *pkt);
628 void nxp_wifi_internal_register_rx_cb(int (*rx_cb_fn)(struct net_if *iface, struct net_pkt *pkt));
629 const struct netif *net_if_get_binding(const char *ifname);
630 #endif /* _WM_NET_H_ */
631