dbus_new.c 48 KB

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