601-ucode_support.patch 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. From: Felix Fietkau <[email protected]>
  2. Date: Fri, 26 May 2023 10:23:59 +0200
  3. Subject: [PATCH] Add ucode support, use ucode for the main ubus object
  4. This implements vastly improved dynamic configuration reload support.
  5. It can handle configuration changes on individual wifi interfaces, as well
  6. as adding/removing interfaces.
  7. --- a/hostapd/Makefile
  8. +++ b/hostapd/Makefile
  9. @@ -168,9 +168,21 @@ OBJS += ../src/eapol_auth/eapol_auth_sm.
  10. ifdef CONFIG_UBUS
  11. CFLAGS += -DUBUS_SUPPORT
  12. -OBJS += ../src/utils/uloop.o
  13. OBJS += ../src/ap/ubus.o
  14. -LIBS += -lubox -lubus
  15. +LIBS += -lubus
  16. +NEED_ULOOP:=y
  17. +endif
  18. +
  19. +ifdef CONFIG_UCODE
  20. +CFLAGS += -DUCODE_SUPPORT
  21. +OBJS += ../src/utils/ucode.o
  22. +OBJS += ../src/ap/ucode.o
  23. +NEED_ULOOP:=y
  24. +endif
  25. +
  26. +ifdef NEED_ULOOP
  27. +OBJS += ../src/utils/uloop.o
  28. +LIBS += -lubox
  29. endif
  30. ifdef CONFIG_CODE_COVERAGE
  31. --- a/hostapd/ctrl_iface.c
  32. +++ b/hostapd/ctrl_iface.c
  33. @@ -5487,6 +5487,7 @@ try_again:
  34. return -1;
  35. }
  36. + interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process;
  37. wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb);
  38. return 0;
  39. @@ -5588,6 +5589,7 @@ fail:
  40. os_free(fname);
  41. interface->global_ctrl_sock = s;
  42. + interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process;
  43. eloop_register_read_sock(s, hostapd_global_ctrl_iface_receive,
  44. interface, NULL);
  45. --- a/hostapd/main.c
  46. +++ b/hostapd/main.c
  47. @@ -1014,6 +1014,7 @@ int main(int argc, char *argv[])
  48. }
  49. hostapd_global_ctrl_iface_init(&interfaces);
  50. + hostapd_ucode_init(&interfaces);
  51. if (hostapd_global_run(&interfaces, daemonize, pid_file)) {
  52. wpa_printf(MSG_ERROR, "Failed to start eloop");
  53. @@ -1023,6 +1024,7 @@ int main(int argc, char *argv[])
  54. ret = 0;
  55. out:
  56. + hostapd_ucode_free();
  57. hostapd_global_ctrl_iface_deinit(&interfaces);
  58. /* Deinitialize all interfaces */
  59. for (i = 0; i < interfaces.count; i++) {
  60. --- a/src/ap/ap_drv_ops.h
  61. +++ b/src/ap/ap_drv_ops.h
  62. @@ -399,6 +399,23 @@ static inline int hostapd_drv_stop_ap(st
  63. return hapd->driver->stop_ap(hapd->drv_priv, link_id);
  64. }
  65. +static inline int hostapd_drv_if_rename(struct hostapd_data *hapd,
  66. + enum wpa_driver_if_type type,
  67. + const char *ifname,
  68. + const char *new_name)
  69. +{
  70. + if (!hapd->driver || !hapd->driver->if_rename || !hapd->drv_priv)
  71. + return -1;
  72. + return hapd->driver->if_rename(hapd->drv_priv, type, ifname, new_name);
  73. +}
  74. +
  75. +static inline int hostapd_drv_set_first_bss(struct hostapd_data *hapd)
  76. +{
  77. + if (!hapd->driver || !hapd->driver->set_first_bss || !hapd->drv_priv)
  78. + return 0;
  79. + return hapd->driver->set_first_bss(hapd->drv_priv);
  80. +}
  81. +
  82. static inline int hostapd_drv_channel_info(struct hostapd_data *hapd,
  83. struct wpa_channel_info *ci)
  84. {
  85. --- a/src/ap/hostapd.c
  86. +++ b/src/ap/hostapd.c
  87. @@ -255,6 +255,8 @@ int hostapd_reload_config(struct hostapd
  88. struct hostapd_config *newconf, *oldconf;
  89. size_t j;
  90. + hostapd_ucode_reload_bss(hapd);
  91. +
  92. if (iface->config_fname == NULL) {
  93. /* Only in-memory config in use - assume it has been updated */
  94. hostapd_clear_old(iface);
  95. @@ -493,6 +495,7 @@ void hostapd_free_hapd_data(struct hosta
  96. hapd->beacon_set_done = 0;
  97. wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
  98. + hostapd_ucode_free_bss(hapd);
  99. hostapd_ubus_free_bss(hapd);
  100. accounting_deinit(hapd);
  101. hostapd_deinit_wpa(hapd);
  102. @@ -687,6 +690,7 @@ void hostapd_cleanup_iface_partial(struc
  103. static void hostapd_cleanup_iface(struct hostapd_iface *iface)
  104. {
  105. wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
  106. + hostapd_ucode_free_iface(iface);
  107. eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
  108. NULL);
  109. @@ -1276,6 +1280,7 @@ static int hostapd_start_beacon(struct h
  110. hapd->driver->set_operstate(hapd->drv_priv, 1);
  111. hostapd_ubus_add_bss(hapd);
  112. + hostapd_ucode_add_bss(hapd);
  113. return 0;
  114. }
  115. @@ -1298,8 +1303,7 @@ static int hostapd_start_beacon(struct h
  116. * initialized. Most of the modules that are initialized here will be
  117. * deinitialized in hostapd_cleanup().
  118. */
  119. -static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
  120. - bool start_beacon)
  121. +int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon)
  122. {
  123. struct hostapd_bss_config *conf = hapd->conf;
  124. u8 ssid[SSID_MAX_LEN + 1];
  125. @@ -2790,7 +2794,7 @@ hostapd_alloc_bss_data(struct hostapd_if
  126. }
  127. -static void hostapd_bss_deinit(struct hostapd_data *hapd)
  128. +void hostapd_bss_deinit(struct hostapd_data *hapd)
  129. {
  130. if (!hapd)
  131. return;
  132. @@ -3608,7 +3612,8 @@ int hostapd_remove_iface(struct hapd_int
  133. hapd_iface = interfaces->iface[i];
  134. if (hapd_iface == NULL)
  135. return -1;
  136. - if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
  137. + if (!os_strcmp(hapd_iface->phy, buf) ||
  138. + !os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
  139. wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
  140. hapd_iface->driver_ap_teardown =
  141. !!(hapd_iface->drv_flags &
  142. --- a/src/ap/hostapd.h
  143. +++ b/src/ap/hostapd.h
  144. @@ -19,6 +19,7 @@
  145. #include "ap_config.h"
  146. #include "drivers/driver.h"
  147. #include "ubus.h"
  148. +#include "ucode.h"
  149. #define OCE_STA_CFON_ENABLED(hapd) \
  150. ((hapd->conf->oce & OCE_STA_CFON) && \
  151. @@ -51,6 +52,10 @@ struct hapd_interfaces {
  152. struct hostapd_config * (*config_read_cb)(const char *config_fname);
  153. int (*ctrl_iface_init)(struct hostapd_data *hapd);
  154. void (*ctrl_iface_deinit)(struct hostapd_data *hapd);
  155. + int (*ctrl_iface_recv)(struct hostapd_data *hapd,
  156. + char *buf, char *reply, int reply_size,
  157. + struct sockaddr_storage *from,
  158. + socklen_t fromlen);
  159. int (*for_each_interface)(struct hapd_interfaces *interfaces,
  160. int (*cb)(struct hostapd_iface *iface,
  161. void *ctx), void *ctx);
  162. @@ -186,6 +191,7 @@ struct hostapd_data {
  163. struct hostapd_config *iconf;
  164. struct hostapd_bss_config *conf;
  165. struct hostapd_ubus_bss ubus;
  166. + struct hostapd_ucode_bss ucode;
  167. int interface_added; /* virtual interface added for this BSS */
  168. unsigned int started:1;
  169. unsigned int disabled:1;
  170. @@ -518,6 +524,7 @@ struct hostapd_sta_info {
  171. */
  172. struct hostapd_iface {
  173. struct hapd_interfaces *interfaces;
  174. + struct hostapd_ucode_iface ucode;
  175. void *owner;
  176. char *config_fname;
  177. struct hostapd_config *conf;
  178. @@ -718,6 +725,8 @@ struct hostapd_iface * hostapd_init(stru
  179. struct hostapd_iface *
  180. hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
  181. const char *config_fname, int debug);
  182. +int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon);
  183. +void hostapd_bss_deinit(struct hostapd_data *hapd);
  184. void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
  185. int reassoc);
  186. void hostapd_interface_deinit_free(struct hostapd_iface *iface);
  187. --- a/src/drivers/driver.h
  188. +++ b/src/drivers/driver.h
  189. @@ -3856,6 +3856,25 @@ struct wpa_driver_ops {
  190. const char *ifname);
  191. /**
  192. + * if_rename - Rename a virtual interface
  193. + * @priv: Private driver interface data
  194. + * @type: Interface type
  195. + * @ifname: Interface name of the virtual interface to be renamed
  196. + * (NULL when renaming the AP BSS interface)
  197. + * @new_name: New interface name of the virtual interface
  198. + * Returns: 0 on success, -1 on failure
  199. + */
  200. + int (*if_rename)(void *priv, enum wpa_driver_if_type type,
  201. + const char *ifname, const char *new_name);
  202. +
  203. + /**
  204. + * set_first_bss - Make a virtual interface the first (primary) bss
  205. + * @priv: Private driver interface data
  206. + * Returns: 0 on success, -1 on failure
  207. + */
  208. + int (*set_first_bss)(void *priv);
  209. +
  210. + /**
  211. * set_sta_vlan - Bind a station into a specific interface (AP only)
  212. * @priv: Private driver interface data
  213. * @ifname: Interface (main or virtual BSS or VLAN)
  214. @@ -6510,6 +6529,7 @@ union wpa_event_data {
  215. /**
  216. * struct ch_switch
  217. + * @count: Count until channel switch activates
  218. * @freq: Frequency of new channel in MHz
  219. * @ht_enabled: Whether this is an HT channel
  220. * @ch_offset: Secondary channel offset
  221. @@ -6520,6 +6540,7 @@ union wpa_event_data {
  222. * @punct_bitmap: Puncturing bitmap
  223. */
  224. struct ch_switch {
  225. + int count;
  226. int freq;
  227. int ht_enabled;
  228. int ch_offset;
  229. --- a/src/drivers/driver_nl80211.c
  230. +++ b/src/drivers/driver_nl80211.c
  231. @@ -75,6 +75,16 @@ enum nlmsgerr_attrs {
  232. #endif /* ANDROID */
  233. +static void handle_nl_debug_hook(struct nl_msg *msg, int tx)
  234. +{
  235. + const struct nlmsghdr *nlh;
  236. +
  237. + if (!wpa_netlink_hook)
  238. + return;
  239. +
  240. + nlh = nlmsg_hdr(msg);
  241. + wpa_netlink_hook(tx, nlh, nlh->nlmsg_len);
  242. +}
  243. static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
  244. {
  245. @@ -429,6 +439,11 @@ static int no_seq_check(struct nl_msg *m
  246. return NL_OK;
  247. }
  248. +static int debug_handler(struct nl_msg *msg, void *arg)
  249. +{
  250. + handle_nl_debug_hook(msg, 0);
  251. + return NL_OK;
  252. +}
  253. static void nl80211_nlmsg_clear(struct nl_msg *msg)
  254. {
  255. @@ -502,6 +517,8 @@ int send_and_recv(struct nl80211_global
  256. if (!msg)
  257. return -ENOMEM;
  258. + handle_nl_debug_hook(msg, 1);
  259. +
  260. err.err = -ENOMEM;
  261. s_nl_cb = nl_socket_get_cb(nl_handle);
  262. @@ -536,6 +553,7 @@ int send_and_recv(struct nl80211_global
  263. err.orig_msg = msg;
  264. err.err_info = err_info;
  265. + nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
  266. nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
  267. nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err.err);
  268. if (ack_handler_custom) {
  269. @@ -939,6 +957,7 @@ nl80211_get_wiphy_data_ap(struct i802_bs
  270. os_free(w);
  271. return NULL;
  272. }
  273. + nl_cb_set(w->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
  274. nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
  275. no_seq_check, NULL);
  276. nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
  277. @@ -1353,7 +1372,7 @@ static void wpa_driver_nl80211_event_rtm
  278. }
  279. wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
  280. namebuf, ifname);
  281. - if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
  282. + if (drv->first_bss->ifindex != ifi->ifi_index) {
  283. wpa_printf(MSG_DEBUG,
  284. "nl80211: Not the main interface (%s) - do not indicate interface down",
  285. drv->first_bss->ifname);
  286. @@ -1389,7 +1408,7 @@ static void wpa_driver_nl80211_event_rtm
  287. }
  288. wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
  289. namebuf, ifname);
  290. - if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
  291. + if (drv->first_bss->ifindex != ifi->ifi_index) {
  292. wpa_printf(MSG_DEBUG,
  293. "nl80211: Not the main interface (%s) - do not indicate interface up",
  294. drv->first_bss->ifname);
  295. @@ -2035,6 +2054,7 @@ static int wpa_driver_nl80211_init_nl_gl
  296. genl_family_put(family);
  297. nl_cache_free(cache);
  298. + nl_cb_set(global->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
  299. nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
  300. no_seq_check, NULL);
  301. nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
  302. @@ -2205,6 +2225,7 @@ static int nl80211_init_bss(struct i802_
  303. if (!bss->nl_cb)
  304. return -1;
  305. + nl_cb_set(bss->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
  306. nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
  307. no_seq_check, NULL);
  308. nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
  309. @@ -8554,6 +8575,7 @@ static void *i802_init(struct hostapd_da
  310. char master_ifname[IFNAMSIZ];
  311. int ifindex, br_ifindex = 0;
  312. int br_added = 0;
  313. + int err;
  314. bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
  315. params->global_priv, 1,
  316. @@ -8613,21 +8635,17 @@ static void *i802_init(struct hostapd_da
  317. (params->num_bridge == 0 || !params->bridge[0]))
  318. add_ifidx(drv, br_ifindex, drv->ifindex);
  319. - if (bss->added_if_into_bridge || bss->already_in_bridge) {
  320. - int err;
  321. -
  322. - drv->rtnl_sk = nl_socket_alloc();
  323. - if (drv->rtnl_sk == NULL) {
  324. - wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
  325. - goto failed;
  326. - }
  327. + drv->rtnl_sk = nl_socket_alloc();
  328. + if (drv->rtnl_sk == NULL) {
  329. + wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
  330. + goto failed;
  331. + }
  332. - err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
  333. - if (err) {
  334. - wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
  335. - nl_geterror(err));
  336. - goto failed;
  337. - }
  338. + err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
  339. + if (err) {
  340. + wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
  341. + nl_geterror(err));
  342. + goto failed;
  343. }
  344. if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
  345. @@ -8992,6 +9010,50 @@ static int wpa_driver_nl80211_if_remove(
  346. return 0;
  347. }
  348. +static int wpa_driver_nl80211_if_rename(struct i802_bss *bss,
  349. + enum wpa_driver_if_type type,
  350. + const char *ifname, const char *new_name)
  351. +{
  352. + struct wpa_driver_nl80211_data *drv = bss->drv;
  353. + struct ifinfomsg ifi = {
  354. + .ifi_family = AF_UNSPEC,
  355. + .ifi_index = bss->ifindex,
  356. + };
  357. + struct nl_msg *msg;
  358. + int res = -ENOMEM;
  359. +
  360. + if (ifname)
  361. + ifi.ifi_index = if_nametoindex(ifname);
  362. +
  363. + msg = nlmsg_alloc_simple(RTM_SETLINK, 0);
  364. + if (!msg)
  365. + return res;
  366. +
  367. + if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
  368. + goto out;
  369. +
  370. + if (nla_put_string(msg, IFLA_IFNAME, new_name))
  371. + goto out;
  372. +
  373. + res = nl_send_auto_complete(drv->rtnl_sk, msg);
  374. + if (res < 0)
  375. + goto out;
  376. +
  377. + res = nl_wait_for_ack(drv->rtnl_sk);
  378. + if (res) {
  379. + wpa_printf(MSG_INFO,
  380. + "nl80211: Renaming device %s to %s failed: %s",
  381. + ifname ? ifname : bss->ifname, new_name, nl_geterror(res));
  382. + goto out;
  383. + }
  384. +
  385. + if (type == WPA_IF_AP_BSS && !ifname)
  386. + os_strlcpy(bss->ifname, new_name, sizeof(bss->ifname));
  387. +
  388. +out:
  389. + nlmsg_free(msg);
  390. + return res;
  391. +}
  392. static int cookie_handler(struct nl_msg *msg, void *arg)
  393. {
  394. @@ -10688,6 +10750,37 @@ static int driver_nl80211_if_remove(void
  395. }
  396. +static int driver_nl80211_if_rename(void *priv, enum wpa_driver_if_type type,
  397. + const char *ifname, const char *new_name)
  398. +{
  399. + struct i802_bss *bss = priv;
  400. + return wpa_driver_nl80211_if_rename(bss, type, ifname, new_name);
  401. +}
  402. +
  403. +
  404. +static int driver_nl80211_set_first_bss(void *priv)
  405. +{
  406. + struct i802_bss *bss = priv, *tbss;
  407. + struct wpa_driver_nl80211_data *drv = bss->drv;
  408. +
  409. + if (drv->first_bss == bss)
  410. + return 0;
  411. +
  412. + for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
  413. + if (tbss->next != bss)
  414. + continue;
  415. +
  416. + tbss->next = bss->next;
  417. + bss->next = drv->first_bss;
  418. + drv->first_bss = bss;
  419. + drv->ctx = bss->ctx;
  420. + return 0;
  421. + }
  422. +
  423. + return -1;
  424. +}
  425. +
  426. +
  427. static int driver_nl80211_send_mlme(void *priv, const u8 *data,
  428. size_t data_len, int noack,
  429. unsigned int freq,
  430. @@ -13881,6 +13974,8 @@ const struct wpa_driver_ops wpa_driver_n
  431. .set_acl = wpa_driver_nl80211_set_acl,
  432. .if_add = wpa_driver_nl80211_if_add,
  433. .if_remove = driver_nl80211_if_remove,
  434. + .if_rename = driver_nl80211_if_rename,
  435. + .set_first_bss = driver_nl80211_set_first_bss,
  436. .send_mlme = driver_nl80211_send_mlme,
  437. .get_hw_feature_data = nl80211_get_hw_feature_data,
  438. .sta_add = wpa_driver_nl80211_sta_add,
  439. --- a/src/drivers/driver_nl80211_event.c
  440. +++ b/src/drivers/driver_nl80211_event.c
  441. @@ -1196,6 +1196,7 @@ static void mlme_event_ch_switch(struct
  442. struct nlattr *bw, struct nlattr *cf1,
  443. struct nlattr *cf2,
  444. struct nlattr *punct_bitmap,
  445. + struct nlattr *count,
  446. int finished)
  447. {
  448. struct i802_bss *bss;
  449. @@ -1259,6 +1260,8 @@ static void mlme_event_ch_switch(struct
  450. data.ch_switch.cf1 = nla_get_u32(cf1);
  451. if (cf2)
  452. data.ch_switch.cf2 = nla_get_u32(cf2);
  453. + if (count)
  454. + data.ch_switch.count = nla_get_u32(count);
  455. if (finished)
  456. bss->flink->freq = data.ch_switch.freq;
  457. @@ -3961,6 +3964,7 @@ static void do_process_drv_event(struct
  458. tb[NL80211_ATTR_CENTER_FREQ1],
  459. tb[NL80211_ATTR_CENTER_FREQ2],
  460. tb[NL80211_ATTR_PUNCT_BITMAP],
  461. + tb[NL80211_ATTR_CH_SWITCH_COUNT],
  462. 0);
  463. break;
  464. case NL80211_CMD_CH_SWITCH_NOTIFY:
  465. @@ -3973,6 +3977,7 @@ static void do_process_drv_event(struct
  466. tb[NL80211_ATTR_CENTER_FREQ1],
  467. tb[NL80211_ATTR_CENTER_FREQ2],
  468. tb[NL80211_ATTR_PUNCT_BITMAP],
  469. + NULL,
  470. 1);
  471. break;
  472. case NL80211_CMD_DISCONNECT:
  473. --- a/src/utils/wpa_debug.c
  474. +++ b/src/utils/wpa_debug.c
  475. @@ -26,6 +26,10 @@ static FILE *wpa_debug_tracing_file = NU
  476. #define WPAS_TRACE_PFX "wpas <%d>: "
  477. #endif /* CONFIG_DEBUG_LINUX_TRACING */
  478. +void (*wpa_printf_hook)(int level, const char *fmt, va_list ap);
  479. +void (*wpa_hexdump_hook)(int level, const char *title, const void *buf,
  480. + size_t len);
  481. +void (*wpa_netlink_hook)(int tx, const void *data, size_t len);
  482. int wpa_debug_level = MSG_INFO;
  483. int wpa_debug_show_keys = 0;
  484. @@ -210,6 +214,12 @@ void _wpa_printf(int level, const char *
  485. {
  486. va_list ap;
  487. + if (wpa_printf_hook) {
  488. + va_start(ap, fmt);
  489. + wpa_printf_hook(level, fmt, ap);
  490. + va_end(ap);
  491. + }
  492. +
  493. if (level >= wpa_debug_level) {
  494. #ifdef CONFIG_ANDROID_LOG
  495. va_start(ap, fmt);
  496. @@ -260,6 +270,9 @@ void _wpa_hexdump(int level, const char
  497. {
  498. size_t i;
  499. + if (wpa_hexdump_hook)
  500. + wpa_hexdump_hook(level, title, buf, len);
  501. +
  502. #ifdef CONFIG_DEBUG_LINUX_TRACING
  503. if (wpa_debug_tracing_file != NULL) {
  504. fprintf(wpa_debug_tracing_file,
  505. --- a/src/utils/wpa_debug.h
  506. +++ b/src/utils/wpa_debug.h
  507. @@ -11,6 +11,10 @@
  508. #include "wpabuf.h"
  509. +extern void (*wpa_printf_hook)(int level, const char *fmt, va_list ap);
  510. +extern void (*wpa_hexdump_hook)(int level, const char *title,
  511. + const void *buf, size_t len);
  512. +extern void (*wpa_netlink_hook)(int tx, const void *data, size_t len);
  513. extern int wpa_debug_level;
  514. extern int wpa_debug_show_keys;
  515. extern int wpa_debug_timestamp;
  516. --- a/wpa_supplicant/Makefile
  517. +++ b/wpa_supplicant/Makefile
  518. @@ -192,8 +192,20 @@ endif
  519. ifdef CONFIG_UBUS
  520. CFLAGS += -DUBUS_SUPPORT
  521. OBJS += ubus.o
  522. +LIBS += -lubus
  523. +NEED_ULOOP:=y
  524. +endif
  525. +
  526. +ifdef CONFIG_UCODE
  527. +CFLAGS += -DUCODE_SUPPORT
  528. +OBJS += ../src/utils/ucode.o
  529. +OBJS += ucode.o
  530. +NEED_ULOOP:=y
  531. +endif
  532. +
  533. +ifdef NEED_ULOOP
  534. OBJS += ../src/utils/uloop.o
  535. -LIBS += -lubox -lubus
  536. +LIBS += -lubox
  537. endif
  538. ifdef CONFIG_CODE_COVERAGE
  539. @@ -1052,6 +1064,9 @@ OBJS += ../src/ap/ctrl_iface_ap.o
  540. ifdef CONFIG_UBUS
  541. OBJS += ../src/ap/ubus.o
  542. endif
  543. +ifdef CONFIG_UCODE
  544. +OBJS += ../src/ap/ucode.o
  545. +endif
  546. endif
  547. CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY
  548. --- a/wpa_supplicant/events.c
  549. +++ b/wpa_supplicant/events.c
  550. @@ -5949,6 +5949,7 @@ void supplicant_event(void *ctx, enum wp
  551. event_to_string(event), event);
  552. #endif /* CONFIG_NO_STDOUT_DEBUG */
  553. + wpas_ucode_event(wpa_s, event, data);
  554. switch (event) {
  555. case EVENT_AUTH:
  556. #ifdef CONFIG_FST
  557. --- a/wpa_supplicant/wpa_supplicant.c
  558. +++ b/wpa_supplicant/wpa_supplicant.c
  559. @@ -1060,6 +1060,7 @@ void wpa_supplicant_set_state(struct wpa
  560. sme_sched_obss_scan(wpa_s, 0);
  561. }
  562. wpa_s->wpa_state = state;
  563. + wpas_ucode_update_state(wpa_s);
  564. #ifdef CONFIG_BGSCAN
  565. if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid)
  566. @@ -7717,6 +7718,7 @@ struct wpa_supplicant * wpa_supplicant_a
  567. #endif /* CONFIG_P2P */
  568. wpas_ubus_add_bss(wpa_s);
  569. + wpas_ucode_add_bss(wpa_s);
  570. return wpa_s;
  571. }
  572. @@ -7744,6 +7746,7 @@ int wpa_supplicant_remove_iface(struct w
  573. struct wpa_supplicant *parent = wpa_s->parent;
  574. #endif /* CONFIG_MESH */
  575. + wpas_ucode_free_bss(wpa_s);
  576. wpas_ubus_free_bss(wpa_s);
  577. /* Remove interface from the global list of interfaces */
  578. @@ -8054,6 +8057,7 @@ struct wpa_global * wpa_supplicant_init(
  579. eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
  580. wpas_periodic, global, NULL);
  581. + wpas_ucode_init(global);
  582. return global;
  583. }
  584. @@ -8092,12 +8096,8 @@ int wpa_supplicant_run(struct wpa_global
  585. eloop_register_signal_terminate(wpa_supplicant_terminate, global);
  586. eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
  587. - wpas_ubus_add(global);
  588. -
  589. eloop_run();
  590. - wpas_ubus_free(global);
  591. -
  592. return 0;
  593. }
  594. @@ -8130,6 +8130,8 @@ void wpa_supplicant_deinit(struct wpa_gl
  595. wpas_notify_supplicant_deinitialized(global);
  596. + wpas_ucode_free();
  597. +
  598. eap_peer_unregister_methods();
  599. #ifdef CONFIG_AP
  600. eap_server_unregister_methods();
  601. --- a/wpa_supplicant/wpa_supplicant_i.h
  602. +++ b/wpa_supplicant/wpa_supplicant_i.h
  603. @@ -22,6 +22,7 @@
  604. #include "wmm_ac.h"
  605. #include "pasn/pasn_common.h"
  606. #include "ubus.h"
  607. +#include "ucode.h"
  608. extern const char *const wpa_supplicant_version;
  609. extern const char *const wpa_supplicant_license;
  610. @@ -697,6 +698,7 @@ struct wpa_supplicant {
  611. unsigned char perm_addr[ETH_ALEN];
  612. char ifname[100];
  613. struct wpas_ubus_bss ubus;
  614. + struct wpas_ucode_bss ucode;
  615. #ifdef CONFIG_MATCH_IFACE
  616. int matched;
  617. #endif /* CONFIG_MATCH_IFACE */