[PATCH]Connman : Improve P2P: Update p2p_listen state , default PBC mode, and  peer PBC request handling

Shailesh Rathod/LGSI Connectivity Team <[email protected]> Mon, 29 Sep 2025 04:06:12 +0000
Newsgroups dev.linux.lists.connman
Message-ID <SE1P216MB2647BC9C66496129729E3E39F01BA@SE1P216MB2647.KORP216.PROD.OUTLOOK.COM>
From 7734bd9ec42e77d0ce8184908f6b31075ab73f31 Mon Sep 17 00:00:00 2001=0A=
From: shailesh <[email protected]>=0A=
Date: Fri, 27 Jun 2025 04:49:26 +0000=0A=
Subject: [PATCH] Improve P2P: Update p2p_listen state , default PBC mode, a=
nd=0A=
=A0peer PBC request handling=0A=
=0A=
- Add support for `p2p_listen` state in `GetProperties` for better P2P stat=
e management.=0A=
- Default to WPS PBC mode if no PIN is provided during peer connection.=0A=
- Automatically process peer device PBC requests and initiate connection.=
=0A=
- Refactor listen state logic to allow dynamic enable/disable with timing p=
arameters.=0A=
- Update D-Bus policy to permit `net.connman.Peer` interface messages.=0A=
---=0A=
=A0gsupplicant/gsupplicant.h | =A037 +++=0A=
=A0gsupplicant/supplicant.c =A0| 558 ++++++++++++++++++++++++++++++++++++++=
=0A=
=A0include/technology.h =A0 =A0 =A0| =A0 9 +=0A=
=A0plugins/wifi.c =A0 =A0 =A0 =A0 =A0 =A0| 433 ++++++++++++++++++++++++++++=
-=0A=
=A0src/connman-dbus.conf =A0 =A0 | =A0 1 +=0A=
=A0src/peer.c =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 5 +-=0A=
=A0src/technology.c =A0 =A0 =A0 =A0 =A0| 177 +++++++++++-=0A=
=A07 files changed, 1209 insertions(+), 11 deletions(-)=0A=
=0A=
diff --git a/gsupplicant/gsupplicant.h b/gsupplicant/gsupplicant.h=0A=
index eecad9c..eaa9083 100644=0A=
--- a/gsupplicant/gsupplicant.h=0A=
+++ b/gsupplicant/gsupplicant.h=0A=
@@ -188,6 +188,7 @@ struct _GSupplicantPeerParams {=0A=
=A0 =A0 bool master;=0A=
=A0 =A0 char *wps_pin;=0A=
=A0 =A0 char *path;=0A=
+ =A0 bool persistent;=0A=
=A0};=0A=
=A0=0A=
=A0typedef struct _GSupplicantPeerParams GSupplicantPeerParams;=0A=
@@ -263,9 +264,11 @@ int g_supplicant_set_country(const char *alpha2,=0A=
=A0/* Interface API */=0A=
=A0struct _GSupplicantInterface;=0A=
=A0struct _GSupplicantPeer;=0A=
+struct _GSupplicantP2PInterface;=0A=
=A0=0A=
=A0typedef struct _GSupplicantInterface GSupplicantInterface;=0A=
=A0typedef struct _GSupplicantPeer GSupplicantPeer;=0A=
+typedef struct _GSupplicantP2PInterface GSupplicantP2PInterface;=0A=
=A0=0A=
=A0typedef void (*GSupplicantInterfaceCallback) (int result,=0A=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantInterface *interface,=0A=
@@ -389,11 +392,34 @@ struct _GSupplicantP2PExtendedListenParams {=0A=
=A0=0A=
=A0typedef struct _GSupplicantP2PExtendedListenParams GSupplicantP2PExtende=
dListenParams;=0A=
=A0=0A=
+struct _GSupplicantP2PDeviceConfigParams {=0A=
+ =A0 GSupplicantInterface *interface;=0A=
+ =A0 char *device_name;=0A=
+ =A0 unsigned char pri_dev_type[8];=0A=
+ =A0 dbus_uint32_t go_intent;=0A=
+ =A0 int persistent_reconnect;=0A=
+ =A0 dbus_uint32_t listen_reg_class;=0A=
+ =A0 dbus_uint32_t listen_channel;=0A=
+ =A0 dbus_uint32_t oper_reg_class;=0A=
+ =A0 dbus_uint32_t oper_channel;=0A=
+ =A0 char *ssid_postfix;=0A=
+ =A0 int intra_bss;=0A=
+ =A0 dbus_uint32_t group_idle;=0A=
+ =A0 dbus_uint32_t disassoc_low_ack;=0A=
+ =A0 const void *user_data;=0A=
+};=0A=
+=0A=
+typedef struct _GSupplicantP2PDeviceConfigParams GSupplicantP2PDeviceConfi=
gParams;=0A=
=A0int g_supplicant_interface_p2p_extended_listen(GSupplicantInterface *int=
erface,=0A=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantP2PExtendedListenParams *ex=
tended_listen_data,=0A=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantInterfaceCallback callback,=
=0A=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 void *user_data);=0A=
=A0=0A=
+int g_supplicant_interface_get_p2p_device_config(GSupplicantInterface *int=
erface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantP2PDeviceConfigPar=
ams *p2p_device_config);=0A=
+int g_supplicant_interface_set_p2p_device_configs(GSupplicantInterface *in=
terface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantP2PDeviceConfigPar=
ams *p2p_device_config_data,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 void *user_data);=0A=
=A0/* Network and Peer API */=0A=
=A0struct _GSupplicantNetwork;=0A=
=A0struct _GSupplicantGroup;=0A=
@@ -489,10 +515,21 @@ struct _GSupplicantCallbacks {=0A=
=A0 =A0 void (*p2p_group_finished)(GSupplicantInterface *interface);=0A=
=A0 =A0 void (*p2p_invitation_result)(GSupplicantInterface *interface, int =
status);=0A=
=A0 =A0 void (*p2p_invitation_received) (GSupplicantInterface *interface, G=
SupplicantPeer *p2p_network, const char *go_dev_addr, bool persistent);=0A=
+ =A0 void (*p2p_prov_disc_requested_pbc) (GSupplicantInterface *interface,=
 GSupplicantPeer *peer);=0A=
+ =A0 void (*p2p_prov_disc_requested_enter_pin) (GSupplicantInterface *inte=
rface, GSupplicantPeer *peer);=0A=
+ =A0 void (*p2p_prov_disc_requested_display_pin) (GSupplicantInterface *in=
terface, GSupplicantPeer *peer, const char *pin);=0A=
+ =A0 void (*p2p_prov_disc_response_enter_pin) (GSupplicantInterface *inter=
face, GSupplicantPeer *peer);=0A=
+ =A0 void (*p2p_prov_disc_response_display_pin) (GSupplicantInterface *int=
erface, GSupplicantPeer *peer, const char *pin);=0A=
+ =A0 void (*p2p_prov_disc_fail) (GSupplicantInterface *interface, GSupplic=
antPeer *peer, const char * status);=0A=
+ =A0 void (*p2p_device_config_loaded) (GSupplicantInterface *interface);=
=0A=
=A0};=0A=
=A0=0A=
=A0typedef struct _GSupplicantCallbacks GSupplicantCallbacks;=0A=
=A0=0A=
+typedef struct _GSupplicantP2PFindParams GSupplicantP2PFindParams;=0A=
+=0A=
+=0A=
+=0A=
=A0int g_supplicant_register(const GSupplicantCallbacks *callbacks);=0A=
=A0void g_supplicant_unregister(const GSupplicantCallbacks *callbacks);=0A=
=A0=0A=
diff --git a/gsupplicant/supplicant.c b/gsupplicant/supplicant.c=0A=
index 6fd7384..494fef3 100644=0A=
--- a/gsupplicant/supplicant.c=0A=
+++ b/gsupplicant/supplicant.c=0A=
@@ -47,6 +47,13 @@=0A=
=A0#define MAX_P2P_SSID_LEN =A0 =A0 =A0 =A0 =A0 32=0A=
=A0#define BSS_UNKNOWN_STRENGTH =A0 =A0-90=0A=
=A0=0A=
+#define WPAS_P2P_WPS_PIN_LENGTH =A0 =A0 =A0 =A08=0A=
+#define MAX_P2P_SSID_LEN =A0 =A0 =A0 =A0 =A0 32=0A=
+=0A=
+=0A=
+typedef void (*g_supplicant_p2p_prov_dics_signal_func) (GSupplicantInterfa=
ce *interface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantPeer* peer, void* params);=0A=
+=0A=
=A0static DBusConnection *connection;=0A=
=A0=0A=
=A0static const GSupplicantCallbacks *callbacks_pointer;=0A=
@@ -273,6 +280,11 @@ struct _GSupplicantGroup {=0A=
=A0 =A0 char * psk;=0A=
=A0};=0A=
=A0=0A=
+struct _GSupplicantP2PInterface {=0A=
+ =A0 char *path;=0A=
+ =A0 GSupplicantP2PDeviceConfigParams *p2p_device_config_param;=0A=
+};=0A=
+=0A=
=A0struct interface_data {=0A=
=A0 =A0 GSupplicantInterface *interface;=0A=
=A0 =A0 char *path; /* Interface path cannot be taken from interface (above=
) as=0A=
@@ -319,6 +331,13 @@ struct interface_scan_data {=0A=
=A0 =A0 void *user_data;=0A=
=A0};=0A=
=A0=0A=
+struct interface_p2p_device_config {=0A=
+ =A0 GSupplicantInterface *interface;=0A=
+ =A0 GSupplicantInterfaceCallback callback;=0A=
+ =A0 GSupplicantP2PDeviceConfigParams *p2p_device_config_params;=0A=
+ =A0 void *user_data;=0A=
+};=0A=
+=0A=
=A0struct g_supplicant_p2p_inv_recv_info {=0A=
=A0 =A0 GSupplicantInterface *interface;=0A=
=A0 =A0 const char *p2p_go_dev_addr;=0A=
@@ -509,6 +528,78 @@ static void callback_system_ready(void)=0A=
=A0 =A0 callbacks_pointer->system_ready();=0A=
=A0}=0A=
=A0=0A=
+static void callback_p2p_prov_disc_requested_pbc(GSupplicantInterface *int=
erface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantPeer *peer, void * data)=
=0A=
+{=0A=
+ =A0 if (!callbacks_pointer)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 if (!callbacks_pointer->p2p_prov_disc_requested_pbc)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 callbacks_pointer->p2p_prov_disc_requested_pbc(interface, peer);=0A=
+}=0A=
+=0A=
+static void callback_p2p_prov_disc_requested_enter_pin(GSupplicantInterfac=
e *interface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantPeer *peer, void * data)=
=0A=
+{=0A=
+ =A0 if (!callbacks_pointer)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 if (!callbacks_pointer->p2p_prov_disc_requested_enter_pin)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 callbacks_pointer->p2p_prov_disc_requested_enter_pin(interface, peer)=
;=0A=
+}=0A=
+=0A=
+static void callback_p2p_prov_disc_requested_display_pin(GSupplicantInterf=
ace *interface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantPeer *peer, const char *pi=
n)=0A=
+{=0A=
+ =A0 if (!callbacks_pointer)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 if (!callbacks_pointer->p2p_prov_disc_requested_display_pin)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 callbacks_pointer->p2p_prov_disc_requested_display_pin(interface, pee=
r, pin);=0A=
+}=0A=
+=0A=
+static void callback_p2p_prov_disc_response_enter_pin(GSupplicantInterface=
 *interface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantPeer *peer, void * data)=
=0A=
+{=0A=
+ =A0 if (!callbacks_pointer)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 if (!callbacks_pointer->p2p_prov_disc_requested_enter_pin)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 callbacks_pointer->p2p_prov_disc_response_enter_pin(interface, peer);=
=0A=
+}=0A=
+=0A=
+static void callback_p2p_prov_disc_response_display_pin(GSupplicantInterfa=
ce *interface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantPeer *peer, const char *pi=
n)=0A=
+{=0A=
+ =A0 if (!callbacks_pointer)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 if (!callbacks_pointer->p2p_prov_disc_requested_display_pin)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 callbacks_pointer->p2p_prov_disc_response_display_pin(interface, peer=
, pin);=0A=
+}=0A=
+=0A=
+static void callback_p2p_prov_disc_fail(GSupplicantInterface *interface,=
=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantPeer *peer, const char *pi=
n)=0A=
+{=0A=
+ =A0 if (!callbacks_pointer)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 if (!callbacks_pointer->p2p_prov_disc_fail)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 callbacks_pointer->p2p_prov_disc_fail(interface, peer, pin);=0A=
+}=0A=
+=0A=
=A0static void callback_system_killed(void)=0A=
=A0{=0A=
=A0 =A0 system_ready =3D FALSE;=0A=
@@ -1027,6 +1118,176 @@ static void debug_strvalmap(const char *label, stru=
ct strvalmap *map,=0A=
=A0 =A0 }=0A=
=A0}=0A=
=A0=0A=
+static void fire_p2p_prov_dics_signal(GSupplicantInterface *interface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 const char* path,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 g_supplicant_p2p_prov_dics_signal_fun=
c signal_func,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 void* signal_params)=0A=
+{=0A=
+ =A0 GSupplicantPeer *peer;=0A=
+=0A=
+ =A0 SUPPLICANT_DBG("");=0A=
+=0A=
+ =A0 peer =3D g_hash_table_lookup(interface->peer_table, path);=0A=
+ =A0 if (!peer)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 signal_func(interface, peer, signal_params);=0A=
+ =A0 g_free(signal_params);=0A=
+}=0A=
+=0A=
+static void interface_p2p_prov_disc_request_or_response(DBusMessageIter *i=
ter,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 void *user_data, bool is_request, cha=
r *wps_method)=0A=
+{=0A=
+ =A0 GSupplicantInterface *interface =3D user_data;=0A=
+ =A0 char *path, *pin =3D NULL;=0A=
+=0A=
+ =A0 if (dbus_message_iter_get_arg_type(iter) !=3D DBUS_TYPE_OBJECT_PATH) =
{=0A=
+ =A0 =A0 =A0 SUPPLICANT_DBG("not object path\n");=0A=
+ =A0 =A0 =A0 return;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 dbus_message_iter_get_basic(iter, &path);=0A=
+=0A=
+ =A0 if (g_str_equal(wps_method, "disp_pin")) {=0A=
+ =A0 =A0 =A0 dbus_message_iter_next(iter);=0A=
+=0A=
+ =A0 =A0 =A0 if (dbus_message_iter_get_arg_type(iter) !=3D DBUS_TYPE_STRIN=
G) {=0A=
+ =A0 =A0 =A0 =A0 =A0 SUPPLICANT_DBG("not string\n");=0A=
+ =A0 =A0 =A0 =A0 =A0 return;=0A=
+ =A0 =A0 =A0 }=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(iter, &pin);=0A=
+=0A=
+ =A0 =A0 =A0 if (!pin || strlen(pin) !=3D WPAS_P2P_WPS_PIN_LENGTH) {=0A=
+ =A0 =A0 =A0 =A0 =A0 SUPPLICANT_DBG("strange\n");=0A=
+ =A0 =A0 =A0 =A0 =A0 return;=0A=
+ =A0 =A0 =A0 }=0A=
+ =A0 }=0A=
+=0A=
+ =A0 g_supplicant_p2p_prov_dics_signal_func callback_method =3D NULL;=0A=
+=0A=
+ =A0 if (is_request) {=0A=
+ =A0 =A0 =A0 if (g_str_equal(wps_method, "pbc"))=0A=
+ =A0 =A0 =A0 =A0 =A0 callback_method =3D callback_p2p_prov_disc_requested_=
pbc;=0A=
+ =A0 =A0 =A0 else if (g_str_equal(wps_method, "enter_pin"))=0A=
+ =A0 =A0 =A0 =A0 =A0 callback_method =3D callback_p2p_prov_disc_requested_=
enter_pin;=0A=
+ =A0 =A0 =A0 else if (g_str_equal(wps_method, "disp_pin"))=0A=
+ =A0 =A0 =A0 =A0 =A0 callback_method =3D callback_p2p_prov_disc_requested_=
display_pin;=0A=
+ =A0 }=0A=
+ =A0 else {=0A=
+ =A0 =A0 =A0 if (g_str_equal(wps_method, "enter_pin"))=0A=
+ =A0 =A0 =A0 =A0 =A0 callback_method =3D callback_p2p_prov_disc_response_e=
nter_pin;=0A=
+ =A0 =A0 =A0 else if (g_str_equal(wps_method, "disp_pin"))=0A=
+ =A0 =A0 =A0 =A0 =A0 callback_method =3D callback_p2p_prov_disc_response_d=
isplay_pin;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 if (callback_method)=0A=
+ =A0 {=0A=
+ =A0 =A0 =A0 pin =3D g_strdup(pin);=0A=
+ =A0 =A0 =A0 fire_p2p_prov_dics_signal(interface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 path,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 callback_method,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (void *)pin);=0A=
+ =A0 }=0A=
+}=0A=
+=0A=
+static void signal_prov_disc_requested_pbc(const char *path, DBusMessageIt=
er *iter)=0A=
+{=0A=
+ =A0 GSupplicantInterface *interface;=0A=
+=0A=
+ =A0 interface =3D g_hash_table_lookup(interface_table, path);=0A=
+ =A0 if (!interface)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 interface_p2p_prov_disc_request_or_response(iter, interface, true, "p=
bc");=0A=
+}=0A=
+=0A=
+static void signal_prov_disc_requested_enter_pin(const char *path, DBusMes=
sageIter *iter)=0A=
+{=0A=
+ =A0 GSupplicantInterface *interface;=0A=
+=0A=
+ =A0 interface =3D g_hash_table_lookup(interface_table, path);=0A=
+ =A0 if (!interface)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 interface_p2p_prov_disc_request_or_response(iter, interface, true, "e=
nter_pin");=0A=
+}=0A=
+=0A=
+static void signal_prov_disc_requested_disp_pin(const char *path, DBusMess=
ageIter *iter)=0A=
+{=0A=
+ =A0 GSupplicantInterface *interface;=0A=
+=0A=
+ =A0 interface =3D g_hash_table_lookup(interface_table, path);=0A=
+ =A0 if (!interface)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 interface_p2p_prov_disc_request_or_response(iter, interface, true, "d=
isp_pin");=0A=
+}=0A=
+=0A=
+static void signal_prov_disc_response_enter_pin(const char *path, DBusMess=
ageIter *iter)=0A=
+{=0A=
+ =A0 GSupplicantInterface *interface;=0A=
+=0A=
+ =A0 interface =3D g_hash_table_lookup(interface_table, path);=0A=
+ =A0 if (!interface)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 interface_p2p_prov_disc_request_or_response(iter, interface, false, "=
enter_pin");=0A=
+}=0A=
+=0A=
+static void signal_prov_disc_response_disp_pin(const char *path, DBusMessa=
geIter *iter)=0A=
+{=0A=
+ =A0 GSupplicantInterface *interface;=0A=
+=0A=
+ =A0 interface =3D g_hash_table_lookup(interface_table, path);=0A=
+ =A0 if (!interface)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 interface_p2p_prov_disc_request_or_response(iter, interface, false, "=
disp_pin");=0A=
+}=0A=
+=0A=
+static void interface_p2p_prov_disc_fail(DBusMessageIter *iter, void *user=
_data)=0A=
+{=0A=
+ =A0 GSupplicantInterface *interface =3D user_data;=0A=
+ =A0 GSupplicantPeer *peer;=0A=
+ =A0 const char *path;=0A=
+ =A0 const char * status;=0A=
+=0A=
+ =A0 if (dbus_message_iter_get_arg_type(iter) !=3D DBUS_TYPE_OBJECT_PATH) =
{=0A=
+ =A0 =A0 =A0 SUPPLICANT_DBG("not object path\n");=0A=
+ =A0 =A0 =A0 return;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 dbus_message_iter_get_basic(iter, &path);=0A=
+=0A=
+ =A0 dbus_message_iter_next(iter);=0A=
+=0A=
+ =A0 if (dbus_message_iter_get_arg_type(iter) !=3D DBUS_TYPE_INT32) {=0A=
+ =A0 =A0 =A0 SUPPLICANT_DBG("not int32\n");=0A=
+ =A0 =A0 =A0 return;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 dbus_message_iter_get_basic(iter, &status);=0A=
+=0A=
+ =A0 peer =3D g_hash_table_lookup(interface->peer_table, path);=0A=
+=0A=
+ =A0 if (!peer)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 callback_p2p_prov_disc_fail(interface, peer, status);=0A=
+}=0A=
+=0A=
+static void signal_prov_disc_fail(const char *path, DBusMessageIter *iter)=
=0A=
+{=0A=
+ =A0 GSupplicantInterface *interface;=0A=
+=0A=
+ =A0 interface =3D g_hash_table_lookup(interface_table, path);=0A=
+ =A0 if (!interface)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 interface_p2p_prov_disc_fail(iter, interface);=0A=
+}=0A=
+=0A=
=A0static void interface_capability_keymgmt(DBusMessageIter *iter, void *us=
er_data)=0A=
=A0{=0A=
=A0 =A0 GSupplicantInterface *interface =3D user_data;=0A=
@@ -4377,6 +4638,14 @@ static struct {=0A=
=A0 =A0 { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GroupFinished", sig=
nal_group_finished },=0A=
=A0 =A0 { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "GONegotiationReques=
t", signal_group_request },=0A=
=A0=0A=
+ =A0 { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "ProvisionDiscoveryPBC=
Request", =A0signal_prov_disc_requested_pbc },=0A=
+ =A0 { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "ProvisionDiscoveryReq=
uestEnterPin", signal_prov_disc_requested_enter_pin },=0A=
+ =A0 { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "ProvisionDiscoveryReq=
uestDisplayPin", =A0 signal_prov_disc_requested_disp_pin },=0A=
+=0A=
+ =A0 { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "ProvisionDiscoveryRes=
ponseEnterPin", =A0 =A0signal_prov_disc_response_enter_pin },=0A=
+ =A0 { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "ProvisionDiscoveryRes=
ponseDisplayPin", =A0signal_prov_disc_response_disp_pin },=0A=
+ =A0 { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "ProvisionDiscoveryFai=
lure", signal_prov_disc_fail },=0A=
+=0A=
=A0 =A0 { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "InvitationResult", =
signal_invitation_result },=0A=
=A0 =A0 { SUPPLICANT_INTERFACE ".Interface.P2PDevice", "InvitationReceived"=
, signal_invitation_received },=0A=
=A0=0A=
@@ -4636,6 +4905,295 @@ int g_supplicant_interface_set_p2p_device_config(GS=
upplicantInterface *interface=0A=
=A0 =A0 return ret;=0A=
=A0}=0A=
=A0=0A=
+static void callback_p2p_device_config_loaded(GSupplicantInterface *interf=
ace)=0A=
+{=0A=
+ =A0 SUPPLICANT_DBG("");=0A=
+=0A=
+ =A0 if (!interface->p2p_support)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 if (callbacks_pointer && callbacks_pointer->p2p_device_config_loaded)=
=0A=
+ =A0 =A0 =A0 callbacks_pointer->p2p_device_config_loaded(interface);=0A=
+}=0A=
+=0A=
+static void p2p_device_config_property_update(DBusMessageIter *iter, void =
*user_data)=0A=
+{=0A=
+ =A0 GSupplicantP2PDeviceConfigParams *p2p_device_config =3D user_data;=0A=
+ =A0 DBusMessageIter iter_dict, iter_dict_entry;=0A=
+ =A0 char *key =3D NULL;=0A=
+=0A=
+ =A0 dbus_message_iter_recurse(iter, &iter_dict);=0A=
+ =A0 dbus_message_iter_get_basic(&iter_dict, &key);=0A=
+=0A=
+ =A0 dbus_message_iter_next(&iter_dict);=0A=
+ =A0 dbus_message_iter_recurse(&iter_dict, &iter_dict_entry);=0A=
+=0A=
+ =A0 if (!key)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 if (g_strcmp0(key, "DeviceName") =3D=3D 0) {=0A=
+ =A0 =A0 =A0 char *name =3D NULL;=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(&iter_dict_entry, &name);=0A=
+=0A=
+ =A0 =A0 =A0 if(p2p_device_config->device_name !=3D NULL){=0A=
+ =A0 =A0 =A0 =A0 =A0 g_free(p2p_device_config->device_name);=0A=
+ =A0 =A0 =A0 =A0 =A0 p2p_device_config->device_name =3D NULL;=0A=
+ =A0 =A0 =A0 }=0A=
+=0A=
+ =A0 =A0 =A0 p2p_device_config->device_name =3D g_strdup(name);=0A=
+=0A=
+ =A0 =A0 =A0 SUPPLICANT_DBG("device_name : %s\n", p2p_device_config->devic=
e_name);=0A=
+ =A0 } else if (g_strcmp0(key, "PrimaryDeviceType") =3D=3D 0) {=0A=
+ =A0 =A0 =A0 DBusMessageIter array;=0A=
+ =A0 =A0 =A0 unsigned char *device_type =3D NULL;=0A=
+ =A0 =A0 =A0 int type_len =3D 0;=0A=
+ =A0 =A0 =A0 int i=3D0;=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_recurse(&iter_dict_entry, &array);=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_fixed_array(&array, &device_type, &type=
_len);=0A=
+=0A=
+ =A0 =A0 =A0 if(type_len =3D=3D 8) {=0A=
+ =A0 =A0 =A0 =A0 =A0 for(i=3D0; i<type_len; i++)=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 p2p_device_config->pri_dev_type[i] =3D device=
_type[i];=0A=
+ =A0 =A0 =A0 } else {=0A=
+ =A0 =A0 =A0 =A0 =A0 SUPPLICANT_DBG("strange device type\n");=0A=
+ =A0 =A0 =A0 }=0A=
+ =A0 } else if (g_strcmp0(key, "GOIntent") =3D=3D 0) {=0A=
+ =A0 =A0 =A0 dbus_uint32_t go_intent;=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(&iter_dict_entry, &go_intent);=0A=
+ =A0 =A0 =A0 p2p_device_config->go_intent =3D go_intent;=0A=
+ =A0 =A0 =A0 SUPPLICANT_DBG("go_intent : %d\n", p2p_device_config->go_inte=
nt);=0A=
+ =A0 } else if (g_strcmp0(key, "PersistentReconnect") =3D=3D 0) {=0A=
+ =A0 =A0 =A0 dbus_bool_t persistent_reconnect;=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(&iter_dict_entry, &persistent_rec=
onnect);=0A=
+ =A0 =A0 =A0 p2p_device_config->persistent_reconnect =3D persistent_reconn=
ect;=0A=
+ =A0 =A0 =A0 SUPPLICANT_DBG("persistent_reconnect : %d\n", p2p_device_conf=
ig->persistent_reconnect);=0A=
+ =A0 } else if (g_strcmp0(key, "ListenRegClass") =3D=3D 0) {=0A=
+ =A0 =A0 =A0 dbus_uint32_t listen_reg_class;=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(&iter_dict_entry, &listen_reg_cla=
ss);=0A=
+ =A0 =A0 =A0 p2p_device_config->listen_reg_class =3D listen_reg_class;=0A=
+ =A0 =A0 =A0 SUPPLICANT_DBG("listen_reg_class : %d\n", p2p_device_config->=
listen_reg_class);=0A=
+ =A0 } else if (g_strcmp0(key, "ListenChannel") =3D=3D 0) {=0A=
+ =A0 =A0 =A0 dbus_uint32_t listen_channel;=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(&iter_dict_entry, &listen_channel=
);=0A=
+ =A0 =A0 =A0 p2p_device_config->listen_channel =3D listen_channel;=0A=
+ =A0 } else if (g_strcmp0(key, "OperRegClass") =3D=3D 0) {=0A=
+ =A0 =A0 =A0 dbus_uint32_t oper_reg_class;=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(&iter_dict_entry, &oper_reg_class=
);=0A=
+ =A0 =A0 =A0 p2p_device_config->oper_reg_class =3D oper_reg_class;=0A=
+ =A0 } else if (g_strcmp0(key, "OperChannel") =3D=3D 0) {=0A=
+ =A0 =A0 =A0 dbus_uint32_t oper_channel;=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(&iter_dict_entry, &oper_channel);=
=0A=
+ =A0 =A0 =A0 p2p_device_config->oper_channel =3D oper_channel;=0A=
+ =A0 } else if (g_strcmp0(key, "SsidPostfix") =3D=3D 0) {=0A=
+ =A0 =A0 =A0 char *ssid_postfix =3D NULL;=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(&iter_dict_entry, &ssid_postfix);=
=0A=
+=0A=
+ =A0 =A0 =A0 if(p2p_device_config->ssid_postfix !=3D NULL){=0A=
+ =A0 =A0 =A0 =A0 =A0 g_free(p2p_device_config->ssid_postfix);=0A=
+ =A0 =A0 =A0 =A0 =A0 p2p_device_config->ssid_postfix =3D NULL;=0A=
+ =A0 =A0 =A0 }=0A=
+=0A=
+ =A0 =A0 =A0 p2p_device_config->ssid_postfix =3D g_strdup(ssid_postfix);=
=0A=
+ =A0 } else if (g_strcmp0(key, "IntraBss") =3D=3D 0) {=0A=
+ =A0 =A0 =A0 dbus_bool_t intra_bss;=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(&iter_dict_entry, &intra_bss);=0A=
+ =A0 =A0 =A0 p2p_device_config->intra_bss =3D intra_bss;=0A=
+ =A0 } else if (g_strcmp0(key, "GroupIdle") =3D=3D 0) {=0A=
+ =A0 =A0 =A0 dbus_uint32_t group_idle;=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(&iter_dict_entry, &group_idle);=
=0A=
+ =A0 =A0 =A0 p2p_device_config->group_idle =3D group_idle;=0A=
+ =A0 } else if (g_strcmp0(key, "disassoc_low_ack") =3D=3D 0) {=0A=
+ =A0 =A0 =A0 dbus_uint32_t disassoc_low_ack;=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(&iter_dict_entry, &disassoc_low_a=
ck);=0A=
+ =A0 =A0 =A0 p2p_device_config->disassoc_low_ack =3D disassoc_low_ack;=0A=
+ =A0 } else=0A=
+ =A0 =A0 =A0 SUPPLICANT_DBG("key %s type %c",=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 key, dbus_message_iter_get_arg_type(&=
iter_dict_entry));=0A=
+}=0A=
+=0A=
+static void p2p_device_config_property(const char *key, DBusMessageIter *i=
ter,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 void *user_data)=0A=
+{=0A=
+ =A0 GSupplicantInterface *interface;=0A=
+ =A0 GSupplicantP2PInterface *p2p_device_interface =3D user_data;=0A=
+ =A0 GSupplicantP2PDeviceConfigParams *p2p_device_config =3D p2p_device_in=
terface->p2p_device_config_param;;=0A=
+=0A=
+ =A0 GSupplicantInterface *check_interface =3D NULL;=0A=
+=0A=
+ =A0 if (key){=0A=
+ =A0 =A0 =A0 check_interface =3D g_hash_table_lookup(interface_table, key)=
;=0A=
+ =A0 =A0 =A0 if (check_interface =3D=3D NULL)=0A=
+ =A0 =A0 =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 =A0 =A0 struct wifi_data *check_wifi =3D g_supplicant_interface_get_d=
ata(check_interface);=0A=
+ =A0 =A0 =A0 if (check_wifi =3D=3D NULL)=0A=
+ =A0 =A0 =A0 =A0 =A0 return;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 if (p2p_device_config->interface->path =3D=3D NULL)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 interface =3D g_hash_table_lookup(interface_table, p2p_device_config-=
>interface->path);=0A=
+ =A0 if (interface =3D=3D NULL || interface !=3D p2p_device_config->interf=
ace) {=0A=
+ =A0 =A0 =A0 g_free(p2p_device_interface->path);=0A=
+ =A0 =A0 =A0 g_free(p2p_device_interface);=0A=
+ =A0 =A0 =A0 return;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 if (iter)=0A=
+ =A0 =A0 =A0 supplicant_dbus_array_foreach(iter, p2p_device_config_propert=
y_update, p2p_device_config);=0A=
+=0A=
+ =A0 callback_p2p_device_config_loaded(p2p_device_config->interface);=0A=
+=0A=
+ =A0 g_free(p2p_device_interface->path);=0A=
+ =A0 g_free(p2p_device_interface);=0A=
+}=0A=
+=0A=
+=0A=
+=0A=
+int g_supplicant_interface_get_p2p_device_config(GSupplicantInterface *int=
erface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantP2PDeviceConfigParams *p2p=
_device_config_data)=0A=
+{=0A=
+ =A0 GSupplicantP2PInterface *p2p_device_interface =3D NULL;=0A=
+ =A0 int ret;=0A=
+=0A=
+ =A0 if (!interface)=0A=
+ =A0 =A0 =A0 return -EINVAL;=0A=
+=0A=
+ =A0 if (!system_available)=0A=
+ =A0 =A0 =A0 return -EFAULT;=0A=
+=0A=
+ =A0 p2p_device_interface =3D g_try_malloc0(sizeof(GSupplicantP2PInterface=
));=0A=
+ =A0 if(!p2p_device_interface)=0A=
+ =A0 =A0 =A0 return -ENOMEM;=0A=
+=0A=
+ =A0 p2p_device_interface->path =3D g_strdup(interface->path);=0A=
+ =A0 p2p_device_interface->p2p_device_config_param =3D p2p_device_config_d=
ata;=0A=
+ =A0 p2p_device_interface->p2p_device_config_param->interface =3D interfac=
e;=0A=
+=0A=
+ =A0 ret =3D supplicant_dbus_property_get(interface->path,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 SUPPLICANT_INTERFACE ".Interface.P2PDevice",=
=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 "P2PDeviceConfig",=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 p2p_device_config_property,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 p2p_device_interface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 NULL);=0A=
+=0A=
+ =A0 if (ret < 0) {=0A=
+ =A0 =A0 =A0 g_free(p2p_device_interface->path);=0A=
+ =A0 =A0 =A0 g_free(p2p_device_interface);=0A=
+ =A0 =A0 =A0 SUPPLICANT_DBG("Unable to get P2P Device configuration");=0A=
+ =A0 }=0A=
+=0A=
+ =A0 return ret;=0A=
+}=0A=
+=0A=
+static void interface_set_p2p_device_config_result(const char *error,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 DBusMessageIter *iter, void *user_data)=0A=
+{=0A=
+ =A0 struct interface_p2p_device_config *config =3D user_data;=0A=
+=0A=
+ =A0 if (error) {=0A=
+ =A0 =A0 =A0 SUPPLICANT_DBG("error %s", error);=0A=
+ =A0 }=0A=
+=0A=
+ =A0 dbus_free(config);=0A=
+}=0A=
+=0A=
+static void interface_set_p2p_device_config_params(DBusMessageIter *iter, =
void *user_data)=0A=
+{=0A=
+ =A0 struct interface_p2p_device_config *config =3D user_data;=0A=
+ =A0 GSupplicantP2PDeviceConfigParams *config_params =3D config->p2p_devic=
e_config_params;=0A=
+ =A0 DBusMessageIter dict;=0A=
+ =A0 uint8_t *pri_dev_type =3D config_params->pri_dev_type;=0A=
+ =A0 uint8_t pri_dev_type_check[8] =3D {0,};=0A=
+=0A=
+ =A0 supplicant_dbus_dict_open(iter, &dict);=0A=
+=0A=
+ =A0 if(config_params->device_name)=0A=
+ =A0 =A0 =A0 supplicant_dbus_dict_append_basic(&dict, "DeviceName", DBUS_T=
YPE_STRING, &config_params->device_name);=0A=
+=0A=
+ =A0 if(memcmp(&pri_dev_type_check[0], pri_dev_type, 8) !=3D 0)=0A=
+ =A0 =A0 =A0 supplicant_dbus_dict_append_fixed_array(&dict, "PrimaryDevice=
Type", DBUS_TYPE_BYTE, &pri_dev_type, 8);=0A=
+=0A=
+ =A0 if(config_params->go_intent !=3D 0)=0A=
+ =A0 =A0 =A0 supplicant_dbus_dict_append_basic(&dict, "GOIntent", DBUS_TYP=
E_UINT32, &config_params->go_intent);=0A=
+=0A=
+ =A0 supplicant_dbus_dict_append_basic(&dict, "PersistentReconnect", DBUS_=
TYPE_BOOLEAN, &config_params->persistent_reconnect);=0A=
+=0A=
+ =A0 if(config_params->listen_reg_class !=3D 0)=0A=
+ =A0 =A0 =A0 supplicant_dbus_dict_append_basic(&dict, "ListenRegClass", DB=
US_TYPE_UINT32, &config_params->listen_reg_class);=0A=
+=0A=
+ =A0 if(config_params->listen_channel !=3D 0)=0A=
+ =A0 =A0 =A0 supplicant_dbus_dict_append_basic(&dict, "ListenChannel", DBU=
S_TYPE_UINT32, &config_params->listen_channel);=0A=
+=0A=
+ =A0 if(config_params->oper_reg_class !=3D 0)=0A=
+ =A0 =A0 =A0 supplicant_dbus_dict_append_basic(&dict, "OperRegClass", DBUS=
_TYPE_UINT32, &config_params->oper_reg_class);=0A=
+=0A=
+ =A0 if(config_params->oper_channel !=3D 0)=0A=
+ =A0 =A0 =A0 supplicant_dbus_dict_append_basic(&dict, "OperChannel", DBUS_=
TYPE_UINT32, &config_params->oper_channel);=0A=
+=0A=
+ =A0 if(config_params->ssid_postfix)=0A=
+ =A0 =A0 =A0 supplicant_dbus_dict_append_basic(&dict, "SsidPostfix", DBUS_=
TYPE_STRING, &config_params->ssid_postfix);=0A=
+=0A=
+ =A0 supplicant_dbus_dict_append_basic(&dict, "IntraBss", DBUS_TYPE_BOOLEA=
N, &config_params->intra_bss);=0A=
+=0A=
+ =A0 if(config_params->group_idle !=3D 0)=0A=
+ =A0 =A0 =A0 supplicant_dbus_dict_append_basic(&dict, "GroupIdle", DBUS_TY=
PE_UINT32, &config_params->group_idle);=0A=
+=0A=
+ =A0 if(config_params->disassoc_low_ack !=3D 0)=0A=
+ =A0 =A0 =A0 supplicant_dbus_dict_append_basic(&dict, "disassoc_low_ack", =
DBUS_TYPE_UINT32, &config_params->disassoc_low_ack);=0A=
+=0A=
+ =A0 supplicant_dbus_dict_close(iter, &dict);=0A=
+}=0A=
+=0A=
+int g_supplicant_interface_set_p2p_device_configs(GSupplicantInterface *in=
terface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 GSupplicantP2PDeviceConfigParams *p2p_device_config_dat=
a,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 void *user_data)=0A=
+{=0A=
+ =A0 struct interface_p2p_device_config *config =3D NULL;=0A=
+ =A0 int ret;=0A=
+=0A=
+ =A0 if (!interface)=0A=
+ =A0 =A0 =A0 return -EINVAL;=0A=
+=0A=
+ =A0 config =3D dbus_malloc0(sizeof(*config));=0A=
+ =A0 if (!config)=0A=
+ =A0 =A0 =A0 return -ENOMEM;=0A=
+=0A=
+ =A0 config->interface =3D interface;=0A=
+ =A0 config->user_data =3D user_data;=0A=
+ =A0 config->p2p_device_config_params =3D p2p_device_config_data;=0A=
+=0A=
+ =A0 ret =3D supplicant_dbus_property_set(interface->path,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 SUPPLICANT_INTERFACE ".Interface.P2PDevice",=
=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 "P2PDeviceConfig", DBUS_TYPE_ARRAY_AS_STRING=
=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 DBUS_TYPE_STRING_AS_STRING=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 DBUS_TYPE_VARIANT_AS_STRING=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 interface_set_p2p_device_config_params,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 interface_set_p2p_device_config_result, confi=
g, NULL);=0A=
+=0A=
+ =A0 if (ret < 0) {=0A=
+ =A0 =A0 =A0 dbus_free(config);=0A=
+ =A0 =A0 =A0 SUPPLICANT_DBG("Unable to set P2P Device configuration");=0A=
+ =A0 }=0A=
+=0A=
+ =A0 return ret;=0A=
+}=0A=
+=0A=
=A0static gboolean peer_lookup_by_identifier(gpointer key, gpointer value,=
=0A=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 gpointer user_data)=
=0A=
=A0{=0A=
diff --git a/include/technology.h b/include/technology.h=0A=
index 965ad49..a094c04 100644=0A=
--- a/include/technology.h=0A=
+++ b/include/technology.h=0A=
@@ -69,6 +69,10 @@ struct connman_technology_driver {=0A=
=A0 =A0 int (*set_p2p_listen) (struct connman_technology *technology, bool =
enable);=0A=
=A0 =A0 int (*set_p2p_go) (DBusMessage *msg, struct connman_technology *tec=
hnology,=0A=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 const char *identifier, con=
st char *passphrase);=0A=
+ =A0 int (*set_p2p_identifier) (struct connman_technology *technology,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 const char *p2p_identifier);=
=0A=
+ =A0 int (*set_p2p_persistent) (struct connman_technology *technology,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 bool persistent_reconnect);=
=0A=
=A0};=0A=
=A0=0A=
=A0int connman_technology_driver_register(struct connman_technology_driver =
*driver);=0A=
@@ -77,6 +81,11 @@ void connman_technology_set_p2p_listen(struct connman_te=
chnology *technology,boo=0A=
=A0bool connman_technology_get_p2p_listen(struct connman_technology *techno=
logy);=0A=
=A0void __connman_technology_p2p_invitation_result(struct connman_technolog=
y *technology,=0A=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 int status);=0A=
+void connman_technology_set_p2p_identifier(struct connman_technology *tech=
nology,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 const char *p2p_ident=
ifier);=0A=
+bool is_technology_enabled(struct connman_technology *technology);=0A=
+bool connman_technology_get_p2p_persistent(struct connman_technology *tech=
nology);=0A=
+void connman_technology_set_p2p_persistent(struct connman_technology *tech=
nology, bool enabled);=0A=
=A0#ifdef __cplusplus=0A=
=A0}=0A=
=A0#endif=0A=
diff --git a/plugins/wifi.c b/plugins/wifi.c=0A=
index c6629f1..121259a 100644=0A=
--- a/plugins/wifi.c=0A=
+++ b/plugins/wifi.c=0A=
@@ -91,6 +91,8 @@ static guint p2p_scan_ref =3D 0;=0A=
=A0=0A=
=A0static int p2p_find_ref =3D -1;=0A=
=A0=0A=
+static int pin_requested_ref =3D -1;=0A=
+=0A=
=A0#define ASSOC_STATUS_AUTH_TIMEOUT 16=0A=
=A0#define ASSOC_STATUS_NO_CLIENT 17=0A=
=A0#define LOAD_SHAPING_MAX_RETRIES 3=0A=
@@ -184,6 +186,10 @@ struct wifi_data {=0A=
=A0 =A0 int disconnect_code;=0A=
=A0 =A0 int assoc_code;=0A=
=A0 =A0 const char *invited_path;=0A=
+ =A0 const char *generated_pin;=0A=
+ =A0 const char *pin_requested_path;=0A=
+ =A0 GSupplicantP2PDeviceConfigParams p2p_device_config;=0A=
+=0A=
=A0};=0A=
=A0=0A=
=A0struct wifi_network {=0A=
@@ -310,6 +316,202 @@ static int tech_set_p2p_go(DBusMessage *msg, struct c=
onnman_technology *technolo=0A=
=A0 =A0 return -err;=0A=
=A0}=0A=
=A0=0A=
+static void save_p2p_identifier(const char *p2p_identifier)=0A=
+{=0A=
+ =A0 GKeyFile *keyfile =3D NULL;=0A=
+ =A0 gchar *identifier =3D NULL;=0A=
+=0A=
+ =A0 keyfile =3D __connman_storage_load_global();=0A=
+ =A0 if(!keyfile)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 identifier =3D g_strdup_printf("%s", "WiFi");=0A=
+ =A0 if (!identifier) {=0A=
+ =A0 =A0 =A0 g_key_file_free(keyfile);=0A=
+ =A0 =A0 =A0 return;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 g_key_file_set_string(keyfile, identifier, "P2PIdentifier", p2p_ident=
ifier);=0A=
+ =A0 g_free(identifier);=0A=
+=0A=
+ =A0 __connman_storage_save_global(keyfile);=0A=
+=0A=
+ =A0 g_key_file_free(keyfile);=0A=
+}=0A=
+=0A=
+static int tech_set_p2p_identifier(struct connman_technology *technology, =
const char *p2p_identifier)=0A=
+{=0A=
+ =A0 GList *list =3D NULL;=0A=
+ =A0 char *old_device_name =3D NULL;=0A=
+ =A0 char *old_ssid_postfix =3D NULL;=0A=
+ =A0 int err =3D -EOPNOTSUPP;=0A=
+=0A=
+ =A0 if (!p2p_technology)=0A=
+ =A0 =A0 =A0 return -EOPNOTSUPP;=0A=
+=0A=
+ =A0 if (is_technology_enabled(p2p_technology)) {=0A=
+ =A0 =A0 =A0 for (list =3D iface_list; list; list =3D list->next) {=0A=
+ =A0 =A0 =A0 =A0 =A0 struct wifi_data *wifi =3D list->data;=0A=
+ =A0 =A0 =A0 =A0 =A0 GSupplicantInterface *iface =3D wifi->interface;=0A=
+=0A=
+ =A0 =A0 =A0 =A0 =A0 if (!g_supplicant_interface_has_p2p(iface))=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 continue;=0A=
+=0A=
+ =A0 =A0 =A0 =A0 =A0 if (wifi->p2p_device_config.device_name)=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 old_device_name =3D wifi->p2p_device_config.d=
evice_name;=0A=
+=0A=
+ =A0 =A0 =A0 =A0 =A0 if (wifi->p2p_device_config.ssid_postfix)=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 old_ssid_postfix =3D wifi->p2p_device_config.=
ssid_postfix;=0A=
+=0A=
+ =A0 =A0 =A0 =A0 =A0 wifi->p2p_device_config.device_name =3D g_strdup(p2p_=
identifier);=0A=
+ =A0 =A0 =A0 =A0 =A0 wifi->p2p_device_config.ssid_postfix =3D g_strdup_pri=
ntf("-%s", p2p_identifier);=0A=
+=0A=
+ =A0 =A0 =A0 =A0 =A0 err =3D g_supplicant_interface_set_p2p_device_configs=
(iface, &wifi->p2p_device_config, NULL);=0A=
+=0A=
+ =A0 =A0 =A0 =A0 =A0 if(err < 0) {=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 g_free(wifi->p2p_device_config.device_name);=
=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 g_free(wifi->p2p_device_config.ssid_postfix);=
=0A=
+=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 wifi->p2p_device_config.device_name =3D old_d=
evice_name;=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 wifi->p2p_device_config.ssid_postfix =3D old_=
ssid_postfix;=0A=
+ =A0 =A0 =A0 =A0 =A0 } else {=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 connman_technology_set_p2p_identifier(technol=
ogy, wifi->p2p_device_config.device_name);=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 save_p2p_identifier(wifi->p2p_device_config.d=
evice_name);=0A=
+=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 g_free(old_device_name);=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 g_free(old_ssid_postfix);=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 old_device_name =3D NULL;=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 old_ssid_postfix =3D NULL;=0A=
+ =A0 =A0 =A0 =A0 =A0 }=0A=
+ =A0 =A0 =A0 }=0A=
+ =A0 } else {=0A=
+ =A0 =A0 =A0 connman_technology_set_p2p_identifier(technology, p2p_identif=
ier);=0A=
+ =A0 =A0 =A0 save_p2p_identifier(p2p_identifier);=0A=
+ =A0 =A0 =A0 err =3D 0;=0A=
+ =A0 }=0A=
+ =A0 return err;=0A=
+}=0A=
+=0A=
+static const char *load_p2p_identifier()=0A=
+{=0A=
+ =A0 GKeyFile *keyfile =3D NULL;=0A=
+ =A0 gchar *identifier =3D NULL;=0A=
+ =A0 const char *p2p_identifier =3D NULL;=0A=
+=0A=
+ =A0 keyfile =3D __connman_storage_load_global();=0A=
+ =A0 if(!keyfile)=0A=
+ =A0 =A0 =A0 return NULL;=0A=
+=0A=
+ =A0 identifier =3D g_strdup_printf("%s", "WiFi");=0A=
+ =A0 if (!identifier) {=0A=
+ =A0 =A0 =A0 g_key_file_free(keyfile);=0A=
+ =A0 =A0 =A0 return NULL;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 p2p_identifier =3D g_key_file_get_string(keyfile, identifier, "P2PIde=
ntifier", NULL);=0A=
+ =A0 g_free(identifier);=0A=
+=0A=
+ =A0 if(!p2p_identifier) {=0A=
+ =A0 =A0 =A0 g_key_file_free(keyfile);=0A=
+ =A0 =A0 =A0 return NULL;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 if(strlen(p2p_identifier) > 32)=0A=
+ =A0 {=0A=
+ =A0 =A0 =A0 g_free(p2p_identifier);=0A=
+ =A0 =A0 =A0 p2p_identifier =3D NULL;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 g_key_file_free(keyfile);=0A=
+=0A=
+ =A0 return p2p_identifier;=0A=
+}=0A=
+=0A=
+static void p2p_device_config_loaded(GSupplicantInterface *interface)=0A=
+{=0A=
+ =A0 struct wifi_data *wifi =3D NULL;=0A=
+ =A0 char dev_type[17] =3D {};=0A=
+ =A0 char hostname[HOST_NAME_MAX+1] =3D {0};=0A=
+ =A0 const char *p2p_identifier;=0A=
+ =A0 char *old_device_name =3D NULL, *old_ssid_postfix =3D NULL;=0A=
+ =A0 int result;=0A=
+=0A=
+ =A0 wifi =3D g_supplicant_interface_get_data(interface);=0A=
+=0A=
+ =A0 if (!wifi)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 p2p_identifier =3D load_p2p_identifier();=0A=
+ =A0 if (wifi->p2p_device_config.device_name)=0A=
+ =A0 =A0 =A0 old_device_name =3D wifi->p2p_device_config.device_name;=0A=
+=0A=
+ =A0 if (wifi->p2p_device_config.ssid_postfix)=0A=
+ =A0 =A0 =A0 old_ssid_postfix =3D wifi->p2p_device_config.ssid_postfix;=0A=
+=0A=
+ =A0 if (!p2p_identifier) {=0A=
+ =A0 =A0 =A0 if (gethostname(hostname, HOST_NAME_MAX) < 0)=0A=
+ =A0 =A0 =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 =A0 =A0 wifi->p2p_device_config.device_name =3D g_strdup(hostname);=
=0A=
+ =A0 }=0A=
+ =A0 else=0A=
+ =A0 =A0 =A0 wifi->p2p_device_config.device_name =3D g_strdup(p2p_identifi=
er);=0A=
+=0A=
+ =A0 if (wifi->p2p_device_config.device_name) {=0A=
+ =A0 =A0 =A0 /* we have to add a hyphen here as wpa-supplicant just adds t=
he postifx to the=0A=
+ =A0 =A0 =A0 =A0* automatically created SSID */=0A=
+ =A0 =A0 =A0 wifi->p2p_device_config.ssid_postfix =3D g_strdup_printf("-%s=
", wifi->p2p_device_config.device_name);=0A=
+ =A0 }=0A=
+=0A=
+ =A0 /**=0A=
+ =A0 =A0* TV icon type listed as Laptop. Reason is the machine type relate=
d interface org.freedesktop.hostname1=0A=
+ =A0 =A0* is not used ,commenting the below source ,using the type from wp=
a_supplicant as it is=0A=
+ =A0 =A0*/=0A=
+ =A0 /* =A0set_device_type(connman_machine_get_type(), dev_type);=0A=
+ =A0 =A0dev_type_str2bin(dev_type, wifi->p2p_device_config.pri_dev_type);*=
/=0A=
+=0A=
+ =A0 result =3D g_supplicant_interface_set_p2p_device_configs(interface, &=
wifi->p2p_device_config, NULL);=0A=
+ =A0 if (result < 0) {=0A=
+ =A0 =A0 =A0 g_free(wifi->p2p_device_config.device_name);=0A=
+ =A0 =A0 =A0 g_free(wifi->p2p_device_config.ssid_postfix);=0A=
+ =A0 =A0 =A0 wifi->p2p_device_config.device_name =3D old_device_name;=0A=
+ =A0 =A0 =A0 wifi->p2p_device_config.ssid_postfix =3D old_ssid_postfix;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 connman_technology_set_p2p_identifier(p2p_technology, wifi->p2p_devic=
e_config.device_name);=0A=
+ =A0 if (old_device_name !=3D wifi->p2p_device_config.device_name)=0A=
+ =A0 =A0 =A0 g_free(old_device_name);=0A=
+ =A0 if (old_ssid_postfix !=3D wifi->p2p_device_config.ssid_postfix)=0A=
+ =A0 =A0 =A0 g_free(old_ssid_postfix);=0A=
+=0A=
+ =A0 =A0g_free(p2p_identifier);=0A=
+}=0A=
+=0A=
+static int tech_set_p2p_persistent(struct connman_technology *technology, =
bool persistent_reconnect)=0A=
+{=0A=
+ =A0 GList *list =3D NULL;=0A=
+ =A0 int err =3D 0;=0A=
+=0A=
+ =A0 if (!p2p_technology)=0A=
+ =A0 =A0 =A0 return -EOPNOTSUPP;=0A=
+=0A=
+ =A0 for (list =3D iface_list; list; list =3D list->next) {=0A=
+ =A0 =A0 =A0 struct wifi_data *wifi =3D list->data;=0A=
+ =A0 =A0 =A0 GSupplicantInterface *iface =3D wifi->interface;=0A=
+=0A=
+ =A0 =A0 =A0 if (!g_supplicant_interface_has_p2p(iface))=0A=
+ =A0 =A0 =A0 =A0 =A0 continue;=0A=
+=0A=
+ =A0 =A0 =A0 wifi->p2p_device_config.persistent_reconnect =3D persistent_r=
econnect;=0A=
+=0A=
+ =A0 =A0 =A0 err =3D g_supplicant_interface_set_p2p_device_configs(iface, =
&wifi->p2p_device_config, NULL);=0A=
+ =A0 =A0 =A0 DBG("g_supplicant_interface_set_p2p_device_configs : %d\n",er=
r);=0A=
+=0A=
+ =A0 }=0A=
+=0A=
+=0A=
+ =A0 return err;=0A=
+}=0A=
=A0=0A=
=A0static struct connman_technology_driver p2p_tech_driver =3D {=0A=
=A0 =A0 .name =A0 =A0 =A0 =3D "p2p",=0A=
@@ -317,6 +519,8 @@ static struct connman_technology_driver p2p_tech_driver=
 =3D {=0A=
=A0 =A0 .probe =A0 =A0 =A0=3D p2p_tech_probe,=0A=
=A0 =A0 .remove =A0 =A0 =3D p2p_tech_remove,=0A=
=A0 =A0 .set_p2p_go =3D tech_set_p2p_go,=0A=
+ =A0 .set_p2p_identifier =3D tech_set_p2p_identifier,=0A=
+ =A0 .set_p2p_persistent =3D tech_set_p2p_persistent,=0A=
=A0};=0A=
=A0=0A=
=A0static bool is_p2p_connecting(void)=0A=
@@ -493,6 +697,11 @@ static int peer_connect(struct connman_peer *peer,=0A=
=A0=0A=
=A0 =A0 peer_params->master =3D connman_peer_service_is_master();=0A=
=A0=0A=
+ =A0 if(connman_technology_get_p2p_persistent(p2p_technology))=0A=
+ =A0 =A0 =A0 peer_params->persistent =3D TRUE;=0A=
+ =A0 else=0A=
+ =A0 =A0 =A0 peer_params->persistent =3D FALSE;=0A=
+=0A=
=A0 =A0 ret =3D g_supplicant_interface_p2p_connect(wifi->interface, peer_pa=
rams,=0A=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 peer_connect_callback, wifi=
);=0A=
=A0 =A0 if (ret =3D=3D -EINPROGRESS) {=0A=
@@ -539,7 +748,6 @@ static int peer_disconnect(struct connman_peer *peer)=
=0A=
=A0 =A0 =A0 =A0 peer_cancel_timeout(wifi);=0A=
=A0 =A0 =A0 =A0 wifi->p2p_device =3D false;=0A=
=A0 =A0 }=0A=
-=0A=
=A0 =A0 return ret;=0A=
=A0}=0A=
=A0=0A=
@@ -1768,6 +1976,10 @@ static int wifi_disable(struct connman_device *devic=
e)=0A=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CONNMAN_SERVICE_TYPE_WIFI, false);=0A=
=A0 =A0 =A0 =A0 connman_device_unref(wifi->device);=0A=
=A0 =A0 }=0A=
+ =A0 if(p2p_technology) {=0A=
+ =A0 =A0 =A0 if (connman_technology_get_p2p_listen(p2p_technology))=0A=
+ =A0 =A0 =A0 =A0 =A0 tech_set_p2p_listen(p2p_technology, false);=0A=
+ =A0 }=0A=
=A0=0A=
=A0 =A0 remove_networks(device, wifi);=0A=
=A0 =A0 remove_peers(wifi);=0A=
@@ -3575,6 +3787,7 @@ static void peer_request(GSupplicantPeer *peer)=0A=
=A0 =A0 if (!connman_peer)=0A=
=A0 =A0 =A0 =A0 return;=0A=
=A0=0A=
+ =A0 peer_connect(connman_peer,CONNMAN_PEER_WPS_PBC,NULL);=0A=
=A0 =A0 connman_peer_request_connection(connman_peer);=0A=
=A0}=0A=
=A0=0A=
@@ -3677,6 +3890,194 @@ static void p2p_group_finished(GSupplicantInterface=
 *interface)=0A=
=A0 =A0 __connman_group_remove(interface);=0A=
=A0}=0A=
=A0=0A=
+=0A=
+=0A=
+static void p2p_prov_disc_requested_pbc(GSupplicantInterface *interface,=
=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantPeer *peer)=0A=
+{=0A=
+ =A0 struct wifi_data *wifi =3D g_supplicant_interface_get_data(interface)=
;=0A=
+ =A0 struct connman_peer *connman_peer;=0A=
+ =A0 const char *identifier, *path;=0A=
+ =A0 const char *sig =3D "pbc";=0A=
+=0A=
+ =A0 if (!wifi || !wifi->device)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 identifier =3D g_supplicant_peer_get_identifier(peer);=0A=
+=0A=
+ =A0 DBG("ident: %s", identifier);=0A=
+=0A=
+ =A0 connman_peer =3D connman_peer_get(wifi->device, identifier);=0A=
+ =A0 if (!connman_peer)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 connman_peer_set_state(connman_peer, CONNMAN_PEER_STATE_IDLE);=0A=
+ =A0 //connman_peer_set_as_master(connman_peer, false);=0A=
+=0A=
+ =A0 path =3D __connman_peer_get_path(connman_peer);=0A=
+=0A=
+ =A0 if (path && p2p_go_identifier) {=0A=
+ =A0 =A0 =A0 connman_dbus_property_changed_basic(path,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CONNMAN_SERVICE_INTERFACE,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "P2PProvDiscRequestedPBC",=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 DBUS_TYPE_STRING, &sig);=0A=
+ =A0 }=0A=
+}=0A=
+=0A=
+static void p2p_prov_disc_requested_enter_pin(GSupplicantInterface *interf=
ace,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantPeer *peer)=0A=
+{=0A=
+ =A0 struct wifi_data *wifi =3D g_supplicant_interface_get_data(interface)=
;=0A=
+ =A0 struct connman_peer *connman_peer;=0A=
+ =A0 struct connman_network *connman_network;=0A=
+ =A0 const char *identifier, *path;=0A=
+ =A0 const char *sig =3D "keypad";=0A=
+=0A=
+ =A0 if (!wifi || !wifi->device)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 identifier =3D g_supplicant_peer_get_identifier(peer);=0A=
+=0A=
+ =A0 DBG("ident: %s", identifier);=0A=
+=0A=
+ =A0 connman_network =3D connman_device_get_network(wifi->device, identifi=
er);=0A=
+ =A0 if (!connman_network)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 //wfds_on_p2p_pin_requested(connman_network, NULL);=0A=
+=0A=
+ =A0 connman_peer =3D connman_peer_get(wifi->device, identifier);=0A=
+ =A0 if (!connman_peer)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 connman_peer_set_state(connman_peer, CONNMAN_PEER_STATE_IDLE);=0A=
+ =A0 connman_peer_set_as_master(connman_peer, false);=0A=
+=0A=
+ =A0 path =3D __connman_peer_get_path(connman_peer);=0A=
+=0A=
+ =A0 if (p2p_go_identifier) {=0A=
+ =A0 =A0 =A0 connman_dbus_property_changed_basic(path,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CONNMAN_SERVICE_INTERFACE,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "P2PProvDiscRequestedEnterPin",=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 DBUS_TYPE_STRING, &sig);=0A=
+ =A0 }=0A=
+}=0A=
+=0A=
+static gboolean p2p_pin_requested(gpointer argv)=0A=
+{=0A=
+ =A0 pin_requested_ref =3D -1;=0A=
+=0A=
+ =A0 return FALSE;=0A=
+}=0A=
+=0A=
+static void p2p_prov_disc_requested_display_pin(GSupplicantInterface *inte=
rface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantPeer *peer, const char *pi=
n)=0A=
+{=0A=
+ =A0 struct wifi_data *wifi =3D g_supplicant_interface_get_data(interface)=
;=0A=
+ =A0 struct connman_peer *connman_peer;=0A=
+ =A0 struct connman_network *connman_network;=0A=
+ =A0 const char *identifier, *path;=0A=
+ =A0 const char *sig =3D "keypad";=0A=
+=0A=
+ =A0 if (!wifi || !wifi->device)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 identifier =3D g_supplicant_peer_get_identifier(peer);=0A=
+=0A=
+ =A0 DBG("ident: %s", identifier);=0A=
+=0A=
+ =A0 /** Throttle pin requested messages */=0A=
+ =A0 if (pin_requested_ref !=3D -1) {=0A=
+ =A0 =A0 =A0 g_source_remove(pin_requested_ref);=0A=
+ =A0 =A0 =A0 pin_requested_ref =3D g_timeout_add_seconds(2, p2p_pin_reques=
ted, NULL);=0A=
+ =A0 =A0 =A0 return;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 connman_network =3D connman_device_get_network(wifi->device, identifi=
er);=0A=
+ =A0 if (!connman_network)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 connman_peer =3D connman_peer_get(wifi->device, identifier);=0A=
+ =A0 if (!connman_peer)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 connman_peer_set_state(connman_peer, CONNMAN_PEER_STATE_IDLE);=0A=
+ =A0 //connman_peer_set_as_master(connman_peer, false);=0A=
+ =A0 path =3D __connman_peer_get_path(connman_peer);=0A=
+=0A=
+ =A0 wifi->generated_pin =3D pin;=0A=
+ =A0 wifi->pin_requested_path =3D connman_network_get_string(connman_netwo=
rk, "Path");=0A=
+=0A=
+ =A0 //wfds_on_p2p_pin_requested(connman_network, pin);=0A=
+=0A=
+ =A0 if (p2p_go_identifier || __connman_group_exist() =3D=3D FALSE) {=0A=
+ =A0 =A0 =A0 connman_dbus_property_changed_basic(path,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CONNMAN_SERVICE_INTERFACE,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "P2PProvDiscRequestedDisplayPin",=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 DBUS_TYPE_STRING, &pin);=0A=
+=0A=
+ =A0 =A0 =A0 pin_requested_ref =3D g_timeout_add_seconds(2, p2p_pin_reques=
ted, NULL);=0A=
+ =A0 }=0A=
+}=0A=
+=0A=
+static void p2p_prov_disc_response_enter_pin(GSupplicantInterface *interfa=
ce,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantPeer *peer)=0A=
+{=0A=
+ =A0 struct wifi_data *wifi;=0A=
+ =A0 const char *identifier;=0A=
+ =A0 struct connman_network *connman_network;=0A=
+=0A=
+ =A0 wifi =3D g_supplicant_interface_get_data(interface);=0A=
+ =A0 identifier =3D g_supplicant_peer_get_identifier(peer);=0A=
+=0A=
+ =A0 DBG("identifier %s", identifier);=0A=
+=0A=
+ =A0 connman_network =3D connman_device_get_network(wifi->device, identifi=
er);=0A=
+ =A0 if (!connman_network)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 //wfds_on_p2p_pin_response(connman_network, NULL);=0A=
+}=0A=
+=0A=
+static void p2p_prov_disc_response_display_pin(GSupplicantInterface *inter=
face,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantPeer *peer, const char *pi=
n)=0A=
+{=0A=
+ =A0 struct wifi_data *wifi;=0A=
+ =A0 const char *identifier;=0A=
+ =A0 struct connman_network *connman_network;=0A=
+=0A=
+ =A0 wifi =3D g_supplicant_interface_get_data(interface);=0A=
+ =A0 identifier =3D g_supplicant_peer_get_identifier(peer);=0A=
+=0A=
+ =A0 DBG("identifier %s", identifier);=0A=
+=0A=
+ =A0 connman_network =3D connman_device_get_network(wifi->device, identifi=
er);=0A=
+ =A0 if (!connman_network)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 //wfds_on_p2p_pin_response(connman_network, pin);=0A=
+}=0A=
+=0A=
+static void p2p_prov_disc_fail(GSupplicantInterface *interface,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GSupplicantPeer *peer, const char * s=
tatus)=0A=
+{=0A=
+ =A0 struct wifi_data *wifi;=0A=
+ =A0 const char *identifier;=0A=
+ =A0 struct connman_network *connman_network;=0A=
+=0A=
+ =A0 wifi =3D g_supplicant_interface_get_data(interface);=0A=
+ =A0 identifier =3D g_supplicant_peer_get_identifier(peer);=0A=
+=0A=
+ =A0 DBG("identifier %s", identifier);=0A=
+=0A=
+ =A0 connman_network =3D connman_device_get_network(wifi->device, identifi=
er);=0A=
+ =A0 if (!connman_network)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 //wfds_on_p2p_prov_failed(connman_network, status);=0A=
+}=0A=
+=0A=
+=0A=
=A0static const GSupplicantCallbacks callbacks =3D {=0A=
=A0 =A0 .system_ready =A0 =A0 =A0 =3D system_ready,=0A=
=A0 =A0 .system_killed =A0 =A0 =A0=3D system_killed,=0A=
@@ -3704,6 +4105,12 @@ static const GSupplicantCallbacks callbacks =3D {=0A=
=A0 =A0 .p2p_group_finished =3D p2p_group_finished,=0A=
=A0 =A0 .p2p_invitation_result =3D p2p_invitation_result,=0A=
=A0 =A0 .p2p_invitation_received =3D p2p_invitation_received,=0A=
+ =A0 .p2p_prov_disc_requested_pbc =3D p2p_prov_disc_requested_pbc,=0A=
+ =A0 .p2p_prov_disc_requested_enter_pin =3D p2p_prov_disc_requested_enter_=
pin,=0A=
+ =A0 .p2p_prov_disc_requested_display_pin =3D p2p_prov_disc_requested_disp=
lay_pin,=0A=
+ =A0 .p2p_prov_disc_response_enter_pin =3D p2p_prov_disc_response_enter_pi=
n,=0A=
+ =A0 .p2p_prov_disc_response_display_pin =3D p2p_prov_disc_response_displa=
y_pin,=0A=
+ =A0 .p2p_prov_disc_fail =3D p2p_prov_disc_fail,=0A=
=A0};=0A=
=A0=0A=
=A0static int tech_probe(struct connman_technology *technology)=0A=
@@ -4104,12 +4511,16 @@ static void wifi_exit(void)=0A=
=A0 =A0 connman_network_driver_unregister(&network_driver);=0A=
=A0}=0A=
=A0=0A=
-static int p2p_enter_listen_state(GSupplicantInterface *interface)=0A=
+static int p2p_enter_listen_state(GSupplicantInterface *interface, bool en=
able)=0A=
=A0{=0A=
- =A0 GSupplicantP2PExtendedListenParams params =3D {=0A=
- =A0 =A0 =A0 .period =3D 50, =A0 =A0 =A0// ms=0A=
- =A0 =A0 =A0 .interval =3D 100 =A0 =A0// ms=0A=
- =A0 };=0A=
+ =A0 GSupplicantP2PExtendedListenParams params;=0A=
+ =A0 if (enable) {=0A=
+ =A0 =A0 =A0 params.period =3D 50; =A0 =A0// ms=0A=
+ =A0 =A0 =A0 params.interval =3D 100; =A0 =A0// ms=0A=
+ =A0 }else {=0A=
+ =A0 =A0 =A0 params.period =3D 0; =A0 =A0 =A0// ms=0A=
+ =A0 =A0 =A0 params.interval =3D 0; =A0 =A0// ms=0A=
+ =A0 }=0A=
=A0=0A=
=A0 =A0 return g_supplicant_interface_p2p_extended_listen(interface, &param=
s, NULL, NULL);=0A=
=A0}=0A=
@@ -4129,7 +4540,15 @@ static int tech_set_p2p_listen(struct connman_techno=
logy *technology, bool enabl=0A=
=A0 =A0 =A0 =A0 =A0 =A0 continue;=0A=
=A0=0A=
=A0 =A0 =A0 =A0 if (wifi->interface){=0A=
- =A0 =A0 =A0 =A0 =A0 err =3D p2p_enter_listen_state(wifi->interface);=0A=
+ =A0 =A0 =A0 =A0 =A0 if (enable) {=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 err =3D p2p_enter_listen_state(wifi->interfac=
e,true);=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!err)=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 connman_technology_set_p2p_listen(tec=
hnology, true);=0A=
+ =A0 =A0 =A0 =A0 =A0 }else {=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 err =3D p2p_enter_listen_state(wifi->interfac=
e,false);=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (!err)=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 connman_technology_set_p2p_listen(tec=
hnology, false);=0A=
+ =A0 =A0 =A0 =A0 =A0 }=0A=
=A0 =A0 =A0 =A0 =A0 =A0 return err;=0A=
=A0 =A0 =A0 =A0 }=0A=
=A0 =A0 }=0A=
diff --git a/src/connman-dbus.conf b/src/connman-dbus.conf=0A=
index 24e2fbc..4ce570d 100644=0A=
--- a/src/connman-dbus.conf=0A=
+++ b/src/connman-dbus.conf=0A=
@@ -10,6 +10,7 @@=0A=
=A0 =A0 =A0 =A0 =A0<allow send_interface=3D"net.connman.Manager"/>=0A=
=A0 =A0 =A0 =A0 =A0<allow send_interface=3D"net.connman.Service"/>=0A=
=A0 =A0 =A0 =A0 =A0<allow send_interface=3D"net.connman.Technology"/>=0A=
+ =A0 =A0 =A0 =A0<allow send_interface=3D"net.connman.Peer"/>=0A=
=A0 =A0 =A0 =A0 =A0<allow send_interface=3D"org.freedesktop.DBus.Properties=
"/>=0A=
=A0 =A0 =A0</policy>=0A=
=A0 =A0 =A0<policy at_console=3D"true">=0A=
diff --git a/src/peer.c b/src/peer.c=0A=
index e81a038..672b4b8 100644=0A=
--- a/src/peer.c=0A=
+++ b/src/peer.c=0A=
@@ -628,9 +628,8 @@ static int peer_connect(struct connman_peer *peer)=0A=
=A0=0A=
=A0 =A0 if (peer_driver->connect){=0A=
=A0 =A0 =A0 =A0 if(!pin || strlen(pin)=3D=3D0){=0A=
- =A0 =A0 =A0 =A0 =A0 err =3D __connman_agent_request_peer_authorization(pe=
er,=0A=
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 request_authorization_cb, tru=
e,=0A=
- =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 get_dbus_sender(peer), NULL);=
=0A=
+ =A0 =A0 =A0 err =3D peer_driver->connect(peer,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CONNMAN_PEER_WPS_PBC, NULL);=0A=
=A0 =A0 =A0 =A0 }else{=0A=
=A0 =A0 =A0 =A0 err =3D peer_driver->connect(peer,=0A=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 CONNMAN_PEER_WPS_PIN, pin);=0A=
diff --git a/src/technology.c b/src/technology.c=0A=
index fcb5f2b..e04c7ea 100644=0A=
--- a/src/technology.c=0A=
+++ b/src/technology.c=0A=
@@ -87,6 +87,8 @@ struct connman_technology {=0A=
=A0 =A0 bool dbus_registered;=0A=
=A0 =A0 bool p2p_listen;=0A=
=A0 =A0 char * wps_pin;=0A=
+ =A0 char *p2p_identifier;=0A=
+ =A0 bool p2p_persistent;=0A=
=A0};=0A=
=A0=0A=
=A0static GSList *driver_list =3D NULL;=0A=
@@ -659,6 +661,14 @@ static void append_properties(DBusMessageIter *iter,=
=0A=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 DBUS_TYPE_BOOLEAN,=0A=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &technology->p2p_listen);=0A=
=A0=0A=
+ =A0 if(technology->p2p_identifier)=0A=
+ =A0 =A0 =A0 connman_dbus_dict_append_basic(&dict, "P2PIdentifier",=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 DBUS_TYPE_STRING,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &technology->p2p_identifier);=0A=
+ =A0 val =3D technology->p2p_persistent;=0A=
+ =A0 connman_dbus_dict_append_basic(&dict, "P2PPersistent",=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 DBUS_TYPE_BOOLEAN,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 &val);=0A=
=A0 =A0 connman_dbus_dict_close(iter, &dict);=0A=
=A0}=0A=
=A0=0A=
@@ -1033,6 +1043,123 @@ static DBusMessage *set_p2p_listen(struct connman_t=
echnology *technology,=0A=
=A0 =A0 return reply;=0A=
=A0}=0A=
=A0=0A=
+static int set_p2p_identifier(struct connman_technology *technology,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 const char *p2p_identifier)=0A=
+{=0A=
+ =A0 int result =3D -EOPNOTSUPP;=0A=
+ =A0 int err =3D 0;=0A=
+ =A0 GSList *tech_drivers =3D NULL;=0A=
+=0A=
+ =A0 if (technology->type !=3D CONNMAN_SERVICE_TYPE_P2P)=0A=
+ =A0 =A0 =A0 return -EINVAL;=0A=
+=0A=
+ =A0 for (tech_drivers =3D technology->driver_list; tech_drivers;=0A=
+ =A0 =A0 =A0 =A0tech_drivers =3D g_slist_next(tech_drivers)) {=0A=
+ =A0 =A0 =A0 struct connman_technology_driver *driver =3D tech_drivers->da=
ta;=0A=
+=0A=
+ =A0 =A0 =A0 if (!driver || !driver->set_p2p_identifier)=0A=
+ =A0 =A0 =A0 =A0 =A0 continue;=0A=
+=0A=
+ =A0 =A0 =A0 err =3D driver->set_p2p_identifier(technology, p2p_identifier=
);=0A=
+=0A=
+ =A0 =A0 =A0 if (result =3D=3D -EINPROGRESS)=0A=
+ =A0 =A0 =A0 =A0 =A0 continue;=0A=
+=0A=
+ =A0 =A0 =A0 if (err =3D=3D -EINPROGRESS || err =3D=3D 0) {=0A=
+ =A0 =A0 =A0 =A0 =A0 result =3D err;=0A=
+ =A0 =A0 =A0 =A0 =A0 continue;=0A=
+ =A0 =A0 =A0 }=0A=
+ =A0 }=0A=
+=0A=
+ =A0 return result;=0A=
+}=0A=
+=0A=
+bool is_technology_enabled(struct connman_technology *technology)=0A=
+{=0A=
+ =A0 return technology =3D=3D NULL ? false : technology->enabled;=0A=
+}=0A=
+=0A=
+bool connman_technology_get_p2p_persistent(struct connman_technology *tech=
nology)=0A=
+{=0A=
+ =A0 return technology->p2p_persistent;=0A=
+}=0A=
+=0A=
+void connman_technology_set_p2p_persistent(struct connman_technology *tech=
nology, bool enabled)=0A=
+{=0A=
+ =A0 GSList *tech_drivers;=0A=
+ =A0 int err =3D 0;=0A=
+ =A0 dbus_bool_t persistent_enabled;=0A=
+=0A=
+ =A0 if (technology->p2p_persistent =3D=3D enabled)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 technology->p2p_persistent =3D enabled;=0A=
+=0A=
+ =A0 for (tech_drivers =3D technology->driver_list; tech_drivers !=3D NULL=
;=0A=
+ =A0 =A0 =A0 tech_drivers =3D g_slist_next(tech_drivers)) {=0A=
+ =A0 =A0 =A0 struct connman_technology_driver *driver =3D tech_drivers->da=
ta;=0A=
+=0A=
+ =A0 =A0 =A0 if (!driver || !driver->set_p2p_persistent)=0A=
+ =A0 =A0 =A0 =A0 =A0 continue;=0A=
+=0A=
+ =A0 =A0 =A0 err =3D driver->set_p2p_persistent(technology, enabled);=0A=
+ =A0 =A0 =A0 if (err < 0)=0A=
+ =A0 =A0 =A0 =A0 =A0 connman_error("Failed to set P2P persistent state");=
=0A=
+ =A0 }=0A=
+=0A=
+ =A0 persistent_enabled =3D technology->p2p_persistent;=0A=
+ =A0 connman_dbus_property_changed_basic(technology->path,=0A=
+ =A0 =A0 =A0 =A0 =A0 CONNMAN_TECHNOLOGY_INTERFACE,=0A=
+ =A0 =A0 =A0 =A0 =A0 "P2PPersistent",=0A=
+ =A0 =A0 =A0 =A0 =A0 DBUS_TYPE_BOOLEAN,=0A=
+ =A0 =A0 =A0 =A0 =A0 &persistent_enabled);=0A=
+}=0A=
+=0A=
+static DBusMessage *set_p2p_persistent(struct connman_technology *technolo=
gy,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 =A0 =A0 DBusMessage *msg, bool enabled)=0A=
+{=0A=
+ =A0 DBusMessage *reply =3D NULL;=0A=
+ =A0 int err =3D 0;=0A=
+ =A0 GSList *tech_drivers =3D NULL;=0A=
+ =A0 dbus_bool_t persistent_enabled;=0A=
+=0A=
+ =A0 __sync_synchronize();=0A=
+=0A=
+ =A0 if (technology->type !=3D CONNMAN_SERVICE_TYPE_P2P || !technology->en=
abled) {=0A=
+ =A0 =A0 =A0 err =3D -EOPNOTSUPP;=0A=
+ =A0 =A0 =A0 goto make_reply;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 if(technology->p2p_persistent =3D=3D enabled)=0A=
+ =A0 =A0 =A0 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);=0A=
+=0A=
+ =A0 technology->p2p_persistent =3D enabled;=0A=
+=0A=
+ =A0 for (tech_drivers =3D technology->driver_list; tech_drivers !=3D NULL=
;=0A=
+ =A0 =A0 =A0 =A0tech_drivers =3D g_slist_next(tech_drivers)) {=0A=
+ =A0 =A0 =A0 struct connman_technology_driver *driver =3D tech_drivers->da=
ta;=0A=
+=0A=
+ =A0 =A0 =A0 if (driver =3D=3D NULL || driver->set_p2p_persistent =3D=3D N=
ULL)=0A=
+ =A0 =A0 =A0 =A0 =A0 continue;=0A=
+=0A=
+ =A0 =A0 =A0 err =3D driver->set_p2p_persistent(technology, enabled);=0A=
+ =A0 }=0A=
+make_reply:=0A=
+ =A0 if (err < 0)=0A=
+ =A0 =A0 =A0 reply =3D __connman_error_failed(msg, -err);=0A=
+ =A0 else {=0A=
+ =A0 =A0 =A0 reply =3D g_dbus_create_reply(msg, DBUS_TYPE_INVALID);=0A=
+=0A=
+ =A0 =A0 =A0 persistent_enabled =3D technology->p2p_persistent;=0A=
+ =A0 =A0 =A0 connman_dbus_property_changed_basic(technology->path,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 CONNMAN_TECHNOLOGY_INTERFACE,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 "P2PPersistent",=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 DBUS_TYPE_BOOLEAN,=0A=
+ =A0 =A0 =A0 =A0 =A0 =A0 =A0 &persistent_enabled);=0A=
+ =A0 }=0A=
+=0A=
+ =A0 return reply;=0A=
+}=0A=
=A0=0A=
=A0static DBusMessage *set_property(DBusConnection *conn,=0A=
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 DBusMessage *msg, void *data)=0A=
@@ -1254,7 +1381,34 @@ static DBusMessage *set_property(DBusConnection *con=
n,=0A=
=A0=0A=
=A0 =A0 if (err < 0)=0A=
=A0 =A0 =A0 =A0 return __connman_error_failed(msg, -err);=0A=
-}else=0A=
+} else if (g_str_equal(name, "P2PIdentifier")) {=0A=
+ =A0 =A0 =A0 int err;=0A=
+ =A0 =A0 =A0 const char *p2p_identifier;=0A=
+=0A=
+ =A0 =A0 =A0 if (type !=3D DBUS_TYPE_STRING)=0A=
+ =A0 =A0 =A0 =A0 =A0 return __connman_error_invalid_arguments(msg);=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(&value, &p2p_identifier);=0A=
+=0A=
+ =A0 =A0 =A0 if(strlen(p2p_identifier) > 32)=0A=
+ =A0 =A0 =A0 =A0 =A0 return __connman_error_invalid_arguments(msg);=0A=
+=0A=
+ =A0 =A0 =A0 err =3D set_p2p_identifier(technology, p2p_identifier);=0A=
+ =A0 =A0 =A0 if (err < 0)=0A=
+ =A0 =A0 =A0 =A0 =A0 return __connman_error_failed(msg, -err);=0A=
+} else if (g_str_equal(name, "P2PPersistent")) {=0A=
+ =A0 =A0 =A0 bool enable;=0A=
+=0A=
+ =A0 =A0 =A0 if (type !=3D DBUS_TYPE_BOOLEAN)=0A=
+ =A0 =A0 =A0 =A0 =A0 return __connman_error_invalid_arguments(msg);=0A=
+=0A=
+ =A0 =A0 =A0 if (technology->type !=3D CONNMAN_SERVICE_TYPE_P2P)=0A=
+ =A0 =A0 =A0 =A0 =A0 return __connman_error_not_supported(msg);=0A=
+=0A=
+ =A0 =A0 =A0 dbus_message_iter_get_basic(&value, &enable);=0A=
+=0A=
+ =A0 =A0 =A0 return set_p2p_persistent(technology, msg, enable);=0A=
+} else=0A=
=A0 =A0 =A0 =A0 return __connman_error_invalid_property(msg);=0A=
=A0=0A=
=A0 =A0 return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);=0A=
@@ -1284,6 +1438,26 @@ static void reply_scan_pending(struct connman_techno=
logy *technology, int err)=0A=
=A0 =A0 }=0A=
=A0}=0A=
=A0=0A=
+void connman_technology_set_p2p_identifier(struct connman_technology *tech=
nology, const char *p2p_identifier)=0A=
+{=0A=
+=0A=
+ =A0 if (technology->p2p_identifier) {=0A=
+ =A0 =A0 =A0 g_free(technology->p2p_identifier);=0A=
+ =A0 =A0 =A0 technology->p2p_identifier =3D NULL;=0A=
+ =A0 }=0A=
+=0A=
+ =A0 if(p2p_identifier =3D=3D NULL)=0A=
+ =A0 =A0 =A0 return;=0A=
+=0A=
+ =A0 technology->p2p_identifier =3D g_strdup(p2p_identifier);=0A=
+=0A=
+ =A0 connman_dbus_property_changed_basic(technology->path,=0A=
+ =A0 =A0 =A0 =A0 =A0 CONNMAN_TECHNOLOGY_INTERFACE,=0A=
+ =A0 =A0 =A0 =A0 =A0 "P2PIdentifier",=0A=
+ =A0 =A0 =A0 =A0 =A0 DBUS_TYPE_STRING,=0A=
+ =A0 =A0 =A0 =A0 =A0 &technology->p2p_identifier);=0A=
+}=0A=
+=0A=
=A0void __connman_technology_scan_started(struct connman_device *device)=0A=
=A0{=0A=
=A0 =A0 DBG("device %p", device);=0A=
@@ -1530,6 +1704,7 @@ static void technology_put(struct connman_technology =
*technology)=0A=
=A0 =A0 g_free(technology->tethering_ident);=0A=
=A0 =A0 g_free(technology->tethering_passphrase);=0A=
=A0 =A0 g_free(technology->tethering_ipaddress);=0A=
+ =A0 g_free(technology->p2p_identifier);=0A=
=A0 =A0 g_free(technology);=0A=
=A0}=0A=
=A0=0A=
=0A=