1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/logging/log.h>
8 LOG_MODULE_REGISTER(wifi_nm, CONFIG_WIFI_NM_LOG_LEVEL);
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/net/wifi_nm.h>
12 
13 /* Used to protect nm data */
14 static K_MUTEX_DEFINE(wifi_nm_lock);
15 
wifi_nm_get_instance(const char * name)16 struct wifi_nm_instance *wifi_nm_get_instance(const char *name)
17 {
18 	STRUCT_SECTION_FOREACH(wifi_nm_instance, nm) {
19 		if (!strcmp(nm->name, name)) {
20 			return nm;
21 		}
22 	}
23 
24 	return NULL;
25 }
26 
wifi_nm_get_instance_iface(struct net_if * iface)27 struct wifi_nm_instance *wifi_nm_get_instance_iface(struct net_if *iface)
28 {
29 	if (!iface || !net_if_is_wifi(iface)) {
30 		return NULL;
31 	}
32 
33 	k_mutex_lock(&wifi_nm_lock, K_FOREVER);
34 	STRUCT_SECTION_FOREACH(wifi_nm_instance, nm) {
35 		for (int i = 0; i < CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES; i++) {
36 			if (nm->mgd_ifaces[i].iface == iface) {
37 				k_mutex_unlock(&wifi_nm_lock);
38 				return nm;
39 			}
40 		}
41 	}
42 	k_mutex_unlock(&wifi_nm_lock);
43 
44 	return NULL;
45 }
46 
wifi_nm_get_type_iface(struct net_if * iface)47 unsigned char wifi_nm_get_type_iface(struct net_if *iface)
48 {
49 	if (!iface || !net_if_is_wifi(iface)) {
50 		return 0;
51 	}
52 
53 	k_mutex_lock(&wifi_nm_lock, K_FOREVER);
54 	STRUCT_SECTION_FOREACH(wifi_nm_instance, nm) {
55 		for (int i = 0; i < CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES; i++) {
56 			if (nm->mgd_ifaces[i].iface == iface) {
57 				k_mutex_unlock(&wifi_nm_lock);
58 				return nm->mgd_ifaces[i].type;
59 			}
60 		}
61 	}
62 
63 	k_mutex_unlock(&wifi_nm_lock);
64 	return 0;
65 }
66 
wifi_nm_iface_is_sta(struct net_if * iface)67 bool wifi_nm_iface_is_sta(struct net_if *iface)
68 {
69 	return wifi_nm_get_type_iface(iface) & (1 << WIFI_TYPE_STA);
70 }
71 
wifi_nm_iface_is_sap(struct net_if * iface)72 bool wifi_nm_iface_is_sap(struct net_if *iface)
73 {
74 	return wifi_nm_get_type_iface(iface) & (1 << WIFI_TYPE_SAP);
75 }
76 
wifi_nm_register_mgd_iface(struct wifi_nm_instance * nm,struct net_if * iface)77 int wifi_nm_register_mgd_iface(struct wifi_nm_instance *nm, struct net_if *iface)
78 {
79 	if (!nm || !iface) {
80 		return -EINVAL;
81 	}
82 
83 	if (!net_if_is_wifi(iface)) {
84 		return -ENOTSUP;
85 	}
86 
87 	k_mutex_lock(&wifi_nm_lock, K_FOREVER);
88 	for (int i = 0; i < CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES; i++) {
89 		if (nm->mgd_ifaces[i].iface == iface) {
90 			k_mutex_unlock(&wifi_nm_lock);
91 			return 0;
92 		}
93 
94 		if (!nm->mgd_ifaces[i].iface) {
95 			nm->mgd_ifaces[i].iface = iface;
96 			k_mutex_unlock(&wifi_nm_lock);
97 			return 0;
98 		}
99 	}
100 	k_mutex_unlock(&wifi_nm_lock);
101 
102 	return -ENOMEM;
103 }
104 
wifi_nm_register_mgd_type_iface(struct wifi_nm_instance * nm,enum wifi_nm_iface_type type,struct net_if * iface)105 int wifi_nm_register_mgd_type_iface(struct wifi_nm_instance *nm,
106 		enum wifi_nm_iface_type type, struct net_if *iface)
107 {
108 	if (!nm || !iface) {
109 		return -EINVAL;
110 	}
111 
112 	if (!net_if_is_wifi(iface)) {
113 		return -ENOTSUP;
114 	}
115 
116 	k_mutex_lock(&wifi_nm_lock, K_FOREVER);
117 	for (int i = 0; i < CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES; i++) {
118 		if (!nm->mgd_ifaces[i].iface) {
119 			nm->mgd_ifaces[i].iface = iface;
120 			nm->mgd_ifaces[i].type = (1 << type);
121 			k_mutex_unlock(&wifi_nm_lock);
122 			return 0;
123 		}
124 	}
125 	k_mutex_unlock(&wifi_nm_lock);
126 
127 	return -ENOMEM;
128 }
129 
wifi_nm_unregister_mgd_iface(struct wifi_nm_instance * nm,struct net_if * iface)130 int wifi_nm_unregister_mgd_iface(struct wifi_nm_instance *nm, struct net_if *iface)
131 {
132 	if (!nm || !iface) {
133 		return -EINVAL;
134 	}
135 
136 	k_mutex_lock(&wifi_nm_lock, K_FOREVER);
137 	for (int i = 0; i < CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES; i++) {
138 		if (nm->mgd_ifaces[i].iface == iface) {
139 			nm->mgd_ifaces[i].iface = NULL;
140 			k_mutex_unlock(&wifi_nm_lock);
141 			return 0;
142 		}
143 	}
144 	k_mutex_unlock(&wifi_nm_lock);
145 
146 	return -ENOENT;
147 }
148