dbus_new.c 100 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825
  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 software may be distributed under the terms of the BSD license.
  8. * See README for more details.
  9. */
  10. #include "includes.h"
  11. #include "common.h"
  12. #include "common/ieee802_11_defs.h"
  13. #include "wps/wps.h"
  14. #include "../config.h"
  15. #include "../wpa_supplicant_i.h"
  16. #include "../bss.h"
  17. #include "../wpas_glue.h"
  18. #include "dbus_new_helpers.h"
  19. #include "dbus_dict_helpers.h"
  20. #include "dbus_new.h"
  21. #include "dbus_new_handlers.h"
  22. #include "dbus_common_i.h"
  23. #include "dbus_new_handlers_p2p.h"
  24. #include "p2p/p2p.h"
  25. #include "../p2p_supplicant.h"
  26. #ifdef CONFIG_AP /* until needed by something else */
  27. /*
  28. * NameOwnerChanged handling
  29. *
  30. * Some services we provide allow an application to register for
  31. * a signal that it needs. While it can also unregister, we must
  32. * be prepared for the case where the application simply crashes
  33. * and thus doesn't clean up properly. The way to handle this in
  34. * DBus is to register for the NameOwnerChanged signal which will
  35. * signal an owner change to NULL if the peer closes the socket
  36. * for whatever reason.
  37. *
  38. * Handle this signal via a filter function whenever necessary.
  39. * The code below also handles refcounting in case in the future
  40. * there will be multiple instances of this subscription scheme.
  41. */
  42. static const char wpas_dbus_noc_filter_str[] =
  43. "interface=org.freedesktop.DBus,member=NameOwnerChanged";
  44. static DBusHandlerResult noc_filter(DBusConnection *conn,
  45. DBusMessage *message, void *data)
  46. {
  47. struct wpas_dbus_priv *priv = data;
  48. if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL)
  49. return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  50. if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS,
  51. "NameOwnerChanged")) {
  52. const char *name;
  53. const char *prev_owner;
  54. const char *new_owner;
  55. DBusError derr;
  56. struct wpa_supplicant *wpa_s;
  57. dbus_error_init(&derr);
  58. if (!dbus_message_get_args(message, &derr,
  59. DBUS_TYPE_STRING, &name,
  60. DBUS_TYPE_STRING, &prev_owner,
  61. DBUS_TYPE_STRING, &new_owner,
  62. DBUS_TYPE_INVALID)) {
  63. /* Ignore this error */
  64. dbus_error_free(&derr);
  65. return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  66. }
  67. for (wpa_s = priv->global->ifaces; wpa_s; wpa_s = wpa_s->next) {
  68. if (wpa_s->preq_notify_peer != NULL &&
  69. os_strcmp(name, wpa_s->preq_notify_peer) == 0 &&
  70. (new_owner == NULL || os_strlen(new_owner) == 0)) {
  71. /* probe request owner disconnected */
  72. os_free(wpa_s->preq_notify_peer);
  73. wpa_s->preq_notify_peer = NULL;
  74. wpas_dbus_unsubscribe_noc(priv);
  75. }
  76. }
  77. }
  78. return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  79. }
  80. void wpas_dbus_subscribe_noc(struct wpas_dbus_priv *priv)
  81. {
  82. priv->dbus_noc_refcnt++;
  83. if (priv->dbus_noc_refcnt > 1)
  84. return;
  85. if (!dbus_connection_add_filter(priv->con, noc_filter, priv, NULL)) {
  86. wpa_printf(MSG_ERROR, "dbus: failed to add filter");
  87. return;
  88. }
  89. dbus_bus_add_match(priv->con, wpas_dbus_noc_filter_str, NULL);
  90. }
  91. void wpas_dbus_unsubscribe_noc(struct wpas_dbus_priv *priv)
  92. {
  93. priv->dbus_noc_refcnt--;
  94. if (priv->dbus_noc_refcnt > 0)
  95. return;
  96. dbus_bus_remove_match(priv->con, wpas_dbus_noc_filter_str, NULL);
  97. dbus_connection_remove_filter(priv->con, noc_filter, priv);
  98. }
  99. #endif /* CONFIG_AP */
  100. /**
  101. * wpas_dbus_signal_interface - Send a interface related event signal
  102. * @wpa_s: %wpa_supplicant network interface data
  103. * @sig_name: signal name - InterfaceAdded or InterfaceRemoved
  104. * @properties: Whether to add second argument with object properties
  105. *
  106. * Notify listeners about event related with interface
  107. */
  108. static void wpas_dbus_signal_interface(struct wpa_supplicant *wpa_s,
  109. const char *sig_name, int properties)
  110. {
  111. struct wpas_dbus_priv *iface;
  112. DBusMessage *msg;
  113. DBusMessageIter iter;
  114. iface = wpa_s->global->dbus;
  115. /* Do nothing if the control interface is not turned on */
  116. if (iface == NULL)
  117. return;
  118. msg = dbus_message_new_signal(WPAS_DBUS_NEW_PATH,
  119. WPAS_DBUS_NEW_INTERFACE, sig_name);
  120. if (msg == NULL)
  121. return;
  122. dbus_message_iter_init_append(msg, &iter);
  123. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  124. &wpa_s->dbus_new_path) ||
  125. (properties &&
  126. !wpa_dbus_get_object_properties(
  127. iface, wpa_s->dbus_new_path,
  128. WPAS_DBUS_NEW_IFACE_INTERFACE, &iter)))
  129. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  130. else
  131. dbus_connection_send(iface->con, msg, NULL);
  132. dbus_message_unref(msg);
  133. }
  134. /**
  135. * wpas_dbus_signal_interface_added - Send a interface created signal
  136. * @wpa_s: %wpa_supplicant network interface data
  137. *
  138. * Notify listeners about creating new interface
  139. */
  140. static void wpas_dbus_signal_interface_added(struct wpa_supplicant *wpa_s)
  141. {
  142. wpas_dbus_signal_interface(wpa_s, "InterfaceAdded", TRUE);
  143. }
  144. /**
  145. * wpas_dbus_signal_interface_removed - Send a interface removed signal
  146. * @wpa_s: %wpa_supplicant network interface data
  147. *
  148. * Notify listeners about removing interface
  149. */
  150. static void wpas_dbus_signal_interface_removed(struct wpa_supplicant *wpa_s)
  151. {
  152. wpas_dbus_signal_interface(wpa_s, "InterfaceRemoved", FALSE);
  153. }
  154. /**
  155. * wpas_dbus_signal_scan_done - send scan done signal
  156. * @wpa_s: %wpa_supplicant network interface data
  157. * @success: indicates if scanning succeed or failed
  158. *
  159. * Notify listeners about finishing a scan
  160. */
  161. void wpas_dbus_signal_scan_done(struct wpa_supplicant *wpa_s, int success)
  162. {
  163. struct wpas_dbus_priv *iface;
  164. DBusMessage *msg;
  165. dbus_bool_t succ;
  166. iface = wpa_s->global->dbus;
  167. /* Do nothing if the control interface is not turned on */
  168. if (iface == NULL)
  169. return;
  170. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  171. WPAS_DBUS_NEW_IFACE_INTERFACE,
  172. "ScanDone");
  173. if (msg == NULL)
  174. return;
  175. succ = success ? TRUE : FALSE;
  176. if (dbus_message_append_args(msg, DBUS_TYPE_BOOLEAN, &succ,
  177. DBUS_TYPE_INVALID))
  178. dbus_connection_send(iface->con, msg, NULL);
  179. else
  180. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  181. dbus_message_unref(msg);
  182. }
  183. /**
  184. * wpas_dbus_signal_bss - Send a BSS related event signal
  185. * @wpa_s: %wpa_supplicant network interface data
  186. * @bss_obj_path: BSS object path
  187. * @sig_name: signal name - BSSAdded or BSSRemoved
  188. * @properties: Whether to add second argument with object properties
  189. *
  190. * Notify listeners about event related with BSS
  191. */
  192. static void wpas_dbus_signal_bss(struct wpa_supplicant *wpa_s,
  193. const char *bss_obj_path,
  194. const char *sig_name, int properties)
  195. {
  196. struct wpas_dbus_priv *iface;
  197. DBusMessage *msg;
  198. DBusMessageIter iter;
  199. iface = wpa_s->global->dbus;
  200. /* Do nothing if the control interface is not turned on */
  201. if (iface == NULL)
  202. return;
  203. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  204. WPAS_DBUS_NEW_IFACE_INTERFACE,
  205. sig_name);
  206. if (msg == NULL)
  207. return;
  208. dbus_message_iter_init_append(msg, &iter);
  209. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  210. &bss_obj_path) ||
  211. (properties &&
  212. !wpa_dbus_get_object_properties(iface, bss_obj_path,
  213. WPAS_DBUS_NEW_IFACE_BSS,
  214. &iter)))
  215. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  216. else
  217. dbus_connection_send(iface->con, msg, NULL);
  218. dbus_message_unref(msg);
  219. }
  220. /**
  221. * wpas_dbus_signal_bss_added - Send a BSS added signal
  222. * @wpa_s: %wpa_supplicant network interface data
  223. * @bss_obj_path: new BSS object path
  224. *
  225. * Notify listeners about adding new BSS
  226. */
  227. static void wpas_dbus_signal_bss_added(struct wpa_supplicant *wpa_s,
  228. const char *bss_obj_path)
  229. {
  230. wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSAdded", TRUE);
  231. }
  232. /**
  233. * wpas_dbus_signal_bss_removed - Send a BSS removed signal
  234. * @wpa_s: %wpa_supplicant network interface data
  235. * @bss_obj_path: BSS object path
  236. *
  237. * Notify listeners about removing BSS
  238. */
  239. static void wpas_dbus_signal_bss_removed(struct wpa_supplicant *wpa_s,
  240. const char *bss_obj_path)
  241. {
  242. wpas_dbus_signal_bss(wpa_s, bss_obj_path, "BSSRemoved", FALSE);
  243. }
  244. /**
  245. * wpas_dbus_signal_blob - Send a blob related event signal
  246. * @wpa_s: %wpa_supplicant network interface data
  247. * @name: blob name
  248. * @sig_name: signal name - BlobAdded or BlobRemoved
  249. *
  250. * Notify listeners about event related with blob
  251. */
  252. static void wpas_dbus_signal_blob(struct wpa_supplicant *wpa_s,
  253. const char *name, const char *sig_name)
  254. {
  255. struct wpas_dbus_priv *iface;
  256. DBusMessage *msg;
  257. iface = wpa_s->global->dbus;
  258. /* Do nothing if the control interface is not turned on */
  259. if (iface == NULL)
  260. return;
  261. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  262. WPAS_DBUS_NEW_IFACE_INTERFACE,
  263. sig_name);
  264. if (msg == NULL)
  265. return;
  266. if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &name,
  267. DBUS_TYPE_INVALID))
  268. dbus_connection_send(iface->con, msg, NULL);
  269. else
  270. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  271. dbus_message_unref(msg);
  272. }
  273. /**
  274. * wpas_dbus_signal_blob_added - Send a blob added signal
  275. * @wpa_s: %wpa_supplicant network interface data
  276. * @name: blob name
  277. *
  278. * Notify listeners about adding a new blob
  279. */
  280. void wpas_dbus_signal_blob_added(struct wpa_supplicant *wpa_s,
  281. const char *name)
  282. {
  283. wpas_dbus_signal_blob(wpa_s, name, "BlobAdded");
  284. }
  285. /**
  286. * wpas_dbus_signal_blob_removed - Send a blob removed signal
  287. * @wpa_s: %wpa_supplicant network interface data
  288. * @name: blob name
  289. *
  290. * Notify listeners about removing blob
  291. */
  292. void wpas_dbus_signal_blob_removed(struct wpa_supplicant *wpa_s,
  293. const char *name)
  294. {
  295. wpas_dbus_signal_blob(wpa_s, name, "BlobRemoved");
  296. }
  297. /**
  298. * wpas_dbus_signal_network - Send a network related event signal
  299. * @wpa_s: %wpa_supplicant network interface data
  300. * @id: new network id
  301. * @sig_name: signal name - NetworkAdded, NetworkRemoved or NetworkSelected
  302. * @properties: determines if add second argument with object properties
  303. *
  304. * Notify listeners about event related with configured network
  305. */
  306. static void wpas_dbus_signal_network(struct wpa_supplicant *wpa_s,
  307. int id, const char *sig_name,
  308. int properties)
  309. {
  310. struct wpas_dbus_priv *iface;
  311. DBusMessage *msg;
  312. DBusMessageIter iter;
  313. char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  314. iface = wpa_s->global->dbus;
  315. /* Do nothing if the control interface is not turned on */
  316. if (iface == NULL)
  317. return;
  318. os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  319. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
  320. wpa_s->dbus_new_path, id);
  321. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  322. WPAS_DBUS_NEW_IFACE_INTERFACE,
  323. sig_name);
  324. if (msg == NULL)
  325. return;
  326. dbus_message_iter_init_append(msg, &iter);
  327. path = net_obj_path;
  328. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  329. &path) ||
  330. (properties &&
  331. !wpa_dbus_get_object_properties(
  332. iface, net_obj_path, WPAS_DBUS_NEW_IFACE_NETWORK,
  333. &iter)))
  334. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  335. else
  336. dbus_connection_send(iface->con, msg, NULL);
  337. dbus_message_unref(msg);
  338. }
  339. /**
  340. * wpas_dbus_signal_network_added - Send a network added signal
  341. * @wpa_s: %wpa_supplicant network interface data
  342. * @id: new network id
  343. *
  344. * Notify listeners about adding new network
  345. */
  346. static void wpas_dbus_signal_network_added(struct wpa_supplicant *wpa_s,
  347. int id)
  348. {
  349. wpas_dbus_signal_network(wpa_s, id, "NetworkAdded", TRUE);
  350. }
  351. /**
  352. * wpas_dbus_signal_network_removed - Send a network removed signal
  353. * @wpa_s: %wpa_supplicant network interface data
  354. * @id: network id
  355. *
  356. * Notify listeners about removing a network
  357. */
  358. static void wpas_dbus_signal_network_removed(struct wpa_supplicant *wpa_s,
  359. int id)
  360. {
  361. wpas_dbus_signal_network(wpa_s, id, "NetworkRemoved", FALSE);
  362. }
  363. /**
  364. * wpas_dbus_signal_network_selected - Send a network selected signal
  365. * @wpa_s: %wpa_supplicant network interface data
  366. * @id: network id
  367. *
  368. * Notify listeners about selecting a network
  369. */
  370. void wpas_dbus_signal_network_selected(struct wpa_supplicant *wpa_s, int id)
  371. {
  372. wpas_dbus_signal_network(wpa_s, id, "NetworkSelected", FALSE);
  373. }
  374. /**
  375. * wpas_dbus_signal_network_request - Indicate that additional information
  376. * (EAP password, etc.) is required to complete the association to this SSID
  377. * @wpa_s: %wpa_supplicant network interface data
  378. * @rtype: The specific additional information required
  379. * @default_text: Optional description of required information
  380. *
  381. * Request additional information or passwords to complete an association
  382. * request.
  383. */
  384. void wpas_dbus_signal_network_request(struct wpa_supplicant *wpa_s,
  385. struct wpa_ssid *ssid,
  386. enum wpa_ctrl_req_type rtype,
  387. const char *default_txt)
  388. {
  389. struct wpas_dbus_priv *iface;
  390. DBusMessage *msg;
  391. DBusMessageIter iter;
  392. char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  393. const char *field, *txt = NULL, *net_ptr;
  394. iface = wpa_s->global->dbus;
  395. /* Do nothing if the control interface is not turned on */
  396. if (iface == NULL)
  397. return;
  398. field = wpa_supplicant_ctrl_req_to_string(rtype, default_txt, &txt);
  399. if (field == NULL)
  400. return;
  401. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  402. WPAS_DBUS_NEW_IFACE_INTERFACE,
  403. "NetworkRequest");
  404. if (msg == NULL)
  405. return;
  406. os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  407. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
  408. wpa_s->dbus_new_path, ssid->id);
  409. net_ptr = &net_obj_path[0];
  410. dbus_message_iter_init_append(msg, &iter);
  411. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  412. &net_ptr) ||
  413. !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &field) ||
  414. !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &txt))
  415. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  416. else
  417. dbus_connection_send(iface->con, msg, NULL);
  418. dbus_message_unref(msg);
  419. }
  420. /**
  421. * wpas_dbus_signal_network_enabled_changed - Signals Enabled property changes
  422. * @wpa_s: %wpa_supplicant network interface data
  423. * @ssid: configured network which Enabled property has changed
  424. *
  425. * Sends PropertyChanged signals containing new value of Enabled property
  426. * for specified network
  427. */
  428. void wpas_dbus_signal_network_enabled_changed(struct wpa_supplicant *wpa_s,
  429. struct wpa_ssid *ssid)
  430. {
  431. char path[WPAS_DBUS_OBJECT_PATH_MAX];
  432. os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
  433. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%d",
  434. wpa_s->dbus_new_path, ssid->id);
  435. wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
  436. WPAS_DBUS_NEW_IFACE_NETWORK, "Enabled");
  437. }
  438. #ifdef CONFIG_WPS
  439. /**
  440. * wpas_dbus_signal_wps_event_success - Signals Success WPS event
  441. * @wpa_s: %wpa_supplicant network interface data
  442. *
  443. * Sends Event dbus signal with name "success" and empty dict as arguments
  444. */
  445. void wpas_dbus_signal_wps_event_success(struct wpa_supplicant *wpa_s)
  446. {
  447. DBusMessage *msg;
  448. DBusMessageIter iter, dict_iter;
  449. struct wpas_dbus_priv *iface;
  450. char *key = "success";
  451. iface = wpa_s->global->dbus;
  452. /* Do nothing if the control interface is not turned on */
  453. if (iface == NULL)
  454. return;
  455. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  456. WPAS_DBUS_NEW_IFACE_WPS, "Event");
  457. if (msg == NULL)
  458. return;
  459. dbus_message_iter_init_append(msg, &iter);
  460. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
  461. !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  462. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  463. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  464. else
  465. dbus_connection_send(iface->con, msg, NULL);
  466. dbus_message_unref(msg);
  467. }
  468. /**
  469. * wpas_dbus_signal_wps_event_fail - Signals Fail WPS event
  470. * @wpa_s: %wpa_supplicant network interface data
  471. *
  472. * Sends Event dbus signal with name "fail" and dictionary containing
  473. * "msg field with fail message number (int32) as arguments
  474. */
  475. void wpas_dbus_signal_wps_event_fail(struct wpa_supplicant *wpa_s,
  476. struct wps_event_fail *fail)
  477. {
  478. DBusMessage *msg;
  479. DBusMessageIter iter, dict_iter;
  480. struct wpas_dbus_priv *iface;
  481. char *key = "fail";
  482. iface = wpa_s->global->dbus;
  483. /* Do nothing if the control interface is not turned on */
  484. if (iface == NULL)
  485. return;
  486. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  487. WPAS_DBUS_NEW_IFACE_WPS, "Event");
  488. if (msg == NULL)
  489. return;
  490. dbus_message_iter_init_append(msg, &iter);
  491. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
  492. !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  493. !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
  494. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  495. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  496. else
  497. dbus_connection_send(iface->con, msg, NULL);
  498. dbus_message_unref(msg);
  499. }
  500. /**
  501. * wpas_dbus_signal_wps_event_m2d - Signals M2D WPS event
  502. * @wpa_s: %wpa_supplicant network interface data
  503. *
  504. * Sends Event dbus signal with name "m2d" and dictionary containing
  505. * fields of wps_event_m2d structure.
  506. */
  507. void wpas_dbus_signal_wps_event_m2d(struct wpa_supplicant *wpa_s,
  508. struct wps_event_m2d *m2d)
  509. {
  510. DBusMessage *msg;
  511. DBusMessageIter iter, dict_iter;
  512. struct wpas_dbus_priv *iface;
  513. char *key = "m2d";
  514. iface = wpa_s->global->dbus;
  515. /* Do nothing if the control interface is not turned on */
  516. if (iface == NULL)
  517. return;
  518. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  519. WPAS_DBUS_NEW_IFACE_WPS, "Event");
  520. if (msg == NULL)
  521. return;
  522. dbus_message_iter_init_append(msg, &iter);
  523. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
  524. !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  525. !wpa_dbus_dict_append_uint16(&dict_iter, "config_methods",
  526. m2d->config_methods) ||
  527. !wpa_dbus_dict_append_byte_array(&dict_iter, "manufacturer",
  528. (const char *) m2d->manufacturer,
  529. m2d->manufacturer_len) ||
  530. !wpa_dbus_dict_append_byte_array(&dict_iter, "model_name",
  531. (const char *) m2d->model_name,
  532. m2d->model_name_len) ||
  533. !wpa_dbus_dict_append_byte_array(&dict_iter, "model_number",
  534. (const char *) m2d->model_number,
  535. m2d->model_number_len) ||
  536. !wpa_dbus_dict_append_byte_array(&dict_iter, "serial_number",
  537. (const char *)
  538. m2d->serial_number,
  539. m2d->serial_number_len) ||
  540. !wpa_dbus_dict_append_byte_array(&dict_iter, "dev_name",
  541. (const char *) m2d->dev_name,
  542. m2d->dev_name_len) ||
  543. !wpa_dbus_dict_append_byte_array(&dict_iter, "primary_dev_type",
  544. (const char *)
  545. m2d->primary_dev_type, 8) ||
  546. !wpa_dbus_dict_append_uint16(&dict_iter, "config_error",
  547. m2d->config_error) ||
  548. !wpa_dbus_dict_append_uint16(&dict_iter, "dev_password_id",
  549. m2d->dev_password_id) ||
  550. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  551. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  552. else
  553. dbus_connection_send(iface->con, msg, NULL);
  554. dbus_message_unref(msg);
  555. }
  556. /**
  557. * wpas_dbus_signal_wps_cred - Signals new credentials
  558. * @wpa_s: %wpa_supplicant network interface data
  559. *
  560. * Sends signal with credentials in directory argument
  561. */
  562. void wpas_dbus_signal_wps_cred(struct wpa_supplicant *wpa_s,
  563. const struct wps_credential *cred)
  564. {
  565. DBusMessage *msg;
  566. DBusMessageIter iter, dict_iter;
  567. struct wpas_dbus_priv *iface;
  568. char *auth_type[5]; /* we have five possible authentication types */
  569. int at_num = 0;
  570. char *encr_type[3]; /* we have three possible encryption types */
  571. int et_num = 0;
  572. iface = wpa_s->global->dbus;
  573. /* Do nothing if the control interface is not turned on */
  574. if (iface == NULL)
  575. return;
  576. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  577. WPAS_DBUS_NEW_IFACE_WPS,
  578. "Credentials");
  579. if (msg == NULL)
  580. return;
  581. dbus_message_iter_init_append(msg, &iter);
  582. if (!wpa_dbus_dict_open_write(&iter, &dict_iter))
  583. goto nomem;
  584. if (cred->auth_type & WPS_AUTH_OPEN)
  585. auth_type[at_num++] = "open";
  586. if (cred->auth_type & WPS_AUTH_WPAPSK)
  587. auth_type[at_num++] = "wpa-psk";
  588. if (cred->auth_type & WPS_AUTH_WPA)
  589. auth_type[at_num++] = "wpa-eap";
  590. if (cred->auth_type & WPS_AUTH_WPA2)
  591. auth_type[at_num++] = "wpa2-eap";
  592. if (cred->auth_type & WPS_AUTH_WPA2PSK)
  593. auth_type[at_num++] = "wpa2-psk";
  594. if (cred->encr_type & WPS_ENCR_NONE)
  595. encr_type[et_num++] = "none";
  596. if (cred->encr_type & WPS_ENCR_TKIP)
  597. encr_type[et_num++] = "tkip";
  598. if (cred->encr_type & WPS_ENCR_AES)
  599. encr_type[et_num++] = "aes";
  600. if ((wpa_s->current_ssid &&
  601. !wpa_dbus_dict_append_byte_array(
  602. &dict_iter, "BSSID",
  603. (const char *) wpa_s->current_ssid->bssid, ETH_ALEN)) ||
  604. !wpa_dbus_dict_append_byte_array(&dict_iter, "SSID",
  605. (const char *) cred->ssid,
  606. cred->ssid_len) ||
  607. !wpa_dbus_dict_append_string_array(&dict_iter, "AuthType",
  608. (const char **) auth_type,
  609. at_num) ||
  610. !wpa_dbus_dict_append_string_array(&dict_iter, "EncrType",
  611. (const char **) encr_type,
  612. et_num) ||
  613. !wpa_dbus_dict_append_byte_array(&dict_iter, "Key",
  614. (const char *) cred->key,
  615. cred->key_len) ||
  616. !wpa_dbus_dict_append_uint32(&dict_iter, "KeyIndex",
  617. cred->key_idx) ||
  618. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  619. goto nomem;
  620. dbus_connection_send(iface->con, msg, NULL);
  621. nomem:
  622. dbus_message_unref(msg);
  623. }
  624. #endif /* CONFIG_WPS */
  625. void wpas_dbus_signal_certification(struct wpa_supplicant *wpa_s,
  626. int depth, const char *subject,
  627. const char *altsubject[],
  628. int num_altsubject,
  629. const char *cert_hash,
  630. const struct wpabuf *cert)
  631. {
  632. struct wpas_dbus_priv *iface;
  633. DBusMessage *msg;
  634. DBusMessageIter iter, dict_iter;
  635. iface = wpa_s->global->dbus;
  636. /* Do nothing if the control interface is not turned on */
  637. if (iface == NULL)
  638. return;
  639. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  640. WPAS_DBUS_NEW_IFACE_INTERFACE,
  641. "Certification");
  642. if (msg == NULL)
  643. return;
  644. dbus_message_iter_init_append(msg, &iter);
  645. if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  646. !wpa_dbus_dict_append_uint32(&dict_iter, "depth", depth) ||
  647. !wpa_dbus_dict_append_string(&dict_iter, "subject", subject) ||
  648. (altsubject && num_altsubject &&
  649. !wpa_dbus_dict_append_string_array(&dict_iter, "altsubject",
  650. altsubject, num_altsubject)) ||
  651. (cert_hash &&
  652. !wpa_dbus_dict_append_string(&dict_iter, "cert_hash",
  653. cert_hash)) ||
  654. (cert &&
  655. !wpa_dbus_dict_append_byte_array(&dict_iter, "cert",
  656. wpabuf_head(cert),
  657. wpabuf_len(cert))) ||
  658. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  659. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  660. else
  661. dbus_connection_send(iface->con, msg, NULL);
  662. dbus_message_unref(msg);
  663. }
  664. void wpas_dbus_signal_eap_status(struct wpa_supplicant *wpa_s,
  665. const char *status, const char *parameter)
  666. {
  667. struct wpas_dbus_priv *iface;
  668. DBusMessage *msg;
  669. DBusMessageIter iter;
  670. iface = wpa_s->global->dbus;
  671. /* Do nothing if the control interface is not turned on */
  672. if (iface == NULL)
  673. return;
  674. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  675. WPAS_DBUS_NEW_IFACE_INTERFACE,
  676. "EAP");
  677. if (msg == NULL)
  678. return;
  679. dbus_message_iter_init_append(msg, &iter);
  680. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &status) ||
  681. !dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
  682. &parameter))
  683. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  684. else
  685. dbus_connection_send(iface->con, msg, NULL);
  686. dbus_message_unref(msg);
  687. }
  688. /**
  689. * wpas_dbus_signal_sta - Send a station related event signal
  690. * @wpa_s: %wpa_supplicant network interface data
  691. * @sta: station mac address
  692. * @sig_name: signal name - StaAuthorized or StaDeauthorized
  693. *
  694. * Notify listeners about event related with station
  695. */
  696. static void wpas_dbus_signal_sta(struct wpa_supplicant *wpa_s,
  697. const u8 *sta, const char *sig_name)
  698. {
  699. struct wpas_dbus_priv *iface;
  700. DBusMessage *msg;
  701. char sta_mac[WPAS_DBUS_OBJECT_PATH_MAX];
  702. char *dev_mac;
  703. os_snprintf(sta_mac, WPAS_DBUS_OBJECT_PATH_MAX, MACSTR, MAC2STR(sta));
  704. dev_mac = sta_mac;
  705. iface = wpa_s->global->dbus;
  706. /* Do nothing if the control interface is not turned on */
  707. if (iface == NULL)
  708. return;
  709. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  710. WPAS_DBUS_NEW_IFACE_INTERFACE, sig_name);
  711. if (msg == NULL)
  712. return;
  713. if (dbus_message_append_args(msg, DBUS_TYPE_STRING, &dev_mac,
  714. DBUS_TYPE_INVALID))
  715. dbus_connection_send(iface->con, msg, NULL);
  716. else
  717. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  718. dbus_message_unref(msg);
  719. wpa_printf(MSG_DEBUG, "dbus: Station MAC address '%s' '%s'",
  720. sta_mac, sig_name);
  721. }
  722. /**
  723. * wpas_dbus_signal_sta_authorized - Send a STA authorized signal
  724. * @wpa_s: %wpa_supplicant network interface data
  725. * @sta: station mac address
  726. *
  727. * Notify listeners a new station has been authorized
  728. */
  729. void wpas_dbus_signal_sta_authorized(struct wpa_supplicant *wpa_s,
  730. const u8 *sta)
  731. {
  732. wpas_dbus_signal_sta(wpa_s, sta, "StaAuthorized");
  733. }
  734. /**
  735. * wpas_dbus_signal_sta_deauthorized - Send a STA deauthorized signal
  736. * @wpa_s: %wpa_supplicant network interface data
  737. * @sta: station mac address
  738. *
  739. * Notify listeners a station has been deauthorized
  740. */
  741. void wpas_dbus_signal_sta_deauthorized(struct wpa_supplicant *wpa_s,
  742. const u8 *sta)
  743. {
  744. wpas_dbus_signal_sta(wpa_s, sta, "StaDeauthorized");
  745. }
  746. #ifdef CONFIG_P2P
  747. /**
  748. * wpas_dbus_signal_p2p_group_removed - Signals P2P group was removed
  749. * @wpa_s: %wpa_supplicant network interface data
  750. * @role: role of this device (client or GO)
  751. * Sends signal with i/f name and role as string arguments
  752. */
  753. void wpas_dbus_signal_p2p_group_removed(struct wpa_supplicant *wpa_s,
  754. const char *role)
  755. {
  756. DBusMessage *msg;
  757. DBusMessageIter iter, dict_iter;
  758. struct wpas_dbus_priv *iface = wpa_s->global->dbus;
  759. struct wpa_supplicant *parent;
  760. /* Do nothing if the control interface is not turned on */
  761. if (iface == NULL)
  762. return;
  763. parent = wpa_s->parent;
  764. if (parent->p2p_mgmt)
  765. parent = parent->parent;
  766. if (!wpa_s->dbus_groupobj_path)
  767. return;
  768. msg = dbus_message_new_signal(parent->dbus_new_path,
  769. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  770. "GroupFinished");
  771. if (msg == NULL)
  772. return;
  773. dbus_message_iter_init_append(msg, &iter);
  774. if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  775. !wpa_dbus_dict_append_object_path(&dict_iter,
  776. "interface_object",
  777. wpa_s->dbus_new_path) ||
  778. !wpa_dbus_dict_append_string(&dict_iter, "role", role) ||
  779. !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
  780. wpa_s->dbus_groupobj_path) ||
  781. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  782. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  783. else
  784. dbus_connection_send(iface->con, msg, NULL);
  785. dbus_message_unref(msg);
  786. }
  787. /**
  788. * wpas_dbus_signal_p2p_provision_discovery - Signals various PD events
  789. *
  790. * @dev_addr - who sent the request or responded to our request.
  791. * @request - Will be 1 if request, 0 for response.
  792. * @status - valid only in case of response
  793. * @config_methods - wps config methods
  794. * @generated_pin - pin to be displayed in case of WPS_CONFIG_DISPLAY method
  795. *
  796. * Sends following provision discovery related events:
  797. * ProvisionDiscoveryRequestDisplayPin
  798. * ProvisionDiscoveryResponseDisplayPin
  799. * ProvisionDiscoveryRequestEnterPin
  800. * ProvisionDiscoveryResponseEnterPin
  801. * ProvisionDiscoveryPBCRequest
  802. * ProvisionDiscoveryPBCResponse
  803. *
  804. * TODO::
  805. * ProvisionDiscoveryFailure (timeout case)
  806. */
  807. void wpas_dbus_signal_p2p_provision_discovery(struct wpa_supplicant *wpa_s,
  808. const u8 *dev_addr, int request,
  809. enum p2p_prov_disc_status status,
  810. u16 config_methods,
  811. unsigned int generated_pin)
  812. {
  813. DBusMessage *msg;
  814. DBusMessageIter iter;
  815. struct wpas_dbus_priv *iface;
  816. char *_signal;
  817. int add_pin = 0;
  818. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  819. int error_ret = 1;
  820. char pin[9], *p_pin = NULL;
  821. iface = wpa_s->global->dbus;
  822. /* Do nothing if the control interface is not turned on */
  823. if (iface == NULL)
  824. return;
  825. if (wpa_s->p2p_mgmt)
  826. wpa_s = wpa_s->parent;
  827. if (request || !status) {
  828. if (config_methods & WPS_CONFIG_DISPLAY)
  829. _signal = request ?
  830. "ProvisionDiscoveryRequestDisplayPin" :
  831. "ProvisionDiscoveryResponseEnterPin";
  832. else if (config_methods & WPS_CONFIG_KEYPAD)
  833. _signal = request ?
  834. "ProvisionDiscoveryRequestEnterPin" :
  835. "ProvisionDiscoveryResponseDisplayPin";
  836. else if (config_methods & WPS_CONFIG_PUSHBUTTON)
  837. _signal = request ? "ProvisionDiscoveryPBCRequest" :
  838. "ProvisionDiscoveryPBCResponse";
  839. else
  840. return; /* Unknown or un-supported method */
  841. } else {
  842. /* Explicit check for failure response */
  843. _signal = "ProvisionDiscoveryFailure";
  844. }
  845. add_pin = ((request && (config_methods & WPS_CONFIG_DISPLAY)) ||
  846. (!request && !status &&
  847. (config_methods & WPS_CONFIG_KEYPAD)));
  848. if (add_pin) {
  849. os_snprintf(pin, sizeof(pin), "%08d", generated_pin);
  850. p_pin = pin;
  851. }
  852. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  853. WPAS_DBUS_NEW_IFACE_P2PDEVICE, _signal);
  854. if (msg == NULL)
  855. return;
  856. /* Check if this is a known peer */
  857. if (!p2p_peer_known(wpa_s->global->p2p, dev_addr))
  858. goto error;
  859. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  860. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
  861. COMPACT_MACSTR,
  862. wpa_s->dbus_new_path, MAC2STR(dev_addr));
  863. path = peer_obj_path;
  864. dbus_message_iter_init_append(msg, &iter);
  865. if (!dbus_message_iter_append_basic(&iter,
  866. DBUS_TYPE_OBJECT_PATH,
  867. &path))
  868. goto error;
  869. if (!request && status)
  870. /* Attach status to ProvisionDiscoveryFailure */
  871. error_ret = !dbus_message_iter_append_basic(&iter,
  872. DBUS_TYPE_INT32,
  873. &status);
  874. else
  875. error_ret = (add_pin &&
  876. !dbus_message_iter_append_basic(&iter,
  877. DBUS_TYPE_STRING,
  878. &p_pin));
  879. error:
  880. if (!error_ret)
  881. dbus_connection_send(iface->con, msg, NULL);
  882. else
  883. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  884. dbus_message_unref(msg);
  885. }
  886. void wpas_dbus_signal_p2p_go_neg_req(struct wpa_supplicant *wpa_s,
  887. const u8 *src, u16 dev_passwd_id)
  888. {
  889. DBusMessage *msg;
  890. DBusMessageIter iter;
  891. struct wpas_dbus_priv *iface;
  892. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  893. iface = wpa_s->global->dbus;
  894. /* Do nothing if the control interface is not turned on */
  895. if (iface == NULL)
  896. return;
  897. if (wpa_s->p2p_mgmt)
  898. wpa_s = wpa_s->parent;
  899. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  900. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
  901. wpa_s->dbus_new_path, MAC2STR(src));
  902. path = peer_obj_path;
  903. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  904. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  905. "GONegotiationRequest");
  906. if (msg == NULL)
  907. return;
  908. dbus_message_iter_init_append(msg, &iter);
  909. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  910. &path) ||
  911. !dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
  912. &dev_passwd_id))
  913. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  914. else
  915. dbus_connection_send(iface->con, msg, NULL);
  916. dbus_message_unref(msg);
  917. }
  918. static int wpas_dbus_get_group_obj_path(struct wpa_supplicant *wpa_s,
  919. const struct wpa_ssid *ssid,
  920. char *group_obj_path)
  921. {
  922. char group_name[3];
  923. if (os_memcmp(ssid->ssid, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN))
  924. return -1;
  925. os_memcpy(group_name, ssid->ssid + P2P_WILDCARD_SSID_LEN, 2);
  926. group_name[2] = '\0';
  927. os_snprintf(group_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  928. "%s/" WPAS_DBUS_NEW_P2P_GROUPS_PART "/%s",
  929. wpa_s->dbus_new_path, group_name);
  930. return 0;
  931. }
  932. struct group_changed_data {
  933. struct wpa_supplicant *wpa_s;
  934. struct p2p_peer_info *info;
  935. };
  936. static int match_group_where_peer_is_client(struct p2p_group *group,
  937. void *user_data)
  938. {
  939. struct group_changed_data *data = user_data;
  940. const struct p2p_group_config *cfg;
  941. struct wpa_supplicant *wpa_s_go;
  942. if (!p2p_group_is_client_connected(group, data->info->p2p_device_addr))
  943. return 1;
  944. cfg = p2p_group_get_config(group);
  945. wpa_s_go = wpas_get_p2p_go_iface(data->wpa_s, cfg->ssid,
  946. cfg->ssid_len);
  947. if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
  948. wpas_dbus_signal_peer_groups_changed(
  949. data->wpa_s->parent, data->info->p2p_device_addr);
  950. return 0;
  951. }
  952. return 1;
  953. }
  954. static void signal_peer_groups_changed(struct p2p_peer_info *info,
  955. void *user_data)
  956. {
  957. struct group_changed_data *data = user_data;
  958. struct wpa_supplicant *wpa_s_go;
  959. wpa_s_go = wpas_get_p2p_client_iface(data->wpa_s,
  960. info->p2p_device_addr);
  961. if (wpa_s_go != NULL && wpa_s_go == data->wpa_s) {
  962. wpas_dbus_signal_peer_groups_changed(data->wpa_s->parent,
  963. info->p2p_device_addr);
  964. return;
  965. }
  966. data->info = info;
  967. p2p_loop_on_all_groups(data->wpa_s->global->p2p,
  968. match_group_where_peer_is_client, data);
  969. data->info = NULL;
  970. }
  971. static void peer_groups_changed(struct wpa_supplicant *wpa_s)
  972. {
  973. struct group_changed_data data;
  974. os_memset(&data, 0, sizeof(data));
  975. data.wpa_s = wpa_s;
  976. p2p_loop_on_known_peers(wpa_s->global->p2p,
  977. signal_peer_groups_changed, &data);
  978. }
  979. /**
  980. * wpas_dbus_signal_p2p_group_started - Signals P2P group has
  981. * started. Emitted when a group is successfully started
  982. * irrespective of the role (client/GO) of the current device
  983. *
  984. * @wpa_s: %wpa_supplicant network interface data
  985. * @ssid: SSID object
  986. * @client: this device is P2P client
  987. * @network_id: network id of the group started, use instead of ssid->id
  988. * to account for persistent groups
  989. */
  990. void wpas_dbus_signal_p2p_group_started(struct wpa_supplicant *wpa_s,
  991. const struct wpa_ssid *ssid,
  992. int client, int network_id)
  993. {
  994. DBusMessage *msg;
  995. DBusMessageIter iter, dict_iter;
  996. struct wpas_dbus_priv *iface;
  997. struct wpa_supplicant *parent;
  998. parent = wpa_s->parent;
  999. if (parent->p2p_mgmt)
  1000. parent = parent->parent;
  1001. iface = parent->global->dbus;
  1002. /* Do nothing if the control interface is not turned on */
  1003. if (iface == NULL)
  1004. return;
  1005. if (wpa_s->dbus_groupobj_path == NULL)
  1006. return;
  1007. /* New interface has been created for this group */
  1008. msg = dbus_message_new_signal(parent->dbus_new_path,
  1009. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1010. "GroupStarted");
  1011. if (msg == NULL)
  1012. return;
  1013. dbus_message_iter_init_append(msg, &iter);
  1014. /*
  1015. * In case the device supports creating a separate interface the
  1016. * DBus client will need to know the object path for the interface
  1017. * object this group was created on, so include it here.
  1018. */
  1019. if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  1020. !wpa_dbus_dict_append_object_path(&dict_iter,
  1021. "interface_object",
  1022. wpa_s->dbus_new_path) ||
  1023. !wpa_dbus_dict_append_string(&dict_iter, "role",
  1024. client ? "client" : "GO") ||
  1025. !wpa_dbus_dict_append_object_path(&dict_iter, "group_object",
  1026. wpa_s->dbus_groupobj_path) ||
  1027. !wpa_dbus_dict_close_write(&iter, &dict_iter)) {
  1028. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  1029. } else {
  1030. dbus_connection_send(iface->con, msg, NULL);
  1031. if (client)
  1032. peer_groups_changed(wpa_s);
  1033. }
  1034. dbus_message_unref(msg);
  1035. }
  1036. /**
  1037. *
  1038. * Method to emit GONegotiation Success or Failure signals based
  1039. * on status.
  1040. * @status: Status of the GO neg request. 0 for success, other for errors.
  1041. */
  1042. void wpas_dbus_signal_p2p_go_neg_resp(struct wpa_supplicant *wpa_s,
  1043. struct p2p_go_neg_results *res)
  1044. {
  1045. DBusMessage *msg;
  1046. DBusMessageIter iter, dict_iter;
  1047. DBusMessageIter iter_dict_entry, iter_dict_val, iter_dict_array;
  1048. struct wpas_dbus_priv *iface;
  1049. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  1050. dbus_int32_t freqs[P2P_MAX_CHANNELS];
  1051. dbus_int32_t *f_array = freqs;
  1052. iface = wpa_s->global->dbus;
  1053. if (wpa_s->p2p_mgmt)
  1054. wpa_s = wpa_s->parent;
  1055. os_memset(freqs, 0, sizeof(freqs));
  1056. /* Do nothing if the control interface is not turned on */
  1057. if (iface == NULL)
  1058. return;
  1059. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1060. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
  1061. wpa_s->dbus_new_path, MAC2STR(res->peer_device_addr));
  1062. path = peer_obj_path;
  1063. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  1064. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1065. res->status ? "GONegotiationFailure" :
  1066. "GONegotiationSuccess");
  1067. if (msg == NULL)
  1068. return;
  1069. dbus_message_iter_init_append(msg, &iter);
  1070. if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  1071. !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
  1072. path) ||
  1073. !wpa_dbus_dict_append_int32(&dict_iter, "status", res->status))
  1074. goto err;
  1075. if (!res->status) {
  1076. int i = 0;
  1077. int freq_list_num = 0;
  1078. if ((res->role_go &&
  1079. !wpa_dbus_dict_append_string(&dict_iter, "passphrase",
  1080. res->passphrase)) ||
  1081. !wpa_dbus_dict_append_string(&dict_iter, "role_go",
  1082. res->role_go ? "GO" :
  1083. "client") ||
  1084. !wpa_dbus_dict_append_int32(&dict_iter, "frequency",
  1085. res->freq) ||
  1086. !wpa_dbus_dict_append_byte_array(&dict_iter, "ssid",
  1087. (const char *) res->ssid,
  1088. res->ssid_len) ||
  1089. !wpa_dbus_dict_append_byte_array(&dict_iter,
  1090. "peer_device_addr",
  1091. (const char *)
  1092. res->peer_device_addr,
  1093. ETH_ALEN) ||
  1094. !wpa_dbus_dict_append_byte_array(&dict_iter,
  1095. "peer_interface_addr",
  1096. (const char *)
  1097. res->peer_interface_addr,
  1098. ETH_ALEN) ||
  1099. !wpa_dbus_dict_append_string(&dict_iter, "wps_method",
  1100. p2p_wps_method_text(
  1101. res->wps_method)))
  1102. goto err;
  1103. for (i = 0; i < P2P_MAX_CHANNELS; i++) {
  1104. if (res->freq_list[i]) {
  1105. freqs[i] = res->freq_list[i];
  1106. freq_list_num++;
  1107. }
  1108. }
  1109. if (!wpa_dbus_dict_begin_array(&dict_iter,
  1110. "frequency_list",
  1111. DBUS_TYPE_INT32_AS_STRING,
  1112. &iter_dict_entry,
  1113. &iter_dict_val,
  1114. &iter_dict_array) ||
  1115. !dbus_message_iter_append_fixed_array(&iter_dict_array,
  1116. DBUS_TYPE_INT32,
  1117. &f_array,
  1118. freq_list_num) ||
  1119. !wpa_dbus_dict_end_array(&dict_iter,
  1120. &iter_dict_entry,
  1121. &iter_dict_val,
  1122. &iter_dict_array) ||
  1123. !wpa_dbus_dict_append_int32(&dict_iter, "persistent_group",
  1124. res->persistent_group) ||
  1125. !wpa_dbus_dict_append_uint32(&dict_iter,
  1126. "peer_config_timeout",
  1127. res->peer_config_timeout))
  1128. goto err;
  1129. }
  1130. if (!wpa_dbus_dict_close_write(&iter, &dict_iter))
  1131. goto err;
  1132. dbus_connection_send(iface->con, msg, NULL);
  1133. err:
  1134. dbus_message_unref(msg);
  1135. }
  1136. /**
  1137. *
  1138. * Method to emit Invitation Result signal based on status and
  1139. * bssid
  1140. * @status: Status of the Invite request. 0 for success, other
  1141. * for errors
  1142. * @bssid : Basic Service Set Identifier
  1143. */
  1144. void wpas_dbus_signal_p2p_invitation_result(struct wpa_supplicant *wpa_s,
  1145. int status, const u8 *bssid)
  1146. {
  1147. DBusMessage *msg;
  1148. DBusMessageIter iter, dict_iter;
  1149. struct wpas_dbus_priv *iface;
  1150. wpa_printf(MSG_DEBUG, "%s", __func__);
  1151. iface = wpa_s->global->dbus;
  1152. /* Do nothing if the control interface is not turned on */
  1153. if (iface == NULL)
  1154. return;
  1155. if (wpa_s->p2p_mgmt)
  1156. wpa_s = wpa_s->parent;
  1157. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  1158. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1159. "InvitationResult");
  1160. if (msg == NULL)
  1161. return;
  1162. dbus_message_iter_init_append(msg, &iter);
  1163. if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  1164. !wpa_dbus_dict_append_int32(&dict_iter, "status", status) ||
  1165. (bssid &&
  1166. !wpa_dbus_dict_append_byte_array(&dict_iter, "BSSID",
  1167. (const char *) bssid,
  1168. ETH_ALEN)) ||
  1169. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  1170. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  1171. else
  1172. dbus_connection_send(iface->con, msg, NULL);
  1173. dbus_message_unref(msg);
  1174. }
  1175. /**
  1176. *
  1177. * Method to emit a signal for a peer joining the group.
  1178. * The signal will carry path to the group member object
  1179. * constructed using p2p i/f addr used for connecting.
  1180. *
  1181. * @wpa_s: %wpa_supplicant network interface data
  1182. * @peer_addr: P2P Device Address of the peer joining the group
  1183. */
  1184. void wpas_dbus_signal_p2p_peer_joined(struct wpa_supplicant *wpa_s,
  1185. const u8 *peer_addr)
  1186. {
  1187. struct wpas_dbus_priv *iface;
  1188. DBusMessage *msg;
  1189. DBusMessageIter iter;
  1190. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  1191. struct wpa_supplicant *parent;
  1192. iface = wpa_s->global->dbus;
  1193. /* Do nothing if the control interface is not turned on */
  1194. if (iface == NULL)
  1195. return;
  1196. if (!wpa_s->dbus_groupobj_path)
  1197. return;
  1198. parent = wpa_s->parent;
  1199. if (parent->p2p_mgmt)
  1200. parent = parent->parent;
  1201. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1202. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
  1203. COMPACT_MACSTR,
  1204. parent->dbus_new_path, MAC2STR(peer_addr));
  1205. msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
  1206. WPAS_DBUS_NEW_IFACE_P2P_GROUP,
  1207. "PeerJoined");
  1208. if (msg == NULL)
  1209. return;
  1210. dbus_message_iter_init_append(msg, &iter);
  1211. path = peer_obj_path;
  1212. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  1213. &path)) {
  1214. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  1215. } else {
  1216. dbus_connection_send(iface->con, msg, NULL);
  1217. wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
  1218. }
  1219. dbus_message_unref(msg);
  1220. }
  1221. /**
  1222. *
  1223. * Method to emit a signal for a peer disconnecting the group.
  1224. * The signal will carry path to the group member object
  1225. * constructed using the P2P Device Address of the peer.
  1226. *
  1227. * @wpa_s: %wpa_supplicant network interface data
  1228. * @peer_addr: P2P Device Address of the peer joining the group
  1229. */
  1230. void wpas_dbus_signal_p2p_peer_disconnected(struct wpa_supplicant *wpa_s,
  1231. const u8 *peer_addr)
  1232. {
  1233. struct wpas_dbus_priv *iface;
  1234. DBusMessage *msg;
  1235. DBusMessageIter iter;
  1236. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  1237. struct wpa_supplicant *parent;
  1238. iface = wpa_s->global->dbus;
  1239. /* Do nothing if the control interface is not turned on */
  1240. if (iface == NULL)
  1241. return;
  1242. if (!wpa_s->dbus_groupobj_path)
  1243. return;
  1244. parent = wpa_s->parent;
  1245. if (parent->p2p_mgmt)
  1246. parent = parent->parent;
  1247. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1248. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
  1249. COMPACT_MACSTR,
  1250. parent->dbus_new_path, MAC2STR(peer_addr));
  1251. msg = dbus_message_new_signal(wpa_s->dbus_groupobj_path,
  1252. WPAS_DBUS_NEW_IFACE_P2P_GROUP,
  1253. "PeerDisconnected");
  1254. if (msg == NULL)
  1255. return;
  1256. dbus_message_iter_init_append(msg, &iter);
  1257. path = peer_obj_path;
  1258. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  1259. &path)) {
  1260. wpa_printf(MSG_ERROR,
  1261. "dbus: Failed to construct PeerDisconnected signal");
  1262. } else {
  1263. dbus_connection_send(iface->con, msg, NULL);
  1264. wpas_dbus_signal_peer_groups_changed(parent, peer_addr);
  1265. }
  1266. dbus_message_unref(msg);
  1267. }
  1268. /**
  1269. *
  1270. * Method to emit a signal for a service discovery request.
  1271. * The signal will carry station address, frequency, dialog token,
  1272. * update indicator and it tlvs
  1273. *
  1274. * @wpa_s: %wpa_supplicant network interface data
  1275. * @sa: station addr (p2p i/f) of the peer
  1276. * @dialog_token: service discovery request dialog token
  1277. * @update_indic: service discovery request update indicator
  1278. * @tlvs: service discovery request genrated byte array of tlvs
  1279. * @tlvs_len: service discovery request tlvs length
  1280. */
  1281. void wpas_dbus_signal_p2p_sd_request(struct wpa_supplicant *wpa_s,
  1282. int freq, const u8 *sa, u8 dialog_token,
  1283. u16 update_indic, const u8 *tlvs,
  1284. size_t tlvs_len)
  1285. {
  1286. DBusMessage *msg;
  1287. DBusMessageIter iter, dict_iter;
  1288. struct wpas_dbus_priv *iface;
  1289. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  1290. iface = wpa_s->global->dbus;
  1291. /* Do nothing if the control interface is not turned on */
  1292. if (iface == NULL)
  1293. return;
  1294. if (wpa_s->p2p_mgmt)
  1295. wpa_s = wpa_s->parent;
  1296. /* Check if this is a known peer */
  1297. if (!p2p_peer_known(wpa_s->global->p2p, sa))
  1298. return;
  1299. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  1300. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1301. "ServiceDiscoveryRequest");
  1302. if (msg == NULL)
  1303. return;
  1304. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1305. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
  1306. COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
  1307. path = peer_obj_path;
  1308. dbus_message_iter_init_append(msg, &iter);
  1309. if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  1310. !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
  1311. path) ||
  1312. !wpa_dbus_dict_append_int32(&dict_iter, "frequency", freq) ||
  1313. !wpa_dbus_dict_append_int32(&dict_iter, "dialog_token",
  1314. dialog_token) ||
  1315. !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
  1316. update_indic) ||
  1317. !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
  1318. (const char *) tlvs,
  1319. tlvs_len) ||
  1320. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  1321. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  1322. else
  1323. dbus_connection_send(iface->con, msg, NULL);
  1324. dbus_message_unref(msg);
  1325. }
  1326. /**
  1327. *
  1328. * Method to emit a signal for a service discovery response.
  1329. * The signal will carry station address, update indicator and it
  1330. * tlvs
  1331. *
  1332. * @wpa_s: %wpa_supplicant network interface data
  1333. * @sa: station addr (p2p i/f) of the peer
  1334. * @update_indic: service discovery request update indicator
  1335. * @tlvs: service discovery request genrated byte array of tlvs
  1336. * @tlvs_len: service discovery request tlvs length
  1337. */
  1338. void wpas_dbus_signal_p2p_sd_response(struct wpa_supplicant *wpa_s,
  1339. const u8 *sa, u16 update_indic,
  1340. const u8 *tlvs, size_t tlvs_len)
  1341. {
  1342. DBusMessage *msg;
  1343. DBusMessageIter iter, dict_iter;
  1344. struct wpas_dbus_priv *iface;
  1345. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  1346. iface = wpa_s->global->dbus;
  1347. /* Do nothing if the control interface is not turned on */
  1348. if (iface == NULL)
  1349. return;
  1350. if (wpa_s->p2p_mgmt)
  1351. wpa_s = wpa_s->parent;
  1352. /* Check if this is a known peer */
  1353. if (!p2p_peer_known(wpa_s->global->p2p, sa))
  1354. return;
  1355. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  1356. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1357. "ServiceDiscoveryResponse");
  1358. if (msg == NULL)
  1359. return;
  1360. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1361. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/"
  1362. COMPACT_MACSTR, wpa_s->dbus_new_path, MAC2STR(sa));
  1363. path = peer_obj_path;
  1364. dbus_message_iter_init_append(msg, &iter);
  1365. if (!wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  1366. !wpa_dbus_dict_append_object_path(&dict_iter, "peer_object",
  1367. path) ||
  1368. !wpa_dbus_dict_append_uint16(&dict_iter, "update_indicator",
  1369. update_indic) ||
  1370. !wpa_dbus_dict_append_byte_array(&dict_iter, "tlvs",
  1371. (const char *) tlvs,
  1372. tlvs_len) ||
  1373. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  1374. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  1375. else
  1376. dbus_connection_send(iface->con, msg, NULL);
  1377. dbus_message_unref(msg);
  1378. }
  1379. /**
  1380. * wpas_dbus_signal_persistent_group - Send a persistent group related
  1381. * event signal
  1382. * @wpa_s: %wpa_supplicant network interface data
  1383. * @id: new persistent group id
  1384. * @sig_name: signal name - PersistentGroupAdded, PersistentGroupRemoved
  1385. * @properties: determines if add second argument with object properties
  1386. *
  1387. * Notify listeners about an event related to persistent groups.
  1388. */
  1389. static void wpas_dbus_signal_persistent_group(struct wpa_supplicant *wpa_s,
  1390. int id, const char *sig_name,
  1391. int properties)
  1392. {
  1393. struct wpas_dbus_priv *iface;
  1394. DBusMessage *msg;
  1395. DBusMessageIter iter;
  1396. char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  1397. iface = wpa_s->global->dbus;
  1398. /* Do nothing if the control interface is not turned on */
  1399. if (iface == NULL)
  1400. return;
  1401. if (wpa_s->p2p_mgmt)
  1402. wpa_s = wpa_s->parent;
  1403. os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1404. "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
  1405. wpa_s->dbus_new_path, id);
  1406. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  1407. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1408. sig_name);
  1409. if (msg == NULL)
  1410. return;
  1411. dbus_message_iter_init_append(msg, &iter);
  1412. path = pgrp_obj_path;
  1413. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  1414. &path) ||
  1415. (properties &&
  1416. !wpa_dbus_get_object_properties(
  1417. iface, pgrp_obj_path,
  1418. WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, &iter)))
  1419. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  1420. else
  1421. dbus_connection_send(iface->con, msg, NULL);
  1422. dbus_message_unref(msg);
  1423. }
  1424. /**
  1425. * wpas_dbus_signal_persistent_group_added - Send a persistent_group
  1426. * added signal
  1427. * @wpa_s: %wpa_supplicant network interface data
  1428. * @id: new persistent group id
  1429. *
  1430. * Notify listeners about addition of a new persistent group.
  1431. */
  1432. static void wpas_dbus_signal_persistent_group_added(
  1433. struct wpa_supplicant *wpa_s, int id)
  1434. {
  1435. wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupAdded",
  1436. TRUE);
  1437. }
  1438. /**
  1439. * wpas_dbus_signal_persistent_group_removed - Send a persistent_group
  1440. * removed signal
  1441. * @wpa_s: %wpa_supplicant network interface data
  1442. * @id: persistent group id
  1443. *
  1444. * Notify listeners about removal of a persistent group.
  1445. */
  1446. static void wpas_dbus_signal_persistent_group_removed(
  1447. struct wpa_supplicant *wpa_s, int id)
  1448. {
  1449. wpas_dbus_signal_persistent_group(wpa_s, id, "PersistentGroupRemoved",
  1450. FALSE);
  1451. }
  1452. /**
  1453. * wpas_dbus_signal_p2p_wps_failed - Signals WpsFailed event
  1454. * @wpa_s: %wpa_supplicant network interface data
  1455. *
  1456. * Sends Event dbus signal with name "fail" and dictionary containing
  1457. * "msg" field with fail message number (int32) as arguments
  1458. */
  1459. void wpas_dbus_signal_p2p_wps_failed(struct wpa_supplicant *wpa_s,
  1460. struct wps_event_fail *fail)
  1461. {
  1462. DBusMessage *msg;
  1463. DBusMessageIter iter, dict_iter;
  1464. struct wpas_dbus_priv *iface;
  1465. char *key = "fail";
  1466. iface = wpa_s->global->dbus;
  1467. /* Do nothing if the control interface is not turned on */
  1468. if (iface == NULL)
  1469. return;
  1470. if (wpa_s->p2p_mgmt)
  1471. wpa_s = wpa_s->parent;
  1472. msg = dbus_message_new_signal(wpa_s->dbus_new_path,
  1473. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  1474. "WpsFailed");
  1475. if (msg == NULL)
  1476. return;
  1477. dbus_message_iter_init_append(msg, &iter);
  1478. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key) ||
  1479. !wpa_dbus_dict_open_write(&iter, &dict_iter) ||
  1480. !wpa_dbus_dict_append_int32(&dict_iter, "msg", fail->msg) ||
  1481. !wpa_dbus_dict_append_int16(&dict_iter, "config_error",
  1482. fail->config_error) ||
  1483. !wpa_dbus_dict_close_write(&iter, &dict_iter))
  1484. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  1485. else
  1486. dbus_connection_send(iface->con, msg, NULL);
  1487. dbus_message_unref(msg);
  1488. }
  1489. #endif /* CONFIG_P2P */
  1490. /**
  1491. * wpas_dbus_signal_prop_changed - Signals change of property
  1492. * @wpa_s: %wpa_supplicant network interface data
  1493. * @property: indicates which property has changed
  1494. *
  1495. * Sends PropertyChanged signals with path, interface and arguments
  1496. * depending on which property has changed.
  1497. */
  1498. void wpas_dbus_signal_prop_changed(struct wpa_supplicant *wpa_s,
  1499. enum wpas_dbus_prop property)
  1500. {
  1501. char *prop;
  1502. dbus_bool_t flush;
  1503. if (wpa_s->dbus_new_path == NULL)
  1504. return; /* Skip signal since D-Bus setup is not yet ready */
  1505. flush = FALSE;
  1506. switch (property) {
  1507. case WPAS_DBUS_PROP_AP_SCAN:
  1508. prop = "ApScan";
  1509. break;
  1510. case WPAS_DBUS_PROP_SCANNING:
  1511. prop = "Scanning";
  1512. break;
  1513. case WPAS_DBUS_PROP_STATE:
  1514. prop = "State";
  1515. break;
  1516. case WPAS_DBUS_PROP_CURRENT_BSS:
  1517. prop = "CurrentBSS";
  1518. break;
  1519. case WPAS_DBUS_PROP_CURRENT_NETWORK:
  1520. prop = "CurrentNetwork";
  1521. break;
  1522. case WPAS_DBUS_PROP_BSSS:
  1523. prop = "BSSs";
  1524. break;
  1525. case WPAS_DBUS_PROP_CURRENT_AUTH_MODE:
  1526. prop = "CurrentAuthMode";
  1527. break;
  1528. case WPAS_DBUS_PROP_DISCONNECT_REASON:
  1529. prop = "DisconnectReason";
  1530. flush = TRUE;
  1531. break;
  1532. default:
  1533. wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
  1534. __func__, property);
  1535. return;
  1536. }
  1537. wpa_dbus_mark_property_changed(wpa_s->global->dbus,
  1538. wpa_s->dbus_new_path,
  1539. WPAS_DBUS_NEW_IFACE_INTERFACE, prop);
  1540. if (flush) {
  1541. wpa_dbus_flush_object_changed_properties(
  1542. wpa_s->global->dbus->con, wpa_s->dbus_new_path);
  1543. }
  1544. }
  1545. /**
  1546. * wpas_dbus_bss_signal_prop_changed - Signals change of BSS property
  1547. * @wpa_s: %wpa_supplicant network interface data
  1548. * @property: indicates which property has changed
  1549. * @id: unique BSS identifier
  1550. *
  1551. * Sends PropertyChanged signals with path, interface, and arguments depending
  1552. * on which property has changed.
  1553. */
  1554. void wpas_dbus_bss_signal_prop_changed(struct wpa_supplicant *wpa_s,
  1555. enum wpas_dbus_bss_prop property,
  1556. unsigned int id)
  1557. {
  1558. char path[WPAS_DBUS_OBJECT_PATH_MAX];
  1559. char *prop;
  1560. switch (property) {
  1561. case WPAS_DBUS_BSS_PROP_SIGNAL:
  1562. prop = "Signal";
  1563. break;
  1564. case WPAS_DBUS_BSS_PROP_FREQ:
  1565. prop = "Frequency";
  1566. break;
  1567. case WPAS_DBUS_BSS_PROP_MODE:
  1568. prop = "Mode";
  1569. break;
  1570. case WPAS_DBUS_BSS_PROP_PRIVACY:
  1571. prop = "Privacy";
  1572. break;
  1573. case WPAS_DBUS_BSS_PROP_RATES:
  1574. prop = "Rates";
  1575. break;
  1576. case WPAS_DBUS_BSS_PROP_WPA:
  1577. prop = "WPA";
  1578. break;
  1579. case WPAS_DBUS_BSS_PROP_RSN:
  1580. prop = "RSN";
  1581. break;
  1582. case WPAS_DBUS_BSS_PROP_WPS:
  1583. prop = "WPS";
  1584. break;
  1585. case WPAS_DBUS_BSS_PROP_IES:
  1586. prop = "IEs";
  1587. break;
  1588. case WPAS_DBUS_BSS_PROP_AGE:
  1589. prop = "Age";
  1590. break;
  1591. default:
  1592. wpa_printf(MSG_ERROR, "dbus: %s: Unknown Property value %d",
  1593. __func__, property);
  1594. return;
  1595. }
  1596. os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
  1597. "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
  1598. wpa_s->dbus_new_path, id);
  1599. wpa_dbus_mark_property_changed(wpa_s->global->dbus, path,
  1600. WPAS_DBUS_NEW_IFACE_BSS, prop);
  1601. }
  1602. /**
  1603. * wpas_dbus_signal_debug_level_changed - Signals change of debug param
  1604. * @global: wpa_global structure
  1605. *
  1606. * Sends PropertyChanged signals informing that debug level has changed.
  1607. */
  1608. void wpas_dbus_signal_debug_level_changed(struct wpa_global *global)
  1609. {
  1610. wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
  1611. WPAS_DBUS_NEW_INTERFACE,
  1612. "DebugLevel");
  1613. }
  1614. /**
  1615. * wpas_dbus_signal_debug_timestamp_changed - Signals change of debug param
  1616. * @global: wpa_global structure
  1617. *
  1618. * Sends PropertyChanged signals informing that debug timestamp has changed.
  1619. */
  1620. void wpas_dbus_signal_debug_timestamp_changed(struct wpa_global *global)
  1621. {
  1622. wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
  1623. WPAS_DBUS_NEW_INTERFACE,
  1624. "DebugTimestamp");
  1625. }
  1626. /**
  1627. * wpas_dbus_signal_debug_show_keys_changed - Signals change of debug param
  1628. * @global: wpa_global structure
  1629. *
  1630. * Sends PropertyChanged signals informing that debug show_keys has changed.
  1631. */
  1632. void wpas_dbus_signal_debug_show_keys_changed(struct wpa_global *global)
  1633. {
  1634. wpa_dbus_mark_property_changed(global->dbus, WPAS_DBUS_NEW_PATH,
  1635. WPAS_DBUS_NEW_INTERFACE,
  1636. "DebugShowKeys");
  1637. }
  1638. static void wpas_dbus_register(struct wpa_dbus_object_desc *obj_desc,
  1639. void *priv,
  1640. WPADBusArgumentFreeFunction priv_free,
  1641. const struct wpa_dbus_method_desc *methods,
  1642. const struct wpa_dbus_property_desc *properties,
  1643. const struct wpa_dbus_signal_desc *signals)
  1644. {
  1645. int n;
  1646. obj_desc->user_data = priv;
  1647. obj_desc->user_data_free_func = priv_free;
  1648. obj_desc->methods = methods;
  1649. obj_desc->properties = properties;
  1650. obj_desc->signals = signals;
  1651. for (n = 0; properties && properties->dbus_property; properties++)
  1652. n++;
  1653. obj_desc->prop_changed_flags = os_zalloc(n);
  1654. if (!obj_desc->prop_changed_flags)
  1655. wpa_printf(MSG_DEBUG, "dbus: %s: can't register handlers",
  1656. __func__);
  1657. }
  1658. static const struct wpa_dbus_method_desc wpas_dbus_global_methods[] = {
  1659. { "CreateInterface", WPAS_DBUS_NEW_INTERFACE,
  1660. (WPADBusMethodHandler) wpas_dbus_handler_create_interface,
  1661. {
  1662. { "args", "a{sv}", ARG_IN },
  1663. { "path", "o", ARG_OUT },
  1664. END_ARGS
  1665. }
  1666. },
  1667. { "RemoveInterface", WPAS_DBUS_NEW_INTERFACE,
  1668. (WPADBusMethodHandler) wpas_dbus_handler_remove_interface,
  1669. {
  1670. { "path", "o", ARG_IN },
  1671. END_ARGS
  1672. }
  1673. },
  1674. { "GetInterface", WPAS_DBUS_NEW_INTERFACE,
  1675. (WPADBusMethodHandler) wpas_dbus_handler_get_interface,
  1676. {
  1677. { "ifname", "s", ARG_IN },
  1678. { "path", "o", ARG_OUT },
  1679. END_ARGS
  1680. }
  1681. },
  1682. { NULL, NULL, NULL, { END_ARGS } }
  1683. };
  1684. static const struct wpa_dbus_property_desc wpas_dbus_global_properties[] = {
  1685. { "DebugLevel", WPAS_DBUS_NEW_INTERFACE, "s",
  1686. wpas_dbus_getter_debug_level,
  1687. wpas_dbus_setter_debug_level
  1688. },
  1689. { "DebugTimestamp", WPAS_DBUS_NEW_INTERFACE, "b",
  1690. wpas_dbus_getter_debug_timestamp,
  1691. wpas_dbus_setter_debug_timestamp
  1692. },
  1693. { "DebugShowKeys", WPAS_DBUS_NEW_INTERFACE, "b",
  1694. wpas_dbus_getter_debug_show_keys,
  1695. wpas_dbus_setter_debug_show_keys
  1696. },
  1697. { "Interfaces", WPAS_DBUS_NEW_INTERFACE, "ao",
  1698. wpas_dbus_getter_interfaces,
  1699. NULL
  1700. },
  1701. { "EapMethods", WPAS_DBUS_NEW_INTERFACE, "as",
  1702. wpas_dbus_getter_eap_methods,
  1703. NULL
  1704. },
  1705. { "Capabilities", WPAS_DBUS_NEW_INTERFACE, "as",
  1706. wpas_dbus_getter_global_capabilities,
  1707. NULL
  1708. },
  1709. #ifdef CONFIG_WIFI_DISPLAY
  1710. { "WFDIEs", WPAS_DBUS_NEW_INTERFACE, "ay",
  1711. wpas_dbus_getter_global_wfd_ies,
  1712. wpas_dbus_setter_global_wfd_ies
  1713. },
  1714. #endif /* CONFIG_WIFI_DISPLAY */
  1715. { NULL, NULL, NULL, NULL, NULL }
  1716. };
  1717. static const struct wpa_dbus_signal_desc wpas_dbus_global_signals[] = {
  1718. { "InterfaceAdded", WPAS_DBUS_NEW_INTERFACE,
  1719. {
  1720. { "path", "o", ARG_OUT },
  1721. { "properties", "a{sv}", ARG_OUT },
  1722. END_ARGS
  1723. }
  1724. },
  1725. { "InterfaceRemoved", WPAS_DBUS_NEW_INTERFACE,
  1726. {
  1727. { "path", "o", ARG_OUT },
  1728. END_ARGS
  1729. }
  1730. },
  1731. /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
  1732. { "PropertiesChanged", WPAS_DBUS_NEW_INTERFACE,
  1733. {
  1734. { "properties", "a{sv}", ARG_OUT },
  1735. END_ARGS
  1736. }
  1737. },
  1738. { NULL, NULL, { END_ARGS } }
  1739. };
  1740. /**
  1741. * wpas_dbus_ctrl_iface_init - Initialize dbus control interface
  1742. * @global: Pointer to global data from wpa_supplicant_init()
  1743. * Returns: 0 on success or -1 on failure
  1744. *
  1745. * Initialize the dbus control interface for wpa_supplicantand and start
  1746. * receiving commands from external programs over the bus.
  1747. */
  1748. int wpas_dbus_ctrl_iface_init(struct wpas_dbus_priv *priv)
  1749. {
  1750. struct wpa_dbus_object_desc *obj_desc;
  1751. int ret;
  1752. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  1753. if (!obj_desc) {
  1754. wpa_printf(MSG_ERROR,
  1755. "Not enough memory to create object description");
  1756. return -1;
  1757. }
  1758. wpas_dbus_register(obj_desc, priv->global, NULL,
  1759. wpas_dbus_global_methods,
  1760. wpas_dbus_global_properties,
  1761. wpas_dbus_global_signals);
  1762. wpa_printf(MSG_DEBUG, "dbus: Register D-Bus object '%s'",
  1763. WPAS_DBUS_NEW_PATH);
  1764. ret = wpa_dbus_ctrl_iface_init(priv, WPAS_DBUS_NEW_PATH,
  1765. WPAS_DBUS_NEW_SERVICE,
  1766. obj_desc);
  1767. if (ret < 0)
  1768. free_dbus_object_desc(obj_desc);
  1769. else
  1770. priv->dbus_new_initialized = 1;
  1771. return ret;
  1772. }
  1773. /**
  1774. * wpas_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface for
  1775. * wpa_supplicant
  1776. * @iface: Pointer to dbus private data from wpas_dbus_init()
  1777. *
  1778. * Deinitialize the dbus control interface that was initialized with
  1779. * wpas_dbus_ctrl_iface_init().
  1780. */
  1781. void wpas_dbus_ctrl_iface_deinit(struct wpas_dbus_priv *iface)
  1782. {
  1783. if (!iface->dbus_new_initialized)
  1784. return;
  1785. wpa_printf(MSG_DEBUG, "dbus: Unregister D-Bus object '%s'",
  1786. WPAS_DBUS_NEW_PATH);
  1787. dbus_connection_unregister_object_path(iface->con,
  1788. WPAS_DBUS_NEW_PATH);
  1789. }
  1790. static void wpa_dbus_free(void *ptr)
  1791. {
  1792. os_free(ptr);
  1793. }
  1794. static const struct wpa_dbus_property_desc wpas_dbus_network_properties[] = {
  1795. { "Properties", WPAS_DBUS_NEW_IFACE_NETWORK, "a{sv}",
  1796. wpas_dbus_getter_network_properties,
  1797. wpas_dbus_setter_network_properties
  1798. },
  1799. { "Enabled", WPAS_DBUS_NEW_IFACE_NETWORK, "b",
  1800. wpas_dbus_getter_enabled,
  1801. wpas_dbus_setter_enabled
  1802. },
  1803. { NULL, NULL, NULL, NULL, NULL }
  1804. };
  1805. static const struct wpa_dbus_signal_desc wpas_dbus_network_signals[] = {
  1806. /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
  1807. { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_NETWORK,
  1808. {
  1809. { "properties", "a{sv}", ARG_OUT },
  1810. END_ARGS
  1811. }
  1812. },
  1813. { NULL, NULL, { END_ARGS } }
  1814. };
  1815. /**
  1816. * wpas_dbus_register_network - Register a configured network with dbus
  1817. * @wpa_s: wpa_supplicant interface structure
  1818. * @ssid: network configuration data
  1819. * Returns: 0 on success, -1 on failure
  1820. *
  1821. * Registers network representing object with dbus
  1822. */
  1823. int wpas_dbus_register_network(struct wpa_supplicant *wpa_s,
  1824. struct wpa_ssid *ssid)
  1825. {
  1826. struct wpas_dbus_priv *ctrl_iface;
  1827. struct wpa_dbus_object_desc *obj_desc;
  1828. struct network_handler_args *arg;
  1829. char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  1830. #ifdef CONFIG_P2P
  1831. /*
  1832. * If it is a persistent group register it as such.
  1833. * This is to handle cases where an interface is being initialized
  1834. * with a list of networks read from config.
  1835. */
  1836. if (network_is_persistent_group(ssid))
  1837. return wpas_dbus_register_persistent_group(wpa_s, ssid);
  1838. #endif /* CONFIG_P2P */
  1839. /* Do nothing if the control interface is not turned on */
  1840. if (wpa_s == NULL || wpa_s->global == NULL)
  1841. return 0;
  1842. ctrl_iface = wpa_s->global->dbus;
  1843. if (ctrl_iface == NULL)
  1844. return 0;
  1845. os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1846. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
  1847. wpa_s->dbus_new_path, ssid->id);
  1848. wpa_printf(MSG_DEBUG, "dbus: Register network object '%s'",
  1849. net_obj_path);
  1850. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  1851. if (!obj_desc) {
  1852. wpa_printf(MSG_ERROR,
  1853. "Not enough memory to create object description");
  1854. goto err;
  1855. }
  1856. /* allocate memory for handlers arguments */
  1857. arg = os_zalloc(sizeof(struct network_handler_args));
  1858. if (!arg) {
  1859. wpa_printf(MSG_ERROR,
  1860. "Not enough memory to create arguments for method");
  1861. goto err;
  1862. }
  1863. arg->wpa_s = wpa_s;
  1864. arg->ssid = ssid;
  1865. wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
  1866. wpas_dbus_network_properties,
  1867. wpas_dbus_network_signals);
  1868. if (wpa_dbus_register_object_per_iface(ctrl_iface, net_obj_path,
  1869. wpa_s->ifname, obj_desc))
  1870. goto err;
  1871. wpas_dbus_signal_network_added(wpa_s, ssid->id);
  1872. return 0;
  1873. err:
  1874. free_dbus_object_desc(obj_desc);
  1875. return -1;
  1876. }
  1877. /**
  1878. * wpas_dbus_unregister_network - Unregister a configured network from dbus
  1879. * @wpa_s: wpa_supplicant interface structure
  1880. * @nid: network id
  1881. * Returns: 0 on success, -1 on failure
  1882. *
  1883. * Unregisters network representing object from dbus
  1884. */
  1885. int wpas_dbus_unregister_network(struct wpa_supplicant *wpa_s, int nid)
  1886. {
  1887. struct wpas_dbus_priv *ctrl_iface;
  1888. char net_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  1889. int ret;
  1890. #ifdef CONFIG_P2P
  1891. struct wpa_ssid *ssid;
  1892. ssid = wpa_config_get_network(wpa_s->conf, nid);
  1893. /* If it is a persistent group unregister it as such */
  1894. if (ssid && network_is_persistent_group(ssid))
  1895. return wpas_dbus_unregister_persistent_group(wpa_s, nid);
  1896. #endif /* CONFIG_P2P */
  1897. /* Do nothing if the control interface is not turned on */
  1898. if (wpa_s->global == NULL || wpa_s->dbus_new_path == NULL)
  1899. return 0;
  1900. ctrl_iface = wpa_s->global->dbus;
  1901. if (ctrl_iface == NULL)
  1902. return 0;
  1903. os_snprintf(net_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1904. "%s/" WPAS_DBUS_NEW_NETWORKS_PART "/%u",
  1905. wpa_s->dbus_new_path, nid);
  1906. wpa_printf(MSG_DEBUG, "dbus: Unregister network object '%s'",
  1907. net_obj_path);
  1908. ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, net_obj_path);
  1909. if (!ret)
  1910. wpas_dbus_signal_network_removed(wpa_s, nid);
  1911. return ret;
  1912. }
  1913. static const struct wpa_dbus_property_desc wpas_dbus_bss_properties[] = {
  1914. { "SSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
  1915. wpas_dbus_getter_bss_ssid,
  1916. NULL
  1917. },
  1918. { "BSSID", WPAS_DBUS_NEW_IFACE_BSS, "ay",
  1919. wpas_dbus_getter_bss_bssid,
  1920. NULL
  1921. },
  1922. { "Privacy", WPAS_DBUS_NEW_IFACE_BSS, "b",
  1923. wpas_dbus_getter_bss_privacy,
  1924. NULL
  1925. },
  1926. { "Mode", WPAS_DBUS_NEW_IFACE_BSS, "s",
  1927. wpas_dbus_getter_bss_mode,
  1928. NULL
  1929. },
  1930. { "Signal", WPAS_DBUS_NEW_IFACE_BSS, "n",
  1931. wpas_dbus_getter_bss_signal,
  1932. NULL
  1933. },
  1934. { "Frequency", WPAS_DBUS_NEW_IFACE_BSS, "q",
  1935. wpas_dbus_getter_bss_frequency,
  1936. NULL
  1937. },
  1938. { "Rates", WPAS_DBUS_NEW_IFACE_BSS, "au",
  1939. wpas_dbus_getter_bss_rates,
  1940. NULL
  1941. },
  1942. { "WPA", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
  1943. wpas_dbus_getter_bss_wpa,
  1944. NULL
  1945. },
  1946. { "RSN", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
  1947. wpas_dbus_getter_bss_rsn,
  1948. NULL
  1949. },
  1950. { "WPS", WPAS_DBUS_NEW_IFACE_BSS, "a{sv}",
  1951. wpas_dbus_getter_bss_wps,
  1952. NULL
  1953. },
  1954. { "IEs", WPAS_DBUS_NEW_IFACE_BSS, "ay",
  1955. wpas_dbus_getter_bss_ies,
  1956. NULL
  1957. },
  1958. { "Age", WPAS_DBUS_NEW_IFACE_BSS, "u",
  1959. wpas_dbus_getter_bss_age,
  1960. NULL
  1961. },
  1962. { NULL, NULL, NULL, NULL, NULL }
  1963. };
  1964. static const struct wpa_dbus_signal_desc wpas_dbus_bss_signals[] = {
  1965. /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
  1966. { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_BSS,
  1967. {
  1968. { "properties", "a{sv}", ARG_OUT },
  1969. END_ARGS
  1970. }
  1971. },
  1972. { NULL, NULL, { END_ARGS } }
  1973. };
  1974. /**
  1975. * wpas_dbus_unregister_bss - Unregister a scanned BSS from dbus
  1976. * @wpa_s: wpa_supplicant interface structure
  1977. * @bssid: scanned network bssid
  1978. * @id: unique BSS identifier
  1979. * Returns: 0 on success, -1 on failure
  1980. *
  1981. * Unregisters BSS representing object from dbus
  1982. */
  1983. int wpas_dbus_unregister_bss(struct wpa_supplicant *wpa_s,
  1984. u8 bssid[ETH_ALEN], unsigned int id)
  1985. {
  1986. struct wpas_dbus_priv *ctrl_iface;
  1987. char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  1988. /* Do nothing if the control interface is not turned on */
  1989. if (wpa_s == NULL || wpa_s->global == NULL)
  1990. return 0;
  1991. ctrl_iface = wpa_s->global->dbus;
  1992. if (ctrl_iface == NULL)
  1993. return 0;
  1994. os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  1995. "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
  1996. wpa_s->dbus_new_path, id);
  1997. wpa_printf(MSG_DEBUG, "dbus: Unregister BSS object '%s'",
  1998. bss_obj_path);
  1999. if (wpa_dbus_unregister_object_per_iface(ctrl_iface, bss_obj_path)) {
  2000. wpa_printf(MSG_ERROR, "dbus: Cannot unregister BSS object %s",
  2001. bss_obj_path);
  2002. return -1;
  2003. }
  2004. wpas_dbus_signal_bss_removed(wpa_s, bss_obj_path);
  2005. wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
  2006. return 0;
  2007. }
  2008. /**
  2009. * wpas_dbus_register_bss - Register a scanned BSS with dbus
  2010. * @wpa_s: wpa_supplicant interface structure
  2011. * @bssid: scanned network bssid
  2012. * @id: unique BSS identifier
  2013. * Returns: 0 on success, -1 on failure
  2014. *
  2015. * Registers BSS representing object with dbus
  2016. */
  2017. int wpas_dbus_register_bss(struct wpa_supplicant *wpa_s,
  2018. u8 bssid[ETH_ALEN], unsigned int id)
  2019. {
  2020. struct wpas_dbus_priv *ctrl_iface;
  2021. struct wpa_dbus_object_desc *obj_desc;
  2022. char bss_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  2023. struct bss_handler_args *arg;
  2024. /* Do nothing if the control interface is not turned on */
  2025. if (wpa_s == NULL || wpa_s->global == NULL)
  2026. return 0;
  2027. ctrl_iface = wpa_s->global->dbus;
  2028. if (ctrl_iface == NULL)
  2029. return 0;
  2030. os_snprintf(bss_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  2031. "%s/" WPAS_DBUS_NEW_BSSIDS_PART "/%u",
  2032. wpa_s->dbus_new_path, id);
  2033. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  2034. if (!obj_desc) {
  2035. wpa_printf(MSG_ERROR,
  2036. "Not enough memory to create object description");
  2037. goto err;
  2038. }
  2039. arg = os_zalloc(sizeof(struct bss_handler_args));
  2040. if (!arg) {
  2041. wpa_printf(MSG_ERROR,
  2042. "Not enough memory to create arguments for handler");
  2043. goto err;
  2044. }
  2045. arg->wpa_s = wpa_s;
  2046. arg->id = id;
  2047. wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
  2048. wpas_dbus_bss_properties,
  2049. wpas_dbus_bss_signals);
  2050. wpa_printf(MSG_DEBUG, "dbus: Register BSS object '%s'",
  2051. bss_obj_path);
  2052. if (wpa_dbus_register_object_per_iface(ctrl_iface, bss_obj_path,
  2053. wpa_s->ifname, obj_desc)) {
  2054. wpa_printf(MSG_ERROR,
  2055. "Cannot register BSSID dbus object %s.",
  2056. bss_obj_path);
  2057. goto err;
  2058. }
  2059. wpas_dbus_signal_bss_added(wpa_s, bss_obj_path);
  2060. wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSSS);
  2061. return 0;
  2062. err:
  2063. free_dbus_object_desc(obj_desc);
  2064. return -1;
  2065. }
  2066. static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
  2067. { "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2068. (WPADBusMethodHandler) wpas_dbus_handler_scan,
  2069. {
  2070. { "args", "a{sv}", ARG_IN },
  2071. END_ARGS
  2072. }
  2073. },
  2074. { "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2075. (WPADBusMethodHandler) wpas_dbus_handler_signal_poll,
  2076. {
  2077. { "args", "a{sv}", ARG_OUT },
  2078. END_ARGS
  2079. }
  2080. },
  2081. { "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2082. (WPADBusMethodHandler) wpas_dbus_handler_disconnect,
  2083. {
  2084. END_ARGS
  2085. }
  2086. },
  2087. { "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2088. (WPADBusMethodHandler) wpas_dbus_handler_add_network,
  2089. {
  2090. { "args", "a{sv}", ARG_IN },
  2091. { "path", "o", ARG_OUT },
  2092. END_ARGS
  2093. }
  2094. },
  2095. { "Reassociate", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2096. (WPADBusMethodHandler) wpas_dbus_handler_reassociate,
  2097. {
  2098. END_ARGS
  2099. }
  2100. },
  2101. { "Reattach", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2102. (WPADBusMethodHandler) wpas_dbus_handler_reattach,
  2103. {
  2104. END_ARGS
  2105. }
  2106. },
  2107. { "RemoveNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2108. (WPADBusMethodHandler) wpas_dbus_handler_remove_network,
  2109. {
  2110. { "path", "o", ARG_IN },
  2111. END_ARGS
  2112. }
  2113. },
  2114. { "RemoveAllNetworks", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2115. (WPADBusMethodHandler) wpas_dbus_handler_remove_all_networks,
  2116. {
  2117. END_ARGS
  2118. }
  2119. },
  2120. { "SelectNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2121. (WPADBusMethodHandler) wpas_dbus_handler_select_network,
  2122. {
  2123. { "path", "o", ARG_IN },
  2124. END_ARGS
  2125. }
  2126. },
  2127. { "NetworkReply", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2128. (WPADBusMethodHandler) wpas_dbus_handler_network_reply,
  2129. {
  2130. { "path", "o", ARG_IN },
  2131. { "field", "s", ARG_IN },
  2132. { "value", "s", ARG_IN },
  2133. END_ARGS
  2134. }
  2135. },
  2136. #ifndef CONFIG_NO_CONFIG_BLOBS
  2137. { "AddBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2138. (WPADBusMethodHandler) wpas_dbus_handler_add_blob,
  2139. {
  2140. { "name", "s", ARG_IN },
  2141. { "data", "ay", ARG_IN },
  2142. END_ARGS
  2143. }
  2144. },
  2145. { "GetBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2146. (WPADBusMethodHandler) wpas_dbus_handler_get_blob,
  2147. {
  2148. { "name", "s", ARG_IN },
  2149. { "data", "ay", ARG_OUT },
  2150. END_ARGS
  2151. }
  2152. },
  2153. { "RemoveBlob", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2154. (WPADBusMethodHandler) wpas_dbus_handler_remove_blob,
  2155. {
  2156. { "name", "s", ARG_IN },
  2157. END_ARGS
  2158. }
  2159. },
  2160. #endif /* CONFIG_NO_CONFIG_BLOBS */
  2161. { "SetPKCS11EngineAndModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2162. (WPADBusMethodHandler)
  2163. wpas_dbus_handler_set_pkcs11_engine_and_module_path,
  2164. {
  2165. { "pkcs11_engine_path", "s", ARG_IN },
  2166. { "pkcs11_module_path", "s", ARG_IN },
  2167. END_ARGS
  2168. }
  2169. },
  2170. #ifdef CONFIG_WPS
  2171. { "Start", WPAS_DBUS_NEW_IFACE_WPS,
  2172. (WPADBusMethodHandler) wpas_dbus_handler_wps_start,
  2173. {
  2174. { "args", "a{sv}", ARG_IN },
  2175. { "output", "a{sv}", ARG_OUT },
  2176. END_ARGS
  2177. }
  2178. },
  2179. #endif /* CONFIG_WPS */
  2180. #ifdef CONFIG_P2P
  2181. { "Find", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2182. (WPADBusMethodHandler) wpas_dbus_handler_p2p_find,
  2183. {
  2184. { "args", "a{sv}", ARG_IN },
  2185. END_ARGS
  2186. }
  2187. },
  2188. { "StopFind", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2189. (WPADBusMethodHandler) wpas_dbus_handler_p2p_stop_find,
  2190. {
  2191. END_ARGS
  2192. }
  2193. },
  2194. { "Listen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2195. (WPADBusMethodHandler) wpas_dbus_handler_p2p_listen,
  2196. {
  2197. { "timeout", "i", ARG_IN },
  2198. END_ARGS
  2199. }
  2200. },
  2201. { "ExtendedListen", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2202. (WPADBusMethodHandler) wpas_dbus_handler_p2p_extendedlisten,
  2203. {
  2204. { "args", "a{sv}", ARG_IN },
  2205. END_ARGS
  2206. }
  2207. },
  2208. { "PresenceRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2209. (WPADBusMethodHandler) wpas_dbus_handler_p2p_presence_request,
  2210. {
  2211. { "args", "a{sv}", ARG_IN },
  2212. END_ARGS
  2213. }
  2214. },
  2215. { "ProvisionDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2216. (WPADBusMethodHandler) wpas_dbus_handler_p2p_prov_disc_req,
  2217. {
  2218. { "peer", "o", ARG_IN },
  2219. { "config_method", "s", ARG_IN },
  2220. END_ARGS
  2221. }
  2222. },
  2223. { "Connect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2224. (WPADBusMethodHandler) wpas_dbus_handler_p2p_connect,
  2225. {
  2226. { "args", "a{sv}", ARG_IN },
  2227. { "generated_pin", "s", ARG_OUT },
  2228. END_ARGS
  2229. }
  2230. },
  2231. { "GroupAdd", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2232. (WPADBusMethodHandler) wpas_dbus_handler_p2p_group_add,
  2233. {
  2234. { "args", "a{sv}", ARG_IN },
  2235. END_ARGS
  2236. }
  2237. },
  2238. { "Invite", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2239. (WPADBusMethodHandler) wpas_dbus_handler_p2p_invite,
  2240. {
  2241. { "args", "a{sv}", ARG_IN },
  2242. END_ARGS
  2243. }
  2244. },
  2245. { "Disconnect", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2246. (WPADBusMethodHandler) wpas_dbus_handler_p2p_disconnect,
  2247. {
  2248. END_ARGS
  2249. }
  2250. },
  2251. { "RejectPeer", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2252. (WPADBusMethodHandler) wpas_dbus_handler_p2p_rejectpeer,
  2253. {
  2254. { "peer", "o", ARG_IN },
  2255. END_ARGS
  2256. }
  2257. },
  2258. { "Flush", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2259. (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush,
  2260. {
  2261. END_ARGS
  2262. }
  2263. },
  2264. { "AddService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2265. (WPADBusMethodHandler) wpas_dbus_handler_p2p_add_service,
  2266. {
  2267. { "args", "a{sv}", ARG_IN },
  2268. END_ARGS
  2269. }
  2270. },
  2271. { "DeleteService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2272. (WPADBusMethodHandler) wpas_dbus_handler_p2p_delete_service,
  2273. {
  2274. { "args", "a{sv}", ARG_IN },
  2275. END_ARGS
  2276. }
  2277. },
  2278. { "FlushService", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2279. (WPADBusMethodHandler) wpas_dbus_handler_p2p_flush_service,
  2280. {
  2281. END_ARGS
  2282. }
  2283. },
  2284. { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2285. (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_req,
  2286. {
  2287. { "args", "a{sv}", ARG_IN },
  2288. { "ref", "t", ARG_OUT },
  2289. END_ARGS
  2290. }
  2291. },
  2292. { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2293. (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_res,
  2294. {
  2295. { "args", "a{sv}", ARG_IN },
  2296. END_ARGS
  2297. }
  2298. },
  2299. { "ServiceDiscoveryCancelRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2300. (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_sd_cancel_req,
  2301. {
  2302. { "args", "t", ARG_IN },
  2303. END_ARGS
  2304. }
  2305. },
  2306. { "ServiceUpdate", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2307. (WPADBusMethodHandler) wpas_dbus_handler_p2p_service_update,
  2308. {
  2309. END_ARGS
  2310. }
  2311. },
  2312. { "ServiceDiscoveryExternal", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2313. (WPADBusMethodHandler) wpas_dbus_handler_p2p_serv_disc_external,
  2314. {
  2315. { "arg", "i", ARG_IN },
  2316. END_ARGS
  2317. }
  2318. },
  2319. { "AddPersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2320. (WPADBusMethodHandler) wpas_dbus_handler_add_persistent_group,
  2321. {
  2322. { "args", "a{sv}", ARG_IN },
  2323. { "path", "o", ARG_OUT },
  2324. END_ARGS
  2325. }
  2326. },
  2327. { "RemovePersistentGroup", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2328. (WPADBusMethodHandler) wpas_dbus_handler_remove_persistent_group,
  2329. {
  2330. { "path", "o", ARG_IN },
  2331. END_ARGS
  2332. }
  2333. },
  2334. { "RemoveAllPersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2335. (WPADBusMethodHandler)
  2336. wpas_dbus_handler_remove_all_persistent_groups,
  2337. {
  2338. END_ARGS
  2339. }
  2340. },
  2341. #endif /* CONFIG_P2P */
  2342. { "FlushBSS", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2343. (WPADBusMethodHandler) wpas_dbus_handler_flush_bss,
  2344. {
  2345. { "age", "u", ARG_IN },
  2346. END_ARGS
  2347. }
  2348. },
  2349. #ifdef CONFIG_AP
  2350. { "SubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2351. (WPADBusMethodHandler) wpas_dbus_handler_subscribe_preq,
  2352. {
  2353. END_ARGS
  2354. }
  2355. },
  2356. { "UnsubscribeProbeReq", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2357. (WPADBusMethodHandler) wpas_dbus_handler_unsubscribe_preq,
  2358. {
  2359. END_ARGS
  2360. }
  2361. },
  2362. #endif /* CONFIG_AP */
  2363. { "EAPLogoff", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2364. (WPADBusMethodHandler) wpas_dbus_handler_eap_logoff,
  2365. {
  2366. END_ARGS
  2367. }
  2368. },
  2369. { "EAPLogon", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2370. (WPADBusMethodHandler) wpas_dbus_handler_eap_logon,
  2371. {
  2372. END_ARGS
  2373. }
  2374. },
  2375. #ifdef CONFIG_AUTOSCAN
  2376. { "AutoScan", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2377. (WPADBusMethodHandler) wpas_dbus_handler_autoscan,
  2378. {
  2379. { "arg", "s", ARG_IN },
  2380. END_ARGS
  2381. }
  2382. },
  2383. #endif /* CONFIG_AUTOSCAN */
  2384. #ifdef CONFIG_TDLS
  2385. { "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2386. (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover,
  2387. {
  2388. { "peer_address", "s", ARG_IN },
  2389. END_ARGS
  2390. }
  2391. },
  2392. { "TDLSSetup", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2393. (WPADBusMethodHandler) wpas_dbus_handler_tdls_setup,
  2394. {
  2395. { "peer_address", "s", ARG_IN },
  2396. END_ARGS
  2397. }
  2398. },
  2399. { "TDLSStatus", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2400. (WPADBusMethodHandler) wpas_dbus_handler_tdls_status,
  2401. {
  2402. { "peer_address", "s", ARG_IN },
  2403. { "status", "s", ARG_OUT },
  2404. END_ARGS
  2405. }
  2406. },
  2407. { "TDLSTeardown", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2408. (WPADBusMethodHandler) wpas_dbus_handler_tdls_teardown,
  2409. {
  2410. { "peer_address", "s", ARG_IN },
  2411. END_ARGS
  2412. }
  2413. },
  2414. #endif /* CONFIG_TDLS */
  2415. { NULL, NULL, NULL, { END_ARGS } }
  2416. };
  2417. static const struct wpa_dbus_property_desc wpas_dbus_interface_properties[] = {
  2418. { "Capabilities", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{sv}",
  2419. wpas_dbus_getter_capabilities,
  2420. NULL
  2421. },
  2422. { "State", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  2423. wpas_dbus_getter_state,
  2424. NULL
  2425. },
  2426. { "Scanning", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
  2427. wpas_dbus_getter_scanning,
  2428. NULL
  2429. },
  2430. { "ApScan", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
  2431. wpas_dbus_getter_ap_scan,
  2432. wpas_dbus_setter_ap_scan
  2433. },
  2434. { "BSSExpireAge", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
  2435. wpas_dbus_getter_bss_expire_age,
  2436. wpas_dbus_setter_bss_expire_age
  2437. },
  2438. { "BSSExpireCount", WPAS_DBUS_NEW_IFACE_INTERFACE, "u",
  2439. wpas_dbus_getter_bss_expire_count,
  2440. wpas_dbus_setter_bss_expire_count
  2441. },
  2442. { "Country", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  2443. wpas_dbus_getter_country,
  2444. wpas_dbus_setter_country
  2445. },
  2446. { "Ifname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  2447. wpas_dbus_getter_ifname,
  2448. NULL
  2449. },
  2450. { "Driver", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  2451. wpas_dbus_getter_driver,
  2452. NULL
  2453. },
  2454. { "BridgeIfname", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  2455. wpas_dbus_getter_bridge_ifname,
  2456. NULL
  2457. },
  2458. { "CurrentBSS", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
  2459. wpas_dbus_getter_current_bss,
  2460. NULL
  2461. },
  2462. { "CurrentNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE, "o",
  2463. wpas_dbus_getter_current_network,
  2464. NULL
  2465. },
  2466. { "CurrentAuthMode", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  2467. wpas_dbus_getter_current_auth_mode,
  2468. NULL
  2469. },
  2470. { "Blobs", WPAS_DBUS_NEW_IFACE_INTERFACE, "a{say}",
  2471. wpas_dbus_getter_blobs,
  2472. NULL
  2473. },
  2474. { "BSSs", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
  2475. wpas_dbus_getter_bsss,
  2476. NULL
  2477. },
  2478. { "Networks", WPAS_DBUS_NEW_IFACE_INTERFACE, "ao",
  2479. wpas_dbus_getter_networks,
  2480. NULL
  2481. },
  2482. { "FastReauth", WPAS_DBUS_NEW_IFACE_INTERFACE, "b",
  2483. wpas_dbus_getter_fast_reauth,
  2484. wpas_dbus_setter_fast_reauth
  2485. },
  2486. { "ScanInterval", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
  2487. wpas_dbus_getter_scan_interval,
  2488. wpas_dbus_setter_scan_interval
  2489. },
  2490. { "PKCS11EnginePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  2491. wpas_dbus_getter_pkcs11_engine_path,
  2492. NULL
  2493. },
  2494. { "PKCS11ModulePath", WPAS_DBUS_NEW_IFACE_INTERFACE, "s",
  2495. wpas_dbus_getter_pkcs11_module_path,
  2496. NULL
  2497. },
  2498. #ifdef CONFIG_WPS
  2499. { "ProcessCredentials", WPAS_DBUS_NEW_IFACE_WPS, "b",
  2500. wpas_dbus_getter_process_credentials,
  2501. wpas_dbus_setter_process_credentials
  2502. },
  2503. { "ConfigMethods", WPAS_DBUS_NEW_IFACE_WPS, "s",
  2504. wpas_dbus_getter_config_methods,
  2505. wpas_dbus_setter_config_methods
  2506. },
  2507. #endif /* CONFIG_WPS */
  2508. #ifdef CONFIG_P2P
  2509. { "P2PDeviceConfig", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "a{sv}",
  2510. wpas_dbus_getter_p2p_device_config,
  2511. wpas_dbus_setter_p2p_device_config
  2512. },
  2513. { "Peers", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
  2514. wpas_dbus_getter_p2p_peers,
  2515. NULL
  2516. },
  2517. { "Role", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "s",
  2518. wpas_dbus_getter_p2p_role,
  2519. NULL
  2520. },
  2521. { "Group", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
  2522. wpas_dbus_getter_p2p_group,
  2523. NULL
  2524. },
  2525. { "PeerGO", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "o",
  2526. wpas_dbus_getter_p2p_peergo,
  2527. NULL
  2528. },
  2529. { "PersistentGroups", WPAS_DBUS_NEW_IFACE_P2PDEVICE, "ao",
  2530. wpas_dbus_getter_persistent_groups,
  2531. NULL
  2532. },
  2533. #endif /* CONFIG_P2P */
  2534. { "DisconnectReason", WPAS_DBUS_NEW_IFACE_INTERFACE, "i",
  2535. wpas_dbus_getter_disconnect_reason,
  2536. NULL
  2537. },
  2538. { NULL, NULL, NULL, NULL, NULL }
  2539. };
  2540. static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = {
  2541. { "ScanDone", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2542. {
  2543. { "success", "b", ARG_OUT },
  2544. END_ARGS
  2545. }
  2546. },
  2547. { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2548. {
  2549. { "path", "o", ARG_OUT },
  2550. { "properties", "a{sv}", ARG_OUT },
  2551. END_ARGS
  2552. }
  2553. },
  2554. { "BSSRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2555. {
  2556. { "path", "o", ARG_OUT },
  2557. END_ARGS
  2558. }
  2559. },
  2560. { "BlobAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2561. {
  2562. { "name", "s", ARG_OUT },
  2563. END_ARGS
  2564. }
  2565. },
  2566. { "BlobRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2567. {
  2568. { "name", "s", ARG_OUT },
  2569. END_ARGS
  2570. }
  2571. },
  2572. { "NetworkAdded", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2573. {
  2574. { "path", "o", ARG_OUT },
  2575. { "properties", "a{sv}", ARG_OUT },
  2576. END_ARGS
  2577. }
  2578. },
  2579. { "NetworkRemoved", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2580. {
  2581. { "path", "o", ARG_OUT },
  2582. END_ARGS
  2583. }
  2584. },
  2585. { "NetworkSelected", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2586. {
  2587. { "path", "o", ARG_OUT },
  2588. END_ARGS
  2589. }
  2590. },
  2591. /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
  2592. { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2593. {
  2594. { "properties", "a{sv}", ARG_OUT },
  2595. END_ARGS
  2596. }
  2597. },
  2598. #ifdef CONFIG_WPS
  2599. { "Event", WPAS_DBUS_NEW_IFACE_WPS,
  2600. {
  2601. { "name", "s", ARG_OUT },
  2602. { "args", "a{sv}", ARG_OUT },
  2603. END_ARGS
  2604. }
  2605. },
  2606. { "Credentials", WPAS_DBUS_NEW_IFACE_WPS,
  2607. {
  2608. { "credentials", "a{sv}", ARG_OUT },
  2609. END_ARGS
  2610. }
  2611. },
  2612. /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
  2613. { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_WPS,
  2614. {
  2615. { "properties", "a{sv}", ARG_OUT },
  2616. END_ARGS
  2617. }
  2618. },
  2619. #endif /* CONFIG_WPS */
  2620. #ifdef CONFIG_P2P
  2621. { "DeviceFound", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2622. {
  2623. { "path", "o", ARG_OUT },
  2624. END_ARGS
  2625. }
  2626. },
  2627. { "DeviceLost", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2628. {
  2629. { "path", "o", ARG_OUT },
  2630. END_ARGS
  2631. }
  2632. },
  2633. { "ProvisionDiscoveryRequestDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2634. {
  2635. { "peer_object", "o", ARG_OUT },
  2636. { "pin", "s", ARG_OUT },
  2637. END_ARGS
  2638. }
  2639. },
  2640. { "ProvisionDiscoveryResponseDisplayPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2641. {
  2642. { "peer_object", "o", ARG_OUT },
  2643. { "pin", "s", ARG_OUT },
  2644. END_ARGS
  2645. }
  2646. },
  2647. { "ProvisionDiscoveryRequestEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2648. {
  2649. { "peer_object", "o", ARG_OUT },
  2650. END_ARGS
  2651. }
  2652. },
  2653. { "ProvisionDiscoveryResponseEnterPin", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2654. {
  2655. { "peer_object", "o", ARG_OUT },
  2656. END_ARGS
  2657. }
  2658. },
  2659. { "ProvisionDiscoveryPBCRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2660. {
  2661. { "peer_object", "o", ARG_OUT },
  2662. END_ARGS
  2663. }
  2664. },
  2665. { "ProvisionDiscoveryPBCResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2666. {
  2667. { "peer_object", "o", ARG_OUT },
  2668. END_ARGS
  2669. }
  2670. },
  2671. { "ProvisionDiscoveryFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2672. {
  2673. { "peer_object", "o", ARG_OUT },
  2674. { "status", "i", ARG_OUT },
  2675. END_ARGS
  2676. }
  2677. },
  2678. { "GroupStarted", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2679. {
  2680. { "properties", "a{sv}", ARG_OUT },
  2681. END_ARGS
  2682. }
  2683. },
  2684. { "GONegotiationSuccess", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2685. {
  2686. { "properties", "a{sv}", ARG_OUT },
  2687. END_ARGS
  2688. }
  2689. },
  2690. { "GONegotiationFailure", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2691. {
  2692. { "properties", "a{sv}", ARG_OUT },
  2693. END_ARGS
  2694. }
  2695. },
  2696. { "GONegotiationRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2697. {
  2698. { "path", "o", ARG_OUT },
  2699. { "dev_passwd_id", "i", ARG_OUT },
  2700. END_ARGS
  2701. }
  2702. },
  2703. { "InvitationResult", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2704. {
  2705. { "invite_result", "a{sv}", ARG_OUT },
  2706. END_ARGS
  2707. }
  2708. },
  2709. { "GroupFinished", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2710. {
  2711. { "properties", "a{sv}", ARG_OUT },
  2712. END_ARGS
  2713. }
  2714. },
  2715. { "ServiceDiscoveryRequest", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2716. {
  2717. { "sd_request", "a{sv}", ARG_OUT },
  2718. END_ARGS
  2719. }
  2720. },
  2721. { "ServiceDiscoveryResponse", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2722. {
  2723. { "sd_response", "a{sv}", ARG_OUT },
  2724. END_ARGS
  2725. }
  2726. },
  2727. { "PersistentGroupAdded", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2728. {
  2729. { "path", "o", ARG_OUT },
  2730. { "properties", "a{sv}", ARG_OUT },
  2731. END_ARGS
  2732. }
  2733. },
  2734. { "PersistentGroupRemoved", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2735. {
  2736. { "path", "o", ARG_OUT },
  2737. END_ARGS
  2738. }
  2739. },
  2740. { "WpsFailed", WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2741. {
  2742. { "name", "s", ARG_OUT },
  2743. { "args", "a{sv}", ARG_OUT },
  2744. END_ARGS
  2745. }
  2746. },
  2747. #endif /* CONFIG_P2P */
  2748. #ifdef CONFIG_AP
  2749. { "ProbeRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2750. {
  2751. { "args", "a{sv}", ARG_OUT },
  2752. END_ARGS
  2753. }
  2754. },
  2755. #endif /* CONFIG_AP */
  2756. { "Certification", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2757. {
  2758. { "certification", "a{sv}", ARG_OUT },
  2759. END_ARGS
  2760. }
  2761. },
  2762. { "EAP", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2763. {
  2764. { "status", "s", ARG_OUT },
  2765. { "parameter", "s", ARG_OUT },
  2766. END_ARGS
  2767. }
  2768. },
  2769. { "StaAuthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2770. {
  2771. { "name", "s", ARG_OUT },
  2772. END_ARGS
  2773. }
  2774. },
  2775. { "StaDeauthorized", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2776. {
  2777. { "name", "s", ARG_OUT },
  2778. END_ARGS
  2779. }
  2780. },
  2781. { "NetworkRequest", WPAS_DBUS_NEW_IFACE_INTERFACE,
  2782. {
  2783. { "path", "o", ARG_OUT },
  2784. { "field", "s", ARG_OUT },
  2785. { "text", "s", ARG_OUT },
  2786. END_ARGS
  2787. }
  2788. },
  2789. { NULL, NULL, { END_ARGS } }
  2790. };
  2791. int wpas_dbus_register_interface(struct wpa_supplicant *wpa_s)
  2792. {
  2793. struct wpa_dbus_object_desc *obj_desc = NULL;
  2794. struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
  2795. int next;
  2796. /* Do nothing if the control interface is not turned on */
  2797. if (ctrl_iface == NULL)
  2798. return 0;
  2799. /* Create and set the interface's object path */
  2800. wpa_s->dbus_new_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
  2801. if (wpa_s->dbus_new_path == NULL)
  2802. return -1;
  2803. next = ctrl_iface->next_objid++;
  2804. os_snprintf(wpa_s->dbus_new_path, WPAS_DBUS_OBJECT_PATH_MAX,
  2805. WPAS_DBUS_NEW_PATH_INTERFACES "/%u",
  2806. next);
  2807. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  2808. if (!obj_desc) {
  2809. wpa_printf(MSG_ERROR,
  2810. "Not enough memory to create object description");
  2811. goto err;
  2812. }
  2813. wpas_dbus_register(obj_desc, wpa_s, NULL, wpas_dbus_interface_methods,
  2814. wpas_dbus_interface_properties,
  2815. wpas_dbus_interface_signals);
  2816. wpa_printf(MSG_DEBUG, "dbus: Register interface object '%s'",
  2817. wpa_s->dbus_new_path);
  2818. if (wpa_dbus_register_object_per_iface(ctrl_iface,
  2819. wpa_s->dbus_new_path,
  2820. wpa_s->ifname, obj_desc))
  2821. goto err;
  2822. wpas_dbus_signal_interface_added(wpa_s);
  2823. return 0;
  2824. err:
  2825. os_free(wpa_s->dbus_new_path);
  2826. wpa_s->dbus_new_path = NULL;
  2827. free_dbus_object_desc(obj_desc);
  2828. return -1;
  2829. }
  2830. int wpas_dbus_unregister_interface(struct wpa_supplicant *wpa_s)
  2831. {
  2832. struct wpas_dbus_priv *ctrl_iface;
  2833. /* Do nothing if the control interface is not turned on */
  2834. if (wpa_s == NULL || wpa_s->global == NULL)
  2835. return 0;
  2836. ctrl_iface = wpa_s->global->dbus;
  2837. if (ctrl_iface == NULL || wpa_s->dbus_new_path == NULL)
  2838. return 0;
  2839. wpa_printf(MSG_DEBUG, "dbus: Unregister interface object '%s'",
  2840. wpa_s->dbus_new_path);
  2841. #ifdef CONFIG_AP
  2842. if (wpa_s->preq_notify_peer) {
  2843. wpas_dbus_unsubscribe_noc(ctrl_iface);
  2844. os_free(wpa_s->preq_notify_peer);
  2845. wpa_s->preq_notify_peer = NULL;
  2846. }
  2847. #endif /* CONFIG_AP */
  2848. if (wpa_dbus_unregister_object_per_iface(ctrl_iface,
  2849. wpa_s->dbus_new_path))
  2850. return -1;
  2851. wpas_dbus_signal_interface_removed(wpa_s);
  2852. os_free(wpa_s->dbus_new_path);
  2853. wpa_s->dbus_new_path = NULL;
  2854. return 0;
  2855. }
  2856. #ifdef CONFIG_P2P
  2857. static const struct wpa_dbus_property_desc wpas_dbus_p2p_peer_properties[] = {
  2858. { "DeviceName", WPAS_DBUS_NEW_IFACE_P2P_PEER, "s",
  2859. wpas_dbus_getter_p2p_peer_device_name,
  2860. NULL
  2861. },
  2862. { "PrimaryDeviceType", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
  2863. wpas_dbus_getter_p2p_peer_primary_device_type,
  2864. NULL
  2865. },
  2866. { "config_method", WPAS_DBUS_NEW_IFACE_P2P_PEER, "q",
  2867. wpas_dbus_getter_p2p_peer_config_method,
  2868. NULL
  2869. },
  2870. { "level", WPAS_DBUS_NEW_IFACE_P2P_PEER, "i",
  2871. wpas_dbus_getter_p2p_peer_level,
  2872. NULL
  2873. },
  2874. { "devicecapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
  2875. wpas_dbus_getter_p2p_peer_device_capability,
  2876. NULL
  2877. },
  2878. { "groupcapability", WPAS_DBUS_NEW_IFACE_P2P_PEER, "y",
  2879. wpas_dbus_getter_p2p_peer_group_capability,
  2880. NULL
  2881. },
  2882. { "SecondaryDeviceTypes", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
  2883. wpas_dbus_getter_p2p_peer_secondary_device_types,
  2884. NULL
  2885. },
  2886. { "VendorExtension", WPAS_DBUS_NEW_IFACE_P2P_PEER, "aay",
  2887. wpas_dbus_getter_p2p_peer_vendor_extension,
  2888. NULL
  2889. },
  2890. { "IEs", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
  2891. wpas_dbus_getter_p2p_peer_ies,
  2892. NULL
  2893. },
  2894. { "DeviceAddress", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ay",
  2895. wpas_dbus_getter_p2p_peer_device_address,
  2896. NULL
  2897. },
  2898. { "Groups", WPAS_DBUS_NEW_IFACE_P2P_PEER, "ao",
  2899. wpas_dbus_getter_p2p_peer_groups,
  2900. NULL
  2901. },
  2902. { NULL, NULL, NULL, NULL, NULL }
  2903. };
  2904. static const struct wpa_dbus_signal_desc wpas_dbus_p2p_peer_signals[] = {
  2905. /* Deprecated: use org.freedesktop.DBus.Properties.PropertiesChanged */
  2906. { "PropertiesChanged", WPAS_DBUS_NEW_IFACE_P2P_PEER,
  2907. {
  2908. { "properties", "a{sv}", ARG_OUT },
  2909. END_ARGS
  2910. }
  2911. },
  2912. { NULL, NULL, { END_ARGS } }
  2913. };
  2914. /**
  2915. * wpas_dbus_signal_peer - Send a peer related event signal
  2916. * @wpa_s: %wpa_supplicant network interface data
  2917. * @dev: peer device object
  2918. * @interface: name of the interface emitting this signal.
  2919. * In case of peer objects, it would be emitted by either
  2920. * the "interface object" or by "peer objects"
  2921. * @sig_name: signal name - DeviceFound
  2922. *
  2923. * Notify listeners about event related with newly found p2p peer device
  2924. */
  2925. static void wpas_dbus_signal_peer(struct wpa_supplicant *wpa_s,
  2926. const u8 *dev_addr, const char *interface,
  2927. const char *sig_name)
  2928. {
  2929. struct wpas_dbus_priv *iface;
  2930. DBusMessage *msg;
  2931. DBusMessageIter iter;
  2932. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX], *path;
  2933. if (wpa_s->p2p_mgmt)
  2934. wpa_s = wpa_s->parent;
  2935. iface = wpa_s->global->dbus;
  2936. /* Do nothing if the control interface is not turned on */
  2937. if (iface == NULL)
  2938. return;
  2939. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  2940. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
  2941. wpa_s->dbus_new_path, MAC2STR(dev_addr));
  2942. msg = dbus_message_new_signal(wpa_s->dbus_new_path, interface,
  2943. sig_name);
  2944. if (msg == NULL)
  2945. return;
  2946. dbus_message_iter_init_append(msg, &iter);
  2947. path = peer_obj_path;
  2948. if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
  2949. &path))
  2950. wpa_printf(MSG_ERROR, "dbus: Failed to construct signal");
  2951. else
  2952. dbus_connection_send(iface->con, msg, NULL);
  2953. dbus_message_unref(msg);
  2954. }
  2955. /**
  2956. * wpas_dbus_signal_peer_found - Send a peer found signal
  2957. * @wpa_s: %wpa_supplicant network interface data
  2958. * @dev: peer device object
  2959. *
  2960. * Notify listeners about find a p2p peer device found
  2961. */
  2962. void wpas_dbus_signal_peer_device_found(struct wpa_supplicant *wpa_s,
  2963. const u8 *dev_addr)
  2964. {
  2965. wpas_dbus_signal_peer(wpa_s, dev_addr,
  2966. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2967. "DeviceFound");
  2968. }
  2969. /**
  2970. * wpas_dbus_signal_peer_lost - Send a peer lost signal
  2971. * @wpa_s: %wpa_supplicant network interface data
  2972. * @dev: peer device object
  2973. *
  2974. * Notify listeners about lost a p2p peer device
  2975. */
  2976. void wpas_dbus_signal_peer_device_lost(struct wpa_supplicant *wpa_s,
  2977. const u8 *dev_addr)
  2978. {
  2979. wpas_dbus_signal_peer(wpa_s, dev_addr,
  2980. WPAS_DBUS_NEW_IFACE_P2PDEVICE,
  2981. "DeviceLost");
  2982. }
  2983. /**
  2984. * wpas_dbus_register_peer - Register a discovered peer object with dbus
  2985. * @wpa_s: wpa_supplicant interface structure
  2986. * @ssid: network configuration data
  2987. * Returns: 0 on success, -1 on failure
  2988. *
  2989. * Registers network representing object with dbus
  2990. */
  2991. int wpas_dbus_register_peer(struct wpa_supplicant *wpa_s, const u8 *dev_addr)
  2992. {
  2993. struct wpas_dbus_priv *ctrl_iface;
  2994. struct wpa_dbus_object_desc *obj_desc;
  2995. struct peer_handler_args *arg;
  2996. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  2997. /* Do nothing if the control interface is not turned on */
  2998. if (wpa_s == NULL || wpa_s->global == NULL)
  2999. return 0;
  3000. ctrl_iface = wpa_s->global->dbus;
  3001. if (ctrl_iface == NULL)
  3002. return 0;
  3003. if (wpa_s->p2p_mgmt)
  3004. wpa_s = wpa_s->parent;
  3005. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  3006. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
  3007. wpa_s->dbus_new_path, MAC2STR(dev_addr));
  3008. wpa_printf(MSG_INFO, "dbus: Register peer object '%s'",
  3009. peer_obj_path);
  3010. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  3011. if (!obj_desc) {
  3012. wpa_printf(MSG_ERROR,
  3013. "Not enough memory to create object description");
  3014. goto err;
  3015. }
  3016. /* allocate memory for handlers arguments */
  3017. arg = os_zalloc(sizeof(struct peer_handler_args));
  3018. if (!arg) {
  3019. wpa_printf(MSG_ERROR,
  3020. "Not enough memory to create arguments for method");
  3021. goto err;
  3022. }
  3023. arg->wpa_s = wpa_s;
  3024. os_memcpy(arg->p2p_device_addr, dev_addr, ETH_ALEN);
  3025. wpas_dbus_register(obj_desc, arg, wpa_dbus_free,
  3026. NULL,
  3027. wpas_dbus_p2p_peer_properties,
  3028. wpas_dbus_p2p_peer_signals);
  3029. if (wpa_dbus_register_object_per_iface(ctrl_iface, peer_obj_path,
  3030. wpa_s->ifname, obj_desc))
  3031. goto err;
  3032. return 0;
  3033. err:
  3034. free_dbus_object_desc(obj_desc);
  3035. return -1;
  3036. }
  3037. /**
  3038. * wpas_dbus_unregister_peer - Unregister a peer object with dbus
  3039. * @wpa_s: wpa_supplicant interface structure
  3040. * @dev_addr: p2p device addr
  3041. * Returns: 0 on success, -1 on failure
  3042. *
  3043. * Registers network representing object with dbus
  3044. */
  3045. int wpas_dbus_unregister_peer(struct wpa_supplicant *wpa_s,
  3046. const u8 *dev_addr)
  3047. {
  3048. struct wpas_dbus_priv *ctrl_iface;
  3049. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  3050. int ret;
  3051. /* Do nothing if the control interface is not turned on */
  3052. if (wpa_s == NULL || wpa_s->global == NULL ||
  3053. wpa_s->dbus_new_path == NULL)
  3054. return 0;
  3055. if (wpa_s->p2p_mgmt)
  3056. wpa_s = wpa_s->parent;
  3057. ctrl_iface = wpa_s->global->dbus;
  3058. if (ctrl_iface == NULL)
  3059. return 0;
  3060. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  3061. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
  3062. wpa_s->dbus_new_path, MAC2STR(dev_addr));
  3063. wpa_printf(MSG_INFO, "dbus: Unregister peer object '%s'",
  3064. peer_obj_path);
  3065. ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, peer_obj_path);
  3066. return ret;
  3067. }
  3068. void wpas_dbus_signal_peer_groups_changed(struct wpa_supplicant *wpa_s,
  3069. const u8 *dev_addr)
  3070. {
  3071. char peer_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  3072. if (wpa_s->p2p_mgmt)
  3073. wpa_s = wpa_s->parent;
  3074. os_snprintf(peer_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  3075. "%s/" WPAS_DBUS_NEW_P2P_PEERS_PART "/" COMPACT_MACSTR,
  3076. wpa_s->dbus_new_path, MAC2STR(dev_addr));
  3077. wpa_dbus_mark_property_changed(wpa_s->global->dbus, peer_obj_path,
  3078. WPAS_DBUS_NEW_IFACE_P2P_PEER, "Groups");
  3079. }
  3080. static const struct wpa_dbus_property_desc wpas_dbus_p2p_group_properties[] = {
  3081. { "Members", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ao",
  3082. wpas_dbus_getter_p2p_group_members,
  3083. NULL
  3084. },
  3085. { "Group", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "o",
  3086. wpas_dbus_getter_p2p_group,
  3087. NULL
  3088. },
  3089. { "Role", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
  3090. wpas_dbus_getter_p2p_role,
  3091. NULL
  3092. },
  3093. { "SSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
  3094. wpas_dbus_getter_p2p_group_ssid,
  3095. NULL
  3096. },
  3097. { "BSSID", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
  3098. wpas_dbus_getter_p2p_group_bssid,
  3099. NULL
  3100. },
  3101. { "Frequency", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "q",
  3102. wpas_dbus_getter_p2p_group_frequency,
  3103. NULL
  3104. },
  3105. { "Passphrase", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "s",
  3106. wpas_dbus_getter_p2p_group_passphrase,
  3107. NULL
  3108. },
  3109. { "PSK", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "ay",
  3110. wpas_dbus_getter_p2p_group_psk,
  3111. NULL
  3112. },
  3113. { "WPSVendorExtensions", WPAS_DBUS_NEW_IFACE_P2P_GROUP, "aay",
  3114. wpas_dbus_getter_p2p_group_vendor_ext,
  3115. wpas_dbus_setter_p2p_group_vendor_ext
  3116. },
  3117. { NULL, NULL, NULL, NULL, NULL }
  3118. };
  3119. static const struct wpa_dbus_signal_desc wpas_dbus_p2p_group_signals[] = {
  3120. { "PeerJoined", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
  3121. {
  3122. { "peer", "o", ARG_OUT },
  3123. END_ARGS
  3124. }
  3125. },
  3126. { "PeerDisconnected", WPAS_DBUS_NEW_IFACE_P2P_GROUP,
  3127. {
  3128. { "peer", "o", ARG_OUT },
  3129. END_ARGS
  3130. }
  3131. },
  3132. { NULL, NULL, { END_ARGS } }
  3133. };
  3134. /**
  3135. * wpas_dbus_register_p2p_group - Register a p2p group object with dbus
  3136. * @wpa_s: wpa_supplicant interface structure
  3137. * @ssid: SSID struct
  3138. * Returns: 0 on success, -1 on failure
  3139. *
  3140. * Registers p2p group representing object with dbus
  3141. */
  3142. void wpas_dbus_register_p2p_group(struct wpa_supplicant *wpa_s,
  3143. struct wpa_ssid *ssid)
  3144. {
  3145. struct wpas_dbus_priv *ctrl_iface;
  3146. struct wpa_dbus_object_desc *obj_desc;
  3147. char group_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  3148. /* Do nothing if the control interface is not turned on */
  3149. if (wpa_s == NULL || wpa_s->global == NULL)
  3150. return;
  3151. ctrl_iface = wpa_s->global->dbus;
  3152. if (ctrl_iface == NULL)
  3153. return;
  3154. if (wpa_s->dbus_groupobj_path) {
  3155. wpa_printf(MSG_INFO, "%s: Group object '%s' already exists",
  3156. __func__, wpa_s->dbus_groupobj_path);
  3157. return;
  3158. }
  3159. if (wpas_dbus_get_group_obj_path(wpa_s, ssid, group_obj_path) < 0)
  3160. return;
  3161. wpa_s->dbus_groupobj_path = os_strdup(group_obj_path);
  3162. if (wpa_s->dbus_groupobj_path == NULL)
  3163. return;
  3164. wpa_printf(MSG_INFO, "dbus: Register group object '%s'",
  3165. group_obj_path);
  3166. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  3167. if (!obj_desc) {
  3168. wpa_printf(MSG_ERROR,
  3169. "Not enough memory to create object description");
  3170. goto err;
  3171. }
  3172. wpas_dbus_register(obj_desc, wpa_s, NULL, NULL,
  3173. wpas_dbus_p2p_group_properties,
  3174. wpas_dbus_p2p_group_signals);
  3175. if (wpa_dbus_register_object_per_iface(ctrl_iface, group_obj_path,
  3176. wpa_s->ifname, obj_desc))
  3177. goto err;
  3178. return;
  3179. err:
  3180. if (wpa_s->dbus_groupobj_path) {
  3181. os_free(wpa_s->dbus_groupobj_path);
  3182. wpa_s->dbus_groupobj_path = NULL;
  3183. }
  3184. free_dbus_object_desc(obj_desc);
  3185. }
  3186. /**
  3187. * wpas_dbus_unregister_p2p_group - Unregister a p2p group object from dbus
  3188. * @wpa_s: wpa_supplicant interface structure
  3189. * @ssid: network name of the p2p group started
  3190. */
  3191. void wpas_dbus_unregister_p2p_group(struct wpa_supplicant *wpa_s,
  3192. const struct wpa_ssid *ssid)
  3193. {
  3194. struct wpas_dbus_priv *ctrl_iface;
  3195. /* Do nothing if the control interface is not turned on */
  3196. if (wpa_s == NULL || wpa_s->global == NULL)
  3197. return;
  3198. if (wpa_s->p2p_mgmt)
  3199. wpa_s = wpa_s->parent;
  3200. ctrl_iface = wpa_s->global->dbus;
  3201. if (ctrl_iface == NULL)
  3202. return;
  3203. if (!wpa_s->dbus_groupobj_path) {
  3204. wpa_printf(MSG_DEBUG,
  3205. "%s: Group object '%s' already unregistered",
  3206. __func__, wpa_s->dbus_groupobj_path);
  3207. return;
  3208. }
  3209. peer_groups_changed(wpa_s);
  3210. wpa_printf(MSG_DEBUG, "dbus: Unregister group object '%s'",
  3211. wpa_s->dbus_groupobj_path);
  3212. wpa_dbus_unregister_object_per_iface(ctrl_iface,
  3213. wpa_s->dbus_groupobj_path);
  3214. os_free(wpa_s->dbus_groupobj_path);
  3215. wpa_s->dbus_groupobj_path = NULL;
  3216. }
  3217. static const struct wpa_dbus_property_desc
  3218. wpas_dbus_persistent_group_properties[] = {
  3219. { "Properties", WPAS_DBUS_NEW_IFACE_PERSISTENT_GROUP, "a{sv}",
  3220. wpas_dbus_getter_persistent_group_properties,
  3221. wpas_dbus_setter_persistent_group_properties
  3222. },
  3223. { NULL, NULL, NULL, NULL, NULL }
  3224. };
  3225. /* No signals intended for persistent group objects */
  3226. /**
  3227. * wpas_dbus_register_persistent_group - Register a configured(saved)
  3228. * persistent group with dbus
  3229. * @wpa_s: wpa_supplicant interface structure
  3230. * @ssid: persistent group (still represented as a network within wpa)
  3231. * configuration data
  3232. * Returns: 0 on success, -1 on failure
  3233. *
  3234. * Registers a persistent group representing object with dbus.
  3235. */
  3236. int wpas_dbus_register_persistent_group(struct wpa_supplicant *wpa_s,
  3237. struct wpa_ssid *ssid)
  3238. {
  3239. struct wpas_dbus_priv *ctrl_iface;
  3240. struct wpa_dbus_object_desc *obj_desc;
  3241. struct network_handler_args *arg;
  3242. char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  3243. /* Do nothing if the control interface is not turned on */
  3244. if (wpa_s == NULL || wpa_s->global == NULL)
  3245. return 0;
  3246. /* Make sure ssid is a persistent group */
  3247. if (ssid->disabled != 2 && !ssid->p2p_persistent_group)
  3248. return -1; /* should we return w/o complaining? */
  3249. if (wpa_s->p2p_mgmt)
  3250. wpa_s = wpa_s->parent;
  3251. ctrl_iface = wpa_s->global->dbus;
  3252. if (ctrl_iface == NULL)
  3253. return 0;
  3254. /*
  3255. * Intentionally not coming up with different numbering scheme
  3256. * for persistent groups.
  3257. */
  3258. os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  3259. "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
  3260. wpa_s->dbus_new_path, ssid->id);
  3261. wpa_printf(MSG_DEBUG, "dbus: Register persistent group object '%s'",
  3262. pgrp_obj_path);
  3263. obj_desc = os_zalloc(sizeof(struct wpa_dbus_object_desc));
  3264. if (!obj_desc) {
  3265. wpa_printf(MSG_ERROR,
  3266. "dbus: Not enough memory to create object description");
  3267. goto err;
  3268. }
  3269. /*
  3270. * Reusing the same context structure as that for networks
  3271. * since these are represented using same data structure.
  3272. */
  3273. /* allocate memory for handlers arguments */
  3274. arg = os_zalloc(sizeof(struct network_handler_args));
  3275. if (!arg) {
  3276. wpa_printf(MSG_ERROR,
  3277. "dbus: Not enough memory to create arguments for method");
  3278. goto err;
  3279. }
  3280. arg->wpa_s = wpa_s;
  3281. arg->ssid = ssid;
  3282. wpas_dbus_register(obj_desc, arg, wpa_dbus_free, NULL,
  3283. wpas_dbus_persistent_group_properties,
  3284. NULL);
  3285. if (wpa_dbus_register_object_per_iface(ctrl_iface, pgrp_obj_path,
  3286. wpa_s->ifname, obj_desc))
  3287. goto err;
  3288. wpas_dbus_signal_persistent_group_added(wpa_s, ssid->id);
  3289. return 0;
  3290. err:
  3291. free_dbus_object_desc(obj_desc);
  3292. return -1;
  3293. }
  3294. /**
  3295. * wpas_dbus_unregister_persistent_group - Unregister a persistent_group
  3296. * from dbus
  3297. * @wpa_s: wpa_supplicant interface structure
  3298. * @nid: network id
  3299. * Returns: 0 on success, -1 on failure
  3300. *
  3301. * Unregisters persistent group representing object from dbus
  3302. *
  3303. * NOTE: There is a slight issue with the semantics here. While the
  3304. * implementation simply means the persistent group is unloaded from memory,
  3305. * it should not get interpreted as the group is actually being erased/removed
  3306. * from persistent storage as well.
  3307. */
  3308. int wpas_dbus_unregister_persistent_group(struct wpa_supplicant *wpa_s,
  3309. int nid)
  3310. {
  3311. struct wpas_dbus_priv *ctrl_iface;
  3312. char pgrp_obj_path[WPAS_DBUS_OBJECT_PATH_MAX];
  3313. int ret;
  3314. /* Do nothing if the control interface is not turned on */
  3315. if (wpa_s == NULL || wpa_s->global == NULL ||
  3316. wpa_s->dbus_new_path == NULL)
  3317. return 0;
  3318. if (wpa_s->p2p_mgmt)
  3319. wpa_s = wpa_s->parent;
  3320. ctrl_iface = wpa_s->global->dbus;
  3321. if (ctrl_iface == NULL)
  3322. return 0;
  3323. os_snprintf(pgrp_obj_path, WPAS_DBUS_OBJECT_PATH_MAX,
  3324. "%s/" WPAS_DBUS_NEW_PERSISTENT_GROUPS_PART "/%u",
  3325. wpa_s->dbus_new_path, nid);
  3326. wpa_printf(MSG_DEBUG, "dbus: Unregister persistent group object '%s'",
  3327. pgrp_obj_path);
  3328. ret = wpa_dbus_unregister_object_per_iface(ctrl_iface, pgrp_obj_path);
  3329. if (!ret)
  3330. wpas_dbus_signal_persistent_group_removed(wpa_s, nid);
  3331. return ret;
  3332. }
  3333. #endif /* CONFIG_P2P */