dbus_new.c 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854
  1. /*
  2. * WPA Supplicant / dbus-based control interface
  3. * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
  4. * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com>
  5. * Copyright (c) 2009, Jouni Malinen <j@w1.fi>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation.
  10. *
  11. * Alternatively, this software may be distributed under the terms of BSD
  12. * license.
  13. *
  14. * See README and COPYING for more details.
  15. */
  16. #include "includes.h"
  17. #include "common.h"
  18. #include "wps/wps.h"
  19. #include "../config.h"
  20. #include "../wpa_supplicant_i.h"
  21. #include "../bss.h"
  22. #include "dbus_new_helpers.h"
  23. #include "dbus_dict_helpers.h"
  24. #include "dbus_new.h"
  25. #include "dbus_new_handlers.h"
  26. #include "dbus_common.h"
  27. #include "dbus_common_i.h"
  28. /**
  29. * wpas_dbus_set_path - Assign a dbus path to an interface
  30. * @wpa_s: wpa_supplicant interface structure
  31. * @path: dbus path to set on the interface
  32. * Returns: 0 on success, -1 on error
  33. */
  34. static int wpas_dbus_set_path(struct wpa_supplicant *wpa_s,
  35. const char *path)
  36. {
  37. u32 len = os_strlen(path);
  38. if (len >= WPAS_DBUS_OBJECT_PATH_MAX)
  39. return -1;
  40. if (wpa_s->dbus_new_path)
  41. return -1;
  42. wpa_s->dbus_new_path = os_strdup(path);
  43. return 0;
  44. }
  45. /**
  46. * wpas_dbus_signal_interface - Send a interface related event signal
  47. * @wpa_s: %wpa_supplicant network interface data
  48. * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
  49. * @properties: determines if add second argument with object properties
  50. *
  51. * Notify listeners about event related with interface
  52. */
  53. static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
  54. const char *sig_name, int properties)
  55. {
  56. struct wpas_dbus_priv *iface;
  57. DBusMessage *_signal;
  58. DBusMessageIter iter, iter_dict;
  59. const char *path;
  60. iface = wpa_s->global->dbus;
  61. /* Do nothing if the control interface is not turned on */
  62. if (iface == NULL)
  63. return;
  64. path = wpas_dbus_get_path(wpa_s);
  65. if (path == NULL) {
  66. wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
  67. "Interface doesn't have a dbus path. "
  68. "Can't send signal.");
  69. return;
  70. }
  71. _signal = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
  72. WPAS_DBUS_NEW_INTERFACE, sig_name);
  73. if (_signal == NULL) {
  74. wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
  75. "enough memory to send scan results signal.");
  76. return;
  77. }
  78. dbus_message_iter_init_append(_signal, &iter);
  79. if(!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  80. &path))
  81. goto err;
  82. if (properties) {
  83. if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
  84. goto err;
  85. wpa_dbus_get_object_properties(iface, path,
  86. WPAS_DBUS_NEW_IFACE_INTERFACE,
  87. &iter_dict);
  88. if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
  89. goto err;
  90. }
  91. dbus_connection_send(iface->con, _signal, NULL);
  92. dbus_message_unref(_signal);
  93. return;
  94. err:
  95. wpa_printf(MSG_ERROR, "wpas_dbus_signal_interface[dbus]: "
  96. "not enough memory to construct signal.");
  97. dbus_message_unref(_signal);
  98. }
  99. /**
  100. * wpas_dbus_signal_interface_added - Send a interface created signal
  101. * @wpa_s: %wpa_supplicant network interface data
  102. *
  103. * Notify listeners about creating new interface
  104. */
  105. static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
  106. {
  107. wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
  108. }
  109. /**
  110. * wpas_dbus_signal_interface_removed - Send a interface removed signal
  111. * @wpa_s: %wpa_supplicant network interface data
  112. *
  113. * Notify listeners about removing interface
  114. */
  115. static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
  116. {
  117. wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
  118. }
  119. /**
  120. * wpas_dbus_signal_scan_done - send scan done signal
  121. * @wpa_s: %wpa_supplicant network interface data
  122. * @success: indicates if scanning succeed or failed
  123. *
  124. * Notify listeners about finishing a scan
  125. */
  126. void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
  127. {
  128. struct wpas_dbus_priv *iface;
  129. DBusMessage *_signal;
  130. const char *path;
  131. dbus_bool_t succ;
  132. iface = wpa_s->global->dbus;
  133. /* Do nothing if the control interface is not turned on */
  134. if (iface == NULL)
  135. return;
  136. path = wpas_dbus_get_path(wpa_s);
  137. if (path == NULL) {
  138. wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
  139. "Interface doesn't have a dbus path. "
  140. "Can't send signal.");
  141. return;
  142. }
  143. _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
  144. "ScanDone");
  145. if (_signal == NULL) {
  146. wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
  147. "enough memory to send signal.");
  148. return;
  149. }
  150. succ = success ? TRUE : FALSE;
  151. if (dbus_message_append_args(_signal, DBUS_TYPE_BOOLEAN, &succ,
  152. DBUS_TYPE_INVALID)) {
  153. dbus_connection_send(iface->con, _signal, NULL);
  154. } else {
  155. wpa_printf(MSG_ERROR, "wpas_dbus_signal_scan_done[dbus]: "
  156. "not enough memory to construct signal.");
  157. }
  158. dbus_message_unref(_signal);
  159. }
  160. /**
  161. * wpas_dbus_signal_blob - Send a BSS related event signal
  162. * @wpa_s: %wpa_supplicant network interface data
  163. * @bss_obj_path: BSS object path
  164. * @sig_name: signal name - BSSAdded or BSSRemoved
  165. * @properties: determines if add second argument with object properties
  166. *
  167. * Notify listeners about event related with BSS
  168. */
  169. static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
  170. const char *bss_obj_path,
  171. const char *sig_name, int properties)
  172. {
  173. struct wpas_dbus_priv *iface;
  174. DBusMessage *_signal;
  175. DBusMessageIter iter, iter_dict;
  176. const char *path;
  177. iface = wpa_s->global->dbus;
  178. /* Do nothing if the control interface is not turned on */
  179. if (iface == NULL)
  180. return;
  181. path = wpas_dbus_get_path(wpa_s);
  182. if (path == NULL) {
  183. wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
  184. "Interface doesn't have a dbus path. "
  185. "Can't send signal.");
  186. return;
  187. }
  188. _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
  189. sig_name);
  190. if (_signal == NULL) {
  191. wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
  192. "enough memory to send signal.");
  193. return;
  194. }
  195. dbus_message_iter_init_append(_signal, &iter);
  196. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  197. &bss_obj_path))
  198. goto err;
  199. if (properties) {
  200. if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
  201. goto err;
  202. wpa_dbus_get_object_properties(iface, bss_obj_path,
  203. WPAS_DBUS_NEW_IFACE_BSSID,
  204. &iter_dict);
  205. if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
  206. goto err;
  207. }
  208. dbus_connection_send(iface->con, _signal, NULL);
  209. dbus_message_unref(_signal);
  210. return;
  211. err:
  212. wpa_printf(MSG_ERROR, "wpas_dbus_signal_bss[dbus]: "
  213. "not enough memory to construct signal.");
  214. dbus_message_unref(_signal);
  215. }
  216. /**
  217. * wpas_dbus_signal_bss_added - Send a BSS added signal
  218. * @wpa_s: %wpa_supplicant network interface data
  219. * @bss_obj_path: new BSS object path
  220. *
  221. * Notify listeners about adding new BSS
  222. */
  223. static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
  224. const char *bss_obj_path)
  225. {
  226. wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
  227. }
  228. /**
  229. * wpas_dbus_signal_bss_removed - Send a BSS removed signal
  230. * @wpa_s: %wpa_supplicant network interface data
  231. * @bss_obj_path: BSS object path
  232. *
  233. * Notify listeners about removing BSS
  234. */
  235. static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
  236. const char *bss_obj_path)
  237. {
  238. wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
  239. }
  240. /**
  241. * wpas_dbus_signal_blob - Send a blob related event signal
  242. * @wpa_s: %wpa_supplicant network interface data
  243. * @name: blob name
  244. * @sig_name: signal name - BlobAdded or BlobRemoved
  245. *
  246. * Notify listeners about event related with blob
  247. */
  248. static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
  249. const char *name, const char *sig_name)
  250. {
  251. struct wpas_dbus_priv *iface;
  252. DBusMessage *_signal;
  253. const char *path;
  254. iface = wpa_s->global->dbus;
  255. /* Do nothing if the control interface is not turned on */
  256. if (iface == NULL)
  257. return;
  258. path = wpas_dbus_get_path(wpa_s);
  259. if (path == NULL) {
  260. wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
  261. "Interface doesn't have a dbus path. "
  262. "Can't send signal.");
  263. return;
  264. }
  265. _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
  266. sig_name);
  267. if (_signal == NULL) {
  268. wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
  269. "enough memory to send signal.");
  270. return;
  271. }
  272. if (dbus_message_append_args(_signal, DBUS_TYPE_STRING, &name,
  273. DBUS_TYPE_INVALID)) {
  274. dbus_connection_send(iface->con, _signal, NULL);
  275. } else {
  276. wpa_printf(MSG_ERROR, "wpas_dbus_signal_blob[dbus]: "
  277. "not enough memory to construct signal.");
  278. }
  279. dbus_message_unref(_signal);
  280. }
  281. /**
  282. * wpas_dbus_signal_blob_added - Send a blob added signal
  283. * @wpa_s: %wpa_supplicant network interface data
  284. * @name: blob name
  285. *
  286. * Notify listeners about adding a new blob
  287. */
  288. void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
  289. const char *name)
  290. {
  291. wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
  292. }
  293. /**
  294. * wpas_dbus_signal_blob_removed - Send a blob removed signal
  295. * @wpa_s: %wpa_supplicant network interface data
  296. * @name: blob name
  297. *
  298. * Notify listeners about removing blob
  299. */
  300. void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
  301. const char *name)
  302. {
  303. wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
  304. }
  305. /**
  306. * wpas_dbus_signal_network - Send a network related event signal
  307. * @wpa_s: %wpa_supplicant network interface data
  308. * @id: new network id
  309. * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
  310. * @properties: determines if add second argument with object properties
  311. *
  312. * Notify listeners about event related with configured network
  313. */
  314. static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
  315. int id, const char *sig_name,
  316. int properties)
  317. {
  318. struct wpas_dbus_priv *iface;
  319. DBusMessage *_signal;
  320. DBusMessageIter iter, iter_dict;
  321. const char *path;
  322. char *net_obj_path;
  323. iface = wpa_s->global->dbus;
  324. /* Do nothing if the control interface is not turned on */
  325. if (iface == NULL)
  326. return;
  327. path = wpas_dbus_get_path(wpa_s);
  328. if (path == NULL) {
  329. wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
  330. "Interface doesn't have a dbus path. "
  331. "Can't send signal.");
  332. return;
  333. }
  334. net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
  335. if (net_obj_path == NULL)
  336. return;
  337. os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  338. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u", path, id);
  339. _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
  340. sig_name);
  341. if (_signal == NULL) {
  342. wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
  343. "enough memory to send signal.");
  344. os_free(net_obj_path);
  345. return;
  346. }
  347. dbus_message_iter_init_append(_signal, &iter);
  348. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  349. &net_obj_path))
  350. goto err;
  351. if (properties) {
  352. if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
  353. goto err;
  354. wpa_dbus_get_object_properties(iface, net_obj_path,
  355. WPAS_DBUS_NEW_IFACE_NETWORK,
  356. &iter_dict);
  357. if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
  358. goto err;
  359. }
  360. dbus_connection_send(iface->con, _signal, NULL);
  361. os_free(net_obj_path);
  362. dbus_message_unref(_signal);
  363. return;
  364. err:
  365. wpa_printf(MSG_ERROR, "wpas_dbus_signal_network[dbus]: "
  366. "not enough memory to construct signal.");
  367. os_free(net_obj_path);
  368. dbus_message_unref(_signal);
  369. }
  370. /**
  371. * wpas_dbus_signal_network_added - Send a network added signal
  372. * @wpa_s: %wpa_supplicant network interface data
  373. * @id: new network id
  374. *
  375. * Notify listeners about adding new network
  376. */
  377. static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
  378. int id)
  379. {
  380. wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
  381. }
  382. /**
  383. * wpas_dbus_signal_network_removed - Send a network removed signal
  384. * @wpa_s: %wpa_supplicant network interface data
  385. * @id: network id
  386. *
  387. * Notify listeners about removing a network
  388. */
  389. static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
  390. int id)
  391. {
  392. wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
  393. }
  394. /**
  395. * wpas_dbus_signal_network_selected - Send a network selected signal
  396. * @wpa_s: %wpa_supplicant network interface data
  397. * @id: network id
  398. *
  399. * Notify listeners about selecting a network
  400. */
  401. void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
  402. {
  403. wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
  404. }
  405. /**
  406. * wpas_dbus_signal_state_changed - Send a state changed signal
  407. * @wpa_s: %wpa_supplicant network interface data
  408. * @new_state: new state wpa_supplicant is entering
  409. * @old_state: old state wpa_supplicant is leaving
  410. *
  411. * Notify listeners that wpa_supplicant has changed state
  412. */
  413. void wpas_dbus_signal_state_changed(struct wpa_supplicant *wpa_s,
  414. enum wpa_states new_state,
  415. enum wpa_states old_state)
  416. {
  417. struct wpas_dbus_priv *iface;
  418. DBusMessage *_signal = NULL;
  419. const char *path;
  420. char *new_state_str, *old_state_str;
  421. char *tmp;
  422. /* Do nothing if the control interface is not turned on */
  423. if (wpa_s->global == NULL)
  424. return;
  425. iface = wpa_s->global->dbus;
  426. if (iface == NULL)
  427. return;
  428. /* Only send signal if state really changed */
  429. if (new_state == old_state)
  430. return;
  431. path = wpas_dbus_get_path(wpa_s);
  432. if (path == NULL) {
  433. perror("wpas_dbus_signal_state_changed[dbus]: "
  434. "interface didn't have a dbus path");
  435. wpa_printf(MSG_ERROR,
  436. "wpas_dbus_signal_state_changed[dbus]: "
  437. "interface didn't have a dbus path; can't send "
  438. "signal.");
  439. return;
  440. }
  441. _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_INTERFACE,
  442. "StateChanged");
  443. if (_signal == NULL) {
  444. perror("wpas_dbus_signal_state_changed[dbus]: "
  445. "couldn't create dbus signal; likely out of memory");
  446. wpa_printf(MSG_ERROR,
  447. "wpas_dbus_signal_state_changed[dbus]: "
  448. "couldn't create dbus signal; likely out of "
  449. "memory.");
  450. return;
  451. }
  452. new_state_str = os_strdup(wpa_supplicant_state_txt(new_state));
  453. old_state_str = os_strdup(wpa_supplicant_state_txt(old_state));
  454. if (new_state_str == NULL || old_state_str == NULL) {
  455. perror("wpas_dbus_signal_state_changed[dbus]: "
  456. "couldn't convert state strings");
  457. wpa_printf(MSG_ERROR,
  458. "wpas_dbus_signal_state_changed[dbus]: "
  459. "couldn't convert state strings.");
  460. goto out;
  461. }
  462. /* make state string lowercase to fit new DBus API convention */
  463. tmp = new_state_str;
  464. while (*tmp) {
  465. *tmp = tolower(*tmp);
  466. tmp++;
  467. }
  468. tmp = old_state_str;
  469. while (*tmp) {
  470. *tmp = tolower(*tmp);
  471. tmp++;
  472. }
  473. if (!dbus_message_append_args(_signal,
  474. DBUS_TYPE_STRING, &new_state_str,
  475. DBUS_TYPE_STRING, &old_state_str,
  476. DBUS_TYPE_INVALID)) {
  477. perror("wpas_dbus_signal_state_changed[dbus]: "
  478. "not enough memory to construct state change signal.");
  479. wpa_printf(MSG_ERROR,
  480. "wpas_dbus_signal_state_changed[dbus]: "
  481. "not enough memory to construct state change "
  482. "signal.");
  483. goto out;
  484. }
  485. dbus_connection_send(iface->con, _signal, NULL);
  486. out:
  487. dbus_message_unref(_signal);
  488. os_free(new_state_str);
  489. os_free(old_state_str);
  490. }
  491. /**
  492. * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
  493. * @wpa_s: %wpa_supplicant network interface data
  494. * @ssid: configured network which Enabled property has changed
  495. *
  496. * Sends PropertyChanged signals containing new value of Enabled property
  497. * for specified network
  498. */
  499. void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
  500. struct wpa_ssid *ssid)
  501. {
  502. struct network_handler_args args = {wpa_s, ssid};
  503. char path[WPAS_DBUS_OBJECT_PATH_MAX];
  504. os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
  505. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
  506. wpas_dbus_get_path(wpa_s), ssid->id);
  507. wpa_dbus_signal_property_changed(wpa_s->global->dbus,
  508. (WPADBusPropertyAccessor)
  509. wpas_dbus_getter_enabled, &args,
  510. path, WPAS_DBUS_NEW_IFACE_NETWORK,
  511. "Enabled");
  512. }
  513. #ifdef CONFIG_WPS
  514. /**
  515. * wpas_dbus_signal_wps_event_success - Signals Success WPS event
  516. * @wpa_s: %wpa_supplicant network interface data
  517. *
  518. * Sends Event dbus signal with name "success" and empty dict as arguments
  519. */
  520. void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
  521. {
  522. DBusMessage *_signal = NULL;
  523. DBusMessageIter iter, dict_iter;
  524. struct wpas_dbus_priv *iface;
  525. char *key = "success";
  526. const char *path;
  527. iface = wpa_s->global->dbus;
  528. /* Do nothing if the control interface is not turned on */
  529. if (iface == NULL)
  530. return;
  531. path = wpas_dbus_get_path(wpa_s);
  532. if (!path) {
  533. wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
  534. "[dbus]: interface has no dbus path set");
  535. return;
  536. }
  537. _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
  538. "Event");
  539. if (!_signal) {
  540. wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
  541. "[dbus]: out of memory when creating a signal");
  542. return;
  543. }
  544. dbus_message_iter_init_append(_signal, &iter);
  545. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
  546. !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  547. !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
  548. wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_success"
  549. "[dbus]: out of memory");
  550. goto out;
  551. }
  552. dbus_connection_send(iface->con, _signal, NULL);
  553. out:
  554. dbus_message_unref(_signal);
  555. }
  556. /**
  557. * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
  558. * @wpa_s: %wpa_supplicant network interface data
  559. *
  560. * Sends Event dbus signal with name "fail" and dictionary containing
  561. * "msg field with fail message number (int32) as arguments
  562. */
  563. void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
  564. struct wps_event_fail *fail)
  565. {
  566. DBusMessage *_signal = NULL;
  567. DBusMessageIter iter, dict_iter;
  568. struct wpas_dbus_priv *iface;
  569. char *key = "fail";
  570. const char *path;
  571. iface = wpa_s->global->dbus;
  572. /* Do nothing if the control interface is not turned on */
  573. if (iface == NULL)
  574. return;
  575. path = wpas_dbus_get_path(wpa_s);
  576. if (!path) {
  577. wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
  578. "interface has no dbus path set");
  579. return;
  580. }
  581. _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
  582. "Event");
  583. if (!_signal) {
  584. wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
  585. "out of memory when creating a signal");
  586. return;
  587. }
  588. dbus_message_iter_init_append(_signal, &iter);
  589. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
  590. !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  591. !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
  592. !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
  593. wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_fail[dbus]: "
  594. "out of memory");
  595. goto out;
  596. }
  597. dbus_connection_send(iface->con, _signal, NULL);
  598. out:
  599. dbus_message_unref(_signal);
  600. }
  601. /**
  602. * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
  603. * @wpa_s: %wpa_supplicant network interface data
  604. *
  605. * Sends Event dbus signal with name "m2d" and dictionary containing
  606. * fields of wps_event_m2d structure.
  607. */
  608. void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
  609. struct wps_event_m2d *m2d)
  610. {
  611. DBusMessage *_signal = NULL;
  612. DBusMessageIter iter, dict_iter;
  613. struct wpas_dbus_priv *iface;
  614. char *key = "m2d";
  615. const char *path;
  616. iface = wpa_s->global->dbus;
  617. /* Do nothing if the control interface is not turned on */
  618. if (iface == NULL)
  619. return;
  620. path = wpas_dbus_get_path(wpa_s);
  621. if (!path) {
  622. wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
  623. "interface has no dbus path set");
  624. return;
  625. }
  626. _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
  627. "Event");
  628. if (!_signal) {
  629. wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
  630. "out of memory when creating a signal");
  631. return;
  632. }
  633. dbus_message_iter_init_append(_signal, &iter);
  634. if (!(dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) &&
  635. wpa_dbus_dict_open_write(&iter, &dict_iter) &&
  636. wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
  637. m2d->config_methods) &&
  638. wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
  639. (const char *) m2d->manufacturer,
  640. m2d->manufacturer_len) &&
  641. wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
  642. (const char *) m2d->model_name,
  643. m2d->model_name_len) &&
  644. wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
  645. (const char *) m2d->model_number,
  646. m2d->model_number_len) &&
  647. wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
  648. (const char *)
  649. m2d->serial_number,
  650. m2d->serial_number_len) &&
  651. wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
  652. (const char *) m2d->dev_name,
  653. m2d->dev_name_len) &&
  654. wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
  655. (const char *)
  656. m2d->primary_dev_type, 8) &&
  657. wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
  658. m2d->config_error) &&
  659. wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
  660. m2d->dev_password_id) &&
  661. wpa_dbus_dict_close_write(&iter, &dict_iter))) {
  662. wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_event_m2d[dbus]: "
  663. "out of memory");
  664. goto out;
  665. }
  666. dbus_connection_send(iface->con, _signal, NULL);
  667. out:
  668. dbus_message_unref(_signal);
  669. }
  670. /**
  671. * wpas_dbus_signal_wps_cred - Signals new credentials
  672. * @wpa_s: %wpa_supplicant network interface data
  673. *
  674. * Sends signal with credentials in directory argument
  675. */
  676. void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
  677. const struct wps_credential *cred)
  678. {
  679. DBusMessage *_signal = NULL;
  680. DBusMessageIter iter, dict_iter;
  681. struct wpas_dbus_priv *iface;
  682. const char *path;
  683. char *auth_type[6]; /* we have six possible authorization types */
  684. int at_num = 0;
  685. char *encr_type[4]; /* we have four possible encryption types */
  686. int et_num = 0;
  687. iface = wpa_s->global->dbus;
  688. /* Do nothing if the control interface is not turned on */
  689. if (iface == NULL)
  690. return;
  691. path = wpas_dbus_get_path(wpa_s);
  692. if (!path) {
  693. wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_cred[dbus]: "
  694. "interface has no dbus path set");
  695. return;
  696. }
  697. _signal = dbus_message_new_signal(path, WPAS_DBUS_NEW_IFACE_WPS,
  698. "Credentials");
  699. if (!_signal) {
  700. wpa_printf(MSG_ERROR, "wpas_dbus_signal_wps_cred[dbus]: "
  701. "out of memory when creating a signal");
  702. return;
  703. }
  704. dbus_message_iter_init_append(_signal, &iter);
  705. if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) {
  706. perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
  707. "when opening a dictionary");
  708. goto nomem;
  709. }
  710. if (cred->auth_type & WPS_AUTH_OPEN)
  711. auth_type[at_num++] = "open";
  712. if (cred->auth_type & WPS_AUTH_WPAPSK)
  713. auth_type[at_num++] = "wpa-psk";
  714. if (cred->auth_type & WPS_AUTH_SHARED)
  715. auth_type[at_num++] = "shared";
  716. if (cred->auth_type & WPS_AUTH_WPA)
  717. auth_type[at_num++] = "wpa-eap";
  718. if (cred->auth_type & WPS_AUTH_WPA2)
  719. auth_type[at_num++] = "wpa2-eap";
  720. if (cred->auth_type & WPS_AUTH_WPA2PSK)
  721. auth_type[at_num++] =
  722. "wpa2-psk";
  723. if (cred->encr_type & WPS_ENCR_NONE)
  724. encr_type[et_num++] = "none";
  725. if (cred->encr_type & WPS_ENCR_WEP)
  726. encr_type[et_num++] = "wep";
  727. if (cred->encr_type & WPS_ENCR_TKIP)
  728. encr_type[et_num++] = "tkip";
  729. if (cred->encr_type & WPS_ENCR_AES)
  730. encr_type[et_num++] = "aes";
  731. if (wpa_s->current_ssid) {
  732. if (!wpa_dbus_dict_append_byte_array(
  733. &dict_iter, "BSSID",
  734. (const char *) wpa_s->current_ssid->bssid,
  735. ETH_ALEN)) {
  736. perror("wpas_dbus_signal_wps_cred[dbus]: out of "
  737. "memory when appending bssid to dictionary");
  738. goto nomem;
  739. }
  740. }
  741. if (!(wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
  742. (const char *) cred->ssid,
  743. cred->ssid_len) &&
  744. wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
  745. (const char **) auth_type,
  746. at_num) &&
  747. wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
  748. (const char **) encr_type,
  749. et_num) &&
  750. wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
  751. (const char *) cred->key,
  752. cred->key_len) &&
  753. wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
  754. cred->key_idx))) {
  755. perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
  756. "when appending to dictionary");
  757. goto nomem;
  758. }
  759. if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) {
  760. perror("wpas_dbus_signal_wps_cred[dbus]: out of memory "
  761. "when closing a dictionary");
  762. goto nomem;
  763. }
  764. dbus_connection_send(iface->con, _signal, NULL);
  765. nomem:
  766. dbus_message_unref(_signal);
  767. }
  768. #endif /* CONFIG_WPS */
  769. /**
  770. * wpas_dbus_signal_prop_changed - Signals change of property
  771. * @wpa_s: %wpa_supplicant network interface data
  772. * @property: indicates which property has changed
  773. *
  774. * Sends ProertyChanged signals with path, interface and arguments
  775. * depending on which property has changed.
  776. */
  777. void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
  778. enum wpas_dbus_prop property)
  779. {
  780. WPADBusPropertyAccessor getter;
  781. char *iface;
  782. char *prop;
  783. void *arg;
  784. switch (property) {
  785. case WPAS_DBUS_PROP_AP_SCAN:
  786. getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan;
  787. arg = wpa_s;
  788. iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
  789. prop = "ApScan";
  790. break;
  791. case WPAS_DBUS_PROP_SCANNING:
  792. getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning;
  793. arg = wpa_s;
  794. iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
  795. prop = "Scanning";
  796. break;
  797. case WPAS_DBUS_PROP_CURRENT_BSS:
  798. getter = (WPADBusPropertyAccessor)
  799. wpas_dbus_getter_current_bss;
  800. arg = wpa_s;
  801. iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
  802. prop = "CurrentBSS";
  803. break;
  804. case WPAS_DBUS_PROP_CURRENT_NETWORK:
  805. getter = (WPADBusPropertyAccessor)
  806. wpas_dbus_getter_current_network;
  807. arg = wpa_s;
  808. iface = WPAS_DBUS_NEW_IFACE_INTERFACE;
  809. prop = "CurrentNetwork";
  810. break;
  811. default:
  812. wpa_printf(MSG_ERROR, "wpas_dbus_signal_prop_changed[dbus]: "
  813. "Unknown Property enum value %d", property);
  814. return;
  815. }
  816. wpa_dbus_signal_property_changed(wpa_s->global->dbus,
  817. getter, arg,
  818. wpas_dbus_get_path(wpa_s), iface,
  819. prop);
  820. }
  821. /**
  822. * wpas_dbus_signal_debug_level_changed - Signals change of debug param
  823. * @global: wpa_global structure
  824. *
  825. * Sends ProertyChanged signals informing that debug level has changed.
  826. */
  827. void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
  828. {
  829. wpa_dbus_signal_property_changed(global->dbus,
  830. (WPADBusPropertyAccessor)
  831. wpas_dbus_getter_debug_level,
  832. global, WPAS_DBUS_NEW_PATH,
  833. WPAS_DBUS_NEW_INTERFACE,
  834. "DebugLevel");
  835. }
  836. /**
  837. * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
  838. * @global: wpa_global structure
  839. *
  840. * Sends ProertyChanged signals informing that debug timestamp has changed.
  841. */
  842. void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
  843. {
  844. wpa_dbus_signal_property_changed(global->dbus,
  845. (WPADBusPropertyAccessor)
  846. wpas_dbus_getter_debug_timestamp,
  847. global, WPAS_DBUS_NEW_PATH,
  848. WPAS_DBUS_NEW_INTERFACE,
  849. "DebugTimestamp");
  850. }
  851. /**
  852. * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
  853. * @global: wpa_global structure
  854. *
  855. * Sends ProertyChanged signals informing that debug show_keys has changed.
  856. */
  857. void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
  858. {
  859. wpa_dbus_signal_property_changed(global->dbus,
  860. (WPADBusPropertyAccessor)
  861. wpas_dbus_getter_debug_show_keys,
  862. global, WPAS_DBUS_NEW_PATH,
  863. WPAS_DBUS_NEW_INTERFACE,
  864. "DebugShowKeys");
  865. }
  866. struct wpas_dbus_method {
  867. const char *name;
  868. const char *iface;
  869. WPADBusMethodHandler handler;
  870. struct wpa_dbus_argument args[3];
  871. };
  872. struct wpas_dbus_property {
  873. const char *name;
  874. const char *iface;
  875. const char *type;
  876. WPADBusPropertyAccessor getter;
  877. WPADBusPropertyAccessor setter;
  878. enum dbus_prop_access _access;
  879. };
  880. struct wpas_dbus_signal {
  881. const char *name;
  882. const char *iface;
  883. struct wpa_dbus_argument args[3];
  884. };
  885. static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
  886. void *priv,
  887. WPADBusArgumentFreeFunction priv_free,
  888. const struct wpas_dbus_method *methods,
  889. const struct wpas_dbus_property *properties,
  890. const struct wpas_dbus_signal *signals)
  891. {
  892. int i;
  893. obj_desc->user_data = priv;
  894. obj_desc->user_data_free_func = priv_free;
  895. for (i = 0; methods && methods[i].name; i++) {
  896. wpa_dbus_method_register(obj_desc, methods[i].iface,
  897. methods[i].name, methods[i].handler,
  898. methods[i].args);
  899. }
  900. for (i = 0; properties && properties[i].name; i++) {
  901. wpa_dbus_property_register(obj_desc, properties[i].iface,
  902. properties[i].name,
  903. properties[i].type,
  904. properties[i].getter,
  905. properties[i].setter,
  906. properties[i]._access);
  907. }
  908. for (i = 0; signals && signals[i].name; i++) {
  909. wpa_dbus_signal_register(obj_desc, signals[i].iface,
  910. signals[i].name, signals[i].args);
  911. }
  912. }
  913. static const struct wpas_dbus_method wpas_dbus_global_methods[] = {
  914. { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
  915. (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
  916. {
  917. { "args", "a{sv}", ARG_IN },
  918. { "path", "o", ARG_OUT },
  919. END_ARGS
  920. }
  921. },
  922. { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
  923. (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
  924. {
  925. { "path", "o", ARG_IN },
  926. END_ARGS
  927. }
  928. },
  929. { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
  930. (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
  931. {
  932. { "ifname", "s", ARG_IN },
  933. { "path", "o", ARG_OUT },
  934. END_ARGS
  935. }
  936. },
  937. { NULL, NULL, NULL, { END_ARGS } }
  938. };
  939. static const struct wpas_dbus_property wpas_dbus_global_properties[] = {
  940. { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "y",
  941. (WPADBusPropertyAccessor) wpas_dbus_getter_debug_level,
  942. (WPADBusPropertyAccessor) wpas_dbus_setter_debug_level,
  943. RW
  944. },
  945. { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
  946. (WPADBusPropertyAccessor) wpas_dbus_getter_debug_timestamp,
  947. (WPADBusPropertyAccessor) wpas_dbus_setter_debug_timestamp,
  948. RW
  949. },
  950. { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
  951. (WPADBusPropertyAccessor) wpas_dbus_getter_debug_show_keys,
  952. (WPADBusPropertyAccessor) wpas_dbus_setter_debug_show_keys,
  953. RW
  954. },
  955. { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
  956. (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces,
  957. NULL,
  958. R
  959. },
  960. { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
  961. (WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods,
  962. NULL,
  963. R
  964. },
  965. { NULL, NULL, NULL, NULL, NULL, 0 }
  966. };
  967. static const struct wpas_dbus_signal wpas_dbus_global_signals[] = {
  968. { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
  969. {
  970. { "path", "o", ARG_OUT },
  971. { "properties", "a{sv}", ARG_OUT },
  972. END_ARGS
  973. }
  974. },
  975. { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
  976. {
  977. { "path", "o", ARG_OUT },
  978. END_ARGS
  979. }
  980. },
  981. { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
  982. {
  983. { "properties", "a{sv}", ARG_OUT },
  984. END_ARGS
  985. }
  986. },
  987. { NULL, NULL, { END_ARGS } }
  988. };
  989. /**
  990. * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
  991. * @global: Pointer to global data from wpa_supplicant_init()
  992. * Returns: 0 on success or -1 on failure
  993. *
  994. * Initialize the dbus control interface for wpa_supplicantand and start
  995. * receiving commands from external programs over the bus.
  996. */
  997. int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
  998. {
  999. struct wpa_dbus_object_desc *obj_desc;
  1000. int ret;
  1001. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  1002. if (!obj_desc) {
  1003. wpa_printf(MSG_ERROR, "Not enough memory "
  1004. "to create object description");
  1005. return -1;
  1006. }
  1007. wpas_dbus_register(obj_desc, priv->global, NULL,
  1008. wpas_dbus_global_methods,
  1009. wpas_dbus_global_properties,
  1010. wpas_dbus_global_signals);
  1011. wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
  1012. WPAS_DBUS_NEW_PATH);
  1013. ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
  1014. WPAS_DBUS_NEW_SERVICE,
  1015. obj_desc);
  1016. if (ret < 0)
  1017. free_dbus_object_desc(obj_desc);
  1018. else
  1019. priv->dbus_new_initialized = 1;
  1020. return ret;
  1021. }
  1022. /**
  1023. * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
  1024. * wpa_supplicant
  1025. * @iface: Pointer to dbus private data from wpas_dbus_init()
  1026. *
  1027. * Deinitialize the dbus control interface that was initialized with
  1028. * wpas_dbus_ctrl_iface_init().
  1029. */
  1030. void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
  1031. {
  1032. if (!iface->dbus_new_initialized)
  1033. return;
  1034. wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
  1035. WPAS_DBUS_NEW_PATH);
  1036. dbus_connection_unregister_object_path(iface->con,
  1037. WPAS_DBUS_NEW_PATH);
  1038. }
  1039. static void wpa_dbus_free(void *ptr)
  1040. {
  1041. os_free(ptr);
  1042. }
  1043. static const struct wpas_dbus_property wpas_dbus_network_properties[] = {
  1044. { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
  1045. (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties,
  1046. (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties,
  1047. RW
  1048. },
  1049. { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
  1050. (WPADBusPropertyAccessor) wpas_dbus_getter_enabled,
  1051. (WPADBusPropertyAccessor) wpas_dbus_setter_enabled,
  1052. RW
  1053. },
  1054. { NULL, NULL, NULL, NULL, NULL, 0 }
  1055. };
  1056. static const struct wpas_dbus_signal wpas_dbus_network_signals[] = {
  1057. { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
  1058. {
  1059. { "properties", "a{sv}", ARG_OUT },
  1060. END_ARGS
  1061. }
  1062. },
  1063. { NULL, NULL, { END_ARGS } }
  1064. };
  1065. /**
  1066. * wpas_dbus_register_network - Register a configured network with dbus
  1067. * @wpa_s: wpa_supplicant interface structure
  1068. * @ssid: network configuration data
  1069. * Returns: 0 on success, -1 on failure
  1070. *
  1071. * Registers network representing object with dbus
  1072. */
  1073. int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
  1074. struct wpa_ssid *ssid)
  1075. {
  1076. struct wpas_dbus_priv *ctrl_iface;
  1077. struct wpa_dbus_object_desc *obj_desc;
  1078. struct network_handler_args *arg = NULL;
  1079. char *net_obj_path;
  1080. /* Do nothing if the control interface is not turned on */
  1081. if (wpa_s == NULL || wpa_s->global == NULL)
  1082. return 0;
  1083. ctrl_iface = wpa_s->global->dbus;
  1084. if (ctrl_iface == NULL)
  1085. return 0;
  1086. net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
  1087. if (net_obj_path == NULL)
  1088. return -1;
  1089. os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1090. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
  1091. wpas_dbus_get_path(wpa_s), ssid->id);
  1092. wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
  1093. net_obj_path);
  1094. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  1095. if (!obj_desc) {
  1096. wpa_printf(MSG_ERROR, "Not enough memory "
  1097. "to create object description");
  1098. goto err;
  1099. }
  1100. /* allocate memory for handlers arguments */
  1101. arg = os_zalloc(sizeof(struct network_handler_args));
  1102. if (!arg) {
  1103. wpa_printf(MSG_ERROR, "Not enough memory "
  1104. "to create arguments for method");
  1105. goto err;
  1106. }
  1107. arg->wpa_s = wpa_s;
  1108. arg->ssid = ssid;
  1109. wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
  1110. wpas_dbus_network_properties,
  1111. wpas_dbus_network_signals);
  1112. if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
  1113. wpa_s->ifname, obj_desc))
  1114. goto err;
  1115. wpas_dbus_signal_network_added(wpa_s, ssid->id);
  1116. os_free(net_obj_path);
  1117. return 0;
  1118. err:
  1119. os_free(net_obj_path);
  1120. os_free(obj_desc);
  1121. os_free(arg);
  1122. return -1;
  1123. }
  1124. /**
  1125. * wpas_dbus_unregister_network - Unregister a configured network from dbus
  1126. * @wpa_s: wpa_supplicant interface structure
  1127. * @nid: network id
  1128. * Returns: 0 on success, -1 on failure
  1129. *
  1130. * Unregisters network representing object from dbus
  1131. */
  1132. int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
  1133. {
  1134. struct wpas_dbus_priv *ctrl_iface;
  1135. char *net_obj_path;
  1136. int ret;
  1137. /* Do nothing if the control interface is not turned on */
  1138. if (wpa_s == NULL || wpa_s->global == NULL)
  1139. return 0;
  1140. ctrl_iface = wpa_s->global->dbus;
  1141. if (ctrl_iface == NULL)
  1142. return 0;
  1143. net_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
  1144. if (net_obj_path == NULL)
  1145. return -1;
  1146. os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1147. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
  1148. wpas_dbus_get_path(wpa_s), nid);
  1149. wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
  1150. net_obj_path);
  1151. ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
  1152. if (!ret)
  1153. wpas_dbus_signal_network_removed(wpa_s, nid);
  1154. os_free(net_obj_path);
  1155. return ret;
  1156. }
  1157. static const struct wpas_dbus_property wpas_dbus_bss_properties[] = {
  1158. { "SSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
  1159. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid,
  1160. NULL,
  1161. R
  1162. },
  1163. { "BSSID", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
  1164. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_bssid,
  1165. NULL,
  1166. R
  1167. },
  1168. { "Privacy", WPAS_DBUS_NEW_IFACE_BSSID, "b",
  1169. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_privacy,
  1170. NULL,
  1171. R
  1172. },
  1173. { "Mode", WPAS_DBUS_NEW_IFACE_BSSID, "s",
  1174. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_mode,
  1175. NULL,
  1176. R
  1177. },
  1178. { "Signal", WPAS_DBUS_NEW_IFACE_BSSID, "n",
  1179. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_signal,
  1180. NULL,
  1181. R
  1182. },
  1183. { "Frequency", WPAS_DBUS_NEW_IFACE_BSSID, "q",
  1184. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_frequency,
  1185. NULL,
  1186. R
  1187. },
  1188. { "MaxRate", WPAS_DBUS_NEW_IFACE_BSSID, "q",
  1189. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_max_rate,
  1190. NULL,
  1191. R
  1192. },
  1193. { "WPAIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
  1194. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpaie,
  1195. NULL,
  1196. R
  1197. },
  1198. { "RSNIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
  1199. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsnie,
  1200. NULL,
  1201. R
  1202. },
  1203. { "WPSIE", WPAS_DBUS_NEW_IFACE_BSSID, "ay",
  1204. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpsie,
  1205. NULL,
  1206. R
  1207. },
  1208. { NULL, NULL, NULL, NULL, NULL, 0 }
  1209. };
  1210. static const struct wpas_dbus_signal wpas_dbus_bss_signals[] = {
  1211. { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSSID,
  1212. {
  1213. { "properties", "a{sv}", ARG_OUT },
  1214. END_ARGS
  1215. }
  1216. },
  1217. { NULL, NULL, { END_ARGS } }
  1218. };
  1219. /**
  1220. * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
  1221. * @wpa_s: wpa_supplicant interface structure
  1222. * @bssid: scanned network bssid
  1223. * @id: unique BSS identifier
  1224. * Returns: 0 on success, -1 on failure
  1225. *
  1226. * Unregisters BSS representing object from dbus
  1227. */
  1228. int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
  1229. u8 bssid[ETH_ALEN], unsigned int id)
  1230. {
  1231. struct wpas_dbus_priv *ctrl_iface;
  1232. char *bss_obj_path;
  1233. /* Do nothing if the control interface is not turned on */
  1234. if (wpa_s == NULL || wpa_s->global == NULL)
  1235. return 0;
  1236. ctrl_iface = wpa_s->global->dbus;
  1237. if (ctrl_iface == NULL)
  1238. return 0;
  1239. bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
  1240. if (bss_obj_path == NULL)
  1241. return -1;
  1242. os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1243. "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
  1244. wpas_dbus_get_path(wpa_s), id);
  1245. wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
  1246. bss_obj_path);
  1247. if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
  1248. wpa_printf(MSG_ERROR,
  1249. "Cannot unregister BSSID dbus object %s.",
  1250. bss_obj_path);
  1251. os_free(bss_obj_path);
  1252. return -1;
  1253. }
  1254. wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
  1255. os_free(bss_obj_path);
  1256. return 0;
  1257. }
  1258. /**
  1259. * wpas_dbus_register_bss - Register a scanned BSS with dbus
  1260. * @wpa_s: wpa_supplicant interface structure
  1261. * @bssid: scanned network bssid
  1262. * @id: unique BSS identifier
  1263. * Returns: 0 on success, -1 on failure
  1264. *
  1265. * Registers BSS representing object with dbus
  1266. */
  1267. int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
  1268. u8 bssid[ETH_ALEN], unsigned int id)
  1269. {
  1270. struct wpas_dbus_priv *ctrl_iface;
  1271. struct wpa_dbus_object_desc *obj_desc;
  1272. char *bss_obj_path;
  1273. struct bss_handler_args *arg = NULL;
  1274. /* Do nothing if the control interface is not turned on */
  1275. if (wpa_s == NULL || wpa_s->global == NULL)
  1276. return 0;
  1277. ctrl_iface = wpa_s->global->dbus;
  1278. if (ctrl_iface == NULL)
  1279. return 0;
  1280. bss_obj_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
  1281. if (bss_obj_path == NULL)
  1282. return -1;
  1283. os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1284. "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
  1285. wpas_dbus_get_path(wpa_s), id);
  1286. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  1287. if (!obj_desc) {
  1288. wpa_printf(MSG_ERROR, "Not enough memory "
  1289. "to create object description");
  1290. goto err;
  1291. }
  1292. arg = os_zalloc(sizeof(struct bss_handler_args));
  1293. if (!arg) {
  1294. wpa_printf(MSG_ERROR, "Not enough memory "
  1295. "to create arguments for handler");
  1296. goto err;
  1297. }
  1298. arg->wpa_s = wpa_s;
  1299. arg->id = id;
  1300. wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
  1301. wpas_dbus_bss_properties,
  1302. wpas_dbus_bss_signals);
  1303. wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
  1304. bss_obj_path);
  1305. if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
  1306. wpa_s->ifname, obj_desc)) {
  1307. wpa_printf(MSG_ERROR,
  1308. "Cannot register BSSID dbus object %s.",
  1309. bss_obj_path);
  1310. goto err;
  1311. }
  1312. wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
  1313. os_free(bss_obj_path);
  1314. return 0;
  1315. err:
  1316. os_free(bss_obj_path);
  1317. os_free(obj_desc);
  1318. os_free(arg);
  1319. return -1;
  1320. }
  1321. static const struct wpas_dbus_method wpas_dbus_interface_methods[] = {
  1322. { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1323. (WPADBusMethodHandler) &wpas_dbus_handler_scan,
  1324. {
  1325. { "args", "a{sv}", ARG_IN },
  1326. END_ARGS
  1327. }
  1328. },
  1329. { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1330. (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
  1331. {
  1332. END_ARGS
  1333. }
  1334. },
  1335. { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1336. (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
  1337. {
  1338. { "args", "a{sv}", ARG_IN },
  1339. { "path", "o", ARG_OUT },
  1340. END_ARGS
  1341. }
  1342. },
  1343. { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1344. (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
  1345. {
  1346. { "path", "o", ARG_IN },
  1347. END_ARGS
  1348. }
  1349. },
  1350. { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1351. (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
  1352. {
  1353. { "path", "o", ARG_IN },
  1354. END_ARGS
  1355. }
  1356. },
  1357. { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1358. (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
  1359. {
  1360. { "name", "s", ARG_IN },
  1361. { "data", "ay", ARG_IN },
  1362. END_ARGS
  1363. }
  1364. },
  1365. { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1366. (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
  1367. {
  1368. { "name", "s", ARG_IN },
  1369. { "data", "ay", ARG_OUT },
  1370. END_ARGS
  1371. }
  1372. },
  1373. { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1374. (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
  1375. {
  1376. { "name", "s", ARG_IN },
  1377. END_ARGS
  1378. }
  1379. },
  1380. #ifdef CONFIG_WPS
  1381. { "Start", WPAS_DBUS_NEW_IFACE_WPS,
  1382. (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
  1383. {
  1384. { "args", "a{sv}", ARG_IN },
  1385. { "output", "a{sv}", ARG_OUT },
  1386. END_ARGS
  1387. }
  1388. },
  1389. #endif /* CONFIG_WPS */
  1390. { NULL, NULL, NULL, { END_ARGS } }
  1391. };
  1392. static const struct wpas_dbus_property wpas_dbus_interface_properties[] = {
  1393. { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
  1394. (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities,
  1395. NULL, R
  1396. },
  1397. { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  1398. (WPADBusPropertyAccessor) wpas_dbus_getter_state,
  1399. NULL, R
  1400. },
  1401. { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
  1402. (WPADBusPropertyAccessor) wpas_dbus_getter_scanning,
  1403. NULL, R
  1404. },
  1405. { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
  1406. (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan,
  1407. (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan,
  1408. RW
  1409. },
  1410. { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  1411. (WPADBusPropertyAccessor) wpas_dbus_getter_ifname,
  1412. NULL, R
  1413. },
  1414. { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  1415. (WPADBusPropertyAccessor) wpas_dbus_getter_driver,
  1416. NULL, R
  1417. },
  1418. { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  1419. (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname,
  1420. NULL, R
  1421. },
  1422. { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
  1423. (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss,
  1424. NULL, R
  1425. },
  1426. { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
  1427. (WPADBusPropertyAccessor) wpas_dbus_getter_current_network,
  1428. NULL, R
  1429. },
  1430. { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
  1431. (WPADBusPropertyAccessor) wpas_dbus_getter_blobs,
  1432. NULL, R
  1433. },
  1434. { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
  1435. (WPADBusPropertyAccessor) wpas_dbus_getter_bsss,
  1436. NULL, R
  1437. },
  1438. { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
  1439. (WPADBusPropertyAccessor) wpas_dbus_getter_networks,
  1440. NULL, R
  1441. },
  1442. #ifdef CONFIG_WPS
  1443. { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
  1444. (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials,
  1445. (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials,
  1446. RW
  1447. },
  1448. #endif /* CONFIG_WPS */
  1449. { NULL, NULL, NULL, NULL, NULL, 0 }
  1450. };
  1451. static const struct wpas_dbus_signal wpas_dbus_interface_signals[] = {
  1452. { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1453. {
  1454. { "success", "b", ARG_OUT },
  1455. END_ARGS
  1456. }
  1457. },
  1458. { "StateChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1459. {
  1460. { "newState", "s", ARG_OUT },
  1461. { "oldState", "s", ARG_OUT },
  1462. END_ARGS
  1463. }
  1464. },
  1465. { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1466. {
  1467. { "path", "o", ARG_OUT },
  1468. { "properties", "a{sv}", ARG_OUT },
  1469. END_ARGS
  1470. }
  1471. },
  1472. { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1473. {
  1474. { "path", "o", ARG_OUT },
  1475. END_ARGS
  1476. }
  1477. },
  1478. { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1479. {
  1480. { "name", "s", ARG_OUT },
  1481. END_ARGS
  1482. }
  1483. },
  1484. { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1485. {
  1486. { "name", "s", ARG_OUT },
  1487. END_ARGS
  1488. }
  1489. },
  1490. { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1491. {
  1492. { "path", "o", ARG_OUT },
  1493. { "properties", "a{sv}", ARG_OUT },
  1494. END_ARGS
  1495. }
  1496. },
  1497. { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1498. {
  1499. { "path", "o", ARG_OUT },
  1500. END_ARGS
  1501. }
  1502. },
  1503. { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1504. {
  1505. { "path", "o", ARG_OUT },
  1506. END_ARGS
  1507. }
  1508. },
  1509. { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1510. {
  1511. { "properties", "a{sv}", ARG_OUT },
  1512. END_ARGS
  1513. }
  1514. },
  1515. #ifdef CONFIG_WPS
  1516. { "Event", WPAS_DBUS_NEW_IFACE_WPS,
  1517. {
  1518. { "name", "s", ARG_OUT },
  1519. { "args", "a{sv}", ARG_OUT },
  1520. END_ARGS
  1521. }
  1522. },
  1523. { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
  1524. {
  1525. { "credentials", "a{sv}", ARG_OUT },
  1526. END_ARGS
  1527. }
  1528. },
  1529. { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
  1530. {
  1531. { "properties", "a{sv}", ARG_OUT },
  1532. END_ARGS
  1533. }
  1534. },
  1535. #endif /* CONFIG_WPS */
  1536. { NULL, NULL, { END_ARGS } }
  1537. };
  1538. int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
  1539. {
  1540. struct wpa_dbus_object_desc *obj_desc = NULL;
  1541. char *path;
  1542. struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
  1543. int next;
  1544. /* Do nothing if the control interface is not turned on */
  1545. if (ctrl_iface == NULL)
  1546. return 0;
  1547. /* Create and set the interface's object path */
  1548. path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
  1549. if (path == NULL)
  1550. return -1;
  1551. next = ctrl_iface->next_objid++;
  1552. os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
  1553. WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
  1554. next);
  1555. if (wpas_dbus_set_path(wpa_s, path)) {
  1556. wpa_printf(MSG_DEBUG,
  1557. "Failed to set dbus path for interface %s",
  1558. wpa_s->ifname);
  1559. goto err;
  1560. }
  1561. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  1562. if (!obj_desc) {
  1563. wpa_printf(MSG_ERROR, "Not enough memory "
  1564. "to create object description");
  1565. goto err;
  1566. }
  1567. wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
  1568. wpas_dbus_interface_properties,
  1569. wpas_dbus_interface_signals);
  1570. wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'", path);
  1571. if (wpa_dbus_register_object_per_iface(ctrl_iface, path, wpa_s->ifname,
  1572. obj_desc))
  1573. goto err;
  1574. wpas_dbus_signal_interface_added(wpa_s);
  1575. os_free(path);
  1576. return 0;
  1577. err:
  1578. os_free(obj_desc);
  1579. os_free(path);
  1580. return -1;
  1581. }
  1582. int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
  1583. {
  1584. struct wpas_dbus_priv *ctrl_iface;
  1585. /* Do nothing if the control interface is not turned on */
  1586. if (wpa_s == NULL || wpa_s->global == NULL)
  1587. return 0;
  1588. ctrl_iface = wpa_s->global->dbus;
  1589. if (ctrl_iface == NULL)
  1590. return 0;
  1591. wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
  1592. wpas_dbus_get_path(wpa_s));
  1593. if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
  1594. wpas_dbus_get_path(wpa_s)))
  1595. return -1;
  1596. wpas_dbus_signal_interface_removed(wpa_s);
  1597. os_free(wpa_s->dbus_new_path);
  1598. wpa_s->dbus_new_path = NULL;
  1599. return 0;
  1600. }
  1601. /**
  1602. * wpas_dbus_get_path - Get an interface's dbus path
  1603. * @wpa_s: %wpa_supplicant interface structure
  1604. * Returns: Interface's dbus object path, or %NULL on error
  1605. */
  1606. const char * wpas_dbus_get_path(struct wpa_supplicant *wpa_s)
  1607. {
  1608. return wpa_s->dbus_new_path;
  1609. }