PHDC P2P Handling
authorAbhijit RD <abhijit.rd@samsung.com>
Fri, 22 Nov 2013 09:50:55 +0000 (15:20 +0530)
committerAbhijit RD <abhijit.rd@samsung.com>
Mon, 23 Dec 2013 04:35:29 +0000 (10:05 +0530)
Added client and server side PHDC implementation for P2P mode

Change-Id: Ieec9ccbf4d962bfdff4a2a42a1e421e9e195877e
Signed-off-by: Abhijit R D<abhijit.rd@samsung.com>
client/include/net_nfc.h
client/include/net_nfc_client_phdc.h [new file with mode: 0755]
client/net_nfc_client.c
client/net_nfc_client_phdc.c [new file with mode: 0755]
common/include/net_nfc_typedef.h
common/net_nfc.xml
daemon/net_nfc_server.c
daemon/net_nfc_server_phdc.c [new file with mode: 0755]
daemon/net_nfc_server_phdc.h [new file with mode: 0755]
daemon/net_nfc_server_process_phdc.c [new file with mode: 0755]
daemon/net_nfc_server_process_phdc.h [new file with mode: 0755]

index 51183ae..6dd4834 100644 (file)
@@ -28,7 +28,7 @@ extern "C" {
 #include "net_nfc_ndef_record.h"
 #include "net_nfc_sign_record.h"
 #include "net_nfc_ndef_message_handover.h"
-
+#include "net_nfc_client_phdc.h"
 #include "net_nfc_client_context.h"
 #include "net_nfc_client_manager.h"
 #include "net_nfc_client_system_handler.h"
diff --git a/client/include/net_nfc_client_phdc.h b/client/include/net_nfc_client_phdc.h
new file mode 100755 (executable)
index 0000000..d88ba2a
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __NET_NFC_CLIENT_PHDC_H__
+#define __NET_NFC_CLIENT_PHDC_H__
+
+#include "net_nfc_typedef.h"
+
+/* PHDC callbacks */
+
+typedef void (*net_nfc_client_phdc_send_completed)(net_nfc_error_e result,
+               void *user_data);
+
+typedef void (*net_nfc_client_phdc_transport_connect_indication)(
+               net_nfc_phdc_handle_h handle_info,void *user_data);
+
+typedef void (*net_nfc_client_phdc_transport_disconnect_indication)(void *user_data);
+
+typedef void (*net_nfc_client_phdc_data_received)(data_s *phdc_data,
+               void *user_data);
+
+typedef void (*net_nfc_client_phdc_event_cb)( net_nfc_error_e result,
+               net_nfc_llcp_state_t event, void *user_data);
+
+/* PHDC client API's*/
+net_nfc_error_e net_nfc_client_phdc_send(net_nfc_phdc_handle_h handle,
+               data_s *data, net_nfc_client_phdc_send_completed callback, void *user_data);
+
+net_nfc_error_e net_nfc_client_phdc_send_sync(net_nfc_phdc_handle_h handle,
+               data_s *data);
+
+/* PHDC client API's - used for registering callbacks*/
+void net_nfc_client_phdc_set_transport_connect_indication(
+               net_nfc_client_phdc_transport_connect_indication callback, void *user_data);
+
+void net_nfc_client_phdc_set_transport_disconnect_indication(
+               net_nfc_client_phdc_transport_disconnect_indication callback, void *user_data);
+
+void net_nfc_client_phdc_set_data_received(
+               net_nfc_client_phdc_data_received callback, void *user_data);
+
+net_nfc_error_e net_nfc_client_phdc_register(net_nfc_phdc_role_e role,
+               const char *san,net_nfc_client_phdc_event_cb callback, void *user_data);
+
+net_nfc_error_e net_nfc_client_phdc_unregister( net_nfc_phdc_role_e role,
+               const char *san);
+
+
+/* PHDC client API's - used for unregistering callbacks*/
+void net_nfc_client_phdc_unset_transport_connect_indication(void);
+
+void net_nfc_client_phdc_unset_transport_disconnect_indication(void);
+
+void net_nfc_client_phdc_unset_data_received(void);
+
+/* Init/Deint function calls*/
+net_nfc_error_e net_nfc_client_phdc_init(void);
+
+void net_nfc_client_phdc_deinit(void);
+
+#endif //__NET_NFC_CLIENT_PHDC_H__
+
+
index 64d5be7..6118ba0 100644 (file)
@@ -31,6 +31,7 @@
 #include "net_nfc_client_llcp.h"
 #include "net_nfc_client_snep.h"
 #include "net_nfc_client_p2p.h"
+#include "net_nfc_client_phdc.h"
 #include "net_nfc_client_system_handler.h"
 #include "net_nfc_client_handover.h"
 
@@ -97,6 +98,8 @@ void net_nfc_client_gdbus_init(void)
                return;
        if(net_nfc_client_handover_init() != NET_NFC_OK)
                return;
+       if(net_nfc_client_phdc_init() != NET_NFC_OK)
+               return;
 }
 
 void net_nfc_client_gdbus_deinit(void)
@@ -110,6 +113,7 @@ void net_nfc_client_gdbus_deinit(void)
        net_nfc_client_transceive_deinit();
        net_nfc_client_ndef_deinit();
        net_nfc_client_tag_deinit();
+       net_nfc_client_phdc_deinit();
        net_nfc_client_manager_deinit();
 #ifdef SECURITY_SERVER
        _deinit_smack();
diff --git a/client/net_nfc_client_phdc.c b/client/net_nfc_client_phdc.c
new file mode 100755 (executable)
index 0000000..09c50cb
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "net_nfc_typedef_internal.h"
+#include "net_nfc_debug_internal.h"
+#include "net_nfc_util_internal.h"
+#include "net_nfc_util_ndef_message.h"
+#include "net_nfc_util_gdbus_internal.h"
+#include "net_nfc_gdbus.h"
+#include "net_nfc_client.h"
+#include "net_nfc_client_manager.h"
+#include "net_nfc_client_phdc.h"
+
+typedef struct _Phdc_SignalHandler PhdcSignalHandler;
+
+static NetNfcGDbusPhdc *phdc_proxy = NULL;
+static PhdcSignalHandler phdc_signal_handler;
+
+struct _Phdc_SignalHandler
+{
+       net_nfc_client_phdc_transport_connect_indication phdc_transport_connect_indication_cb;
+       net_nfc_client_phdc_transport_disconnect_indication phdc_transport_disconnect_indication_cb;
+       net_nfc_client_phdc_data_received phdc_data_received_cb;
+
+       gpointer phdc_transport_connect_indication_data;
+       gpointer phdc_transport_disconnect_indication_data;
+       gpointer phdc_data_received_data;
+};
+
+
+static void _phdc_event_cb(NetNfcGDbusPhdc *object, gint arg_result,
+               guint arg_event,guint arg_user_data)
+{
+       GVariant *parameter = (GVariant *)GUINT_TO_POINTER(arg_user_data);
+
+       NFC_DBG(" result [%d], event [%d], user_data [%p]",
+                        arg_result, arg_event, parameter);
+
+       if (parameter != NULL)
+       {
+               void *user_data;
+               net_nfc_client_phdc_event_cb callback;
+
+               g_variant_get(parameter, "(uu)",
+                       (guint *)&callback,
+                       (guint *)&user_data);
+
+               if (callback != NULL)
+               {
+                       callback( arg_result, arg_event, user_data);
+               }
+       }
+
+       if (arg_event == NET_NFC_LLCP_UNREGISTERED)
+       {
+               g_variant_unref(parameter);
+       }
+
+}
+
+
+static void phdc_transport_disconnect_indication(GObject *source_object, gpointer user_data)
+{
+       NFC_INFO(">>> SIGNAL arrived");
+
+       RET_IF(NULL == phdc_signal_handler.phdc_transport_disconnect_indication_cb);
+
+       phdc_signal_handler.phdc_transport_disconnect_indication_cb(
+                       phdc_signal_handler.phdc_transport_disconnect_indication_data);
+}
+
+static void phdc_transport_connect_indication(GObject *source_object,
+               guint arg_handle, gpointer user_data)
+{
+       net_nfc_phdc_handle_h handle_info = NULL;
+
+       NFC_INFO(">>> SIGNAL arrived");
+
+       handle_info = GUINT_TO_POINTER(arg_handle);
+
+       RET_IF(NULL == phdc_signal_handler.phdc_transport_connect_indication_cb);
+
+       phdc_signal_handler.phdc_transport_connect_indication_cb(handle_info,
+                       phdc_signal_handler.phdc_transport_connect_indication_data);
+}
+
+static void phdc_call_send(GObject *source_object,GAsyncResult *res, gpointer user_data)
+{
+       gboolean ret;
+       GVariant *parameter = (GVariant *)user_data;
+       GError *error = NULL;
+       net_nfc_error_e out_result;
+       net_nfc_client_phdc_send_completed callback;
+       net_nfc_phdc_handle_h handle;
+       void *user_param;
+
+       NFC_INFO(">>> phdc_call_send \n");
+
+       ret = net_nfc_gdbus_phdc_call_send_finish(NET_NFC_GDBUS_PHDC(source_object),
+                       (gint *)&out_result, res, &error);
+
+       if (FALSE == ret)
+       {
+               out_result = NET_NFC_IPC_FAIL;
+
+               NFC_ERR("Can not finish phdc send: %s", error->message);
+               g_error_free(error);
+       }
+
+       g_variant_get(parameter, "(uuu)",
+       (guint *)&callback,
+       (guint *)&user_param,
+       (guint *)&handle);
+
+       NFC_INFO(">>> phdc_call_send  %p\n", handle);
+
+       if (callback != NULL)
+       {
+               callback( out_result, user_param);
+       }
+
+       g_variant_unref(parameter);
+}
+
+static void phdc_device_data_received(GObject *source_object,GVariant *arg_data,
+               gpointer user_data)
+{
+       data_s phdc_data = { NULL, };
+
+       NFC_INFO(">>> SIGNAL arrived");
+
+       RET_IF(NULL == phdc_signal_handler.phdc_data_received_cb);
+
+       net_nfc_util_gdbus_variant_to_data_s(arg_data, &phdc_data);
+       phdc_signal_handler.phdc_data_received_cb(&phdc_data,
+                       phdc_signal_handler.phdc_data_received_data);
+
+       net_nfc_util_free_data(&phdc_data);
+}
+
+API net_nfc_error_e net_nfc_client_phdc_send(net_nfc_phdc_handle_h handle,
+               data_s *data, net_nfc_client_phdc_send_completed callback, void *user_data)
+{
+       GVariant *arg_data;
+       GVariant *parameter;
+
+       NFC_INFO(">>> net_nfc_client_phdc_send \n");
+
+       RETV_IF(NULL == phdc_proxy, NET_NFC_NOT_INITIALIZED);
+
+       /* prevent executing daemon when nfc is off */
+       RETV_IF(net_nfc_client_manager_is_activated() == false, NET_NFC_INVALID_STATE);
+
+       parameter = g_variant_new("(uuu)",
+               GPOINTER_TO_UINT(callback),
+               GPOINTER_TO_UINT(user_data),
+               GPOINTER_TO_UINT(handle));
+
+
+       arg_data = net_nfc_util_gdbus_data_to_variant(data);
+
+       net_nfc_gdbus_phdc_call_send(phdc_proxy,
+               GPOINTER_TO_UINT(handle),
+               arg_data,
+               net_nfc_client_gdbus_get_privilege(),
+               NULL,
+               phdc_call_send,
+               parameter);
+
+       return NET_NFC_OK;
+}
+
+
+API net_nfc_error_e net_nfc_client_phdc_send_sync(net_nfc_phdc_handle_h handle,
+               data_s *data)
+{
+       gboolean ret;
+       GVariant *arg_data;
+       GError *error = NULL;
+
+       net_nfc_error_e out_result;
+
+       RETV_IF(NULL == phdc_proxy, NET_NFC_NOT_INITIALIZED);
+
+       /* prevent executing daemon when nfc is off */
+       RETV_IF(net_nfc_client_manager_is_activated() == false, NET_NFC_INVALID_STATE);
+
+       arg_data = net_nfc_util_gdbus_data_to_variant(data);
+
+       ret = net_nfc_gdbus_phdc_call_send_sync(phdc_proxy,
+                       GPOINTER_TO_UINT(handle),
+                       arg_data,
+                       net_nfc_client_gdbus_get_privilege(),
+                       (gint *)&out_result,
+                       NULL,
+                       &error);
+
+       if(FALSE == ret)
+       {
+               NFC_ERR("phdc send (sync call) failed: %s", error->message);
+
+               g_error_free(error);
+               out_result = NET_NFC_IPC_FAIL;
+       }
+
+       return out_result;
+}
+
+API net_nfc_error_e net_nfc_client_phdc_register(net_nfc_phdc_role_e role,
+               const char *san,net_nfc_client_phdc_event_cb callback, void *user_data)
+{
+       GError *error = NULL;
+       GVariant *parameter;
+       net_nfc_error_e result = NET_NFC_OK;
+
+       RETV_IF(NULL == phdc_proxy, NET_NFC_NOT_INITIALIZED);
+
+       /* prevent executing daemon when nfc is off */
+       RETV_IF(net_nfc_client_manager_is_activated() == false, NET_NFC_INVALID_STATE);
+
+       parameter = g_variant_new("(uu)",
+                       GPOINTER_TO_UINT(callback),
+                       GPOINTER_TO_UINT(user_data));
+
+       if (net_nfc_gdbus_phdc_call_register_role_sync(phdc_proxy,
+                               role,
+                               san,
+                               GPOINTER_TO_UINT(parameter),
+                               net_nfc_client_gdbus_get_privilege(),
+                               (gint *)&result,
+                               NULL,
+                               &error) == FALSE)
+       {
+               NFC_ERR("phdc register role(sync call) failed: %s", error->message);
+               g_error_free(error);
+               result = NET_NFC_IPC_FAIL;
+               g_variant_unref(parameter);
+       }
+
+       return result;
+}
+
+API net_nfc_error_e net_nfc_client_phdc_unregister( net_nfc_phdc_role_e role,
+               const char *san)
+{
+       GError *error = NULL;
+       net_nfc_error_e result = NET_NFC_OK;
+
+       RETV_IF(NULL == phdc_proxy, NET_NFC_NOT_INITIALIZED);
+
+       /* prevent executing daemon when nfc is off */
+       RETV_IF(net_nfc_client_manager_is_activated() == false, NET_NFC_INVALID_STATE);
+
+       if (net_nfc_gdbus_phdc_call_unregister_role_sync(phdc_proxy,
+                               role,
+                               san,
+                               net_nfc_client_gdbus_get_privilege(),
+                               (gint *)&result,
+                               NULL,
+                               &error) == FALSE)
+       {
+               NFC_ERR("phdc unregister role(sync call) failed: %s", error->message);
+               g_error_free(error);
+
+               result = NET_NFC_IPC_FAIL;
+       }
+
+       return result;
+}
+
+
+API void net_nfc_client_phdc_set_transport_connect_indication(
+               net_nfc_client_phdc_transport_connect_indication callback, void *user_data)
+{
+       RET_IF(NULL == callback);
+
+       phdc_signal_handler.phdc_transport_connect_indication_cb = callback;
+       phdc_signal_handler.phdc_transport_connect_indication_data = user_data;
+}
+
+API void net_nfc_client_phdc_set_transport_disconnect_indication(
+               net_nfc_client_phdc_transport_disconnect_indication callback, void *user_data)
+{
+       RET_IF(NULL == callback);
+
+       phdc_signal_handler.phdc_transport_disconnect_indication_cb = callback;
+       phdc_signal_handler.phdc_transport_disconnect_indication_data = user_data;
+}
+
+API void net_nfc_client_phdc_set_data_received(
+               net_nfc_client_phdc_data_received callback, void *user_data)
+{
+       RET_IF(NULL == callback);
+
+       phdc_signal_handler.phdc_data_received_cb = callback;
+       phdc_signal_handler.phdc_data_received_data = user_data;
+}
+
+API void net_nfc_client_phdc_unset_transport_connect_indication(void)
+{
+       phdc_signal_handler.phdc_transport_connect_indication_cb = NULL;
+       phdc_signal_handler.phdc_transport_connect_indication_data= NULL;
+}
+
+
+API void net_nfc_client_phdc_unset_transport_disconnect_indication(void)
+{
+       phdc_signal_handler.phdc_transport_disconnect_indication_cb = NULL;
+       phdc_signal_handler.phdc_transport_disconnect_indication_data = NULL;
+}
+
+API void net_nfc_client_phdc_unset_data_received(void)
+{
+       phdc_signal_handler.phdc_data_received_cb = NULL;
+       phdc_signal_handler.phdc_data_received_data = NULL;
+}
+
+net_nfc_error_e net_nfc_client_phdc_init(void)
+{
+       GError *error = NULL;
+
+       if (phdc_proxy)
+       {
+               NFC_WARN("Already initialized");
+               return NET_NFC_OK;
+       }
+
+       phdc_proxy = net_nfc_gdbus_phdc_proxy_new_for_bus_sync(
+                       G_BUS_TYPE_SYSTEM,
+                       G_DBUS_PROXY_FLAGS_NONE,
+                       "org.tizen.NetNfcService",
+                       "/org/tizen/NetNfcService/Phdc",
+                       NULL,
+                       &error);
+       if (NULL == phdc_proxy)
+       {
+               NFC_ERR("Can not create proxy : %s", error->message);
+               g_error_free(error);
+
+               return NET_NFC_UNKNOWN_ERROR;
+       }
+
+       net_nfc_client_phdc_unset_transport_connect_indication();
+       net_nfc_client_phdc_unset_transport_disconnect_indication();
+       net_nfc_client_phdc_unset_data_received();
+
+       g_signal_connect(phdc_proxy, "phdc_connect",
+                       G_CALLBACK(phdc_transport_connect_indication), NULL);
+
+       g_signal_connect(phdc_proxy, "phdc_disconnect",
+                       G_CALLBACK(phdc_transport_disconnect_indication), NULL);
+
+       g_signal_connect(phdc_proxy, "phdc_received",
+                       G_CALLBACK(phdc_device_data_received), NULL);
+
+       g_signal_connect(phdc_proxy, "phdc-event", G_CALLBACK(_phdc_event_cb), NULL);
+
+
+       return NET_NFC_OK;
+}
+
+void net_nfc_client_phdc_deinit(void)
+{
+       if (phdc_proxy)
+       {
+               g_object_unref(phdc_proxy);
+               phdc_proxy = NULL;
+       }
+
+       net_nfc_client_phdc_unset_transport_connect_indication();
+       net_nfc_client_phdc_unset_transport_disconnect_indication();
+       net_nfc_client_phdc_unset_data_received();
+
+}
+
index 1032360..f82fd62 100644 (file)
@@ -390,9 +390,17 @@ typedef enum
        NET_NFC_CONN_HANDOVER_CARRIER_UNKNOWN,
 } net_nfc_conn_handover_carrier_type_e;
 
+typedef enum
+{
+       NET_NFC_PHDC_UNKNOWN = 0x00,
+       NET_NFC_PHDC_MANAGER ,
+       NET_NFC_PHDC_AGENT,
+} net_nfc_phdc_role_e;
+
+
 /**
   This structure is just data, to express bytes array
 */
+ */
 typedef struct
 {
        uint8_t *buffer;
@@ -482,6 +490,9 @@ typedef uint32_t net_nfc_llcp_socket_t;
 
 typedef void *net_nfc_snep_handle_h;
 
+typedef void *net_nfc_phdc_handle_h;
+
+
 // LLCP Callback
 typedef void (*net_nfc_llcp_socket_cb)(net_nfc_llcp_message_e message,
                net_nfc_error_e result, void *data, void *user_data, void *trans_data);
index bd2d851..b913b6b 100644 (file)
     </signal>
   </interface>
 
+  <interface name="org.tizen.NetNfcService.Phdc">
+    <!--
+      Send
+    -->
+    <method name="Send">
+      <arg type="u" name="handle" direction="in" />
+      <arg type="a(y)" name="data" direction="in" />
+      <arg type="a(y)" name="privilege" direction="in" />
+      <arg type="i" name="result" direction="out" />
+    </method>
+
+    <!--
+      Register Role
+    -->
+    <method name="RegisterRole">
+      <arg type="u" name="role" direction="in" />
+      <arg type="s" name="san" direction="in" />
+      <arg type="u" name="user_data" direction="in" />
+      <arg type="a(y)" name="privilege" direction="in" />
+      <arg type="i" name="result" direction="out" />
+    </method>
+
+    <!--
+      Unregister Role
+    -->
+    <method name="UnregisterRole">
+      <arg type="u" name="role" direction="in" />
+      <arg type="s" name="san" direction="in" />
+      <arg type="a(y)" name="privilege" direction="in" />
+      <arg type="i" name="result" direction="out" />
+    </method>
+
+     <!--
+      Disconnect
+    -->
+    <signal name="Phdc_disconnect" />
+
+    <!--
+      Connect
+    -->
+    <signal name="Phdc_connect">
+      <arg type="u" name="handle" />
+    </signal>
+
+   <!--
+      Receive
+    -->
+    <signal name="Phdc_received">
+      <arg type="a(y)" name="data" />
+    </signal>
+
+    <!--
+      PhdcEvent - Register completion indication
+    -->
+    <signal name="PhdcEvent">
+      <arg type="i" name="result" />
+      <arg type="u" name="event" />
+      <arg type="u" name="user_data" />
+    </signal>
+  </interface>
+
 </node>
index d5555c5..e6448fb 100644 (file)
@@ -22,6 +22,7 @@
 #include "net_nfc_gdbus.h"
 #include "net_nfc_server.h"
 #include "net_nfc_server_common.h"
+#include "net_nfc_server_phdc.h"
 #include "net_nfc_server_vconf.h"
 #include "net_nfc_server_manager.h"
 #include "net_nfc_server_util.h"
@@ -216,6 +217,12 @@ static void net_nfc_server_gdbus_init(void)
                return;
        }
 
+       if (net_nfc_server_phdc_init(connection) == FALSE)
+       {
+               NFC_ERR("Can not init phdc");
+               return;
+       }
+
        if (net_nfc_server_controller_thread_init() == FALSE)
        {
                NFC_ERR("Can not init controller thread");
@@ -238,7 +245,7 @@ static void net_nfc_server_gdbus_deinit(void)
        net_nfc_server_se_deinit();
        net_nfc_server_snep_deinit();
        net_nfc_server_system_handler_deinit();
-
+       net_nfc_server_phdc_deinit();
        net_nfc_server_gdbus_deinit_client_context();
 
        net_nfc_server_controller_thread_deinit();
diff --git a/daemon/net_nfc_server_phdc.c b/daemon/net_nfc_server_phdc.c
new file mode 100755 (executable)
index 0000000..91f33f2
--- /dev/null
@@ -0,0 +1,675 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "net_nfc_debug_internal.h"
+#include "net_nfc_util_internal.h"
+#include "net_nfc_util_gdbus_internal.h"
+#include "net_nfc_server_controller.h"
+#include "net_nfc_gdbus.h"
+#include "net_nfc_server_common.h"
+#include "net_nfc_server_tag.h"
+#include "net_nfc_server_context.h"
+#include "net_nfc_server_process_phdc.h"
+#include "net_nfc_server_phdc.h"
+#include "net_nfc_server_llcp.h"
+
+typedef struct _PhdcSendData PhdcSendData;
+
+struct _PhdcSendData
+{
+       NetNfcGDbusPhdc *phdc;
+       GDBusMethodInvocation *invocation;
+       guint32 phdc_handle;
+       data_s data;
+};
+
+static NetNfcGDbusPhdc *phdc_skeleton = NULL;
+
+
+static gboolean _phdc_send_request_cb_(net_nfc_phdc_handle_h handle,
+               net_nfc_error_e result, net_nfc_server_phdc_indication_type indication,
+               gpointer *user_data)
+{
+
+       NFC_DBG("phdc_send_request_cb_result [%d]",result);
+
+       GVariant *parameter = (GVariant *)user_data;
+
+       g_assert(parameter != NULL);
+
+       NetNfcGDbusPhdc *object;
+       GDBusMethodInvocation *invocation;
+       net_nfc_phdc_handle_h phdc_handle;
+       GVariant *phdc_data ;
+
+       g_variant_get(parameter,
+               "(uuu@a(y))",
+               (guint *)&object,
+               (guint *)&invocation,
+               (guint *)&phdc_handle,
+               (guint *)&phdc_data);
+
+       net_nfc_gdbus_phdc_complete_send(object, invocation, (gint)result);
+
+       g_variant_unref(phdc_data);
+       g_object_unref(invocation);
+       g_object_unref(object);
+       g_variant_unref(parameter);
+
+       result = NET_NFC_OK;
+       return result;
+
+}
+
+static void phdc_send_data_thread_func(gpointer user_data)
+{
+       NetNfcGDbusPhdc *object;
+       GDBusMethodInvocation *invocation;
+       net_nfc_error_e result;
+       net_nfc_phdc_handle_h handle = NULL;
+       GVariant *phdc_data;
+       data_s data = { NULL, };
+
+       if (NULL == user_data)
+       {
+               NFC_ERR("cannot get PHDC client data");
+               return;
+       }
+
+       NFC_DBG(">>> phdc_send_data_thread_func");
+
+       g_variant_get((GVariant *)user_data,
+               "(uuu@a(y))",
+               (guint *)&object,
+               (guint *)&invocation,
+               (guint *)&handle,
+               &phdc_data);
+
+       g_assert(object != NULL);
+       g_assert(invocation != NULL);
+
+       net_nfc_util_gdbus_variant_to_data_s(phdc_data, &data);
+
+       result = net_nfc_server_phdc_agent_request(handle, &data,
+                       _phdc_send_request_cb_, user_data);
+
+       if (result != NET_NFC_OK)
+       {
+               net_nfc_gdbus_phdc_complete_send(object, invocation, (gint)result);
+
+               g_object_unref(invocation);
+               g_object_unref(object);
+               g_variant_unref(user_data);
+       }
+
+       g_variant_unref(phdc_data);
+}
+
+static gboolean phdc_handle_send(NetNfcGDbusPhdc *phdc,
+       GDBusMethodInvocation *invocation, //object for handling remote calls,provides a way to asynly return data
+       guint handle,
+       GVariant* user_data,
+       GVariant *smack_privilege)
+{
+       bool ret;
+       gboolean result;
+       GVariant *parameter = NULL;
+
+       NFC_INFO(">>> REQUEST from [%s]",g_dbus_method_invocation_get_sender(invocation));
+
+       /* check privilege and update client context */
+       ret = net_nfc_server_gdbus_check_privilege(invocation, smack_privilege,
+                       "nfc-manager::p2p", "w");
+
+       if(FALSE == ret)
+       {
+               NFC_ERR("permission denied, and finished request");
+               result = NET_NFC_SECURITY_FAIL;
+               goto ERROR;
+       }
+
+       parameter = g_variant_new("(uuu@a(y))",
+               GPOINTER_TO_UINT(g_object_ref(phdc)),
+               GPOINTER_TO_UINT(g_object_ref(invocation)),
+               handle,
+               user_data);
+
+       if (NULL == parameter)
+       {
+               NFC_ERR("Memory allocation failed");
+               result = NET_NFC_ALLOC_FAIL;
+
+               goto ERROR;
+       }
+
+       result = net_nfc_server_controller_async_queue_push(phdc_send_data_thread_func, parameter);
+
+       if (FALSE == result)
+       {
+               /* return error if queue was blocked */
+               NFC_ERR("controller is processing important message..");
+               result = NET_NFC_BUSY;
+
+               goto ERROR;
+
+       }
+
+       return TRUE;
+
+       ERROR :
+
+       if (parameter != NULL)
+       {
+               g_object_unref(invocation);
+               g_object_unref(phdc);
+               g_variant_unref(parameter);
+       }
+
+       net_nfc_gdbus_phdc_complete_send(phdc, invocation, result);
+       return TRUE;
+}
+
+void net_nfc_server_phdc_data_received_indication(data_s *arg_data)
+{
+       NFC_INFO("=net_nfc_server_phdc_transport_data_received_indication=");
+
+       GVariant *data;
+       data = net_nfc_util_gdbus_data_to_variant(arg_data);
+
+       if (NULL == phdc_skeleton)
+       {
+               NFC_ERR("phdc_skeleton is not initialized");
+               return;
+       }
+
+       net_nfc_gdbus_phdc_emit_phdc_received(phdc_skeleton, data);
+}
+
+static void _emit_phdc_event_signal(GVariant *parameter,
+               net_nfc_phdc_handle_h handle, net_nfc_error_e result, uint32_t type)
+{
+       gboolean ret;
+       char *client_id = NULL;
+       void *user_data = NULL;
+       GError *error = NULL;
+       GDBusConnection *connection;
+
+       g_variant_get(parameter, "(usu)", (guint *)&connection, &client_id,
+                       (guint *)&user_data);
+
+       ret = g_dbus_connection_emit_signal(
+                       connection,
+                       client_id,
+                       "/org/tizen/NetNfcService/Phdc",
+                       "org.tizen.NetNfcService.Phdc",
+                       "PhdcEvent",
+                       g_variant_new("(iuu)", (gint)result, type,
+                               GPOINTER_TO_UINT(user_data)), &error);
+
+       if (FALSE == ret)
+       {
+               if (error != NULL && error->message != NULL)
+                       NFC_ERR("g_dbus_connection_emit_signal failed : %s", error->message);
+               else
+                       NFC_ERR("g_dbus_connection_emit_signal failed");
+       }
+
+       g_free(client_id);
+}
+
+static void _server_phdc_agent_cb_(net_nfc_phdc_handle_h handle,
+               net_nfc_error_e result, net_nfc_server_phdc_indication_type indication, data_s *data)
+{
+       if(NET_NFC_OK != result)
+       {
+               net_nfc_server_phdc_transport_disconnect_indication();
+               return;
+       }
+
+       RET_IF(NULL == handle);
+
+       NFC_DBG(" handle [%p], result[%d]", handle, result);
+
+       if( NET_NFC_PHDC_TARGET_CONNECTED == indication)
+               net_nfc_server_phdc_transport_connect_indication(handle);
+       else if(NET_NFC_PHDC_DATA_RECEIVED == indication)
+               net_nfc_server_phdc_data_received_indication(data);
+
+       return;
+}
+
+
+static void _phdc_agent_activate_cb(int event, net_nfc_target_handle_s *handle,
+               uint32_t sap, const char *san, void *user_param)
+{
+       net_nfc_error_e result = NET_NFC_OK;
+       GVariant *parameter = (GVariant *)user_param;
+       char *client_id = NULL;
+       void *user_data = NULL;
+       GVariant *param = NULL;
+       GDBusConnection *connection = NULL;
+
+       NFC_DBG("event [%d], handle [%p], sap [%d], san [%s]", event, handle, sap, san);
+
+       if (NET_NFC_LLCP_START == event)
+       {
+               g_variant_get(parameter, "(usu)", (guint *)&connection, &client_id, (guint *)&user_data);
+
+               param = g_variant_new("(usu)", GPOINTER_TO_UINT(g_object_ref(connection)),client_id,
+                               GPOINTER_TO_UINT(user_data));
+
+               g_free(client_id);
+
+               /* start phdc agent service*/
+               result = net_nfc_server_phdc_agent_start(handle, (char *)san, sap,
+                               _server_phdc_agent_cb_, param);
+
+               if (NET_NFC_OK == result)
+               {
+                       _emit_phdc_event_signal(parameter, handle, result, event);
+               }
+               else
+               {
+                       NFC_ERR("net_nfc_server_phdc_manager_start failed, [%d]", result);
+                       g_variant_unref(param);
+               }
+       }
+       else
+       {
+               _emit_phdc_event_signal(parameter, handle, result, NET_NFC_LLCP_UNREGISTERED);
+               /* unregister server */
+               g_variant_unref(parameter);
+       }
+
+}
+
+static void _server_phdc_manager_cb_(net_nfc_phdc_handle_h handle,
+               net_nfc_error_e result, net_nfc_server_phdc_indication_type indication, data_s *data)
+{
+
+       if(NET_NFC_OK != result)
+       {
+               net_nfc_server_phdc_transport_disconnect_indication();
+               return;
+       }
+
+       RET_IF(NULL == handle);
+
+       NFC_DBG("result [%d], data [%p]", result, data);
+
+       if( NET_NFC_PHDC_TARGET_CONNECTED == indication)
+               net_nfc_server_phdc_transport_connect_indication(handle);
+       else if(NET_NFC_PHDC_DATA_RECEIVED == indication)
+               net_nfc_server_phdc_data_received_indication(data);
+
+       return ;
+}
+
+
+static void _phdc_manager_activate_cb(int event, net_nfc_target_handle_s *handle,
+               uint32_t sap, const char *san, void *user_param)
+{
+       net_nfc_error_e result = NET_NFC_OK;
+       GVariant *parameter = (GVariant *)user_param;
+       char *client_id = NULL;
+       void *user_data = NULL;
+       GVariant *param = NULL;
+       GDBusConnection *connection = NULL;
+
+       NFC_DBG("event [%d], handle [%p], sap [%d], san [%s]", event, handle, sap, san);
+
+       if (NET_NFC_LLCP_START == event)
+       {
+               g_variant_get(parameter, "(usu)", (guint *)&connection, &client_id, (guint *)&user_data);
+
+               param = g_variant_new("(usu)", GPOINTER_TO_UINT(g_object_ref(connection)),client_id,
+                               GPOINTER_TO_UINT(user_data));
+
+               g_free(client_id);
+
+               /* start phdc manager service*/
+               result = net_nfc_server_phdc_manager_start(handle, (char *)san, sap,
+                               _server_phdc_manager_cb_, param);
+
+               if (NET_NFC_OK == result)
+               {
+                       _emit_phdc_event_signal(parameter, handle, result, event);
+               }
+               else
+               {
+                       NFC_ERR("net_nfc_server_phdc_manager_start failed, [%d]", result);
+                       g_variant_unref(param);
+               }
+       }
+       else
+       {
+               _emit_phdc_event_signal(parameter, handle, result, NET_NFC_LLCP_UNREGISTERED);
+               /* unregister server */
+               g_variant_unref(parameter);
+       }
+
+}
+
+static void phdc_register_server_thread_func(gpointer user_data)
+{
+       gchar *arg_san = NULL;
+       guint arg_role;
+       guint arg_sap;
+       guint arg_user_data;
+       net_nfc_error_e result = NET_NFC_OK;
+       NetNfcGDbusPhdc *object = NULL;
+       g_assert(user_data != NULL);
+       GVariant *parameter = NULL;
+       GDBusConnection *connection = NULL;
+       GDBusMethodInvocation *invocation = NULL;
+
+       g_variant_get((GVariant *)user_data, "(uuusu)", (guint *)&object, (guint *)&invocation,
+                       &arg_role, &arg_san, &arg_user_data);
+
+       g_assert(object != NULL);
+       g_assert(invocation != NULL);
+
+       connection = g_dbus_method_invocation_get_connection(invocation);
+
+       parameter = g_variant_new("(usu)", GPOINTER_TO_UINT(g_object_ref(connection)),
+                       g_dbus_method_invocation_get_sender(invocation), arg_user_data);
+
+       if (parameter != NULL)
+       {
+               if(!strcmp(arg_san,PHDC_SAN))
+               {
+                       arg_san = PHDC_SAN;
+                       arg_sap = PHDC_SAP;
+               }
+               else if (!strcmp(arg_san,PHDS_SAN))
+               {
+                       arg_san = PHDS_SAN;
+                       arg_sap = PHDS_SAP;
+               }
+               else
+               {
+                       // anything else, as of now,defaulting to PHDC default server
+                       arg_san = PHDC_SAN;
+                       arg_sap = PHDC_SAP;
+               }
+
+               if(NET_NFC_PHDC_MANAGER == arg_role)
+               {
+                       result = net_nfc_server_llcp_register_service(
+                                       g_dbus_method_invocation_get_sender(invocation), arg_sap,
+                                       arg_san, _phdc_manager_activate_cb,     parameter);
+               }
+               else if(NET_NFC_PHDC_AGENT == arg_role)
+               {
+                       result = net_nfc_server_llcp_register_service(
+                                       g_dbus_method_invocation_get_sender(invocation), arg_sap,
+                                       arg_san, _phdc_agent_activate_cb,       parameter);
+               }
+
+               if (result != NET_NFC_OK)
+               {
+                       NFC_ERR("net_nfc_service_llcp_register_service failed, [%d]", result);
+                       g_object_unref(connection);
+                       g_variant_unref(parameter);
+               }
+       }
+       else
+       {
+               result = NET_NFC_ALLOC_FAIL;
+               g_object_unref(connection);
+       }
+
+       net_nfc_gdbus_phdc_complete_register_role(object, invocation, result);
+
+
+       g_variant_unref(user_data);
+
+
+}
+
+static gboolean phdc_handle_register(
+               NetNfcGDbusPhdc *object,
+               GDBusMethodInvocation *invocation,
+               guint arg_role,
+               const gchar *arg_san,
+               guint arg_user_data,
+               GVariant *arg_privilege)
+{
+       bool ret;
+       gboolean result;
+       GVariant *parameter = NULL;
+
+       NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
+
+       /* check privilege and update client context */
+       ret = net_nfc_server_gdbus_check_privilege(invocation, arg_privilege,
+                       "nfc-manager::p2p", "rw");
+       if (FALSE == ret)
+       {
+               NFC_ERR("permission denied, and finished request");
+               result = NET_NFC_SECURITY_FAIL;
+               goto ERROR;
+       }
+
+       parameter = g_variant_new("(uuusu)", GPOINTER_TO_UINT(g_object_ref(object)),
+                       GPOINTER_TO_UINT(g_object_ref(invocation)), arg_role, arg_san, arg_user_data);
+
+       if (parameter == NULL)
+       {
+               NFC_ERR("Memory allocation failed");
+               result = NET_NFC_ALLOC_FAIL;
+               goto ERROR;
+       }
+       if(net_nfc_server_controller_async_queue_push(
+                       phdc_register_server_thread_func, parameter) == FALSE)
+       {
+               NFC_ERR("controller is processing important message.");
+               result = NET_NFC_ALLOC_FAIL;
+               goto ERROR;
+       }
+
+       return TRUE;
+
+       ERROR :
+       if (parameter != NULL)
+       {
+               g_object_unref(invocation);
+               g_object_unref(object);
+               g_variant_unref(parameter);
+       }
+
+       net_nfc_gdbus_phdc_complete_register_role(object,
+               invocation,
+               result);
+
+       return TRUE;
+}
+
+static void phdc_unregister_server_thread_func(gpointer user_data)
+{
+       guint arg_role;
+       guint arg_sap;
+       gchar *arg_san = NULL;
+       net_nfc_error_e result;
+       NetNfcGDbusSnep *object = NULL;
+       GDBusMethodInvocation *invocation = NULL;
+
+       g_assert(user_data != NULL);
+
+       g_variant_get((GVariant *)user_data, "(uuus)", (guint *)&object, (guint *)&invocation,
+                       &arg_role, &arg_san);
+
+       g_assert(object != NULL);
+       g_assert(invocation != NULL);
+
+       if(!strcmp(arg_san,PHDS_SAN))
+               arg_sap = PHDS_SAP;
+       else
+               arg_sap = PHDC_SAP;
+
+       result = net_nfc_server_llcp_unregister_service(
+                       g_dbus_method_invocation_get_sender(invocation), arg_sap, arg_san);
+
+       net_nfc_gdbus_snep_complete_server_unregister(object, invocation, result);
+
+       g_free(arg_san);
+
+       g_object_unref(invocation);
+       g_object_unref(object);
+
+       g_variant_unref(user_data);
+}
+
+static gboolean phdc_handle_unregister(
+               NetNfcGDbusPhdc *object,
+               GDBusMethodInvocation *invocation,
+               guint arg_role,
+               const gchar *arg_san,
+               GVariant *arg_privilege)
+{
+       bool ret;
+       gboolean result;
+       GVariant *parameter = NULL;
+
+       NFC_INFO(">>> REQUEST from [%s]", g_dbus_method_invocation_get_sender(invocation));
+
+       /* check privilege and update client context */
+       ret = net_nfc_server_gdbus_check_privilege(invocation, arg_privilege,
+                       "nfc-manager::p2p", "rw");
+
+       if (FALSE == ret)
+       {
+               NFC_ERR("permission denied, and finished request");
+               result = NET_NFC_SECURITY_FAIL;
+               goto ERROR;
+       }
+
+       parameter = g_variant_new("(uuus)", GPOINTER_TO_UINT(g_object_ref(object)),
+                       GPOINTER_TO_UINT(g_object_ref(invocation)), arg_role, arg_san);
+
+       if (parameter == NULL)
+       {
+               NFC_ERR("Memory allocation failed");
+               result = NET_NFC_ALLOC_FAIL;
+               goto ERROR;
+       }
+       if(net_nfc_server_controller_async_queue_push(
+                       phdc_unregister_server_thread_func, parameter) == FALSE)
+       {
+               NFC_ERR("controller is processing important message.");
+               result = NET_NFC_ALLOC_FAIL;
+               goto ERROR;
+       }
+
+       return TRUE;
+
+       ERROR :
+       if (parameter != NULL)
+       {
+                       g_object_unref(invocation);
+                       g_object_unref(object);
+
+                       g_variant_unref(parameter);
+       }
+
+       net_nfc_gdbus_phdc_complete_register_role(object,
+               invocation,
+               result);
+
+       return TRUE;
+}
+
+
+gboolean net_nfc_server_phdc_init(GDBusConnection *connection)
+{
+       gboolean result;
+       GError *error = NULL;
+
+       if (phdc_skeleton)
+               net_nfc_server_phdc_deinit();
+
+       phdc_skeleton = net_nfc_gdbus_phdc_skeleton_new();
+
+       g_signal_connect(phdc_skeleton,"handle-send", G_CALLBACK(phdc_handle_send), NULL);
+
+       g_signal_connect(phdc_skeleton,"handle-register-role", G_CALLBACK(phdc_handle_register), NULL);
+
+       g_signal_connect(phdc_skeleton,"handle-unregister-role", G_CALLBACK(phdc_handle_unregister), NULL);
+
+       result = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(phdc_skeleton),
+                       connection, "/org/tizen/NetNfcService/Phdc", &error);
+
+       if (FALSE == result)
+       {
+               g_error_free(error);
+               net_nfc_server_phdc_deinit();
+       }
+
+       return result;
+}
+
+void net_nfc_server_phdc_deinit(void)
+{
+       if (phdc_skeleton)
+       {
+               g_object_unref(phdc_skeleton);
+               phdc_skeleton = NULL;
+       }
+}
+
+void net_nfc_server_phdc_transport_disconnect_indication(void)
+{
+       NFC_INFO("====== phdc target disconnected ======");
+
+       /* release target information */
+       net_nfc_server_free_target_info();
+
+       if (phdc_skeleton != NULL)
+               net_nfc_gdbus_phdc_emit_phdc_disconnect(phdc_skeleton);
+}
+
+
+void net_nfc_server_phdc_transport_connect_indication(net_nfc_phdc_handle_h handle)
+{
+       NFC_INFO("====== phdc target connected ======");
+
+       if (NULL == phdc_skeleton)
+       {
+               NFC_ERR("phdc_skeleton is not initialized");
+               return;
+       }
+
+       net_nfc_gdbus_phdc_emit_phdc_connect(phdc_skeleton, GPOINTER_TO_UINT(handle));
+}
+
+void net_nfc_server_phdc_data_sent(net_nfc_error_e result, gpointer user_data)
+{
+       PhdcSendData *data = (PhdcSendData *)user_data;
+
+       g_assert(data != NULL);
+       g_assert(data->phdc != NULL);
+       g_assert(data->invocation != NULL);
+
+       net_nfc_gdbus_phdc_complete_send(data->phdc, data->invocation, (gint)result);
+
+       net_nfc_util_free_data(&data->data);
+
+       g_object_unref(data->invocation);
+       g_object_unref(data->phdc);
+
+       g_free(data);
+}
+
diff --git a/daemon/net_nfc_server_phdc.h b/daemon/net_nfc_server_phdc.h
new file mode 100755 (executable)
index 0000000..a772283
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __NET_NFC_SERVER_PHDC_H__
+#define __NET_NFC_SERVER_PHDC_H__
+
+#include <gio/gio.h>
+#include "net_nfc_typedef_internal.h"
+
+gboolean net_nfc_server_phdc_init(GDBusConnection *connection);
+
+void net_nfc_server_phdc_deinit(void);
+
+/* server side */
+void net_nfc_server_phdc_transport_disconnect_indication(void);
+
+void net_nfc_server_phdc_transport_connect_indication(net_nfc_phdc_handle_h handle);
+
+void net_nfc_server_phdc_data_received_indication(data_s *arg_data);
+
+void net_nfc_server_phdc_data_sent(net_nfc_error_e result, gpointer user_data);
+
+#endif //__NET_NFC_SERVER_PHDC_H__
\ No newline at end of file
diff --git a/daemon/net_nfc_server_process_phdc.c b/daemon/net_nfc_server_process_phdc.c
new file mode 100755 (executable)
index 0000000..2574d4b
--- /dev/null
@@ -0,0 +1,912 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+#include "net_nfc_debug_internal.h"
+#include "net_nfc_server_tag.h"
+#include "net_nfc_util_defines.h"
+#include "net_nfc_util_internal.h"
+#include "net_nfc_util_gdbus_internal.h"
+#include "net_nfc_server_llcp.h"
+#include "net_nfc_server_util.h"
+#include "net_nfc_server_process_phdc.h"
+#include "net_nfc_server_controller.h"
+#include "net_nfc_server_phdc.h"
+
+
+
+typedef struct _net_nfc_server_phdc_pdu_t
+{
+       uint8_t data[128];
+}
+__attribute__ ((packed)) net_nfc_server_phdc_pdu_t;
+
+//callback for internal send/receive
+typedef void (*_net_nfc_server_phdc_operation_cb)(
+               net_nfc_error_e result,
+               data_s *data,
+               void *user_param);
+
+static void _net_nfc_server_phdc_agent_connected_cb(net_nfc_error_e result,
+               net_nfc_target_handle_s *handle,
+               net_nfc_llcp_socket_t socket,
+               data_s *data,
+               void *user_param);
+
+typedef struct _net_nfc_server_phdc_op_context_t
+{
+       net_nfc_target_handle_s *handle;
+       net_nfc_error_e result;
+       int socket;
+       uint32_t state;
+       uint32_t current;
+       uint16_t miu;
+       data_s data;
+       _net_nfc_server_phdc_operation_cb cb;
+       void *user_param;
+}net_nfc_server_phdc_op_context_t;
+
+
+typedef struct _net_nfc_server_phdc_job_t
+{
+       net_nfc_server_phdc_context_t *context;
+       net_nfc_target_handle_s *handle;
+       net_nfc_error_e result;
+       net_nfc_llcp_socket_t socket;
+       uint32_t state;
+       data_s data;
+       net_nfc_server_phdc_send_cb cb;
+       void *user_param;
+}net_nfc_server_phdc_job_t;
+
+static void _net_nfc_server_phdc_agent_process(
+               net_nfc_server_phdc_job_t *job);
+
+static void _net_nfc_server_phdc_destory_context(
+               net_nfc_server_phdc_op_context_t *context);
+
+static void _net_nfc_server_phdc_clear_queue(
+               gpointer data,
+               gpointer user_data);
+
+static void _net_nfc_server_phdc_socket_error_cb(net_nfc_error_e result,
+               net_nfc_target_handle_s *handle,
+               net_nfc_llcp_socket_t socket,
+               data_s *data,
+               void *user_param);
+
+static void _net_nfc_server_phdc_recv_cb(
+               net_nfc_llcp_socket_t socket,
+               net_nfc_error_e result,
+               data_s *data,
+               void *extra,
+               void *user_param);
+
+static void _net_nfc_server_phdc_recv(
+               net_nfc_server_phdc_op_context_t *context);
+
+static net_nfc_server_phdc_op_context_t* _net_nfc_server_phdc_create_recv_context(
+               net_nfc_target_handle_s *handle,
+               net_nfc_llcp_socket_t socket,
+               void *cb,
+               void *user_param);
+
+static void _net_nfc_server_phdc_manager_op_cb(
+               net_nfc_error_e result,
+               data_s *data,
+               void *user_param);
+
+
+static net_nfc_error_e net_nfc_server_phdc_recv(
+               net_nfc_target_handle_s *handle,
+               net_nfc_llcp_socket_t socket,
+               _net_nfc_server_phdc_operation_cb cb,
+               void *user_param);
+
+static void _net_nfc_server_phdc_manager_process(
+               net_nfc_server_phdc_context_t *context);
+
+static void _net_nfc_server_phdc_incoming_cb(net_nfc_error_e result,
+               net_nfc_target_handle_s *handle,
+               net_nfc_llcp_socket_t socket,
+               data_s *data,
+               void *user_param);
+
+
+static void _net_nfc_server_phdc_destory_context(net_nfc_server_phdc_op_context_t *context)
+{
+       if (context != NULL)
+       {
+               if (context->data.buffer != NULL)
+                       net_nfc_util_free_data(&context->data);
+
+               _net_nfc_util_free_mem(context);
+       }
+}
+
+static void _net_nfc_server_phdc_clear_queue(gpointer data,gpointer user_data)
+{
+       net_nfc_server_phdc_job_t *job = (net_nfc_server_phdc_job_t *)data;
+
+       if (job != NULL)
+       {
+               if (job->cb != NULL)
+               {
+                       job->cb((net_nfc_phdc_handle_h)job->context,NET_NFC_OPERATION_FAIL,
+                               NET_NFC_PHDC_OPERATION_FAILED, job->user_param);
+               }
+
+               if (job->data.buffer != NULL)
+                       net_nfc_util_free_data(&job->data);
+
+               _net_nfc_util_free_mem(job);
+       }
+}
+
+static void _net_nfc_server_phdc_socket_error_cb(net_nfc_error_e result,
+               net_nfc_target_handle_s *handle, net_nfc_llcp_socket_t socket, data_s *data,
+               void *user_param)
+{
+       net_nfc_server_phdc_context_t *context = (net_nfc_server_phdc_context_t *)user_param;
+
+       NFC_DBG("_net_nfc_server_phdc_socket_error_cb socket [%x], result [%d]",
+                       socket, result);
+
+       RET_IF(NULL == context);
+
+       if (context->data.buffer != NULL)
+               net_nfc_util_free_data(&context->data);
+
+       g_queue_foreach(&context->queue, _net_nfc_server_phdc_clear_queue, NULL);
+
+       _net_nfc_util_free_mem(context);
+}
+
+
+static void _net_nfc_server_phdc_recv_cb(net_nfc_llcp_socket_t socket,
+               net_nfc_error_e result, data_s *data, void *extra, void *user_param)
+{
+       net_nfc_server_phdc_op_context_t *context =
+               (net_nfc_server_phdc_op_context_t *)user_param;
+
+       uint8_t *buffer = NULL;
+       uint16_t pdu_length = 0;
+
+       NFC_DBG("_net_nfc_server_phdc_recv_cb, socket[%x], result[%d]", socket, result);
+
+       RET_IF(NULL == context);
+
+       context->result = result;
+
+       if (result != NET_NFC_OK)
+       {
+               NFC_ERR("error [%d]", result);
+               context->state = NET_NFC_STATE_ERROR;
+               goto END;
+       }
+
+       if (NULL == data || NULL == data->buffer || 0 == data->length)
+       {
+               NFC_ERR("invalid response");
+               context->state = NET_NFC_STATE_ERROR;
+               goto END;
+       }
+
+       //first 2 bytes is phdc header length
+       memcpy(&pdu_length,data->buffer,PHDC_HEADER_LEN);
+
+       pdu_length = ntohs(pdu_length);
+       NFC_INFO("pdu_legth [%d]", pdu_length);
+
+       if(pdu_length > 0)
+       {
+               /* buffer create */
+               net_nfc_util_alloc_data(&context->data,pdu_length);
+               if (NULL == context->data.buffer)
+               {
+                       NFC_ERR("net_nfc_util_alloc_data failed");
+                       context->result = NET_NFC_ALLOC_FAIL;
+                       goto END;
+               }
+               buffer =data->buffer;
+               context->data.length = data->length - PHDC_HEADER_LEN;
+
+               /* copy data */
+               if(context->data.length > 0)
+               {
+                       memcpy(context->data.buffer ,buffer, context->data.length);
+                       NFC_DBG("receive progress... [%d", context->data.length);
+               }
+       }
+END:
+       context->cb(context->result, &context->data, context->user_param);
+}
+
+
+static void _net_nfc_server_phdc_recv(net_nfc_server_phdc_op_context_t *context)
+{
+       RET_IF(NULL == context);
+
+       bool ret;
+       net_nfc_error_e result;
+
+       NFC_DBG("socket [%x] waiting data.....", context->socket);
+
+       ret = net_nfc_controller_llcp_recv(context->handle, context->socket, context->miu,
+                       &result, _net_nfc_server_phdc_recv_cb, context);
+
+       if(false == ret)
+       {
+               NFC_ERR("net_nfc_controller_llcp_recv failed, [%d]", result);
+
+               context->result = result;
+               context->cb(context->result, &context->data, context->user_param);
+
+               _net_nfc_server_phdc_destory_context(context);
+       }
+
+}
+
+
+static net_nfc_server_phdc_op_context_t* _net_nfc_server_phdc_create_recv_context(
+               net_nfc_target_handle_s *handle, net_nfc_llcp_socket_t socket, void *cb,
+               void *user_param)
+{
+
+       bool ret;
+       net_nfc_error_e result;
+       net_nfc_server_phdc_op_context_t *context = NULL;
+       net_nfc_llcp_config_info_s config;
+
+       ret = net_nfc_controller_llcp_get_remote_config(handle, &config, &result);
+
+       if(false == ret)
+       {
+               NFC_ERR("net_nfc_controller_llcp_get_remote_config failed, [%d]",       result);
+               return NULL;
+       }
+
+       _net_nfc_util_alloc_mem(context, sizeof(*context));
+
+       RETV_IF(NULL == context, NULL);
+
+       context->handle = handle;
+       context->state = NET_NFC_LLCP_STEP_01;
+       context->socket = socket;
+       context->cb = cb;
+       context->user_param = user_param;
+       context->miu = MIN(config.miu, net_nfc_server_llcp_get_miu());
+
+       return context;
+}
+
+
+static net_nfc_error_e net_nfc_server_phdc_recv(net_nfc_target_handle_s *handle,
+               net_nfc_llcp_socket_t socket, _net_nfc_server_phdc_operation_cb cb,
+               void *user_param)
+{
+       net_nfc_error_e result;
+       net_nfc_server_phdc_op_context_t *context = NULL;
+
+       /* create context */
+       context = _net_nfc_server_phdc_create_recv_context(handle, socket, cb, user_param);
+
+       if (context != NULL)
+       {
+               _net_nfc_server_phdc_recv(context);
+               result = NET_NFC_OK;
+       }
+       else
+       {
+               result = NET_NFC_ALLOC_FAIL;
+
+               if (cb != NULL)
+                       cb(result, NULL, user_param);
+       }
+
+       return result;
+}
+
+
+static void _net_nfc_server_phdc_agent_connected_cb(net_nfc_error_e result,
+               net_nfc_target_handle_s *handle, net_nfc_llcp_socket_t socket, data_s *data,
+               void *user_param)
+{
+       net_nfc_server_phdc_context_t *context =
+               (net_nfc_server_phdc_context_t *)user_param;
+
+       RET_IF(NULL == context);
+
+       context->socket = socket;
+
+       if (NET_NFC_OK == result)
+               NFC_DBG("socket [%x] connected. send message", socket);
+       else
+               NFC_ERR("connect socket failed, [%d]", result);
+
+       net_nfc_server_phdc_recv(handle, socket,
+               _net_nfc_server_phdc_manager_op_cb,
+               context);
+
+       if (context->cb != NULL)
+               context->cb((net_nfc_phdc_handle_h)context, result,
+                       NET_NFC_PHDC_TARGET_CONNECTED, NULL);
+
+}
+
+net_nfc_error_e net_nfc_server_phdc_agent_connect(net_nfc_target_handle_s *handle,
+               const char *san, sap_t sap,     net_nfc_server_phdc_cb cb, void *user_param)
+{
+       bool ret;
+       net_nfc_error_e result;
+       net_nfc_server_phdc_context_t *context = NULL;
+
+       RETV_IF(NULL == handle, NET_NFC_NULL_PARAMETER);
+
+       ret = net_nfc_server_target_connected(handle);
+
+       if(FALSE == ret)
+               return NET_NFC_NOT_CONNECTED;
+
+       _net_nfc_util_alloc_mem(context, sizeof(*context));
+
+       if (NULL == context)
+       {
+               NFC_ERR("_net_nfc_util_alloc_mem failed");
+               result = NET_NFC_ALLOC_FAIL;
+               goto ERROR;
+       }
+
+       context->handle = handle;
+       context->cb = cb;
+       context->user_param = user_param;
+
+       result = net_nfc_server_llcp_simple_client(handle, san,         sap,
+                       _net_nfc_server_phdc_agent_connected_cb,
+                       _net_nfc_server_phdc_socket_error_cb,
+                       context);
+
+       if (result != NET_NFC_OK)
+       {
+               NFC_ERR("net_nfc_server_llcp_simple_client failed, [%d]", result);
+               goto ERROR;
+       }
+
+       if (san != NULL)
+               NFC_DBG("start phdc agent san [%s]", san);
+       else
+               NFC_DBG("start phdc agent, sap [%d]", sap);
+
+       return result;
+
+ERROR :
+       if (context != NULL)
+       {
+               if (context->data.buffer != NULL)
+               {
+                       net_nfc_util_free_data(&context->data);
+               }
+               _net_nfc_util_free_mem(context);
+       }
+
+       return result;
+}
+
+
+static void _net_nfc_server_phdc_agent_do_job(
+               net_nfc_server_phdc_context_t *context)
+{
+       if (context->state == NET_NFC_LLCP_IDLE && g_queue_is_empty(&context->queue) == false)
+       {
+               net_nfc_server_phdc_job_t *job;
+
+               job = g_queue_pop_head(&context->queue);
+               if (job != NULL)
+               {
+                       context->state = NET_NFC_LLCP_STEP_01;
+                       job->state = NET_NFC_LLCP_STEP_01;
+                       _net_nfc_server_phdc_agent_process(job);
+               }
+       }
+}
+
+static net_nfc_server_phdc_op_context_t* _net_nfc_server_phdc_create_send_context(
+               net_nfc_target_handle_s *handle, net_nfc_llcp_socket_t socket, data_s *data,
+               void *cb, void *user_param)
+{
+       bool ret;
+       uint32_t data_len = 0;
+       uint16_t length;
+       uint8_t *buffer = NULL;
+       net_nfc_server_phdc_op_context_t *context = NULL;
+       net_nfc_llcp_config_info_s config;
+       net_nfc_error_e result;
+
+       ret = net_nfc_controller_llcp_get_remote_config(handle,
+                       &config, &result);
+
+       if(FALSE == ret)
+       {
+               NFC_ERR("net_nfc_controller_llcp_get_remote_config failed, [%d]",       result);
+               return NULL;
+       }
+
+       _net_nfc_util_alloc_mem(context, sizeof(*context));
+       RETV_IF(NULL == context, NULL);
+
+       if (data != NULL)
+               data_len =data->length;
+
+       if (data_len > 0)
+       {
+               net_nfc_util_alloc_data(&context->data,data_len+PHDC_HEADER_LEN);
+               if (NULL == context->data.buffer)
+               {
+                       _net_nfc_util_free_mem(context);
+                       return NULL;
+               }
+
+               length = (uint16_t)data->length;
+               length +=PHDC_HEADER_LEN;
+               buffer = context->data.buffer;
+
+               if(data->buffer != NULL)
+               {
+                       uint16_t network_length = htons(length);
+                       memcpy(buffer,&network_length,PHDC_HEADER_LEN);
+                       buffer+=PHDC_HEADER_LEN;
+                       memcpy(buffer,data->buffer,data->length);
+                       context->data.length = length;
+               }
+       }
+
+       context->handle = handle;
+       context->socket = socket;
+       context->cb = cb;
+       context->user_param = user_param;
+       context->miu = MIN(config.miu, net_nfc_server_llcp_get_miu());
+
+       return context;
+}
+
+static void _net_nfc_server_phdc_send_cb(net_nfc_llcp_socket_t socket,
+               net_nfc_error_e result, data_s *data, void *extra, void *user_param)
+{
+       net_nfc_server_phdc_op_context_t *context =
+               (net_nfc_server_phdc_op_context_t *)user_param;
+
+       NFC_DBG("_net_nfc_server_phdc_send_cb, socket[%x], result[%d]", socket, result);
+
+       RET_IF(NULL == context);
+
+       context->result = result;
+
+       /* complete and invoke callback */
+       context->cb(context->result, NULL, context->user_param);
+
+       _net_nfc_server_phdc_destory_context(context);
+}
+
+
+static void _net_nfc_server_phdc_send(net_nfc_server_phdc_op_context_t *context)
+{
+       bool ret;
+       data_s req_msg;
+       net_nfc_error_e result;
+
+       RET_IF(NULL == context);
+
+       req_msg.length = context->data.length;
+       req_msg.buffer = context->data.buffer;
+
+       NFC_DBG("try to send data, socket [%x]",context->socket);
+
+       ret= net_nfc_controller_llcp_send(context->handle, context->socket,
+                       &req_msg, &result, _net_nfc_server_phdc_send_cb, context);
+
+       if(FALSE == ret)
+       {
+               NFC_ERR("net_nfc_controller_llcp_send failed, [%d]",result);
+               context->result = result;
+
+               context->cb(context->result, NULL, context->user_param);
+               _net_nfc_server_phdc_destory_context(context);
+       }
+}
+
+static void _net_nfc_server_phdc_agent_send_cb(net_nfc_error_e result,data_s *data,
+               void *user_param)
+{
+       net_nfc_server_phdc_job_t*job = (net_nfc_server_phdc_job_t *)user_param;
+
+       RET_IF(NULL == job);
+
+       job->result = result;
+
+       if (NET_NFC_OK ==result)
+       {
+               job->state = NET_NFC_LLCP_STEP_RETURN;
+               net_nfc_util_free_data(&job->data);
+       }
+       else
+       {
+               NFC_ERR("net_nfc_server_phdc_send failed, [%d]", result);
+               job->state = NET_NFC_STATE_ERROR;
+       }
+
+       _net_nfc_server_phdc_agent_process(job);
+}
+
+
+net_nfc_error_e net_nfc_server_phdc_send(net_nfc_target_handle_s *handle,
+               net_nfc_llcp_socket_t socket, data_s *data, _net_nfc_server_phdc_operation_cb cb,
+               void *user_param)
+{
+       net_nfc_error_e result;
+       net_nfc_server_phdc_op_context_t *context = NULL;
+
+       /* create context */
+       context = _net_nfc_server_phdc_create_send_context(handle, socket,data,
+                       cb, user_param);
+
+       if (context != NULL)
+       {
+               /* send data */
+               _net_nfc_server_phdc_send(context);
+               result = NET_NFC_OK;
+       }
+       else
+       {
+               NFC_ERR("_net_nfc_server_phdc_create_send_context failed");
+               result = NET_NFC_ALLOC_FAIL;
+
+               if (cb != NULL)
+                       cb(result, NULL, user_param);
+       }
+
+       return result;
+}
+
+static void _net_nfc_server_phdc_agent_process(net_nfc_server_phdc_job_t *job)
+{
+       bool finish = false;
+
+       RET_IF(NULL == job);
+
+       switch (job->state)
+       {
+       case NET_NFC_LLCP_STEP_01 :
+               NFC_DBG("NET_NFC_LLCP_STEP_01");
+
+               /* send request */
+               net_nfc_server_phdc_send(job->handle, job->socket,      &job->data,
+                               _net_nfc_server_phdc_agent_send_cb, job);
+               break;
+
+       case NET_NFC_LLCP_STEP_RETURN :
+               NFC_DBG("NET_NFC_LLCP_STEP_RETURN");
+
+               /* complete and invoke callback */
+               if (job->cb != NULL)
+               {
+                       job->cb((net_nfc_phdc_handle_h)job->context, NET_NFC_OK,
+                               NET_NFC_PHDC_DATA_RECEIVED, job->user_param);
+               }
+               /* finish job */
+               finish = true;
+               break;
+
+       case NET_NFC_STATE_ERROR :
+       default :
+               NFC_ERR("NET_NFC_STATE_ERROR");
+
+               /* error, invoke callback */
+               NFC_ERR("phdc_agent_send failed, [%d]", job->result);
+               if (job->cb != NULL)
+               {
+                       job->cb((net_nfc_phdc_handle_h)job->context, job->result,
+                               NET_NFC_PHDC_OPERATION_FAILED, job->user_param);
+               }
+               /* finish job */
+               finish = TRUE;
+               break;
+       }
+
+       if (TRUE == finish)
+       {
+               net_nfc_server_phdc_context_t *context = job->context;
+
+               if (job->data.buffer != NULL)
+                       net_nfc_util_free_data(&job->data);
+
+               _net_nfc_util_free_mem(job);
+               context->state = NET_NFC_LLCP_IDLE;
+               _net_nfc_server_phdc_agent_do_job(context);
+       }
+}
+
+
+net_nfc_error_e net_nfc_server_phdc_agent_request(net_nfc_phdc_handle_h handle,
+               data_s *data, net_nfc_server_phdc_send_cb cb, void *user_param)
+{
+       bool ret;
+       net_nfc_error_e result = NET_NFC_OK;
+       net_nfc_server_phdc_job_t *job = NULL;
+       net_nfc_server_phdc_context_t *context = (net_nfc_server_phdc_context_t *)handle;
+
+       RETV_IF(NULL == handle, NET_NFC_NULL_PARAMETER);
+       RETV_IF(NULL == data, NET_NFC_NULL_PARAMETER);
+       RETV_IF(NULL == data->buffer, NET_NFC_NULL_PARAMETER);
+
+       ret =net_nfc_server_target_connected(context->handle);
+
+       if(FALSE == ret)
+               return NET_NFC_NOT_CONNECTED;
+
+       /* check type */
+       _net_nfc_util_alloc_mem(job, sizeof(*job));
+       if (job != NULL)
+       {
+               net_nfc_util_alloc_data(&job->data, data->length);
+               if (job->data.buffer != NULL)
+                       memcpy(job->data.buffer, data->buffer, data->length);
+
+               job->cb = cb;
+               job->user_param = user_param;
+               job->context = context;
+               job->handle = context->handle;
+               job->socket = context->socket;
+               g_queue_push_tail(&context->queue, job);
+       }
+       else
+               return NET_NFC_ALLOC_FAIL;
+
+       NFC_INFO("enqueued jobs [%d]", g_queue_get_length(&context->queue));
+
+       /* if agent is idle, starts sending request */
+       if (context->state == NET_NFC_LLCP_IDLE)
+               _net_nfc_server_phdc_agent_do_job(context);
+       else
+               NFC_INFO("agent is working. this job will be enqueued");
+
+       return result;
+}
+
+
+net_nfc_error_e net_nfc_server_phdc_agent_start(net_nfc_target_handle_s *handle,
+               const char *san, sap_t sap, net_nfc_server_phdc_cb cb, void *user_param)
+{
+       net_nfc_error_e result;
+
+       RETV_IF(NULL == handle, NET_NFC_NULL_PARAMETER);
+       RETV_IF(NULL == san, NET_NFC_NULL_PARAMETER);
+
+               /* start PHDC Agent, register your callback */
+               result =  net_nfc_server_phdc_agent_connect(handle, san, sap,
+                               cb, user_param);
+
+               if (result != NET_NFC_OK)
+               {
+                       NFC_ERR("net_nfc_server_phdc_agent_connect failed, [%d]",result);
+               }
+               return result;
+}
+
+static void _net_nfc_server_phdc_manager_op_cb( net_nfc_error_e result, data_s *data,
+               void *user_param)
+{
+       net_nfc_server_phdc_context_t *context =
+               (net_nfc_server_phdc_context_t *)user_param;
+
+       NFC_DBG("_net_nfc_server_phdc_manager_op_cb result [%d]", result);
+
+       RET_IF(NULL == context);
+
+       context->result = result;
+       if (NET_NFC_OK == result && data != NULL && data->buffer != NULL)
+       {
+               NFC_DBG("received message, length [%d]", data->length);
+
+               net_nfc_util_alloc_data(&context->data, data->length);
+               if (context->data.buffer != NULL)
+               {
+                       memcpy(context->data.buffer,data->buffer, data->length);
+                       context->state = NET_NFC_LLCP_STEP_02;
+               }
+               else
+               {
+                       NFC_ERR("net_nfc_util_alloc_data failed");
+                       context->state = NET_NFC_STATE_ERROR;
+                       context->result = NET_NFC_ALLOC_FAIL;
+               }
+       }
+       else
+       {
+               NFC_ERR("net_nfc_server_phdc_recv failed, [%d]", result);
+               context->state = NET_NFC_STATE_ERROR;
+       }
+
+       _net_nfc_server_phdc_manager_process(context);
+
+}
+
+
+static void _net_nfc_server_phdc_manager_process(
+               net_nfc_server_phdc_context_t *context)
+{
+       bool finish = false;
+       RET_IF(NULL == context);
+
+       switch (context->state)
+       {
+       case NET_NFC_LLCP_STEP_01 :
+               NFC_INFO("NET_NFC_LLCP_STEP_01 ");
+               /*receive the Agent data*/
+               net_nfc_server_phdc_recv(       context->handle,context->socket,
+                               _net_nfc_server_phdc_manager_op_cb, context);
+               break;
+       case NET_NFC_LLCP_STEP_02 :
+               NFC_INFO("NET_NFC_LLCP_STEP_02");
+               if (context->cb != NULL)
+               {
+                       /* complete operation and invoke the callback*/
+                       context->cb((net_nfc_phdc_handle_h)context,NET_NFC_OK,
+                                       NET_NFC_PHDC_DATA_RECEIVED, &context->data);
+               }
+               finish = true;
+               break;
+       case NET_NFC_STATE_ERROR :
+               NFC_INFO("NET_NFC_STATE_ERROR");
+       default :
+               if (context->cb != NULL)
+               {
+                       context->cb((net_nfc_phdc_handle_h)context,context->result,
+                                       NET_NFC_PHDC_OPERATION_FAILED,&context->data);
+               }
+               return;
+               break;
+       }
+
+       if(true == finish)
+       {
+               context->state = NET_NFC_LLCP_IDLE;
+
+               net_nfc_server_phdc_recv(context->handle,
+                       context->socket,
+                       _net_nfc_server_phdc_manager_op_cb,
+                       context);
+
+       }
+}
+
+
+static void _net_nfc_server_phdc_incoming_cb(net_nfc_error_e result,
+               net_nfc_target_handle_s *handle, net_nfc_llcp_socket_t socket, data_s *data,
+               void *user_param)
+{
+       net_nfc_server_phdc_context_t *context =
+               (net_nfc_server_phdc_context_t *)user_param;
+
+       net_nfc_server_phdc_context_t *accept_context = NULL;
+
+       RET_IF(NULL == context);
+
+       NFC_DBG("phdc incoming socket [%x], result [%d]", socket, result);
+
+       if (result != NET_NFC_OK)
+       {
+               NFC_ERR("listen socket failed, [%d]", result);
+               goto ERROR;
+       }
+
+       _net_nfc_util_alloc_mem(accept_context, sizeof(*accept_context));
+
+       if (NULL == accept_context)
+       {
+               NFC_ERR("_net_nfc_util_alloc_mem failed");
+               result = NET_NFC_ALLOC_FAIL;
+               goto ERROR;
+       }
+
+       accept_context->handle = context->handle;
+       accept_context->socket = socket;
+       accept_context->cb = context->cb;
+       accept_context->user_param = context->user_param;
+       accept_context->state = NET_NFC_LLCP_STEP_01;
+
+       result = net_nfc_server_llcp_simple_accept(handle, socket,
+                       _net_nfc_server_phdc_socket_error_cb, accept_context);
+
+       if (result != NET_NFC_OK)
+       {
+               NFC_ERR("net_nfc_server_llcp_simple_accept failed, [%d]",result);
+               goto ERROR;
+       }
+
+       NFC_DBG("socket [%x] accepted.. waiting for request message", socket);
+
+       accept_context->cb((net_nfc_phdc_handle_h)accept_context, result,
+                       NET_NFC_PHDC_TARGET_CONNECTED, data);
+
+       _net_nfc_server_phdc_manager_process(accept_context);
+
+       return;
+ERROR :
+       if (accept_context != NULL)
+       {
+               _net_nfc_util_free_mem(accept_context);
+       }
+}
+
+net_nfc_error_e net_nfc_server_phdc_manager_start(net_nfc_target_handle_s *handle,
+               const char *san, sap_t sap,     net_nfc_server_phdc_cb cb,      void *user_param)
+{
+       bool ret;
+       net_nfc_error_e result;
+       net_nfc_server_phdc_context_t *context = NULL;
+
+       RETV_IF(NULL == handle, NET_NFC_NULL_PARAMETER);
+       RETV_IF(NULL == san, NET_NFC_NULL_PARAMETER);
+
+       ret = net_nfc_server_target_connected(handle);
+
+       if(FALSE == ret)
+               return NET_NFC_NOT_CONNECTED;
+
+       _net_nfc_util_alloc_mem(context, sizeof(*context));
+       if(NULL == context)
+       {
+               NFC_ERR("_create_phdc_context failed");
+               result = NET_NFC_ALLOC_FAIL;
+               goto ERROR;
+       }
+
+       context->handle = handle;
+       context->cb = cb;
+       context->user_param = user_param;
+       context->state = NET_NFC_LLCP_STEP_01;
+
+       if(!strcmp(san,PHDC_SAN))
+       {
+               /*Handle the default PHDC SAN*/
+               result = net_nfc_server_llcp_simple_server(handle,      san,sap,
+                               _net_nfc_server_phdc_incoming_cb,_net_nfc_server_phdc_socket_error_cb,
+                               context);
+       }
+       else
+       {
+               /*Handle other SAN, Implement as and when needed.*/
+               result = NET_NFC_NOT_SUPPORTED;
+       }
+
+       if (result != NET_NFC_OK)
+       {
+               NFC_ERR("net_nfc_server_llcp_simple_server failed, [%d]",result);
+               goto ERROR;
+       }
+
+       NFC_DBG("start phdc manager, san [%s], sap [%d]", san, sap);
+       return result;
+
+ERROR :
+       if (context != NULL)
+               _net_nfc_util_free_mem(context);
+
+       return result;
+}
+
+///////////////////////////////////////////////////////////////////
+
diff --git a/daemon/net_nfc_server_process_phdc.h b/daemon/net_nfc_server_process_phdc.h
new file mode 100755 (executable)
index 0000000..7e34d9d
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *              http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef __NET_NFC_SERVER_PROCESS_PHDC_H__
+#define __NET_NFC_SERVER_PROCESS_PHDC_H__
+
+#include "net_nfc_gdbus.h"
+#include "net_nfc_typedef_internal.h"
+
+#define PHDC_SAP 0x16
+#define PHDS_SAP 0x17
+#define PHDC_SAN "urn:nfc:sn:phdc"
+#define PHDS_SAN "urn:nfc:sn:phds"
+#define PHDC_HEADER_LEN 2
+
+typedef enum
+{
+       NET_NFC_PHDC_OPERATION_FAILED = 0,
+       NET_NFC_PHDC_TARGET_CONNECTED ,
+       NET_NFC_PHDC_DATA_RECEIVED
+}net_nfc_server_phdc_indication_type;
+
+
+//callback for manager connection accept / agent connect
+typedef void (*net_nfc_server_phdc_cb)(net_nfc_phdc_handle_h handle,
+               net_nfc_error_e result, net_nfc_server_phdc_indication_type indication, data_s *data);
+
+//callback for data send
+typedef gboolean (*net_nfc_server_phdc_send_cb)(net_nfc_phdc_handle_h handle,
+               net_nfc_error_e result, net_nfc_server_phdc_indication_type indication, gpointer *user_data);
+
+typedef struct _net_nfc_server_phdc_context_t net_nfc_server_phdc_context_t;
+
+struct _net_nfc_server_phdc_context_t
+{
+       net_nfc_target_handle_s *handle;
+       net_nfc_error_e result;
+       net_nfc_llcp_socket_t socket;
+       uint32_t state;
+       data_s data;
+       net_nfc_server_phdc_cb cb;
+       void *user_param;
+       GQueue queue;
+};
+
+net_nfc_error_e net_nfc_server_phdc_manager_start(net_nfc_target_handle_s *handle,
+               const char *san, sap_t sap, net_nfc_server_phdc_cb cb,  void *user_param);
+
+net_nfc_error_e net_nfc_server_phdc_agent_start(net_nfc_target_handle_s *handle,
+               const char *san, sap_t sap, net_nfc_server_phdc_cb cb, void *user_param);
+
+net_nfc_error_e net_nfc_server_phdc_agent_request(net_nfc_phdc_handle_h handle,
+               data_s *data, net_nfc_server_phdc_send_cb cb, void *user_param);
+
+
+#endif//__NET_NFC_SERVER_PROCESS_PHDC_H__
+