ctrl_iface_dbus_new.c 55 KB

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