dbus_new.c 77 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957
  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-2010, 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 "common/ieee802_11_defs.h"
  19. #include "wps/wps.h"
  20. #include "../config.h"
  21. #include "../wpa_supplicant_i.h"
  22. #include "../bss.h"
  23. #include "dbus_new_helpers.h"
  24. #include "dbus_dict_helpers.h"
  25. #include "dbus_new.h"
  26. #include "dbus_new_handlers.h"
  27. #include "dbus_common.h"
  28. #include "dbus_common_i.h"
  29. #include "dbus_new_handlers_p2p.h"
  30. #include "p2p/p2p.h"
  31. /**
  32. * wpas_dbus_signal_interface - Send a interface related event signal
  33. * @wpa_s: %wpa_supplicant network interface data
  34. * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
  35. * @properties: Whether to add second argument with object properties
  36. *
  37. * Notify listeners about event related with interface
  38. */
  39. static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
  40. const char *sig_name, int properties)
  41. {
  42. struct wpas_dbus_priv *iface;
  43. DBusMessage *msg;
  44. DBusMessageIter iter, iter_dict;
  45. iface = wpa_s->global->dbus;
  46. /* Do nothing if the control interface is not turned on */
  47. if (iface == NULL)
  48. return;
  49. msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
  50. WPAS_DBUS_NEW_INTERFACE, sig_name);
  51. if (msg == NULL)
  52. return;
  53. dbus_message_iter_init_append(msg, &iter);
  54. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  55. &wpa_s->dbus_new_path))
  56. goto err;
  57. if (properties) {
  58. if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
  59. goto err;
  60. wpa_dbus_get_object_properties(iface, wpa_s->dbus_new_path,
  61. WPAS_DBUS_NEW_IFACE_INTERFACE,
  62. &iter_dict);
  63. if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
  64. goto err;
  65. }
  66. dbus_connection_send(iface->con, msg, NULL);
  67. dbus_message_unref(msg);
  68. return;
  69. err:
  70. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  71. dbus_message_unref(msg);
  72. }
  73. /**
  74. * wpas_dbus_signal_interface_added - Send a interface created signal
  75. * @wpa_s: %wpa_supplicant network interface data
  76. *
  77. * Notify listeners about creating new interface
  78. */
  79. static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
  80. {
  81. wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
  82. }
  83. /**
  84. * wpas_dbus_signal_interface_removed - Send a interface removed signal
  85. * @wpa_s: %wpa_supplicant network interface data
  86. *
  87. * Notify listeners about removing interface
  88. */
  89. static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
  90. {
  91. wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
  92. }
  93. /**
  94. * wpas_dbus_signal_scan_done - send scan done signal
  95. * @wpa_s: %wpa_supplicant network interface data
  96. * @success: indicates if scanning succeed or failed
  97. *
  98. * Notify listeners about finishing a scan
  99. */
  100. void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
  101. {
  102. struct wpas_dbus_priv *iface;
  103. DBusMessage *msg;
  104. dbus_bool_t succ;
  105. iface = wpa_s->global->dbus;
  106. /* Do nothing if the control interface is not turned on */
  107. if (iface == NULL)
  108. return;
  109. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  110. WPAS_DBUS_NEW_IFACE_INTERFACE,
  111. "ScanDone");
  112. if (msg == NULL)
  113. return;
  114. succ = success ? TRUE : FALSE;
  115. if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
  116. DBUS_TYPE_INVALID))
  117. dbus_connection_send(iface->con, msg, NULL);
  118. else
  119. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  120. dbus_message_unref(msg);
  121. }
  122. /**
  123. * wpas_dbus_signal_blob - Send a BSS related event signal
  124. * @wpa_s: %wpa_supplicant network interface data
  125. * @bss_obj_path: BSS object path
  126. * @sig_name: signal name - BSSAdded or BSSRemoved
  127. * @properties: Whether to add second argument with object properties
  128. *
  129. * Notify listeners about event related with BSS
  130. */
  131. static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
  132. const char *bss_obj_path,
  133. const char *sig_name, int properties)
  134. {
  135. struct wpas_dbus_priv *iface;
  136. DBusMessage *msg;
  137. DBusMessageIter iter, iter_dict;
  138. iface = wpa_s->global->dbus;
  139. /* Do nothing if the control interface is not turned on */
  140. if (iface == NULL)
  141. return;
  142. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  143. WPAS_DBUS_NEW_IFACE_INTERFACE,
  144. sig_name);
  145. if (msg == NULL)
  146. return;
  147. dbus_message_iter_init_append(msg, &iter);
  148. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  149. &bss_obj_path))
  150. goto err;
  151. if (properties) {
  152. if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
  153. goto err;
  154. wpa_dbus_get_object_properties(iface, bss_obj_path,
  155. WPAS_DBUS_NEW_IFACE_BSS,
  156. &iter_dict);
  157. if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
  158. goto err;
  159. }
  160. dbus_connection_send(iface->con, msg, NULL);
  161. dbus_message_unref(msg);
  162. return;
  163. err:
  164. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  165. dbus_message_unref(msg);
  166. }
  167. /**
  168. * wpas_dbus_signal_bss_added - Send a BSS added signal
  169. * @wpa_s: %wpa_supplicant network interface data
  170. * @bss_obj_path: new BSS object path
  171. *
  172. * Notify listeners about adding new BSS
  173. */
  174. static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
  175. const char *bss_obj_path)
  176. {
  177. wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
  178. }
  179. /**
  180. * wpas_dbus_signal_bss_removed - Send a BSS removed signal
  181. * @wpa_s: %wpa_supplicant network interface data
  182. * @bss_obj_path: BSS object path
  183. *
  184. * Notify listeners about removing BSS
  185. */
  186. static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
  187. const char *bss_obj_path)
  188. {
  189. wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
  190. }
  191. /**
  192. * wpas_dbus_signal_blob - Send a blob related event signal
  193. * @wpa_s: %wpa_supplicant network interface data
  194. * @name: blob name
  195. * @sig_name: signal name - BlobAdded or BlobRemoved
  196. *
  197. * Notify listeners about event related with blob
  198. */
  199. static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
  200. const char *name, const char *sig_name)
  201. {
  202. struct wpas_dbus_priv *iface;
  203. DBusMessage *msg;
  204. iface = wpa_s->global->dbus;
  205. /* Do nothing if the control interface is not turned on */
  206. if (iface == NULL)
  207. return;
  208. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  209. WPAS_DBUS_NEW_IFACE_INTERFACE,
  210. sig_name);
  211. if (msg == NULL)
  212. return;
  213. if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
  214. DBUS_TYPE_INVALID))
  215. dbus_connection_send(iface->con, msg, NULL);
  216. else
  217. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  218. dbus_message_unref(msg);
  219. }
  220. /**
  221. * wpas_dbus_signal_blob_added - Send a blob added signal
  222. * @wpa_s: %wpa_supplicant network interface data
  223. * @name: blob name
  224. *
  225. * Notify listeners about adding a new blob
  226. */
  227. void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
  228. const char *name)
  229. {
  230. wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
  231. }
  232. /**
  233. * wpas_dbus_signal_blob_removed - Send a blob removed signal
  234. * @wpa_s: %wpa_supplicant network interface data
  235. * @name: blob name
  236. *
  237. * Notify listeners about removing blob
  238. */
  239. void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
  240. const char *name)
  241. {
  242. wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
  243. }
  244. /**
  245. * wpas_dbus_signal_network - Send a network related event signal
  246. * @wpa_s: %wpa_supplicant network interface data
  247. * @id: new network id
  248. * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
  249. * @properties: determines if add second argument with object properties
  250. *
  251. * Notify listeners about event related with configured network
  252. */
  253. static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
  254. int id, const char *sig_name,
  255. int properties)
  256. {
  257. struct wpas_dbus_priv *iface;
  258. DBusMessage *msg;
  259. DBusMessageIter iter, iter_dict;
  260. char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  261. iface = wpa_s->global->dbus;
  262. /* Do nothing if the control interface is not turned on */
  263. if (iface == NULL)
  264. return;
  265. os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  266. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
  267. wpa_s->dbus_new_path, id);
  268. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  269. WPAS_DBUS_NEW_IFACE_INTERFACE,
  270. sig_name);
  271. if (msg == NULL)
  272. return;
  273. dbus_message_iter_init_append(msg, &iter);
  274. path = net_obj_path;
  275. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  276. &path))
  277. goto err;
  278. if (properties) {
  279. if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
  280. goto err;
  281. wpa_dbus_get_object_properties(iface, net_obj_path,
  282. WPAS_DBUS_NEW_IFACE_NETWORK,
  283. &iter_dict);
  284. if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
  285. goto err;
  286. }
  287. dbus_connection_send(iface->con, msg, NULL);
  288. dbus_message_unref(msg);
  289. return;
  290. err:
  291. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  292. dbus_message_unref(msg);
  293. }
  294. /**
  295. * wpas_dbus_signal_network_added - Send a network added signal
  296. * @wpa_s: %wpa_supplicant network interface data
  297. * @id: new network id
  298. *
  299. * Notify listeners about adding new network
  300. */
  301. static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
  302. int id)
  303. {
  304. wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
  305. }
  306. /**
  307. * wpas_dbus_signal_network_removed - Send a network removed signal
  308. * @wpa_s: %wpa_supplicant network interface data
  309. * @id: network id
  310. *
  311. * Notify listeners about removing a network
  312. */
  313. static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
  314. int id)
  315. {
  316. wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
  317. }
  318. /**
  319. * wpas_dbus_signal_network_selected - Send a network selected signal
  320. * @wpa_s: %wpa_supplicant network interface data
  321. * @id: network id
  322. *
  323. * Notify listeners about selecting a network
  324. */
  325. void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
  326. {
  327. wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
  328. }
  329. /**
  330. * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
  331. * @wpa_s: %wpa_supplicant network interface data
  332. * @ssid: configured network which Enabled property has changed
  333. *
  334. * Sends PropertyChanged signals containing new value of Enabled property
  335. * for specified network
  336. */
  337. void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
  338. struct wpa_ssid *ssid)
  339. {
  340. char path[WPAS_DBUS_OBJECT_PATH_MAX];
  341. os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
  342. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
  343. wpa_s->dbus_new_path, ssid->id);
  344. wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
  345. WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
  346. }
  347. #ifdef CONFIG_WPS
  348. /**
  349. * wpas_dbus_signal_wps_event_success - Signals Success WPS event
  350. * @wpa_s: %wpa_supplicant network interface data
  351. *
  352. * Sends Event dbus signal with name "success" and empty dict as arguments
  353. */
  354. void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
  355. {
  356. DBusMessage *msg;
  357. DBusMessageIter iter, dict_iter;
  358. struct wpas_dbus_priv *iface;
  359. char *key = "success";
  360. iface = wpa_s->global->dbus;
  361. /* Do nothing if the control interface is not turned on */
  362. if (iface == NULL)
  363. return;
  364. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  365. WPAS_DBUS_NEW_IFACE_WPS, "Event");
  366. if (msg == NULL)
  367. return;
  368. dbus_message_iter_init_append(msg, &iter);
  369. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
  370. !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  371. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  372. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  373. else
  374. dbus_connection_send(iface->con, msg, NULL);
  375. dbus_message_unref(msg);
  376. }
  377. /**
  378. * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
  379. * @wpa_s: %wpa_supplicant network interface data
  380. *
  381. * Sends Event dbus signal with name "fail" and dictionary containing
  382. * "msg field with fail message number (int32) as arguments
  383. */
  384. void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
  385. struct wps_event_fail *fail)
  386. {
  387. DBusMessage *msg;
  388. DBusMessageIter iter, dict_iter;
  389. struct wpas_dbus_priv *iface;
  390. char *key = "fail";
  391. iface = wpa_s->global->dbus;
  392. /* Do nothing if the control interface is not turned on */
  393. if (iface == NULL)
  394. return;
  395. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  396. WPAS_DBUS_NEW_IFACE_WPS, "Event");
  397. if (msg == NULL)
  398. return;
  399. dbus_message_iter_init_append(msg, &iter);
  400. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
  401. !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  402. !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
  403. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  404. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  405. else
  406. dbus_connection_send(iface->con, msg, NULL);
  407. dbus_message_unref(msg);
  408. }
  409. /**
  410. * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
  411. * @wpa_s: %wpa_supplicant network interface data
  412. *
  413. * Sends Event dbus signal with name "m2d" and dictionary containing
  414. * fields of wps_event_m2d structure.
  415. */
  416. void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
  417. struct wps_event_m2d *m2d)
  418. {
  419. DBusMessage *msg;
  420. DBusMessageIter iter, dict_iter;
  421. struct wpas_dbus_priv *iface;
  422. char *key = "m2d";
  423. iface = wpa_s->global->dbus;
  424. /* Do nothing if the control interface is not turned on */
  425. if (iface == NULL)
  426. return;
  427. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  428. WPAS_DBUS_NEW_IFACE_WPS, "Event");
  429. if (msg == NULL)
  430. return;
  431. dbus_message_iter_init_append(msg, &iter);
  432. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
  433. !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  434. !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
  435. m2d->config_methods) ||
  436. !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
  437. (const char *) m2d->manufacturer,
  438. m2d->manufacturer_len) ||
  439. !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
  440. (const char *) m2d->model_name,
  441. m2d->model_name_len) ||
  442. !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
  443. (const char *) m2d->model_number,
  444. m2d->model_number_len) ||
  445. !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
  446. (const char *)
  447. m2d->serial_number,
  448. m2d->serial_number_len) ||
  449. !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
  450. (const char *) m2d->dev_name,
  451. m2d->dev_name_len) ||
  452. !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
  453. (const char *)
  454. m2d->primary_dev_type, 8) ||
  455. !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
  456. m2d->config_error) ||
  457. !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
  458. m2d->dev_password_id) ||
  459. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  460. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  461. else
  462. dbus_connection_send(iface->con, msg, NULL);
  463. dbus_message_unref(msg);
  464. }
  465. /**
  466. * wpas_dbus_signal_wps_cred - Signals new credentials
  467. * @wpa_s: %wpa_supplicant network interface data
  468. *
  469. * Sends signal with credentials in directory argument
  470. */
  471. void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
  472. const struct wps_credential *cred)
  473. {
  474. DBusMessage *msg;
  475. DBusMessageIter iter, dict_iter;
  476. struct wpas_dbus_priv *iface;
  477. char *auth_type[6]; /* we have six possible authorization types */
  478. int at_num = 0;
  479. char *encr_type[4]; /* we have four possible encryption types */
  480. int et_num = 0;
  481. iface = wpa_s->global->dbus;
  482. /* Do nothing if the control interface is not turned on */
  483. if (iface == NULL)
  484. return;
  485. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  486. WPAS_DBUS_NEW_IFACE_WPS,
  487. "Credentials");
  488. if (msg == NULL)
  489. return;
  490. dbus_message_iter_init_append(msg, &iter);
  491. if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
  492. goto nomem;
  493. if (cred->auth_type & WPS_AUTH_OPEN)
  494. auth_type[at_num++] = "open";
  495. if (cred->auth_type & WPS_AUTH_WPAPSK)
  496. auth_type[at_num++] = "wpa-psk";
  497. if (cred->auth_type & WPS_AUTH_SHARED)
  498. auth_type[at_num++] = "shared";
  499. if (cred->auth_type & WPS_AUTH_WPA)
  500. auth_type[at_num++] = "wpa-eap";
  501. if (cred->auth_type & WPS_AUTH_WPA2)
  502. auth_type[at_num++] = "wpa2-eap";
  503. if (cred->auth_type & WPS_AUTH_WPA2PSK)
  504. auth_type[at_num++] =
  505. "wpa2-psk";
  506. if (cred->encr_type & WPS_ENCR_NONE)
  507. encr_type[et_num++] = "none";
  508. if (cred->encr_type & WPS_ENCR_WEP)
  509. encr_type[et_num++] = "wep";
  510. if (cred->encr_type & WPS_ENCR_TKIP)
  511. encr_type[et_num++] = "tkip";
  512. if (cred->encr_type & WPS_ENCR_AES)
  513. encr_type[et_num++] = "aes";
  514. if (wpa_s->current_ssid) {
  515. if (!wpa_dbus_dict_append_byte_array(
  516. &dict_iter, "BSSID",
  517. (const char *) wpa_s->current_ssid->bssid,
  518. ETH_ALEN))
  519. goto nomem;
  520. }
  521. if (!wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
  522. (const char *) cred->ssid,
  523. cred->ssid_len) ||
  524. !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
  525. (const char **) auth_type,
  526. at_num) ||
  527. !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
  528. (const char **) encr_type,
  529. et_num) ||
  530. !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
  531. (const char *) cred->key,
  532. cred->key_len) ||
  533. !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
  534. cred->key_idx) ||
  535. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  536. goto nomem;
  537. dbus_connection_send(iface->con, msg, NULL);
  538. nomem:
  539. dbus_message_unref(msg);
  540. }
  541. #endif /* CONFIG_WPS */
  542. #ifdef CONFIG_P2P
  543. /**
  544. * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
  545. * @wpa_s: %wpa_supplicant network interface data
  546. * @role: role of this device (client or GO)
  547. * Sends signal with i/f name and role as string arguments
  548. */
  549. void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
  550. const char *role)
  551. {
  552. DBusMessage *msg;
  553. DBusMessageIter iter;
  554. struct wpas_dbus_priv *iface = wpa_s->global->dbus;
  555. char *ifname = wpa_s->ifname;
  556. /* Do nothing if the control interface is not turned on */
  557. if (iface == NULL)
  558. return;
  559. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  560. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  561. "GroupFinished");
  562. if (msg == NULL)
  563. return;
  564. dbus_message_iter_init_append(msg, &iter);
  565. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &ifname)) {
  566. wpa_printf(MSG_ERROR, "dbus: Failed to construct GroupFinished"
  567. "signal -not enough memory for ifname ");
  568. goto err;
  569. }
  570. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &role))
  571. wpa_printf(MSG_ERROR, "dbus: Failed to construct GroupFinished"
  572. "signal -not enough memory for role ");
  573. else
  574. dbus_connection_send(iface->con, msg, NULL);
  575. err:
  576. dbus_message_unref(msg);
  577. }
  578. /**
  579. * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
  580. *
  581. * @dev_addr - who sent the request or responded to our request.
  582. * @request - Will be 1 if request, 0 for response.
  583. * @status - valid only in case of response
  584. * @config_methods - wps config methods
  585. * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
  586. *
  587. * Sends following provision discovery related events:
  588. * ProvisionDiscoveryRequestDisplayPin
  589. * ProvisionDiscoveryResponseDisplayPin
  590. * ProvisionDiscoveryRequestEnterPin
  591. * ProvisionDiscoveryResponseEnterPin
  592. * ProvisionDiscoveryPBCRequest
  593. * ProvisionDiscoveryPBCResponse
  594. *
  595. * TODO::
  596. * ProvisionDiscoveryFailure (timeout case)
  597. */
  598. void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
  599. const u8 *dev_addr, int request,
  600. enum p2p_prov_disc_status status,
  601. u16 config_methods,
  602. unsigned int generated_pin)
  603. {
  604. DBusMessage *msg;
  605. DBusMessageIter iter;
  606. struct wpas_dbus_priv *iface;
  607. char *_signal;
  608. int add_pin = 0;
  609. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  610. int error_ret = 1;
  611. char pin[9], *p_pin = NULL;
  612. iface = wpa_s->global->dbus;
  613. /* Do nothing if the control interface is not turned on */
  614. if (iface == NULL)
  615. return;
  616. if (request || !status) {
  617. if (config_methods & WPS_CONFIG_DISPLAY)
  618. _signal = request ?
  619. "ProvisionDiscoveryRequestDisplayPin" :
  620. "ProvisionDiscoveryResponseEnterPin";
  621. else if (config_methods & WPS_CONFIG_KEYPAD)
  622. _signal = request ?
  623. "ProvisionDiscoveryRequestEnterPin" :
  624. "ProvisionDiscoveryResponseDisplayPin";
  625. else if (config_methods & WPS_CONFIG_PUSHBUTTON)
  626. _signal = request ? "ProvisionDiscoveryPBCRequest" :
  627. "ProvisionDiscoveryPBCResponse";
  628. else
  629. return; /* Unknown or un-supported method */
  630. } else if (!request && status)
  631. /* Explicit check for failure response */
  632. _signal = "ProvisionDiscoveryFailure";
  633. add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
  634. (!request && !status &&
  635. (config_methods & WPS_CONFIG_KEYPAD)));
  636. if (add_pin) {
  637. os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
  638. p_pin = pin;
  639. }
  640. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  641. WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
  642. if (msg == NULL)
  643. return;
  644. /* Check if this is a known peer */
  645. if (p2p_get_peer_info(wpa_s->global->p2p, dev_addr, 0, NULL, 0) < 0)
  646. goto error;
  647. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  648. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
  649. COMPACT_MACSTR,
  650. wpa_s->dbus_new_path, MAC2STR(dev_addr));
  651. path = peer_obj_path;
  652. dbus_message_iter_init_append(msg, &iter);
  653. if (!dbus_message_iter_append_basic(&iter,
  654. DBUS_TYPE_OBJECT_PATH,
  655. &path))
  656. goto error;
  657. if (!request && status)
  658. /* Attach status to ProvisionDiscoveryFailure */
  659. error_ret = !dbus_message_iter_append_basic(&iter,
  660. DBUS_TYPE_INT32,
  661. &status);
  662. else
  663. error_ret = (add_pin &&
  664. !dbus_message_iter_append_basic(&iter,
  665. DBUS_TYPE_STRING,
  666. &p_pin));
  667. error:
  668. if (!error_ret)
  669. dbus_connection_send(iface->con, msg, NULL);
  670. else
  671. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  672. dbus_message_unref(msg);
  673. }
  674. void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
  675. const u8 *src, u16 dev_passwd_id)
  676. {
  677. DBusMessage *msg;
  678. DBusMessageIter iter;
  679. struct wpas_dbus_priv *iface;
  680. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  681. iface = wpa_s->global->dbus;
  682. /* Do nothing if the control interface is not turned on */
  683. if (iface == NULL)
  684. return;
  685. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  686. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
  687. wpa_s->dbus_new_path, MAC2STR(src));
  688. path = peer_obj_path;
  689. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  690. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  691. "GONegotiationRequest");
  692. if (msg == NULL)
  693. return;
  694. dbus_message_iter_init_append(msg, &iter);
  695. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  696. &path) ||
  697. !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
  698. &dev_passwd_id))
  699. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  700. else
  701. dbus_connection_send(iface->con, msg, NULL);
  702. dbus_message_unref(msg);
  703. }
  704. static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
  705. const struct wpa_ssid *ssid,
  706. char *group_obj_path)
  707. {
  708. char group_name[3];
  709. if (os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
  710. return -1;
  711. memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
  712. group_name[2] = '\0';
  713. os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  714. "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
  715. wpa_s->dbus_new_path, group_name);
  716. return 0;
  717. }
  718. /**
  719. * wpas_dbus_signal_p2p_group_started - Signals P2P group has
  720. * started.Emitted when a group is succesfully started
  721. * irrespective of the role (client/GO) of the current device
  722. *
  723. * @wpa_s: %wpa_supplicant network interface data
  724. * @ssid: SSID object
  725. * @client: this device is P2P client
  726. * @network_id: network id of the group started, use instead of ssid->id
  727. * to account for persistent groups
  728. */
  729. void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
  730. const struct wpa_ssid *ssid,
  731. int client, int network_id)
  732. {
  733. DBusMessage *msg;
  734. DBusMessageIter iter, dict_iter;
  735. struct wpas_dbus_priv *iface;
  736. char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  737. char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  738. iface = wpa_s->parent->global->dbus;
  739. /* Do nothing if the control interface is not turned on */
  740. if (iface == NULL)
  741. return;
  742. if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
  743. return;
  744. /* New interface has been created for this group */
  745. msg = dbus_message_new_signal(wpa_s->parent->dbus_new_path,
  746. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  747. "GroupStarted");
  748. if (msg == NULL)
  749. return;
  750. dbus_message_iter_init_append(msg, &iter);
  751. if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
  752. goto nomem;
  753. /*
  754. * In case the device supports creating a separate interface the
  755. * DBus client will need to know the object path for the interface
  756. * object this group was created on, so include it here.
  757. */
  758. if (!wpa_dbus_dict_append_object_path(&dict_iter,
  759. "interface_object",
  760. wpa_s->dbus_new_path))
  761. goto nomem;
  762. if (!wpa_dbus_dict_append_string(&dict_iter, "role",
  763. client ? "client" : "GO"))
  764. goto nomem;
  765. os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  766. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
  767. wpa_s->parent->dbus_new_path, network_id);
  768. if (!wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
  769. group_obj_path) ||
  770. !wpa_dbus_dict_append_object_path(&dict_iter, "network_object",
  771. net_obj_path) ||
  772. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  773. goto nomem;
  774. dbus_connection_send(iface->con, msg, NULL);
  775. nomem:
  776. dbus_message_unref(msg);
  777. }
  778. /**
  779. *
  780. * Method to emit GONeogtiation Success or Failure signals based
  781. * on status.
  782. * @status: Status of the GO neg request. 0 for success, other for errors.
  783. */
  784. void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s, int status)
  785. {
  786. DBusMessage *msg;
  787. DBusMessageIter iter;
  788. struct wpas_dbus_priv *iface;
  789. iface = wpa_s->global->dbus;
  790. /* Do nothing if the control interface is not turned on */
  791. if (iface == NULL)
  792. return;
  793. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  794. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  795. status ? "GONegotiationFailure" :
  796. "GONegotiationSuccess");
  797. if (msg == NULL)
  798. return;
  799. if (status) {
  800. dbus_message_iter_init_append(msg, &iter);
  801. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32,
  802. &status)) {
  803. wpa_printf(MSG_ERROR,
  804. "dbus: Failed to construct signal");
  805. goto err;
  806. }
  807. }
  808. dbus_connection_send(iface->con, msg, NULL);
  809. err:
  810. dbus_message_unref(msg);
  811. }
  812. /**
  813. *
  814. * Method to emit Invitation Result signal based on status and
  815. * bssid
  816. * @status: Status of the Invite request. 0 for success, other
  817. * for errors
  818. * @bssid : Basic Service Set Identifier
  819. */
  820. void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
  821. int status, const u8 *bssid)
  822. {
  823. DBusMessage *msg;
  824. DBusMessageIter iter, dict_iter;
  825. struct wpas_dbus_priv *iface;
  826. wpa_printf(MSG_INFO, "%s\n", __func__);
  827. iface = wpa_s->global->dbus;
  828. /* Do nothing if the control interface is not turned on */
  829. if (iface == NULL)
  830. return;
  831. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  832. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  833. "InvitationResult");
  834. if (msg == NULL)
  835. return;
  836. dbus_message_iter_init_append(msg, &iter);
  837. if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
  838. goto nomem;
  839. if (!wpa_dbus_dict_append_int32(&dict_iter, "status", status))
  840. goto nomem;
  841. if (bssid) {
  842. if (!wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
  843. (const char *) bssid,
  844. ETH_ALEN))
  845. goto nomem;
  846. }
  847. if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
  848. goto nomem;
  849. dbus_connection_send(iface->con, msg, NULL);
  850. nomem:
  851. dbus_message_unref(msg);
  852. }
  853. /**
  854. *
  855. * Method to emit a signal for a peer joining the group.
  856. * The signal will carry path to the group member object
  857. * constructed using p2p i/f addr used for connecting.
  858. *
  859. * @wpa_s: %wpa_supplicant network interface data
  860. * @member_addr: addr (p2p i/f) of the peer joining the group
  861. */
  862. void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
  863. const u8 *member)
  864. {
  865. struct wpas_dbus_priv *iface;
  866. DBusMessage *msg;
  867. DBusMessageIter iter;
  868. char groupmember_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  869. iface = wpa_s->global->dbus;
  870. /* Do nothing if the control interface is not turned on */
  871. if (iface == NULL)
  872. return;
  873. if (!wpa_s->dbus_groupobj_path)
  874. return;
  875. os_snprintf(groupmember_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  876. "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART "/"
  877. COMPACT_MACSTR,
  878. wpa_s->dbus_groupobj_path, MAC2STR(member));
  879. msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
  880. WPAS_DBUS_NEW_IFACE_P2P_GROUP,
  881. "PeerJoined");
  882. if (msg == NULL)
  883. return;
  884. dbus_message_iter_init_append(msg, &iter);
  885. path = groupmember_obj_path;
  886. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  887. &path))
  888. goto err;
  889. dbus_connection_send(iface->con, msg, NULL);
  890. dbus_message_unref(msg);
  891. return;
  892. err:
  893. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  894. dbus_message_unref(msg);
  895. }
  896. /**
  897. *
  898. * Method to emit a signal for a peer disconnecting the group.
  899. * The signal will carry path to the group member object
  900. * constructed using p2p i/f addr used for connecting.
  901. *
  902. * @wpa_s: %wpa_supplicant network interface data
  903. * @member_addr: addr (p2p i/f) of the peer joining the group
  904. */
  905. void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
  906. const u8 *member)
  907. {
  908. struct wpas_dbus_priv *iface;
  909. DBusMessage *msg;
  910. DBusMessageIter iter;
  911. char groupmember_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  912. iface = wpa_s->global->dbus;
  913. /* Do nothing if the control interface is not turned on */
  914. if (iface == NULL)
  915. return;
  916. if (!wpa_s->dbus_groupobj_path)
  917. return;
  918. os_snprintf(groupmember_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  919. "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART "/"
  920. COMPACT_MACSTR,
  921. wpa_s->dbus_groupobj_path, MAC2STR(member));
  922. msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
  923. WPAS_DBUS_NEW_IFACE_P2P_GROUP,
  924. "PeerDisconnected");
  925. if (msg == NULL)
  926. return;
  927. dbus_message_iter_init_append(msg, &iter);
  928. path = groupmember_obj_path;
  929. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  930. &path))
  931. goto err;
  932. dbus_connection_send(iface->con, msg, NULL);
  933. dbus_message_unref(msg);
  934. return;
  935. err:
  936. wpa_printf(MSG_ERROR, "dbus: Failed to construct PeerDisconnected "
  937. "signal");
  938. dbus_message_unref(msg);
  939. }
  940. /**
  941. *
  942. * Method to emit a signal for a service discovery request.
  943. * The signal will carry station address, frequency, dialog token,
  944. * update indicator and it tlvs
  945. *
  946. * @wpa_s: %wpa_supplicant network interface data
  947. * @sa: station addr (p2p i/f) of the peer
  948. * @dialog_token: service discovery request dialog token
  949. * @update_indic: service discovery request update indicator
  950. * @tlvs: service discovery request genrated byte array of tlvs
  951. * @tlvs_len: service discovery request tlvs length
  952. */
  953. void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
  954. int freq, const u8 *sa, u8 dialog_token,
  955. u16 update_indic, const u8 *tlvs,
  956. size_t tlvs_len)
  957. {
  958. DBusMessage *msg;
  959. DBusMessageIter iter, dict_iter;
  960. struct wpas_dbus_priv *iface;
  961. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  962. iface = wpa_s->global->dbus;
  963. /* Do nothing if the control interface is not turned on */
  964. if (iface == NULL)
  965. return;
  966. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  967. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  968. "ServiceDiscoveryRequest");
  969. if (msg == NULL)
  970. return;
  971. /* Check if this is a known peer */
  972. if (p2p_get_peer_info(wpa_s->global->p2p, sa, 0, NULL, 0) < 0)
  973. goto error;
  974. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  975. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
  976. COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
  977. path = peer_obj_path;
  978. dbus_message_iter_init_append(msg, &iter);
  979. if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
  980. goto error;
  981. if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
  982. path) ||
  983. !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
  984. !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
  985. dialog_token) ||
  986. !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
  987. update_indic) ||
  988. !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
  989. (const char *) tlvs,
  990. tlvs_len) ||
  991. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  992. goto error;
  993. dbus_connection_send(iface->con, msg, NULL);
  994. dbus_message_unref(msg);
  995. return;
  996. error:
  997. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  998. dbus_message_unref(msg);
  999. }
  1000. /**
  1001. *
  1002. * Method to emit a signal for a service discovery response.
  1003. * The signal will carry station address, update indicator and it
  1004. * tlvs
  1005. *
  1006. * @wpa_s: %wpa_supplicant network interface data
  1007. * @sa: station addr (p2p i/f) of the peer
  1008. * @update_indic: service discovery request update indicator
  1009. * @tlvs: service discovery request genrated byte array of tlvs
  1010. * @tlvs_len: service discovery request tlvs length
  1011. */
  1012. void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
  1013. const u8 *sa, u16 update_indic,
  1014. const u8 *tlvs, size_t tlvs_len)
  1015. {
  1016. DBusMessage *msg;
  1017. DBusMessageIter iter, dict_iter;
  1018. struct wpas_dbus_priv *iface;
  1019. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  1020. iface = wpa_s->global->dbus;
  1021. /* Do nothing if the control interface is not turned on */
  1022. if (iface == NULL)
  1023. return;
  1024. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  1025. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1026. "ServiceDiscoveryResponse");
  1027. if (msg == NULL)
  1028. return;
  1029. /* Check if this is a known peer */
  1030. if (p2p_get_peer_info(wpa_s->global->p2p, sa, 0, NULL, 0) < 0)
  1031. goto error;
  1032. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1033. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
  1034. COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
  1035. path = peer_obj_path;
  1036. dbus_message_iter_init_append(msg, &iter);
  1037. if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
  1038. goto error;
  1039. if (!wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
  1040. path) ||
  1041. !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
  1042. update_indic) ||
  1043. !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
  1044. (const char *) tlvs,
  1045. tlvs_len) ||
  1046. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  1047. goto error;
  1048. dbus_connection_send(iface->con, msg, NULL);
  1049. dbus_message_unref(msg);
  1050. return;
  1051. error:
  1052. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  1053. dbus_message_unref(msg);
  1054. }
  1055. #endif /*CONFIG_P2P*/
  1056. /**
  1057. * wpas_dbus_signal_prop_changed - Signals change of property
  1058. * @wpa_s: %wpa_supplicant network interface data
  1059. * @property: indicates which property has changed
  1060. *
  1061. * Sends PropertyChanged signals with path, interface and arguments
  1062. * depending on which property has changed.
  1063. */
  1064. void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
  1065. enum wpas_dbus_prop property)
  1066. {
  1067. WPADBusPropertyAccessor getter;
  1068. char *prop;
  1069. if (wpa_s->dbus_new_path == NULL)
  1070. return; /* Skip signal since D-Bus setup is not yet ready */
  1071. switch (property) {
  1072. case WPAS_DBUS_PROP_AP_SCAN:
  1073. getter = (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan;
  1074. prop = "ApScan";
  1075. break;
  1076. case WPAS_DBUS_PROP_SCANNING:
  1077. getter = (WPADBusPropertyAccessor) wpas_dbus_getter_scanning;
  1078. prop = "Scanning";
  1079. break;
  1080. case WPAS_DBUS_PROP_STATE:
  1081. getter = (WPADBusPropertyAccessor) wpas_dbus_getter_state;
  1082. prop = "State";
  1083. break;
  1084. case WPAS_DBUS_PROP_CURRENT_BSS:
  1085. getter = (WPADBusPropertyAccessor)
  1086. wpas_dbus_getter_current_bss;
  1087. prop = "CurrentBSS";
  1088. break;
  1089. case WPAS_DBUS_PROP_CURRENT_NETWORK:
  1090. getter = (WPADBusPropertyAccessor)
  1091. wpas_dbus_getter_current_network;
  1092. prop = "CurrentNetwork";
  1093. break;
  1094. case WPAS_DBUS_PROP_BSSS:
  1095. getter = (WPADBusPropertyAccessor) wpas_dbus_getter_bsss;
  1096. prop = "BSSs";
  1097. break;
  1098. case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
  1099. getter = (WPADBusPropertyAccessor)
  1100. wpas_dbus_getter_current_auth_mode;
  1101. prop = "CurrentAuthMode";
  1102. break;
  1103. default:
  1104. wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
  1105. __func__, property);
  1106. return;
  1107. }
  1108. wpa_dbus_mark_property_changed(wpa_s->global->dbus,
  1109. wpa_s->dbus_new_path,
  1110. WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
  1111. }
  1112. /**
  1113. * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
  1114. * @wpa_s: %wpa_supplicant network interface data
  1115. * @property: indicates which property has changed
  1116. * @id: unique BSS identifier
  1117. *
  1118. * Sends PropertyChanged signals with path, interface, and arguments depending
  1119. * on which property has changed.
  1120. */
  1121. void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
  1122. enum wpas_dbus_bss_prop property,
  1123. unsigned int id)
  1124. {
  1125. char path[WPAS_DBUS_OBJECT_PATH_MAX];
  1126. char *prop;
  1127. switch (property) {
  1128. case WPAS_DBUS_BSS_PROP_SIGNAL:
  1129. prop = "Signal";
  1130. break;
  1131. case WPAS_DBUS_BSS_PROP_FREQ:
  1132. prop = "Frequency";
  1133. break;
  1134. case WPAS_DBUS_BSS_PROP_MODE:
  1135. prop = "Mode";
  1136. break;
  1137. case WPAS_DBUS_BSS_PROP_PRIVACY:
  1138. prop = "Privacy";
  1139. break;
  1140. case WPAS_DBUS_BSS_PROP_RATES:
  1141. prop = "Rates";
  1142. break;
  1143. case WPAS_DBUS_BSS_PROP_WPA:
  1144. prop = "WPA";
  1145. break;
  1146. case WPAS_DBUS_BSS_PROP_RSN:
  1147. prop = "RSN";
  1148. break;
  1149. case WPAS_DBUS_BSS_PROP_IES:
  1150. prop = "IEs";
  1151. break;
  1152. default:
  1153. wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
  1154. __func__, property);
  1155. return;
  1156. }
  1157. os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
  1158. "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
  1159. wpa_s->dbus_new_path, id);
  1160. wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
  1161. WPAS_DBUS_NEW_IFACE_BSS, prop);
  1162. }
  1163. /**
  1164. * wpas_dbus_signal_debug_level_changed - Signals change of debug param
  1165. * @global: wpa_global structure
  1166. *
  1167. * Sends PropertyChanged signals informing that debug level has changed.
  1168. */
  1169. void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
  1170. {
  1171. wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
  1172. WPAS_DBUS_NEW_INTERFACE,
  1173. "DebugLevel");
  1174. }
  1175. /**
  1176. * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
  1177. * @global: wpa_global structure
  1178. *
  1179. * Sends PropertyChanged signals informing that debug timestamp has changed.
  1180. */
  1181. void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
  1182. {
  1183. wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
  1184. WPAS_DBUS_NEW_INTERFACE,
  1185. "DebugTimestamp");
  1186. }
  1187. /**
  1188. * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
  1189. * @global: wpa_global structure
  1190. *
  1191. * Sends PropertyChanged signals informing that debug show_keys has changed.
  1192. */
  1193. void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
  1194. {
  1195. wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
  1196. WPAS_DBUS_NEW_INTERFACE,
  1197. "DebugShowKeys");
  1198. }
  1199. static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
  1200. void *priv,
  1201. WPADBusArgumentFreeFunction priv_free,
  1202. const struct wpa_dbus_method_desc *methods,
  1203. const struct wpa_dbus_property_desc *properties,
  1204. const struct wpa_dbus_signal_desc *signals)
  1205. {
  1206. int n;
  1207. obj_desc->user_data = priv;
  1208. obj_desc->user_data_free_func = priv_free;
  1209. obj_desc->methods = methods;
  1210. obj_desc->properties = properties;
  1211. obj_desc->signals = signals;
  1212. for (n = 0; properties && properties->dbus_property; properties++)
  1213. n++;
  1214. obj_desc->prop_changed_flags = os_zalloc(n);
  1215. if (!obj_desc->prop_changed_flags)
  1216. wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
  1217. __func__);
  1218. }
  1219. static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
  1220. { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
  1221. (WPADBusMethodHandler) &wpas_dbus_handler_create_interface,
  1222. {
  1223. { "args", "a{sv}", ARG_IN },
  1224. { "path", "o", ARG_OUT },
  1225. END_ARGS
  1226. }
  1227. },
  1228. { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
  1229. (WPADBusMethodHandler) &wpas_dbus_handler_remove_interface,
  1230. {
  1231. { "path", "o", ARG_IN },
  1232. END_ARGS
  1233. }
  1234. },
  1235. { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
  1236. (WPADBusMethodHandler) &wpas_dbus_handler_get_interface,
  1237. {
  1238. { "ifname", "s", ARG_IN },
  1239. { "path", "o", ARG_OUT },
  1240. END_ARGS
  1241. }
  1242. },
  1243. { NULL, NULL, NULL, { END_ARGS } }
  1244. };
  1245. static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
  1246. { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
  1247. (WPADBusPropertyAccessor) wpas_dbus_getter_debug_level,
  1248. (WPADBusPropertyAccessor) wpas_dbus_setter_debug_level,
  1249. RW
  1250. },
  1251. { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
  1252. (WPADBusPropertyAccessor) wpas_dbus_getter_debug_timestamp,
  1253. (WPADBusPropertyAccessor) wpas_dbus_setter_debug_timestamp,
  1254. RW
  1255. },
  1256. { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
  1257. (WPADBusPropertyAccessor) wpas_dbus_getter_debug_show_keys,
  1258. (WPADBusPropertyAccessor) wpas_dbus_setter_debug_show_keys,
  1259. RW
  1260. },
  1261. { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
  1262. (WPADBusPropertyAccessor) &wpas_dbus_getter_interfaces,
  1263. NULL,
  1264. R
  1265. },
  1266. { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
  1267. (WPADBusPropertyAccessor) wpas_dbus_getter_eap_methods,
  1268. NULL,
  1269. R
  1270. },
  1271. { NULL, NULL, NULL, NULL, NULL, 0 }
  1272. };
  1273. static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
  1274. { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
  1275. {
  1276. { "path", "o", ARG_OUT },
  1277. { "properties", "a{sv}", ARG_OUT },
  1278. END_ARGS
  1279. }
  1280. },
  1281. { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
  1282. {
  1283. { "path", "o", ARG_OUT },
  1284. END_ARGS
  1285. }
  1286. },
  1287. { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
  1288. {
  1289. { "properties", "a{sv}", ARG_OUT },
  1290. END_ARGS
  1291. }
  1292. },
  1293. { NULL, NULL, { END_ARGS } }
  1294. };
  1295. /**
  1296. * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
  1297. * @global: Pointer to global data from wpa_supplicant_init()
  1298. * Returns: 0 on success or -1 on failure
  1299. *
  1300. * Initialize the dbus control interface for wpa_supplicantand and start
  1301. * receiving commands from external programs over the bus.
  1302. */
  1303. int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
  1304. {
  1305. struct wpa_dbus_object_desc *obj_desc;
  1306. int ret;
  1307. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  1308. if (!obj_desc) {
  1309. wpa_printf(MSG_ERROR, "Not enough memory "
  1310. "to create object description");
  1311. return -1;
  1312. }
  1313. wpas_dbus_register(obj_desc, priv->global, NULL,
  1314. wpas_dbus_global_methods,
  1315. wpas_dbus_global_properties,
  1316. wpas_dbus_global_signals);
  1317. wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
  1318. WPAS_DBUS_NEW_PATH);
  1319. ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
  1320. WPAS_DBUS_NEW_SERVICE,
  1321. obj_desc);
  1322. if (ret < 0)
  1323. free_dbus_object_desc(obj_desc);
  1324. else
  1325. priv->dbus_new_initialized = 1;
  1326. return ret;
  1327. }
  1328. /**
  1329. * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
  1330. * wpa_supplicant
  1331. * @iface: Pointer to dbus private data from wpas_dbus_init()
  1332. *
  1333. * Deinitialize the dbus control interface that was initialized with
  1334. * wpas_dbus_ctrl_iface_init().
  1335. */
  1336. void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
  1337. {
  1338. if (!iface->dbus_new_initialized)
  1339. return;
  1340. wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
  1341. WPAS_DBUS_NEW_PATH);
  1342. dbus_connection_unregister_object_path(iface->con,
  1343. WPAS_DBUS_NEW_PATH);
  1344. }
  1345. static void wpa_dbus_free(void *ptr)
  1346. {
  1347. os_free(ptr);
  1348. }
  1349. static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
  1350. { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
  1351. (WPADBusPropertyAccessor) wpas_dbus_getter_network_properties,
  1352. (WPADBusPropertyAccessor) wpas_dbus_setter_network_properties,
  1353. RW
  1354. },
  1355. { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
  1356. (WPADBusPropertyAccessor) wpas_dbus_getter_enabled,
  1357. (WPADBusPropertyAccessor) wpas_dbus_setter_enabled,
  1358. RW
  1359. },
  1360. { NULL, NULL, NULL, NULL, NULL, 0 }
  1361. };
  1362. static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
  1363. { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
  1364. {
  1365. { "properties", "a{sv}", ARG_OUT },
  1366. END_ARGS
  1367. }
  1368. },
  1369. { NULL, NULL, { END_ARGS } }
  1370. };
  1371. /**
  1372. * wpas_dbus_register_network - Register a configured network with dbus
  1373. * @wpa_s: wpa_supplicant interface structure
  1374. * @ssid: network configuration data
  1375. * Returns: 0 on success, -1 on failure
  1376. *
  1377. * Registers network representing object with dbus
  1378. */
  1379. int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
  1380. struct wpa_ssid *ssid)
  1381. {
  1382. struct wpas_dbus_priv *ctrl_iface;
  1383. struct wpa_dbus_object_desc *obj_desc;
  1384. struct network_handler_args *arg;
  1385. char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  1386. /* Do nothing if the control interface is not turned on */
  1387. if (wpa_s == NULL || wpa_s->global == NULL)
  1388. return 0;
  1389. ctrl_iface = wpa_s->global->dbus;
  1390. if (ctrl_iface == NULL)
  1391. return 0;
  1392. os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1393. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
  1394. wpa_s->dbus_new_path, ssid->id);
  1395. wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
  1396. net_obj_path);
  1397. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  1398. if (!obj_desc) {
  1399. wpa_printf(MSG_ERROR, "Not enough memory "
  1400. "to create object description");
  1401. goto err;
  1402. }
  1403. /* allocate memory for handlers arguments */
  1404. arg = os_zalloc(sizeof(struct network_handler_args));
  1405. if (!arg) {
  1406. wpa_printf(MSG_ERROR, "Not enough memory "
  1407. "to create arguments for method");
  1408. goto err;
  1409. }
  1410. arg->wpa_s = wpa_s;
  1411. arg->ssid = ssid;
  1412. wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
  1413. wpas_dbus_network_properties,
  1414. wpas_dbus_network_signals);
  1415. if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
  1416. wpa_s->ifname, obj_desc))
  1417. goto err;
  1418. wpas_dbus_signal_network_added(wpa_s, ssid->id);
  1419. return 0;
  1420. err:
  1421. free_dbus_object_desc(obj_desc);
  1422. return -1;
  1423. }
  1424. /**
  1425. * wpas_dbus_unregister_network - Unregister a configured network from dbus
  1426. * @wpa_s: wpa_supplicant interface structure
  1427. * @nid: network id
  1428. * Returns: 0 on success, -1 on failure
  1429. *
  1430. * Unregisters network representing object from dbus
  1431. */
  1432. int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
  1433. {
  1434. struct wpas_dbus_priv *ctrl_iface;
  1435. char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  1436. int ret;
  1437. /* Do nothing if the control interface is not turned on */
  1438. if (wpa_s == NULL || wpa_s->global == NULL ||
  1439. wpa_s->dbus_new_path == NULL)
  1440. return 0;
  1441. ctrl_iface = wpa_s->global->dbus;
  1442. if (ctrl_iface == NULL)
  1443. return 0;
  1444. os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1445. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
  1446. wpa_s->dbus_new_path, nid);
  1447. wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
  1448. net_obj_path);
  1449. ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
  1450. if (!ret)
  1451. wpas_dbus_signal_network_removed(wpa_s, nid);
  1452. return ret;
  1453. }
  1454. static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
  1455. { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
  1456. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ssid,
  1457. NULL,
  1458. R
  1459. },
  1460. { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
  1461. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_bssid,
  1462. NULL,
  1463. R
  1464. },
  1465. { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
  1466. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_privacy,
  1467. NULL,
  1468. R
  1469. },
  1470. { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
  1471. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_mode,
  1472. NULL,
  1473. R
  1474. },
  1475. { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
  1476. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_signal,
  1477. NULL,
  1478. R
  1479. },
  1480. { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
  1481. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_frequency,
  1482. NULL,
  1483. R
  1484. },
  1485. { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
  1486. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rates,
  1487. NULL,
  1488. R
  1489. },
  1490. { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
  1491. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_wpa,
  1492. NULL,
  1493. R
  1494. },
  1495. { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
  1496. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_rsn,
  1497. NULL,
  1498. R
  1499. },
  1500. { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
  1501. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_ies,
  1502. NULL,
  1503. R
  1504. },
  1505. { NULL, NULL, NULL, NULL, NULL, 0 }
  1506. };
  1507. static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
  1508. { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
  1509. {
  1510. { "properties", "a{sv}", ARG_OUT },
  1511. END_ARGS
  1512. }
  1513. },
  1514. { NULL, NULL, { END_ARGS } }
  1515. };
  1516. /**
  1517. * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
  1518. * @wpa_s: wpa_supplicant interface structure
  1519. * @bssid: scanned network bssid
  1520. * @id: unique BSS identifier
  1521. * Returns: 0 on success, -1 on failure
  1522. *
  1523. * Unregisters BSS representing object from dbus
  1524. */
  1525. int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
  1526. u8 bssid[ETH_ALEN], unsigned int id)
  1527. {
  1528. struct wpas_dbus_priv *ctrl_iface;
  1529. char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  1530. /* Do nothing if the control interface is not turned on */
  1531. if (wpa_s == NULL || wpa_s->global == NULL)
  1532. return 0;
  1533. ctrl_iface = wpa_s->global->dbus;
  1534. if (ctrl_iface == NULL)
  1535. return 0;
  1536. os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1537. "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
  1538. wpa_s->dbus_new_path, id);
  1539. wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
  1540. bss_obj_path);
  1541. if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
  1542. wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
  1543. bss_obj_path);
  1544. return -1;
  1545. }
  1546. wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
  1547. wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
  1548. return 0;
  1549. }
  1550. /**
  1551. * wpas_dbus_register_bss - Register a scanned BSS with dbus
  1552. * @wpa_s: wpa_supplicant interface structure
  1553. * @bssid: scanned network bssid
  1554. * @id: unique BSS identifier
  1555. * Returns: 0 on success, -1 on failure
  1556. *
  1557. * Registers BSS representing object with dbus
  1558. */
  1559. int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
  1560. u8 bssid[ETH_ALEN], unsigned int id)
  1561. {
  1562. struct wpas_dbus_priv *ctrl_iface;
  1563. struct wpa_dbus_object_desc *obj_desc;
  1564. char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  1565. struct bss_handler_args *arg;
  1566. /* Do nothing if the control interface is not turned on */
  1567. if (wpa_s == NULL || wpa_s->global == NULL)
  1568. return 0;
  1569. ctrl_iface = wpa_s->global->dbus;
  1570. if (ctrl_iface == NULL)
  1571. return 0;
  1572. os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1573. "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
  1574. wpa_s->dbus_new_path, id);
  1575. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  1576. if (!obj_desc) {
  1577. wpa_printf(MSG_ERROR, "Not enough memory "
  1578. "to create object description");
  1579. goto err;
  1580. }
  1581. arg = os_zalloc(sizeof(struct bss_handler_args));
  1582. if (!arg) {
  1583. wpa_printf(MSG_ERROR, "Not enough memory "
  1584. "to create arguments for handler");
  1585. goto err;
  1586. }
  1587. arg->wpa_s = wpa_s;
  1588. arg->id = id;
  1589. wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
  1590. wpas_dbus_bss_properties,
  1591. wpas_dbus_bss_signals);
  1592. wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
  1593. bss_obj_path);
  1594. if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
  1595. wpa_s->ifname, obj_desc)) {
  1596. wpa_printf(MSG_ERROR,
  1597. "Cannot register BSSID dbus object %s.",
  1598. bss_obj_path);
  1599. goto err;
  1600. }
  1601. wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
  1602. wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
  1603. return 0;
  1604. err:
  1605. free_dbus_object_desc(obj_desc);
  1606. return -1;
  1607. }
  1608. static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
  1609. { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1610. (WPADBusMethodHandler) &wpas_dbus_handler_scan,
  1611. {
  1612. { "args", "a{sv}", ARG_IN },
  1613. END_ARGS
  1614. }
  1615. },
  1616. { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1617. (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
  1618. {
  1619. END_ARGS
  1620. }
  1621. },
  1622. { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1623. (WPADBusMethodHandler) &wpas_dbus_handler_add_network,
  1624. {
  1625. { "args", "a{sv}", ARG_IN },
  1626. { "path", "o", ARG_OUT },
  1627. END_ARGS
  1628. }
  1629. },
  1630. { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1631. (WPADBusMethodHandler) &wpas_dbus_handler_remove_network,
  1632. {
  1633. { "path", "o", ARG_IN },
  1634. END_ARGS
  1635. }
  1636. },
  1637. { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1638. (WPADBusMethodHandler) &wpas_dbus_handler_remove_all_networks,
  1639. {
  1640. END_ARGS
  1641. }
  1642. },
  1643. { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1644. (WPADBusMethodHandler) &wpas_dbus_handler_select_network,
  1645. {
  1646. { "path", "o", ARG_IN },
  1647. END_ARGS
  1648. }
  1649. },
  1650. { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1651. (WPADBusMethodHandler) &wpas_dbus_handler_add_blob,
  1652. {
  1653. { "name", "s", ARG_IN },
  1654. { "data", "ay", ARG_IN },
  1655. END_ARGS
  1656. }
  1657. },
  1658. { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1659. (WPADBusMethodHandler) &wpas_dbus_handler_get_blob,
  1660. {
  1661. { "name", "s", ARG_IN },
  1662. { "data", "ay", ARG_OUT },
  1663. END_ARGS
  1664. }
  1665. },
  1666. { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1667. (WPADBusMethodHandler) &wpas_dbus_handler_remove_blob,
  1668. {
  1669. { "name", "s", ARG_IN },
  1670. END_ARGS
  1671. }
  1672. },
  1673. #ifdef CONFIG_WPS
  1674. { "Start", WPAS_DBUS_NEW_IFACE_WPS,
  1675. (WPADBusMethodHandler) &wpas_dbus_handler_wps_start,
  1676. {
  1677. { "args", "a{sv}", ARG_IN },
  1678. { "output", "a{sv}", ARG_OUT },
  1679. END_ARGS
  1680. }
  1681. },
  1682. #endif /* CONFIG_WPS */
  1683. #ifdef CONFIG_P2P
  1684. { "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1685. (WPADBusMethodHandler)wpas_dbus_handler_p2p_find,
  1686. {
  1687. { "args", "a{sv}", ARG_IN },
  1688. END_ARGS
  1689. }
  1690. },
  1691. { "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1692. (WPADBusMethodHandler)wpas_dbus_handler_p2p_stop_find,
  1693. {
  1694. END_ARGS
  1695. }
  1696. },
  1697. { "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1698. (WPADBusMethodHandler)wpas_dbus_handler_p2p_listen,
  1699. {
  1700. { "timeout", "i", ARG_IN },
  1701. END_ARGS
  1702. }
  1703. },
  1704. { "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1705. (WPADBusMethodHandler)wpas_dbus_handler_p2p_extendedlisten,
  1706. {
  1707. { "args", "a{sv}", ARG_IN },
  1708. END_ARGS
  1709. }
  1710. },
  1711. { "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1712. (WPADBusMethodHandler)wpas_dbus_handler_p2p_presence_request,
  1713. {
  1714. { "args", "a{sv}", ARG_IN },
  1715. END_ARGS
  1716. }
  1717. },
  1718. { "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1719. (WPADBusMethodHandler)wpas_dbus_handler_p2p_prov_disc_req,
  1720. {
  1721. { "peer", "o", ARG_IN },
  1722. { "config_method", "s", ARG_IN },
  1723. END_ARGS
  1724. }
  1725. },
  1726. { "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1727. (WPADBusMethodHandler)wpas_dbus_handler_p2p_connect,
  1728. {
  1729. { "args", "a{sv}", ARG_IN },
  1730. { "generated_pin", "i", ARG_OUT },
  1731. END_ARGS
  1732. }
  1733. },
  1734. { "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1735. (WPADBusMethodHandler)wpas_dbus_handler_p2p_group_add,
  1736. {
  1737. { "args", "a{sv}", ARG_IN },
  1738. END_ARGS
  1739. }
  1740. },
  1741. { "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1742. (WPADBusMethodHandler)wpas_dbus_handler_p2p_invite,
  1743. {
  1744. { "args", "a{sv}", ARG_IN },
  1745. END_ARGS
  1746. }
  1747. },
  1748. { "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1749. (WPADBusMethodHandler)wpas_dbus_handler_p2p_disconnect,
  1750. {
  1751. END_ARGS
  1752. }
  1753. },
  1754. { "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1755. (WPADBusMethodHandler)wpas_dbus_handler_p2p_rejectpeer,
  1756. {
  1757. { "peer", "o", ARG_IN },
  1758. END_ARGS
  1759. }
  1760. },
  1761. { "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1762. (WPADBusMethodHandler)wpas_dbus_handler_p2p_flush,
  1763. {
  1764. END_ARGS
  1765. }
  1766. },
  1767. { "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1768. (WPADBusMethodHandler)wpas_dbus_handler_p2p_add_service,
  1769. {
  1770. { "args", "a{sv}", ARG_IN },
  1771. END_ARGS
  1772. }
  1773. },
  1774. { "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1775. (WPADBusMethodHandler)wpas_dbus_handler_p2p_delete_service,
  1776. {
  1777. { "args", "a{sv}", ARG_IN },
  1778. END_ARGS
  1779. }
  1780. },
  1781. { "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1782. (WPADBusMethodHandler)wpas_dbus_handler_p2p_flush_service,
  1783. {
  1784. END_ARGS
  1785. }
  1786. },
  1787. { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1788. (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_req,
  1789. {
  1790. { "args", "a{sv}", ARG_IN },
  1791. END_ARGS
  1792. }
  1793. },
  1794. { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1795. (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_res,
  1796. {
  1797. { "args", "a{sv}", ARG_IN },
  1798. END_ARGS
  1799. }
  1800. },
  1801. { "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1802. (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_sd_cancel_req,
  1803. {
  1804. { "args", "t", ARG_IN },
  1805. END_ARGS
  1806. }
  1807. },
  1808. { "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1809. (WPADBusMethodHandler)wpas_dbus_handler_p2p_service_update,
  1810. {
  1811. END_ARGS
  1812. }
  1813. },
  1814. { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1815. (WPADBusMethodHandler)wpas_dbus_handler_p2p_serv_disc_external,
  1816. {
  1817. { "arg", "i", ARG_IN },
  1818. END_ARGS
  1819. }
  1820. },
  1821. { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1822. (WPADBusMethodHandler)wpas_dbus_handler_p2p_serv_disc_external,
  1823. {
  1824. { "arg", "i", ARG_IN },
  1825. END_ARGS
  1826. }
  1827. },
  1828. #endif /* CONFIG_P2P */
  1829. { "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1830. (WPADBusMethodHandler) &wpas_dbus_handler_flush_bss,
  1831. {
  1832. { "age", "u", ARG_IN },
  1833. END_ARGS
  1834. }
  1835. },
  1836. { NULL, NULL, NULL, { END_ARGS } }
  1837. };
  1838. static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
  1839. { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
  1840. (WPADBusPropertyAccessor) wpas_dbus_getter_capabilities,
  1841. NULL, R
  1842. },
  1843. { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  1844. (WPADBusPropertyAccessor) wpas_dbus_getter_state,
  1845. NULL, R
  1846. },
  1847. { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
  1848. (WPADBusPropertyAccessor) wpas_dbus_getter_scanning,
  1849. NULL, R
  1850. },
  1851. { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
  1852. (WPADBusPropertyAccessor) wpas_dbus_getter_ap_scan,
  1853. (WPADBusPropertyAccessor) wpas_dbus_setter_ap_scan,
  1854. RW
  1855. },
  1856. { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
  1857. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_expire_age,
  1858. (WPADBusPropertyAccessor) wpas_dbus_setter_bss_expire_age,
  1859. RW
  1860. },
  1861. { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
  1862. (WPADBusPropertyAccessor) wpas_dbus_getter_bss_expire_count,
  1863. (WPADBusPropertyAccessor) wpas_dbus_setter_bss_expire_count,
  1864. RW
  1865. },
  1866. { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  1867. (WPADBusPropertyAccessor) wpas_dbus_getter_country,
  1868. (WPADBusPropertyAccessor) wpas_dbus_setter_country,
  1869. RW
  1870. },
  1871. { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  1872. (WPADBusPropertyAccessor) wpas_dbus_getter_ifname,
  1873. NULL, R
  1874. },
  1875. { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  1876. (WPADBusPropertyAccessor) wpas_dbus_getter_driver,
  1877. NULL, R
  1878. },
  1879. { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  1880. (WPADBusPropertyAccessor) wpas_dbus_getter_bridge_ifname,
  1881. NULL, R
  1882. },
  1883. { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
  1884. (WPADBusPropertyAccessor) wpas_dbus_getter_current_bss,
  1885. NULL, R
  1886. },
  1887. { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
  1888. (WPADBusPropertyAccessor) wpas_dbus_getter_current_network,
  1889. NULL, R
  1890. },
  1891. { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  1892. (WPADBusPropertyAccessor) wpas_dbus_getter_current_auth_mode,
  1893. NULL, R
  1894. },
  1895. { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
  1896. (WPADBusPropertyAccessor) wpas_dbus_getter_blobs,
  1897. NULL, R
  1898. },
  1899. { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
  1900. (WPADBusPropertyAccessor) wpas_dbus_getter_bsss,
  1901. NULL, R
  1902. },
  1903. { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
  1904. (WPADBusPropertyAccessor) wpas_dbus_getter_networks,
  1905. NULL, R
  1906. },
  1907. #ifdef CONFIG_WPS
  1908. { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
  1909. (WPADBusPropertyAccessor) wpas_dbus_getter_process_credentials,
  1910. (WPADBusPropertyAccessor) wpas_dbus_setter_process_credentials,
  1911. RW
  1912. },
  1913. #endif /* CONFIG_WPS */
  1914. #ifdef CONFIG_P2P
  1915. { "P2PDeviceProperties", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
  1916. (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_device_properties,
  1917. (WPADBusPropertyAccessor) wpas_dbus_setter_p2p_device_properties,
  1918. RW
  1919. },
  1920. { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
  1921. (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peers,
  1922. NULL, R
  1923. },
  1924. { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
  1925. (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_role,
  1926. NULL, R
  1927. },
  1928. { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
  1929. (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group,
  1930. NULL, R
  1931. },
  1932. { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
  1933. (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peergo,
  1934. NULL, R
  1935. },
  1936. #endif /* CONFIG_P2P */
  1937. { NULL, NULL, NULL, NULL, NULL, 0 }
  1938. };
  1939. static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
  1940. { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1941. {
  1942. { "success", "b", ARG_OUT },
  1943. END_ARGS
  1944. }
  1945. },
  1946. { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1947. {
  1948. { "path", "o", ARG_OUT },
  1949. { "properties", "a{sv}", ARG_OUT },
  1950. END_ARGS
  1951. }
  1952. },
  1953. { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1954. {
  1955. { "path", "o", ARG_OUT },
  1956. END_ARGS
  1957. }
  1958. },
  1959. { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1960. {
  1961. { "name", "s", ARG_OUT },
  1962. END_ARGS
  1963. }
  1964. },
  1965. { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1966. {
  1967. { "name", "s", ARG_OUT },
  1968. END_ARGS
  1969. }
  1970. },
  1971. { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1972. {
  1973. { "path", "o", ARG_OUT },
  1974. { "properties", "a{sv}", ARG_OUT },
  1975. END_ARGS
  1976. }
  1977. },
  1978. { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1979. {
  1980. { "path", "o", ARG_OUT },
  1981. END_ARGS
  1982. }
  1983. },
  1984. { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1985. {
  1986. { "path", "o", ARG_OUT },
  1987. END_ARGS
  1988. }
  1989. },
  1990. { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
  1991. {
  1992. { "properties", "a{sv}", ARG_OUT },
  1993. END_ARGS
  1994. }
  1995. },
  1996. #ifdef CONFIG_WPS
  1997. { "Event", WPAS_DBUS_NEW_IFACE_WPS,
  1998. {
  1999. { "name", "s", ARG_OUT },
  2000. { "args", "a{sv}", ARG_OUT },
  2001. END_ARGS
  2002. }
  2003. },
  2004. { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
  2005. {
  2006. { "credentials", "a{sv}", ARG_OUT },
  2007. END_ARGS
  2008. }
  2009. },
  2010. { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
  2011. {
  2012. { "properties", "a{sv}", ARG_OUT },
  2013. END_ARGS
  2014. }
  2015. },
  2016. #endif /* CONFIG_WPS */
  2017. #ifdef CONFIG_P2P
  2018. { "P2PStateChanged", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2019. {
  2020. { "states", "a{ss}", ARG_OUT },
  2021. END_ARGS
  2022. }
  2023. },
  2024. { "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2025. {
  2026. { "path", "o", ARG_OUT },
  2027. { "properties", "a{sv}", ARG_OUT },
  2028. END_ARGS
  2029. }
  2030. },
  2031. { "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2032. {
  2033. { "path", "o", ARG_OUT },
  2034. END_ARGS
  2035. }
  2036. },
  2037. { "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2038. {
  2039. { "peer_object", "o", ARG_OUT },
  2040. { "pin", "s", ARG_OUT },
  2041. END_ARGS
  2042. }
  2043. },
  2044. { "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2045. {
  2046. { "peer_object", "o", ARG_OUT },
  2047. { "pin", "s", ARG_OUT },
  2048. END_ARGS
  2049. }
  2050. },
  2051. { "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2052. {
  2053. { "peer_object", "o", ARG_OUT },
  2054. END_ARGS
  2055. }
  2056. },
  2057. { "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2058. {
  2059. { "peer_object", "o", ARG_OUT },
  2060. END_ARGS
  2061. }
  2062. },
  2063. { "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2064. {
  2065. { "peer_object", "o", ARG_OUT },
  2066. END_ARGS
  2067. }
  2068. },
  2069. { "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2070. {
  2071. { "peer_object", "o", ARG_OUT },
  2072. END_ARGS
  2073. }
  2074. },
  2075. { "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2076. {
  2077. { "peer_object", "o", ARG_OUT },
  2078. { "status", "i", ARG_OUT },
  2079. END_ARGS
  2080. }
  2081. },
  2082. { "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2083. {
  2084. { "properties", "a{sv}", ARG_OUT },
  2085. END_ARGS
  2086. }
  2087. },
  2088. { "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2089. {
  2090. END_ARGS
  2091. }
  2092. },
  2093. { "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2094. {
  2095. { "status", "i", ARG_OUT },
  2096. END_ARGS
  2097. }
  2098. },
  2099. { "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2100. {
  2101. { "path", "o", ARG_OUT },
  2102. { "dev_passwd_id", "i", ARG_OUT },
  2103. END_ARGS
  2104. }
  2105. },
  2106. { "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2107. {
  2108. { "invite_result", "a{sv}", ARG_OUT },
  2109. END_ARGS
  2110. }
  2111. },
  2112. { "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2113. {
  2114. { "ifname", "s", ARG_OUT },
  2115. { "role", "s", ARG_OUT },
  2116. END_ARGS
  2117. }
  2118. },
  2119. { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2120. {
  2121. { "sd_request", "a{sv}", ARG_OUT },
  2122. END_ARGS
  2123. }
  2124. },
  2125. { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2126. {
  2127. { "sd_response", "a{sv}", ARG_OUT },
  2128. END_ARGS
  2129. }
  2130. },
  2131. #endif /* CONFIG_P2P */
  2132. { NULL, NULL, { END_ARGS } }
  2133. };
  2134. int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
  2135. {
  2136. struct wpa_dbus_object_desc *obj_desc = NULL;
  2137. struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
  2138. int next;
  2139. /* Do nothing if the control interface is not turned on */
  2140. if (ctrl_iface == NULL)
  2141. return 0;
  2142. /* Create and set the interface's object path */
  2143. wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
  2144. if (wpa_s->dbus_new_path == NULL)
  2145. return -1;
  2146. next = ctrl_iface->next_objid++;
  2147. os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
  2148. WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
  2149. next);
  2150. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  2151. if (!obj_desc) {
  2152. wpa_printf(MSG_ERROR, "Not enough memory "
  2153. "to create object description");
  2154. goto err;
  2155. }
  2156. wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
  2157. wpas_dbus_interface_properties,
  2158. wpas_dbus_interface_signals);
  2159. wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
  2160. wpa_s->dbus_new_path);
  2161. if (wpa_dbus_register_object_per_iface(ctrl_iface,
  2162. wpa_s->dbus_new_path,
  2163. wpa_s->ifname, obj_desc))
  2164. goto err;
  2165. wpas_dbus_signal_interface_added(wpa_s);
  2166. return 0;
  2167. err:
  2168. os_free(wpa_s->dbus_new_path);
  2169. wpa_s->dbus_new_path = NULL;
  2170. free_dbus_object_desc(obj_desc);
  2171. return -1;
  2172. }
  2173. int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
  2174. {
  2175. struct wpas_dbus_priv *ctrl_iface;
  2176. /* Do nothing if the control interface is not turned on */
  2177. if (wpa_s == NULL || wpa_s->global == NULL)
  2178. return 0;
  2179. ctrl_iface = wpa_s->global->dbus;
  2180. if (ctrl_iface == NULL)
  2181. return 0;
  2182. wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
  2183. wpa_s->dbus_new_path);
  2184. if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
  2185. wpa_s->dbus_new_path))
  2186. return -1;
  2187. wpas_dbus_signal_interface_removed(wpa_s);
  2188. os_free(wpa_s->dbus_new_path);
  2189. wpa_s->dbus_new_path = NULL;
  2190. return 0;
  2191. }
  2192. #ifdef CONFIG_P2P
  2193. static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
  2194. { "Properties", WPAS_DBUS_NEW_IFACE_P2P_PEER, "a{sv}",
  2195. (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peer_properties,
  2196. NULL, R
  2197. },
  2198. { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
  2199. (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_peer_ies,
  2200. NULL, R
  2201. },
  2202. { NULL, NULL, NULL, NULL, NULL, 0 }
  2203. };
  2204. static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
  2205. { NULL, NULL, { END_ARGS } }
  2206. };
  2207. /**
  2208. * wpas_dbus_signal_peer - Send a peer related event signal
  2209. * @wpa_s: %wpa_supplicant network interface data
  2210. * @dev: peer device object
  2211. * @interface: name of the interface emitting this signal.
  2212. * In case of peer objects, it would be emitted by either
  2213. * the "interface object" or by "peer objects"
  2214. * @sig_name: signal name - DeviceFound
  2215. *
  2216. * Notify listeners about event related with newly found p2p peer device
  2217. */
  2218. static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
  2219. const u8 *dev_addr, const char *interface,
  2220. const char *sig_name)
  2221. {
  2222. struct wpas_dbus_priv *iface;
  2223. DBusMessage *msg;
  2224. DBusMessageIter iter;
  2225. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  2226. iface = wpa_s->global->dbus;
  2227. /* Do nothing if the control interface is not turned on */
  2228. if (iface == NULL)
  2229. return;
  2230. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  2231. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
  2232. wpa_s->dbus_new_path, MAC2STR(dev_addr));
  2233. msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
  2234. sig_name);
  2235. if (msg == NULL)
  2236. return;
  2237. dbus_message_iter_init_append(msg, &iter);
  2238. path = peer_obj_path;
  2239. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  2240. &path))
  2241. goto err;
  2242. dbus_connection_send(iface->con, msg, NULL);
  2243. dbus_message_unref(msg);
  2244. return;
  2245. err:
  2246. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  2247. dbus_message_unref(msg);
  2248. }
  2249. /**
  2250. * wpas_dbus_signal_peer_found - Send a peer found signal
  2251. * @wpa_s: %wpa_supplicant network interface data
  2252. * @dev: peer device object
  2253. *
  2254. * Notify listeners about find a p2p peer device found
  2255. */
  2256. void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
  2257. const u8 *dev_addr)
  2258. {
  2259. wpas_dbus_signal_peer(wpa_s, dev_addr,
  2260. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2261. "DeviceFound");
  2262. }
  2263. /**
  2264. * wpas_dbus_signal_peer_lost - Send a peer lost signal
  2265. * @wpa_s: %wpa_supplicant network interface data
  2266. * @dev: peer device object
  2267. *
  2268. * Notify listeners about lost a p2p peer device
  2269. */
  2270. void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
  2271. const u8 *dev_addr)
  2272. {
  2273. wpas_dbus_signal_peer(wpa_s, dev_addr,
  2274. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2275. "DeviceLost");
  2276. }
  2277. /**
  2278. * wpas_dbus_register_peer - Register a discovered peer object with dbus
  2279. * @wpa_s: wpa_supplicant interface structure
  2280. * @ssid: network configuration data
  2281. * Returns: 0 on success, -1 on failure
  2282. *
  2283. * Registers network representing object with dbus
  2284. */
  2285. int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
  2286. {
  2287. struct wpas_dbus_priv *ctrl_iface;
  2288. struct wpa_dbus_object_desc *obj_desc;
  2289. struct peer_handler_args *arg;
  2290. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  2291. /* Do nothing if the control interface is not turned on */
  2292. if (wpa_s == NULL || wpa_s->global == NULL)
  2293. return 0;
  2294. ctrl_iface = wpa_s->global->dbus;
  2295. if (ctrl_iface == NULL)
  2296. return 0;
  2297. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  2298. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
  2299. wpa_s->dbus_new_path, MAC2STR(dev_addr));
  2300. wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
  2301. peer_obj_path);
  2302. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  2303. if (!obj_desc) {
  2304. wpa_printf(MSG_ERROR, "Not enough memory "
  2305. "to create object description");
  2306. goto err;
  2307. }
  2308. /* allocate memory for handlers arguments */
  2309. arg = os_zalloc(sizeof(struct peer_handler_args));
  2310. if (!arg) {
  2311. wpa_printf(MSG_ERROR, "Not enough memory "
  2312. "to create arguments for method");
  2313. goto err;
  2314. }
  2315. arg->wpa_s = wpa_s;
  2316. os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
  2317. wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
  2318. NULL,
  2319. wpas_dbus_p2p_peer_properties,
  2320. wpas_dbus_p2p_peer_signals);
  2321. if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
  2322. wpa_s->ifname, obj_desc))
  2323. goto err;
  2324. return 0;
  2325. err:
  2326. free_dbus_object_desc(obj_desc);
  2327. return -1;
  2328. }
  2329. /**
  2330. * wpas_dbus_unregister_peer - Unregister a peer object with dbus
  2331. * @wpa_s: wpa_supplicant interface structure
  2332. * @dev_addr: p2p device addr
  2333. * Returns: 0 on success, -1 on failure
  2334. *
  2335. * Registers network representing object with dbus
  2336. */
  2337. int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
  2338. const u8 *dev_addr)
  2339. {
  2340. struct wpas_dbus_priv *ctrl_iface;
  2341. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  2342. int ret;
  2343. /* Do nothing if the control interface is not turned on */
  2344. if (wpa_s == NULL || wpa_s->global == NULL ||
  2345. wpa_s->dbus_new_path == NULL)
  2346. return 0;
  2347. ctrl_iface = wpa_s->global->dbus;
  2348. if (ctrl_iface == NULL)
  2349. return 0;
  2350. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  2351. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
  2352. wpa_s->dbus_new_path, MAC2STR(dev_addr));
  2353. wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
  2354. peer_obj_path);
  2355. ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
  2356. return ret;
  2357. }
  2358. static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
  2359. { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
  2360. (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group_members,
  2361. NULL, R
  2362. },
  2363. { "Properties",
  2364. WPAS_DBUS_NEW_IFACE_P2P_GROUP, "a{sv}",
  2365. (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group_properties,
  2366. (WPADBusPropertyAccessor) wpas_dbus_setter_p2p_group_properties,
  2367. RW
  2368. },
  2369. { NULL, NULL, NULL, NULL, NULL, 0 }
  2370. };
  2371. static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
  2372. { "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
  2373. {
  2374. { "peer", "o", ARG_OUT },
  2375. END_ARGS
  2376. }
  2377. },
  2378. { "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
  2379. {
  2380. { "peer", "o", ARG_OUT },
  2381. END_ARGS
  2382. }
  2383. },
  2384. { NULL, NULL, { END_ARGS } }
  2385. };
  2386. /**
  2387. * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
  2388. * @wpa_s: wpa_supplicant interface structure
  2389. * @ssid: SSID struct
  2390. * Returns: 0 on success, -1 on failure
  2391. *
  2392. * Registers p2p group representing object with dbus
  2393. */
  2394. void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
  2395. struct wpa_ssid *ssid)
  2396. {
  2397. struct wpas_dbus_priv *ctrl_iface;
  2398. struct wpa_dbus_object_desc *obj_desc;
  2399. char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  2400. /* Do nothing if the control interface is not turned on */
  2401. if (wpa_s == NULL || wpa_s->global == NULL)
  2402. return;
  2403. ctrl_iface = wpa_s->global->dbus;
  2404. if (ctrl_iface == NULL)
  2405. return;
  2406. if (wpa_s->dbus_groupobj_path) {
  2407. wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
  2408. __func__, wpa_s->dbus_groupobj_path);
  2409. return;
  2410. }
  2411. if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
  2412. return;
  2413. wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
  2414. if (wpa_s->dbus_groupobj_path == NULL)
  2415. return;
  2416. wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
  2417. group_obj_path);
  2418. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  2419. if (!obj_desc) {
  2420. wpa_printf(MSG_ERROR, "Not enough memory "
  2421. "to create object description");
  2422. goto err;
  2423. }
  2424. wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
  2425. wpas_dbus_p2p_group_properties,
  2426. wpas_dbus_p2p_group_signals);
  2427. if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
  2428. wpa_s->ifname, obj_desc))
  2429. goto err;
  2430. return;
  2431. err:
  2432. if (wpa_s->dbus_groupobj_path) {
  2433. os_free(wpa_s->dbus_groupobj_path);
  2434. wpa_s->dbus_groupobj_path = NULL;
  2435. }
  2436. free_dbus_object_desc(obj_desc);
  2437. }
  2438. /**
  2439. * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
  2440. * @wpa_s: wpa_supplicant interface structure
  2441. * @ssid: network name of the p2p group started
  2442. */
  2443. void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
  2444. const struct wpa_ssid *ssid)
  2445. {
  2446. struct wpas_dbus_priv *ctrl_iface;
  2447. /* Do nothing if the control interface is not turned on */
  2448. if (wpa_s == NULL || wpa_s->global == NULL)
  2449. return;
  2450. ctrl_iface = wpa_s->global->dbus;
  2451. if (ctrl_iface == NULL)
  2452. return;
  2453. if (!wpa_s->dbus_groupobj_path) {
  2454. wpa_printf(MSG_DEBUG,
  2455. "%s: Group object '%s' already unregistered",
  2456. __func__, wpa_s->dbus_groupobj_path);
  2457. return;
  2458. }
  2459. wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
  2460. wpa_s->dbus_groupobj_path);
  2461. wpa_dbus_unregister_object_per_iface(ctrl_iface,
  2462. wpa_s->dbus_groupobj_path);
  2463. os_free(wpa_s->dbus_groupobj_path);
  2464. wpa_s->dbus_groupobj_path = NULL;
  2465. }
  2466. static const struct wpa_dbus_property_desc
  2467. wpas_dbus_p2p_groupmember_properties[] = {
  2468. { "Properties", WPAS_DBUS_NEW_IFACE_P2P_GROUPMEMBER, "a{sv}",
  2469. (WPADBusPropertyAccessor) wpas_dbus_getter_p2p_group_properties,
  2470. NULL, R
  2471. },
  2472. { NULL, NULL, NULL, NULL, NULL, 0 }
  2473. };
  2474. /**
  2475. * wpas_dbus_register_p2p_groupmember - Register a p2p groupmember
  2476. * object with dbus
  2477. * @wpa_s: wpa_supplicant interface structure
  2478. * @p2p_if_addr: i/f addr of the device joining this group
  2479. *
  2480. * Registers p2p groupmember representing object with dbus
  2481. */
  2482. void wpas_dbus_register_p2p_groupmember(struct wpa_supplicant *wpa_s,
  2483. const u8 *p2p_if_addr)
  2484. {
  2485. struct wpas_dbus_priv *ctrl_iface;
  2486. struct wpa_dbus_object_desc *obj_desc = NULL;
  2487. struct groupmember_handler_args *arg;
  2488. char groupmember_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  2489. /* Do nothing if the control interface is not turned on */
  2490. if (wpa_s == NULL || wpa_s->global == NULL)
  2491. return;
  2492. ctrl_iface = wpa_s->global->dbus;
  2493. if (ctrl_iface == NULL)
  2494. return;
  2495. if (!wpa_s->dbus_groupobj_path)
  2496. return;
  2497. os_snprintf(groupmember_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  2498. "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART "/" COMPACT_MACSTR,
  2499. wpa_s->dbus_groupobj_path, MAC2STR(p2p_if_addr));
  2500. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  2501. if (!obj_desc) {
  2502. wpa_printf(MSG_ERROR, "Not enough memory "
  2503. "to create object description");
  2504. goto err;
  2505. }
  2506. /* allocate memory for handlers arguments */
  2507. arg = os_zalloc(sizeof(struct groupmember_handler_args));
  2508. if (!arg) {
  2509. wpa_printf(MSG_ERROR, "Not enough memory "
  2510. "to create arguments for method");
  2511. goto err;
  2512. }
  2513. arg->wpa_s = wpa_s;
  2514. os_memcpy(arg->member_addr, p2p_if_addr, ETH_ALEN);
  2515. wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
  2516. wpas_dbus_p2p_groupmember_properties, NULL);
  2517. if (wpa_dbus_register_object_per_iface(ctrl_iface, groupmember_obj_path,
  2518. wpa_s->ifname, obj_desc))
  2519. goto err;
  2520. wpa_printf(MSG_INFO,
  2521. "dbus: Registered group member object '%s' successfully",
  2522. groupmember_obj_path);
  2523. return;
  2524. err:
  2525. free_dbus_object_desc(obj_desc);
  2526. }
  2527. /**
  2528. * wpas_dbus_unregister_p2p_groupmember - Unregister a p2p groupmember
  2529. * object with dbus
  2530. * @wpa_s: wpa_supplicant interface structure
  2531. * @p2p_if_addr: i/f addr of the device joining this group
  2532. *
  2533. * Unregisters p2p groupmember representing object with dbus
  2534. */
  2535. void wpas_dbus_unregister_p2p_groupmember(struct wpa_supplicant *wpa_s,
  2536. const u8 *p2p_if_addr)
  2537. {
  2538. struct wpas_dbus_priv *ctrl_iface;
  2539. char groupmember_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  2540. /* Do nothing if the control interface is not turned on */
  2541. if (wpa_s == NULL || wpa_s->global == NULL)
  2542. return;
  2543. ctrl_iface = wpa_s->global->dbus;
  2544. if (ctrl_iface == NULL)
  2545. return;
  2546. if (!wpa_s->dbus_groupobj_path)
  2547. return;
  2548. os_snprintf(groupmember_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  2549. "%s/" WPAS_DBUS_NEW_P2P_GROUPMEMBERS_PART "/" COMPACT_MACSTR,
  2550. wpa_s->dbus_groupobj_path, MAC2STR(p2p_if_addr));
  2551. wpa_dbus_unregister_object_per_iface(ctrl_iface, groupmember_obj_path);
  2552. }
  2553. #endif /* CONFIG_P2P */