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