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