developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 1 | --- a/hostapd/Makefile |
| 2 | +++ b/hostapd/Makefile |
developer | 2a20969 | 2023-08-14 20:23:42 +0800 | [diff] [blame] | 3 | @@ -166,6 +166,12 @@ OBJS += ../src/common/hw_features_common |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 4 | |
| 5 | OBJS += ../src/eapol_auth/eapol_auth_sm.o |
| 6 | |
| 7 | +ifdef CONFIG_UBUS |
| 8 | +CFLAGS += -DUBUS_SUPPORT |
developer | 2a20969 | 2023-08-14 20:23:42 +0800 | [diff] [blame] | 9 | +OBJS += ../src/utils/uloop.o |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 10 | +OBJS += ../src/ap/ubus.o |
| 11 | +LIBS += -lubox -lubus |
| 12 | +endif |
| 13 | |
| 14 | ifdef CONFIG_CODE_COVERAGE |
| 15 | CFLAGS += -O0 -fprofile-arcs -ftest-coverage |
| 16 | --- a/src/ap/hostapd.h |
| 17 | +++ b/src/ap/hostapd.h |
| 18 | @@ -18,6 +18,7 @@ |
| 19 | #include "utils/list.h" |
| 20 | #include "ap_config.h" |
| 21 | #include "drivers/driver.h" |
| 22 | +#include "ubus.h" |
| 23 | |
| 24 | #define OCE_STA_CFON_ENABLED(hapd) \ |
| 25 | ((hapd->conf->oce & OCE_STA_CFON) && \ |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 26 | @@ -184,6 +185,7 @@ struct hostapd_data { |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 27 | struct hostapd_iface *iface; |
| 28 | struct hostapd_config *iconf; |
| 29 | struct hostapd_bss_config *conf; |
| 30 | + struct hostapd_ubus_bss ubus; |
| 31 | int interface_added; /* virtual interface added for this BSS */ |
| 32 | unsigned int started:1; |
| 33 | unsigned int disabled:1; |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 34 | @@ -695,6 +697,7 @@ hostapd_alloc_bss_data(struct hostapd_if |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 35 | struct hostapd_bss_config *bss); |
| 36 | int hostapd_setup_interface(struct hostapd_iface *iface); |
| 37 | int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err); |
| 38 | +void hostapd_set_own_neighbor_report(struct hostapd_data *hapd); |
| 39 | void hostapd_interface_deinit(struct hostapd_iface *iface); |
| 40 | void hostapd_interface_free(struct hostapd_iface *iface); |
| 41 | struct hostapd_iface * hostapd_alloc_iface(void); |
| 42 | --- a/src/ap/hostapd.c |
| 43 | +++ b/src/ap/hostapd.c |
developer | dfb5098 | 2023-09-11 13:34:36 +0800 | [diff] [blame] | 44 | @@ -435,6 +435,7 @@ void hostapd_free_hapd_data(struct hosta |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 45 | hapd->beacon_set_done = 0; |
| 46 | |
| 47 | wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); |
| 48 | + hostapd_ubus_free_bss(hapd); |
| 49 | accounting_deinit(hapd); |
| 50 | hostapd_deinit_wpa(hapd); |
| 51 | vlan_deinit(hapd); |
developer | dfb5098 | 2023-09-11 13:34:36 +0800 | [diff] [blame] | 52 | @@ -1187,6 +1188,8 @@ static int hostapd_start_beacon(struct h |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 53 | if (hapd->driver && hapd->driver->set_operstate) |
| 54 | hapd->driver->set_operstate(hapd->drv_priv, 1); |
| 55 | |
| 56 | + hostapd_ubus_add_bss(hapd); |
| 57 | + |
| 58 | return 0; |
| 59 | } |
| 60 | |
developer | dfb5098 | 2023-09-11 13:34:36 +0800 | [diff] [blame] | 61 | @@ -2275,6 +2278,7 @@ static int hostapd_setup_interface_compl |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 62 | if (err) |
| 63 | goto fail; |
| 64 | |
| 65 | + hostapd_ubus_add_iface(iface); |
| 66 | wpa_printf(MSG_DEBUG, "Completing interface initialization"); |
| 67 | if (iface->freq) { |
| 68 | #ifdef NEED_AP_MLME |
developer | dfb5098 | 2023-09-11 13:34:36 +0800 | [diff] [blame] | 69 | @@ -2494,6 +2498,7 @@ dfs_offload: |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 70 | |
| 71 | fail: |
| 72 | wpa_printf(MSG_ERROR, "Interface initialization failed"); |
| 73 | + hostapd_ubus_free_iface(iface); |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 74 | |
| 75 | if (iface->is_no_ir) { |
| 76 | hostapd_set_state(iface, HAPD_IFACE_NO_IR); |
developer | dfb5098 | 2023-09-11 13:34:36 +0800 | [diff] [blame] | 77 | @@ -2984,6 +2989,7 @@ void hostapd_interface_deinit_free(struc |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 78 | (unsigned int) iface->conf->num_bss); |
| 79 | driver = iface->bss[0]->driver; |
| 80 | drv_priv = iface->bss[0]->drv_priv; |
| 81 | + hostapd_ubus_free_iface(iface); |
| 82 | hostapd_interface_deinit(iface); |
| 83 | wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", |
| 84 | __func__, driver, drv_priv); |
| 85 | --- a/src/ap/ieee802_11.c |
| 86 | +++ b/src/ap/ieee802_11.c |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 87 | @@ -2786,7 +2786,7 @@ static void handle_auth(struct hostapd_d |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 88 | u16 auth_alg, auth_transaction, status_code; |
| 89 | u16 resp = WLAN_STATUS_SUCCESS; |
| 90 | struct sta_info *sta = NULL; |
| 91 | - int res, reply_res; |
| 92 | + int res, reply_res, ubus_resp; |
| 93 | u16 fc; |
| 94 | const u8 *challenge = NULL; |
| 95 | u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN]; |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 96 | @@ -2795,6 +2795,11 @@ static void handle_auth(struct hostapd_d |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 97 | struct radius_sta rad_info; |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 98 | const u8 *dst, *sa, *bssid; |
| 99 | bool mld_sta = false; |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 100 | + struct hostapd_ubus_request req = { |
| 101 | + .type = HOSTAPD_UBUS_AUTH_REQ, |
| 102 | + .mgmt_frame = mgmt, |
| 103 | + .ssi_signal = rssi, |
| 104 | + }; |
| 105 | |
| 106 | if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { |
| 107 | wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)", |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 108 | @@ -2986,6 +2991,13 @@ static void handle_auth(struct hostapd_d |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 109 | resp = WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 110 | goto fail; |
| 111 | } |
| 112 | + ubus_resp = hostapd_ubus_handle_event(hapd, &req); |
| 113 | + if (ubus_resp) { |
| 114 | + wpa_printf(MSG_DEBUG, "Station " MACSTR " rejected by ubus handler.\n", |
| 115 | + MAC2STR(mgmt->sa)); |
| 116 | + resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 117 | + goto fail; |
| 118 | + } |
| 119 | if (res == HOSTAPD_ACL_PENDING) |
| 120 | return; |
| 121 | |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 122 | @@ -5161,7 +5173,7 @@ static void handle_assoc(struct hostapd_ |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 123 | int resp = WLAN_STATUS_SUCCESS; |
| 124 | u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 125 | const u8 *pos; |
| 126 | - int left, i; |
| 127 | + int left, i, ubus_resp; |
| 128 | struct sta_info *sta; |
| 129 | u8 *tmp = NULL; |
| 130 | #ifdef CONFIG_FILS |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 131 | @@ -5374,6 +5386,11 @@ static void handle_assoc(struct hostapd_ |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 132 | left = res; |
| 133 | } |
| 134 | #endif /* CONFIG_FILS */ |
| 135 | + struct hostapd_ubus_request req = { |
| 136 | + .type = HOSTAPD_UBUS_ASSOC_REQ, |
| 137 | + .mgmt_frame = mgmt, |
| 138 | + .ssi_signal = rssi, |
| 139 | + }; |
| 140 | |
| 141 | /* followed by SSID and Supported rates; and HT capabilities if 802.11n |
| 142 | * is used */ |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 143 | @@ -5472,6 +5489,13 @@ static void handle_assoc(struct hostapd_ |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 144 | } |
| 145 | #endif /* CONFIG_FILS */ |
| 146 | |
| 147 | + ubus_resp = hostapd_ubus_handle_event(hapd, &req); |
| 148 | + if (ubus_resp) { |
| 149 | + wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n", |
| 150 | + MAC2STR(mgmt->sa)); |
| 151 | + resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE; |
| 152 | + goto fail; |
| 153 | + } |
| 154 | fail: |
| 155 | |
| 156 | /* |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 157 | @@ -5753,6 +5777,7 @@ static void handle_disassoc(struct hosta |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 158 | (unsigned long) len); |
| 159 | return; |
| 160 | } |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 161 | + hostapd_ubus_notify(hapd, "disassoc", mgmt->sa); |
| 162 | |
| 163 | sta = ap_get_sta(hapd, mgmt->sa); |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 164 | if (!sta) { |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 165 | @@ -5784,6 +5809,8 @@ static void handle_deauth(struct hostapd |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 166 | /* Clear the PTKSA cache entries for PASN */ |
| 167 | ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE); |
| 168 | |
| 169 | + hostapd_ubus_notify(hapd, "deauth", mgmt->sa); |
| 170 | + |
| 171 | sta = ap_get_sta(hapd, mgmt->sa); |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 172 | if (!sta) { |
| 173 | wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 174 | --- a/src/ap/beacon.c |
| 175 | +++ b/src/ap/beacon.c |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 176 | @@ -1036,6 +1036,12 @@ void handle_probe_req(struct hostapd_dat |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 177 | u16 csa_offs[2]; |
| 178 | size_t csa_offs_len; |
| 179 | struct radius_sta rad_info; |
| 180 | + struct hostapd_ubus_request req = { |
| 181 | + .type = HOSTAPD_UBUS_PROBE_REQ, |
| 182 | + .mgmt_frame = mgmt, |
| 183 | + .ssi_signal = ssi_signal, |
| 184 | + .elems = &elems, |
| 185 | + }; |
| 186 | |
| 187 | if (hapd->iconf->rssi_ignore_probe_request && ssi_signal && |
| 188 | ssi_signal < hapd->iconf->rssi_ignore_probe_request) |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 189 | @@ -1222,6 +1228,12 @@ void handle_probe_req(struct hostapd_dat |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 190 | } |
| 191 | #endif /* CONFIG_P2P */ |
| 192 | |
| 193 | + if (hostapd_ubus_handle_event(hapd, &req)) { |
| 194 | + wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n", |
| 195 | + MAC2STR(mgmt->sa)); |
| 196 | + return; |
| 197 | + } |
| 198 | + |
| 199 | /* TODO: verify that supp_rates contains at least one matching rate |
| 200 | * with AP configuration */ |
| 201 | |
| 202 | --- a/src/ap/drv_callbacks.c |
| 203 | +++ b/src/ap/drv_callbacks.c |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 204 | @@ -260,6 +260,10 @@ int hostapd_notif_assoc(struct hostapd_d |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 205 | u16 reason = WLAN_REASON_UNSPECIFIED; |
| 206 | int status = WLAN_STATUS_SUCCESS; |
| 207 | const u8 *p2p_dev_addr = NULL; |
| 208 | + struct hostapd_ubus_request req = { |
| 209 | + .type = HOSTAPD_UBUS_ASSOC_REQ, |
| 210 | + .addr = addr, |
| 211 | + }; |
| 212 | |
| 213 | if (addr == NULL) { |
| 214 | /* |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 215 | @@ -396,6 +400,12 @@ int hostapd_notif_assoc(struct hostapd_d |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 216 | goto fail; |
| 217 | } |
| 218 | |
| 219 | + if (hostapd_ubus_handle_event(hapd, &req)) { |
| 220 | + wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n", |
| 221 | + MAC2STR(req.addr)); |
| 222 | + goto fail; |
| 223 | + } |
| 224 | + |
| 225 | #ifdef CONFIG_P2P |
| 226 | if (elems.p2p) { |
| 227 | wpabuf_free(sta->p2p_ie); |
| 228 | --- a/src/ap/sta_info.c |
| 229 | +++ b/src/ap/sta_info.c |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 230 | @@ -471,6 +471,7 @@ void ap_handle_timer(void *eloop_ctx, vo |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 231 | hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, |
| 232 | HOSTAPD_LEVEL_INFO, "deauthenticated due to " |
| 233 | "local deauth request"); |
| 234 | + hostapd_ubus_notify(hapd, "local-deauth", sta->addr); |
| 235 | ap_free_sta(hapd, sta); |
| 236 | return; |
| 237 | } |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 238 | @@ -626,6 +627,7 @@ skip_poll: |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 239 | mlme_deauthenticate_indication( |
| 240 | hapd, sta, |
| 241 | WLAN_REASON_PREV_AUTH_NOT_VALID); |
| 242 | + hostapd_ubus_notify(hapd, "inactive-deauth", sta->addr); |
| 243 | ap_free_sta(hapd, sta); |
| 244 | break; |
| 245 | } |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 246 | @@ -1344,15 +1346,28 @@ void ap_sta_set_authorized(struct hostap |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 247 | sta->addr, authorized, dev_addr); |
| 248 | |
| 249 | if (authorized) { |
| 250 | + static const char * const auth_algs[] = { |
| 251 | + [WLAN_AUTH_OPEN] = "open", |
| 252 | + [WLAN_AUTH_SHARED_KEY] = "shared", |
| 253 | + [WLAN_AUTH_FT] = "ft", |
| 254 | + [WLAN_AUTH_SAE] = "sae", |
| 255 | + [WLAN_AUTH_FILS_SK] = "fils-sk", |
| 256 | + [WLAN_AUTH_FILS_SK_PFS] = "fils-sk-pfs", |
| 257 | + [WLAN_AUTH_FILS_PK] = "fils-pk", |
| 258 | + [WLAN_AUTH_PASN] = "pasn", |
| 259 | + }; |
| 260 | + const char *auth_alg = NULL; |
developer | 505c943 | 2023-05-12 18:58:17 +0800 | [diff] [blame] | 261 | const u8 *dpp_pkhash; |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 262 | const char *keyid; |
developer | 505c943 | 2023-05-12 18:58:17 +0800 | [diff] [blame] | 263 | char dpp_pkhash_buf[100]; |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 264 | char keyid_buf[100]; |
| 265 | char ip_addr[100]; |
| 266 | + char alg_buf[100]; |
| 267 | |
developer | 505c943 | 2023-05-12 18:58:17 +0800 | [diff] [blame] | 268 | dpp_pkhash_buf[0] = '\0'; |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 269 | keyid_buf[0] = '\0'; |
| 270 | ip_addr[0] = '\0'; |
| 271 | + alg_buf[0] = '\0'; |
| 272 | #ifdef CONFIG_P2P |
| 273 | if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) { |
| 274 | os_snprintf(ip_addr, sizeof(ip_addr), |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 275 | @@ -1362,6 +1377,13 @@ void ap_sta_set_authorized(struct hostap |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 276 | } |
| 277 | #endif /* CONFIG_P2P */ |
| 278 | |
| 279 | + if (sta->auth_alg < ARRAY_SIZE(auth_algs)) |
| 280 | + auth_alg = auth_algs[sta->auth_alg]; |
| 281 | + |
| 282 | + if (auth_alg) |
| 283 | + os_snprintf(alg_buf, sizeof(alg_buf), |
developer | 505c943 | 2023-05-12 18:58:17 +0800 | [diff] [blame] | 284 | + " auth_alg=%s", auth_alg); |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 285 | + |
| 286 | keyid = ap_sta_wpa_get_keyid(hapd, sta); |
| 287 | if (keyid) { |
| 288 | os_snprintf(keyid_buf, sizeof(keyid_buf), |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 289 | @@ -1380,17 +1402,19 @@ void ap_sta_set_authorized(struct hostap |
developer | 505c943 | 2023-05-12 18:58:17 +0800 | [diff] [blame] | 290 | dpp_pkhash, SHA256_MAC_LEN); |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 291 | } |
| 292 | |
developer | 505c943 | 2023-05-12 18:58:17 +0800 | [diff] [blame] | 293 | - wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s", |
| 294 | - buf, ip_addr, keyid_buf, dpp_pkhash_buf); |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 295 | + hostapd_ubus_notify_authorized(hapd, sta, auth_alg); |
developer | 505c943 | 2023-05-12 18:58:17 +0800 | [diff] [blame] | 296 | + wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s%s", |
| 297 | + buf, ip_addr, keyid_buf, dpp_pkhash_buf, alg_buf); |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 298 | |
| 299 | if (hapd->msg_ctx_parent && |
| 300 | hapd->msg_ctx_parent != hapd->msg_ctx) |
| 301 | wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO, |
developer | 505c943 | 2023-05-12 18:58:17 +0800 | [diff] [blame] | 302 | - AP_STA_CONNECTED "%s%s%s%s", |
| 303 | + AP_STA_CONNECTED "%s%s%s%s%s", |
| 304 | buf, ip_addr, keyid_buf, |
| 305 | - dpp_pkhash_buf); |
| 306 | + dpp_pkhash_buf, alg_buf); |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 307 | } else { |
| 308 | wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); |
| 309 | + hostapd_ubus_notify(hapd, "disassoc", sta->addr); |
| 310 | |
| 311 | if (hapd->msg_ctx_parent && |
| 312 | hapd->msg_ctx_parent != hapd->msg_ctx) |
| 313 | --- a/src/ap/wpa_auth_glue.c |
| 314 | +++ b/src/ap/wpa_auth_glue.c |
developer | 505c943 | 2023-05-12 18:58:17 +0800 | [diff] [blame] | 315 | @@ -269,6 +269,7 @@ static void hostapd_wpa_auth_psk_failure |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 316 | struct hostapd_data *hapd = ctx; |
| 317 | wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR, |
| 318 | MAC2STR(addr)); |
| 319 | + hostapd_ubus_notify(hapd, "key-mismatch", addr); |
| 320 | } |
| 321 | |
| 322 | |
| 323 | --- a/wpa_supplicant/Makefile |
| 324 | +++ b/wpa_supplicant/Makefile |
developer | dfb5098 | 2023-09-11 13:34:36 +0800 | [diff] [blame] | 325 | @@ -192,6 +192,13 @@ ifdef CONFIG_EAPOL_TEST |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 326 | CFLAGS += -Werror -DEAPOL_TEST |
| 327 | endif |
| 328 | |
| 329 | +ifdef CONFIG_UBUS |
| 330 | +CFLAGS += -DUBUS_SUPPORT |
| 331 | +OBJS += ubus.o |
developer | 2a20969 | 2023-08-14 20:23:42 +0800 | [diff] [blame] | 332 | +OBJS += ../src/utils/uloop.o |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 333 | +LIBS += -lubox -lubus |
| 334 | +endif |
| 335 | + |
| 336 | ifdef CONFIG_CODE_COVERAGE |
| 337 | CFLAGS += -O0 -fprofile-arcs -ftest-coverage |
| 338 | LIBS += -lgcov |
developer | dfb5098 | 2023-09-11 13:34:36 +0800 | [diff] [blame] | 339 | @@ -987,6 +994,9 @@ ifdef CONFIG_CTRL_IFACE_MIB |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 340 | CFLAGS += -DCONFIG_CTRL_IFACE_MIB |
| 341 | endif |
| 342 | OBJS += ../src/ap/ctrl_iface_ap.o |
| 343 | +ifdef CONFIG_UBUS |
| 344 | +OBJS += ../src/ap/ubus.o |
| 345 | +endif |
| 346 | endif |
| 347 | |
| 348 | CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY |
| 349 | --- a/wpa_supplicant/wpa_supplicant.c |
| 350 | +++ b/wpa_supplicant/wpa_supplicant.c |
developer | bf0f2d6 | 2023-11-14 17:01:47 +0800 | [diff] [blame] | 351 | @@ -7595,6 +7595,8 @@ struct wpa_supplicant * wpa_supplicant_a |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 352 | } |
| 353 | #endif /* CONFIG_P2P */ |
| 354 | |
| 355 | + wpas_ubus_add_bss(wpa_s); |
| 356 | + |
| 357 | return wpa_s; |
| 358 | } |
| 359 | |
developer | bf0f2d6 | 2023-11-14 17:01:47 +0800 | [diff] [blame] | 360 | @@ -7621,6 +7623,8 @@ int wpa_supplicant_remove_iface(struct w |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 361 | struct wpa_supplicant *parent = wpa_s->parent; |
| 362 | #endif /* CONFIG_MESH */ |
| 363 | |
| 364 | + wpas_ubus_free_bss(wpa_s); |
| 365 | + |
| 366 | /* Remove interface from the global list of interfaces */ |
| 367 | prev = global->ifaces; |
| 368 | if (prev == wpa_s) { |
developer | bf0f2d6 | 2023-11-14 17:01:47 +0800 | [diff] [blame] | 369 | @@ -7967,8 +7971,12 @@ int wpa_supplicant_run(struct wpa_global |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 370 | eloop_register_signal_terminate(wpa_supplicant_terminate, global); |
| 371 | eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); |
| 372 | |
| 373 | + wpas_ubus_add(global); |
| 374 | + |
| 375 | eloop_run(); |
| 376 | |
| 377 | + wpas_ubus_free(global); |
| 378 | + |
| 379 | return 0; |
| 380 | } |
| 381 | |
| 382 | --- a/wpa_supplicant/wpa_supplicant_i.h |
| 383 | +++ b/wpa_supplicant/wpa_supplicant_i.h |
developer | 505c943 | 2023-05-12 18:58:17 +0800 | [diff] [blame] | 384 | @@ -21,6 +21,7 @@ |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 385 | #include "config_ssid.h" |
| 386 | #include "wmm_ac.h" |
developer | 505c943 | 2023-05-12 18:58:17 +0800 | [diff] [blame] | 387 | #include "pasn/pasn_common.h" |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 388 | +#include "ubus.h" |
| 389 | |
| 390 | extern const char *const wpa_supplicant_version; |
| 391 | extern const char *const wpa_supplicant_license; |
developer | dfb5098 | 2023-09-11 13:34:36 +0800 | [diff] [blame] | 392 | @@ -319,6 +320,8 @@ struct wpa_global { |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 393 | #endif /* CONFIG_WIFI_DISPLAY */ |
| 394 | |
| 395 | struct psk_list_entry *add_psk; /* From group formation */ |
| 396 | + |
| 397 | + struct ubus_object ubus_global; |
| 398 | }; |
| 399 | |
| 400 | |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 401 | @@ -685,6 +688,7 @@ struct wpa_supplicant { |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 402 | unsigned char own_addr[ETH_ALEN]; |
| 403 | unsigned char perm_addr[ETH_ALEN]; |
| 404 | char ifname[100]; |
| 405 | + struct wpas_ubus_bss ubus; |
| 406 | #ifdef CONFIG_MATCH_IFACE |
| 407 | int matched; |
| 408 | #endif /* CONFIG_MATCH_IFACE */ |
| 409 | --- a/wpa_supplicant/wps_supplicant.c |
| 410 | +++ b/wpa_supplicant/wps_supplicant.c |
| 411 | @@ -33,6 +33,7 @@ |
| 412 | #include "p2p/p2p.h" |
| 413 | #include "p2p_supplicant.h" |
| 414 | #include "wps_supplicant.h" |
| 415 | +#include "ubus.h" |
| 416 | |
| 417 | |
| 418 | #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG |
developer | 505c943 | 2023-05-12 18:58:17 +0800 | [diff] [blame] | 419 | @@ -402,6 +403,8 @@ static int wpa_supplicant_wps_cred(void |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 420 | wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", |
| 421 | cred->cred_attr, cred->cred_attr_len); |
| 422 | |
| 423 | + wpas_ubus_notify(wpa_s, cred); |
| 424 | + |
| 425 | if (wpa_s->conf->wps_cred_processing == 1) |
| 426 | return 0; |
| 427 | |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 428 | --- a/wpa_supplicant/main.c |
| 429 | +++ b/wpa_supplicant/main.c |
developer | dfb5098 | 2023-09-11 13:34:36 +0800 | [diff] [blame] | 430 | @@ -203,7 +203,7 @@ int main(int argc, char *argv[]) |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 431 | |
| 432 | for (;;) { |
| 433 | c = getopt(argc, argv, |
developer | dfb5098 | 2023-09-11 13:34:36 +0800 | [diff] [blame] | 434 | - "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuv::W"); |
| 435 | + "b:Bc:C:D:de:f:g:G:hi:I:KLMm:nNo:O:p:P:qsTtuv::W"); |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 436 | if (c < 0) |
| 437 | break; |
| 438 | switch (c) { |
developer | dfb5098 | 2023-09-11 13:34:36 +0800 | [diff] [blame] | 439 | @@ -268,6 +268,9 @@ int main(int argc, char *argv[]) |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 440 | params.conf_p2p_dev = optarg; |
| 441 | break; |
| 442 | #endif /* CONFIG_P2P */ |
| 443 | + case 'n': |
| 444 | + iface_count = 0; |
| 445 | + break; |
| 446 | case 'o': |
| 447 | params.override_driver = optarg; |
| 448 | break; |
| 449 | --- a/src/ap/rrm.c |
| 450 | +++ b/src/ap/rrm.c |
| 451 | @@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report |
| 452 | return; |
| 453 | wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s", |
| 454 | MAC2STR(addr), token, rep_mode, report); |
| 455 | + if (len < sizeof(struct rrm_measurement_beacon_report)) |
| 456 | + return; |
| 457 | + hostapd_ubus_notify_beacon_report(hapd, addr, token, rep_mode, (struct rrm_measurement_beacon_report*) pos, len); |
| 458 | } |
| 459 | |
| 460 | |
| 461 | @@ -352,6 +355,9 @@ void hostapd_handle_radio_measurement(st |
| 462 | mgmt->u.action.u.rrm.action, MAC2STR(mgmt->sa)); |
| 463 | |
| 464 | switch (mgmt->u.action.u.rrm.action) { |
| 465 | + case WLAN_RRM_LINK_MEASUREMENT_REPORT: |
| 466 | + hostapd_ubus_handle_link_measurement(hapd, buf, len); |
| 467 | + break; |
| 468 | case WLAN_RRM_RADIO_MEASUREMENT_REPORT: |
| 469 | hostapd_handle_radio_msmt_report(hapd, buf, len); |
| 470 | break; |
| 471 | --- a/src/ap/vlan_init.c |
| 472 | +++ b/src/ap/vlan_init.c |
| 473 | @@ -22,6 +22,7 @@ |
| 474 | static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, |
| 475 | int existsok) |
| 476 | { |
| 477 | + bool vlan_exists = iface_exists(vlan->ifname); |
| 478 | int ret; |
| 479 | #ifdef CONFIG_WEP |
| 480 | int i; |
| 481 | @@ -36,7 +37,7 @@ static int vlan_if_add(struct hostapd_da |
| 482 | } |
| 483 | #endif /* CONFIG_WEP */ |
| 484 | |
| 485 | - if (!iface_exists(vlan->ifname)) |
| 486 | + if (!vlan_exists) |
| 487 | ret = hostapd_vlan_if_add(hapd, vlan->ifname); |
| 488 | else if (!existsok) |
| 489 | return -1; |
| 490 | @@ -51,6 +52,9 @@ static int vlan_if_add(struct hostapd_da |
| 491 | if (hapd->wpa_auth) |
| 492 | ret = wpa_auth_ensure_group(hapd->wpa_auth, vlan->vlan_id); |
| 493 | |
| 494 | + if (!ret && !vlan_exists) |
| 495 | + hostapd_ubus_add_vlan(hapd, vlan); |
| 496 | + |
| 497 | if (ret == 0) |
| 498 | return ret; |
| 499 | |
| 500 | @@ -77,6 +81,8 @@ int vlan_if_remove(struct hostapd_data * |
| 501 | "WPA deinitialization for VLAN %d failed (%d)", |
| 502 | vlan->vlan_id, ret); |
| 503 | |
| 504 | + hostapd_ubus_remove_vlan(hapd, vlan); |
| 505 | + |
| 506 | return hostapd_vlan_if_remove(hapd, vlan->ifname); |
| 507 | } |
| 508 | |
| 509 | --- a/src/ap/dfs.c |
| 510 | +++ b/src/ap/dfs.c |
developer | e35b8e4 | 2023-10-16 11:04:00 +0800 | [diff] [blame] | 511 | @@ -1216,6 +1216,8 @@ int hostapd_dfs_pre_cac_expired(struct h |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 512 | "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", |
| 513 | freq, ht_enabled, chan_offset, chan_width, cf1, cf2); |
| 514 | |
| 515 | + hostapd_ubus_notify_radar_detected(iface, freq, chan_width, cf1, cf2); |
| 516 | + |
| 517 | /* Proceed only if DFS is not offloaded to the driver */ |
| 518 | if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) |
| 519 | return 0; |
| 520 | --- a/src/ap/airtime_policy.c |
| 521 | +++ b/src/ap/airtime_policy.c |
| 522 | @@ -112,8 +112,14 @@ static void set_sta_weights(struct hosta |
| 523 | { |
| 524 | struct sta_info *sta; |
| 525 | |
| 526 | - for (sta = hapd->sta_list; sta; sta = sta->next) |
| 527 | - sta_set_airtime_weight(hapd, sta, weight); |
| 528 | + for (sta = hapd->sta_list; sta; sta = sta->next) { |
| 529 | + unsigned int sta_weight = weight; |
| 530 | + |
| 531 | + if (sta->dyn_airtime_weight) |
| 532 | + sta_weight = (weight * sta->dyn_airtime_weight) / 256; |
| 533 | + |
| 534 | + sta_set_airtime_weight(hapd, sta, sta_weight); |
| 535 | + } |
| 536 | } |
| 537 | |
| 538 | |
| 539 | @@ -244,7 +250,10 @@ int airtime_policy_new_sta(struct hostap |
| 540 | unsigned int weight; |
| 541 | |
| 542 | if (hapd->iconf->airtime_mode == AIRTIME_MODE_STATIC) { |
| 543 | - weight = get_weight_for_sta(hapd, sta->addr); |
| 544 | + if (sta->dyn_airtime_weight) |
| 545 | + weight = sta->dyn_airtime_weight; |
| 546 | + else |
| 547 | + weight = get_weight_for_sta(hapd, sta->addr); |
| 548 | if (weight) |
| 549 | return sta_set_airtime_weight(hapd, sta, weight); |
| 550 | } |
| 551 | --- a/src/ap/sta_info.h |
| 552 | +++ b/src/ap/sta_info.h |
developer | 8bff647 | 2023-07-17 11:11:44 +0800 | [diff] [blame] | 553 | @@ -322,6 +322,7 @@ struct sta_info { |
developer | 29c4d2d | 2022-12-26 19:41:22 +0800 | [diff] [blame] | 554 | #endif /* CONFIG_TESTING_OPTIONS */ |
| 555 | #ifdef CONFIG_AIRTIME_POLICY |
| 556 | unsigned int airtime_weight; |
| 557 | + unsigned int dyn_airtime_weight; |
| 558 | struct os_reltime backlogged_until; |
| 559 | #endif /* CONFIG_AIRTIME_POLICY */ |
| 560 | |
| 561 | --- a/src/ap/wnm_ap.c |
| 562 | +++ b/src/ap/wnm_ap.c |
| 563 | @@ -455,7 +455,8 @@ static void ieee802_11_rx_bss_trans_mgmt |
| 564 | MAC2STR(addr), reason, hex ? " neighbor=" : "", hex); |
| 565 | os_free(hex); |
| 566 | |
| 567 | - ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); |
| 568 | + if (!hostapd_ubus_notify_bss_transition_query(hapd, addr, dialog_token, reason, pos, end - pos)) |
| 569 | + ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token); |
| 570 | } |
| 571 | |
| 572 | |
| 573 | @@ -477,7 +478,7 @@ static void ieee802_11_rx_bss_trans_mgmt |
| 574 | size_t len) |
| 575 | { |
| 576 | u8 dialog_token, status_code, bss_termination_delay; |
| 577 | - const u8 *pos, *end; |
| 578 | + const u8 *pos, *end, *target_bssid = NULL; |
| 579 | int enabled = hapd->conf->bss_transition; |
| 580 | struct sta_info *sta; |
| 581 | |
| 582 | @@ -524,6 +525,7 @@ static void ieee802_11_rx_bss_trans_mgmt |
| 583 | wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field"); |
| 584 | return; |
| 585 | } |
| 586 | + target_bssid = pos; |
| 587 | sta->agreed_to_steer = 1; |
| 588 | eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta); |
| 589 | eloop_register_timeout(2, 0, ap_sta_reset_steer_flag_timer, |
| 590 | @@ -543,6 +545,10 @@ static void ieee802_11_rx_bss_trans_mgmt |
| 591 | MAC2STR(addr), status_code, bss_termination_delay); |
| 592 | } |
| 593 | |
| 594 | + hostapd_ubus_notify_bss_transition_response(hapd, sta->addr, dialog_token, |
| 595 | + status_code, bss_termination_delay, |
| 596 | + target_bssid, pos, end - pos); |
| 597 | + |
| 598 | wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", |
| 599 | pos, end - pos); |
| 600 | } |
developer | 2a20969 | 2023-08-14 20:23:42 +0800 | [diff] [blame] | 601 | --- a/src/utils/eloop.c |
| 602 | +++ b/src/utils/eloop.c |
| 603 | @@ -77,6 +77,9 @@ struct eloop_sock_table { |
| 604 | struct eloop_data { |
| 605 | int max_sock; |
| 606 | |
| 607 | + eloop_timeout_poll_handler timeout_poll_cb; |
| 608 | + eloop_poll_handler poll_cb; |
| 609 | + |
| 610 | size_t count; /* sum of all table counts */ |
| 611 | #ifdef CONFIG_ELOOP_POLL |
| 612 | size_t max_pollfd_map; /* number of pollfds_map currently allocated */ |
| 613 | @@ -1121,6 +1124,12 @@ void eloop_run(void) |
| 614 | os_reltime_sub(&timeout->time, &now, &tv); |
| 615 | else |
| 616 | tv.sec = tv.usec = 0; |
| 617 | + } |
| 618 | + |
| 619 | + if (eloop.timeout_poll_cb && eloop.timeout_poll_cb(&tv, !!timeout)) |
| 620 | + timeout = (void *)1; |
| 621 | + |
| 622 | + if (timeout) { |
| 623 | #if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) |
| 624 | timeout_ms = tv.sec * 1000 + tv.usec / 1000; |
| 625 | #endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */ |
| 626 | @@ -1190,7 +1199,8 @@ void eloop_run(void) |
| 627 | eloop.exceptions.changed = 0; |
| 628 | |
| 629 | eloop_process_pending_signals(); |
| 630 | - |
| 631 | + if (eloop.poll_cb) |
| 632 | + eloop.poll_cb(); |
| 633 | |
| 634 | /* check if some registered timeouts have occurred */ |
| 635 | timeout = dl_list_first(&eloop.timeout, struct eloop_timeout, |
| 636 | @@ -1252,6 +1262,14 @@ out: |
| 637 | return; |
| 638 | } |
| 639 | |
| 640 | +int eloop_register_cb(eloop_poll_handler poll_cb, |
| 641 | + eloop_timeout_poll_handler timeout_cb) |
| 642 | +{ |
| 643 | + eloop.poll_cb = poll_cb; |
| 644 | + eloop.timeout_poll_cb = timeout_cb; |
| 645 | + |
| 646 | + return 0; |
| 647 | +} |
| 648 | |
| 649 | void eloop_terminate(void) |
| 650 | { |
| 651 | --- a/src/utils/eloop.h |
| 652 | +++ b/src/utils/eloop.h |
| 653 | @@ -65,6 +65,9 @@ typedef void (*eloop_timeout_handler)(vo |
| 654 | */ |
| 655 | typedef void (*eloop_signal_handler)(int sig, void *signal_ctx); |
| 656 | |
| 657 | +typedef bool (*eloop_timeout_poll_handler)(struct os_reltime *tv, bool tv_set); |
| 658 | +typedef void (*eloop_poll_handler)(void); |
| 659 | + |
| 660 | /** |
| 661 | * eloop_init() - Initialize global event loop data |
| 662 | * Returns: 0 on success, -1 on failure |
| 663 | @@ -73,6 +76,9 @@ typedef void (*eloop_signal_handler)(int |
| 664 | */ |
| 665 | int eloop_init(void); |
| 666 | |
| 667 | +int eloop_register_cb(eloop_poll_handler poll_cb, |
| 668 | + eloop_timeout_poll_handler timeout_cb); |
| 669 | + |
| 670 | /** |
| 671 | * eloop_register_read_sock - Register handler for read events |
| 672 | * @sock: File descriptor number for the socket |
| 673 | @@ -320,6 +326,8 @@ int eloop_register_signal_reconfig(eloop |
| 674 | */ |
| 675 | int eloop_sock_requeue(void); |
| 676 | |
| 677 | +void eloop_add_uloop(void); |
| 678 | + |
| 679 | /** |
| 680 | * eloop_run - Start the event loop |
| 681 | * |
| 682 | --- /dev/null |
| 683 | +++ b/src/utils/uloop.c |
| 684 | @@ -0,0 +1,64 @@ |
| 685 | +#include <libubox/uloop.h> |
| 686 | +#include "includes.h" |
| 687 | +#include "common.h" |
| 688 | +#include "eloop.h" |
| 689 | + |
| 690 | +static void eloop_uloop_event_cb(int sock, void *eloop_ctx, void *sock_ctx) |
| 691 | +{ |
| 692 | +} |
| 693 | + |
| 694 | +static void eloop_uloop_fd_cb(struct uloop_fd *fd, unsigned int events) |
| 695 | +{ |
| 696 | + unsigned int changed = events ^ fd->flags; |
| 697 | + |
| 698 | + if (changed & ULOOP_READ) { |
| 699 | + if (events & ULOOP_READ) |
| 700 | + eloop_register_sock(fd->fd, EVENT_TYPE_READ, eloop_uloop_event_cb, fd, fd); |
| 701 | + else |
| 702 | + eloop_unregister_sock(fd->fd, EVENT_TYPE_READ); |
| 703 | + } |
| 704 | + |
| 705 | + if (changed & ULOOP_WRITE) { |
| 706 | + if (events & ULOOP_WRITE) |
| 707 | + eloop_register_sock(fd->fd, EVENT_TYPE_WRITE, eloop_uloop_event_cb, fd, fd); |
| 708 | + else |
| 709 | + eloop_unregister_sock(fd->fd, EVENT_TYPE_WRITE); |
| 710 | + } |
| 711 | +} |
| 712 | + |
| 713 | +static bool uloop_timeout_poll_handler(struct os_reltime *tv, bool tv_set) |
| 714 | +{ |
| 715 | + struct os_reltime tv_uloop; |
| 716 | + int timeout_ms = uloop_get_next_timeout(); |
| 717 | + |
| 718 | + if (timeout_ms < 0) |
| 719 | + return false; |
| 720 | + |
| 721 | + tv_uloop.sec = timeout_ms / 1000; |
| 722 | + tv_uloop.usec = (timeout_ms % 1000) * 1000; |
| 723 | + |
| 724 | + if (!tv_set || os_reltime_before(&tv_uloop, tv)) { |
| 725 | + *tv = tv_uloop; |
| 726 | + return true; |
| 727 | + } |
| 728 | + |
| 729 | + return false; |
| 730 | +} |
| 731 | + |
| 732 | +static void uloop_poll_handler(void) |
| 733 | +{ |
| 734 | + uloop_run_timeout(0); |
| 735 | +} |
| 736 | + |
| 737 | +void eloop_add_uloop(void) |
| 738 | +{ |
| 739 | + static bool init_done = false; |
| 740 | + |
| 741 | + if (!init_done) { |
| 742 | + uloop_init(); |
| 743 | + uloop_fd_set_cb = eloop_uloop_fd_cb; |
| 744 | + init_done = true; |
| 745 | + } |
| 746 | + |
| 747 | + eloop_register_cb(uloop_poll_handler, uloop_timeout_poll_handler); |
| 748 | +} |