Tizen 2.1 base tizen tizen_2.1 2.1b_release accepted/tizen/20130520.101037 accepted/tizen_2.1/20130425.035224 submit/tizen/20130517.044914 submit/tizen_2.1/20130424.231304
authorJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:47:27 +0000 (01:47 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:47:27 +0000 (01:47 +0900)
CMakeLists.txt
Changelog [new file with mode: 0644]
packaging/neard-plugin.spec
src/neard-plugin.c
src/nfc.h [new file with mode: 0644]

index f3bd4e0..3e1a0dc 100755 (executable)
@@ -14,7 +14,7 @@ MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
 
 INCLUDE(FindPkgConfig)
 
-pkg_check_modules(pkgs REQUIRED glib-2.0 dbus-1 dbus-glib-1 nfc-common-lib neardal)
+pkg_check_modules(pkgs REQUIRED glib-2.0 nfc-common-lib neardal)
 
 FOREACH(flag ${pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
diff --git a/Changelog b/Changelog
new file mode 100644 (file)
index 0000000..60cb807
--- /dev/null
+++ b/Changelog
@@ -0,0 +1,14 @@
+ver 0.4:
+       Fix spec file
+       Add support for support_nfc and eedata_register_set APIs
+
+ver 0.3
+       nfc.h license change
+
+ver 0.2:
+       Add initial peer to peer support.
+
+ver 0.1:
+       Added reader mode support for NFC types 1,2,3 and 4.
+       Added writer mode support for NFC types 1,2,3 and 4.
+
index 16d36ea..e0be389 100644 (file)
@@ -1,16 +1,14 @@
 Name:      neard-plugin
 Summary:   Neard OAL plugin
-Version:   0.1
+Version:   0.4
 Release:   1
 Group:     System/Networking
-License:   GPLv2
+License:   Apache 2.0
 Source0:   neard-plugin-%{version}.tar.gz
 Source1:   packaging/neard-plugin.manifest
 Requires(post):   /sbin/ldconfig
 Requires(postun): /sbin/ldconfig
 BuildRequires:   pkgconfig(glib-2.0)
-BuildRequires:   pkgconfig(dbus-1)
-BuildRequires:   pkgconfig(dbus-glib-1)
 BuildRequires:   pkgconfig(nfc-common-lib)
 BuildRequires:   pkgconfig(neardal)
 BuildRequires:   cmake
index 5ba443c..2ca233e 100644 (file)
  * limitations under the License.
  */
 
-#include <time.h>
-#include <sys/time.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <stdarg.h>
 #include <unistd.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -25,6 +24,9 @@
 #include <malloc.h>
 #include <syslog.h>
 #include <glib.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <linux/socket.h>
 
 #include "net_nfc_oem_controller.h"
 #include "net_nfc_typedef.h"
 #include "net_nfc_util_ndef_record.h"
 
 #include "neardal.h"
+#include "nfc.h"
 
 #ifndef NET_NFC_EXPORT_API
 #define NET_NFC_EXPORT_API __attribute__((visibility("default")))
 #endif
 
+/* HACK HACK */
+#ifndef AF_NFC
+#define AF_NFC 39
+#endif
+
 /* TODO get real data */
 #define NET_NFC_JEWEL_PICC_MAX_SIZE            116
 #define NET_NFC_MIFARE_ULTRA_PICC_MAX_SIZE     48
@@ -170,19 +178,43 @@ static bool neard_plugin_llcp_get_remote_socket_info(
                                        net_nfc_llcp_socket_t socket,
                                        net_nfc_llcp_socket_option_s * option,
                                        net_nfc_error_e* result);
+static bool neard_plugin_support_nfc(net_nfc_error_e* result);
+static bool neard_plugin_eedata_register_set(net_nfc_error_e* result,
+                                       uint32_t mode, uint32_t reg_id,
+                                       data_s* data);
 
 /*************************** INTERFACE END ***********************************/
 
+struct neard_plugin_p2p_data {
+       uint32_t adapter_idx;
+       uint32_t target_idx;
+       int socket;
+       GIOChannel *channel;
+       guint watch;
+       void *user_param;
+       GList *client_list;
+       net_nfc_target_handle_s* handle;
+};
+
 static char *neard_adp_path = NULL;
 static bool neard_adp_powered = false;
 static bool neard_adp_polling = false;
+static char *neard_adp_mode   = NULL;
 static net_nfc_target_handle_s *current_handle = NULL;
 static neardal_tag *tag = NULL;
+static neardal_dev *dev = NULL;
+static GHashTable *server_hash;
+
+static void neard_plugin_debug(const char *format, ...)
+                       __attribute__((format(printf, 1, 2)));
+
+#define DBG(fmt, arg...) neard_plugin_debug("%d:%s() " fmt, \
+                               __LINE__ ,__FUNCTION__ , ## arg);
 
 /* neard plugin logging functions */
 static void neard_plugin_log_open(const char *name)
 {
-       openlog(name, LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_USER);
+       openlog(name, LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
 }
 
 static void neard_plugin_log_close(void)
@@ -199,8 +231,6 @@ static void neard_plugin_debug(const char *format, ...)
        va_end(ap);
 }
 
-#define DBG(fmt, arg...) neard_plugin_debug("%d:%s() " fmt, __LINE__, __FUNCTION__, ## arg) 
-
 /* Target handle related functions */
 static bool __neard_plugin_is_valid_target_handle(
                                net_nfc_target_handle_s *handle)
@@ -211,23 +241,23 @@ static bool __neard_plugin_is_valid_target_handle(
 static void __neard_plugin_make_valid_target_handle(
                                net_nfc_target_handle_s **handle)
 {
-       if (current_handle != NULL); /* already allocated */
+       if (current_handle != NULL) {
+               *handle = current_handle;
+               return;
+       }
 
        *handle = g_try_malloc0(sizeof(net_nfc_target_handle_s));
        if (*handle != NULL)
                current_handle = *handle;
 }
 
-static void __neard_plugin_make_invalid_target_handle(
-                               net_nfc_target_handle_s* handle)
+static void __neard_plugin_make_invalid_target_handle()
 
 {
         if (current_handle != NULL) {
                g_free(current_handle);
                 current_handle = NULL;
         }
-
-       handle = NULL;
 }
 
 /* neard plugin helper funtions */
@@ -235,7 +265,7 @@ static int __neard_plugin_convert_target_type(const char *type)
 {
        int t_type;
 
-       DBG("");
+       DBG(" %s", type);
 
        /* TODO tag sub types */
 
@@ -278,6 +308,73 @@ static uint32_t __neard_plugin_get_tag_id(const char *name)
        return id;
 }
 
+static uint32_t __neard_plugin_get_dev_id(const char *name)
+{
+       uint32_t id;
+       char **s;
+
+       s = g_strsplit(name, "device", 2);
+       id = atoi(s[1]);
+       g_strfreev(s);
+
+       return id;
+}
+
+static uint32_t __neard_plugin_get_adapter_id(const char *name)
+{
+       uint32_t id;
+       char **s;
+
+       s = g_strsplit(name, "nfc", 2);
+       id = atoi(s[1]);
+       g_strfreev(s);
+
+       return id;
+}
+
+static void __neard_plugin_free_client(gpointer data, gpointer user_data)
+{
+       int socket = GPOINTER_TO_INT(data);
+
+       DBG("");
+       close(socket);
+}
+
+static gboolean __neard_plugin_free_server(gpointer key, gpointer value,
+                                               gpointer user_data)
+{
+       int socket = GPOINTER_TO_INT(key);
+       struct neard_plugin_p2p_data *server = value;
+
+       if (server == NULL)
+               return TRUE;
+
+       if (server->watch > 0)
+               g_source_remove(server->watch);
+
+       server->watch = 0;
+
+       if (server->client_list != NULL) {
+               g_list_foreach(server->client_list,
+                               __neard_plugin_free_client, NULL);
+               g_list_free(server->client_list);
+               server->client_list = NULL;
+       }
+
+       close(socket);
+
+       return TRUE;
+}
+
+static void __neard_plugin_free_server_hash(void)
+{
+       DBG("");
+
+       g_hash_table_foreach_remove(server_hash,
+                                       __neard_plugin_free_server,
+                                       NULL);
+}
+
 /* neardal callbaks */
 static void __neardal_adp_added_cb(const char *adpName, void *user_data)
 {
@@ -310,11 +407,19 @@ static void __neardal_adp_prop_changed_cb(char *adpName, char *propName,
        if (!g_strcmp0(propName, "Polling")) {
                if ((int*) value == 0) {
                        neard_adp_polling = false;
-                       DBG(" polling stopped ");
+                       DBG(" Stopped");
                } else {
                        neard_adp_polling = true;
-                       DBG(" polling started ");
+                       DBG(" Started");
                }
+       } else if (!g_strcmp0(propName, "Mode")) {
+               if (neard_adp_mode) {
+                       g_free(neard_adp_mode);
+                       neard_adp_mode = NULL;
+               }
+
+               neard_adp_mode = g_strdup((char *)value);
+               DBG(" '%s'", neard_adp_mode);
        }
 }
 
@@ -378,6 +483,83 @@ static void __neardal_record_found_cb(const char *rcdName, void *user_data)
 
 }
 
+static void __neardal_device_found_cb(const char *devName, void *user_data)
+{
+       net_nfc_target_handle_s *handle = NULL;
+       net_nfc_request_target_detected_t *dev_detected = NULL;
+
+       DBG("");
+
+       if (g_hash_table_size(server_hash) > 0) {
+                __neard_plugin_free_server_hash();
+       }
+
+       if (neardal_get_dev_properties(devName, &dev) != NEARDAL_SUCCESS)
+               return;
+
+       __neard_plugin_make_valid_target_handle(&handle);
+       if (handle == NULL)
+               goto out_err;
+
+       handle->connection_id = __neard_plugin_get_dev_id(devName);
+
+       dev_detected = g_try_malloc0(sizeof(net_nfc_request_target_detected_t));
+       if (dev_detected == NULL)
+               goto out_err;
+
+       dev_detected->length = sizeof(net_nfc_request_target_detected_t);
+       dev_detected->request_type = NET_NFC_MESSAGE_SERVICE_STANDALONE_TARGET_DETECTED;
+       /* Note: This one is neard role, depends upon neard role we are
+        * deciding detected device role. */
+       dev_detected->devType = __neard_plugin_convert_target_type(neard_adp_mode);
+       dev_detected->number_of_keys = 0;
+       dev_detected->target_info_values.length = 0;
+
+       if (dev_detected->devType == NET_NFC_NFCIP1_INITIATOR)
+               handle->connection_type = NET_NFC_P2P_CONNECTION_TARGET;
+       else if(dev_detected->devType == NET_NFC_NFCIP1_TARGET)
+               handle->connection_type = NET_NFC_P2P_CONNECTION_INITIATOR;
+
+       dev_detected->handle = handle;
+
+       if (interface_target_detection_cb != NULL)
+               interface_target_detection_cb(dev_detected, NULL);
+
+       return;
+
+out_err:
+       g_free(dev_detected);
+}
+
+static void __neardal_device_lost_cb(const char *devName, void *user_data)
+{
+       net_nfc_request_llcp_msg_t *message;
+
+       DBG("");
+
+       __neard_plugin_free_server_hash();
+       __neard_plugin_make_invalid_target_handle();
+
+       if (dev != NULL) {
+               neardal_free_device(dev);
+               dev = NULL;
+       }
+
+       message = g_try_malloc0(sizeof(net_nfc_request_llcp_msg_t));
+       if (message != NULL) {
+               message->length = sizeof(net_nfc_request_llcp_msg_t);
+               message->request_type = NET_NFC_MESSAGE_SERVICE_LLCP_DEACTIVATED;
+               interface_llcp_event_cb(message, NULL);
+       }
+
+       if (neard_adp_polling == true)
+               return;
+
+       if (neardal_start_poll_loop(neard_adp_path,
+                       NEARD_ADP_MODE_DUAL) == NEARDAL_SUCCESS)
+               neard_adp_polling = true;
+}
+
 static errorCode_t __neardal_init(void)
 {
        errorCode_t err;
@@ -387,6 +569,10 @@ static errorCode_t __neardal_init(void)
 
        DBG("");
 
+       server_hash = g_hash_table_new_full(g_direct_hash,
+                                               g_direct_equal,
+                                               NULL, NULL);
+
        /* Get neard adapters */
        err = neardal_get_adapters(&adapters, &len);
        if (err != NEARDAL_SUCCESS)
@@ -465,7 +651,11 @@ static bool neard_plugin_init(net_nfc_error_e *result)
                neardal_set_cb_tag_lost(
                        __neardal_tag_lost_cb, NULL) != NEARDAL_SUCCESS ||
                neardal_set_cb_record_found(
-                       __neardal_record_found_cb, NULL) != NEARDAL_SUCCESS) {
+                       __neardal_record_found_cb, NULL) != NEARDAL_SUCCESS ||
+               neardal_set_cb_dev_found(
+                       __neardal_device_found_cb, NULL) != NEARDAL_SUCCESS ||
+               neardal_set_cb_dev_lost(
+                       __neardal_device_lost_cb, NULL) != NEARDAL_SUCCESS) {
 
                *result = NET_NFC_INVALID_HANDLE;
 
@@ -501,11 +691,27 @@ static bool neard_plugin_deinit(void)
                neard_adp_path = NULL;
        }
 
+       if (neard_adp_mode) {
+               g_free(neard_adp_mode);
+               neard_adp_mode = NULL;
+       }
+
        if (tag != NULL) {
                neardal_free_tag(tag);
                tag = NULL;
        }
 
+       if (dev != NULL) {
+               neardal_free_device(dev);
+               dev = NULL;
+       }
+
+       if (server_hash != NULL) {
+               __neard_plugin_free_server_hash();
+               g_hash_table_destroy(server_hash);
+               server_hash = NULL;
+       }
+
        neardal_destroy();
        neard_plugin_log_close();
 
@@ -537,12 +743,42 @@ static bool neard_plugin_unregister_listener()
        DBG("");
 
        interface_target_detection_cb = NULL;
-       interface_se_transaction_cb     = NULL;
+       interface_se_transaction_cb   = NULL;
        interface_llcp_event_cb   = NULL;
 
        return true;
 }
 
+static bool neard_plugin_support_nfc(net_nfc_error_e* result)
+{
+       char **adapters = NULL;
+       int len;
+       errorCode_t err;
+
+       DBG("");
+
+       if (result == NULL)
+               return false;
+
+       /* Get neard adapters */
+       err = neardal_get_adapters(&adapters, &len);
+       if (err != NEARDAL_SUCCESS) {
+               *result = NET_NFC_NOT_SUPPORTED;
+               return false;
+       }
+
+       if (!(len > 0 && adapters != NULL)) {
+               *result = NET_NFC_NOT_SUPPORTED;
+               return false;
+       }
+
+       neardal_free_array(&adapters);
+       adapters = NULL;
+
+       *result = NET_NFC_OK;
+       return true;
+}
+
 static bool neard_plugin_check_firmware_version(net_nfc_error_e* result)
 {
        DBG("");
@@ -573,6 +809,11 @@ static bool neard_plugin_get_stack_information(
 {
        DBG("");
 
+       if (result == NULL)
+               return false;
+
+       *result = NET_NFC_NOT_SUPPORTED;
+
        return false;
 }
 
@@ -583,6 +824,17 @@ static bool neard_plugin_configure_discovery(
 {
        DBG("");
 
+       if (result == NULL)
+               return false;
+
+       if (mode == NET_NFC_DISCOVERY_MODE_CONFIG &&
+                       config == NET_NFC_ALL_ENABLE) {
+               *result = NET_NFC_OK;
+               return true;
+       }
+
+       *result = NET_NFC_NOT_SUPPORTED;
+
        return false;
 }
 
@@ -592,7 +844,7 @@ static bool neard_plugin_get_secure_element_list(
 {
        DBG("");
 
-       if (result == FALSE)
+       if (result == NULL)
                return false;
 
        *result = NET_NFC_NOT_SUPPORTED;
@@ -607,7 +859,7 @@ static bool neard_plugin_set_secure_element_mode(
 {
        DBG("");
 
-       if (result == FALSE)
+       if (result == NULL)
                return false;
 
        *result = NET_NFC_NOT_SUPPORTED;
@@ -651,7 +903,7 @@ static bool neard_plugin_disconnect(net_nfc_target_handle_s* handle,
                return false;
        }
 
-       __neard_plugin_make_invalid_target_handle(handle);
+       __neard_plugin_make_invalid_target_handle();
         *result = NET_NFC_OK;
 
        return true;
@@ -721,9 +973,10 @@ static bool neard_plugin_check_ndef(net_nfc_target_handle_s* handle,
                break;
        }
 
-       g_free(ndef);
-       *real_data_size = len;
+       if (ndef != NULL)
+               g_free(ndef);
 
+       *real_data_size = len;
        *result = NET_NFC_OK;
 
        return true;
@@ -748,7 +1001,7 @@ static bool neard_plugin_check_target_presence(net_nfc_target_handle_s* handle,
        }
 
        if (tag == NULL) {
-               DBG("target lost");
+               DBG(" not connected");
                *result = NET_NFC_NOT_CONNECTED;
                return false;
        }
@@ -959,7 +1212,13 @@ static bool neard_plugin_llcp_config(net_nfc_llcp_config_info_s *config,
                return false;
        }
 
-       return false;
+       /* TODO : have to set these config options */
+       DBG("set llcp config params lto=%d, miu=%d, option=0x%02x, wks=0x%02x): ",
+               config->lto, config->miu, config->option, config->wks);
+
+       *result = NET_NFC_OK;
+
+       return true;
 }
 
 static bool neard_plugin_llcp_check_llcp(net_nfc_target_handle_s *handle,
@@ -967,7 +1226,24 @@ static bool neard_plugin_llcp_check_llcp(net_nfc_target_handle_s *handle,
 {
        DBG("");
 
-       return false;
+       if (result == NULL)
+               return false;
+
+       if (handle == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (!__neard_plugin_is_valid_target_handle(handle)) {
+               *result = NET_NFC_INVALID_HANDLE;
+               return false;
+       }
+
+       /* TODO : how ??? (adapter->protocals == NFC_DEP)*/
+
+       *result = NET_NFC_OK;
+
+       return true;
 }
 
 static bool neard_plugin_llcp_activate_llcp(net_nfc_target_handle_s *handle,
@@ -975,38 +1251,249 @@ static bool neard_plugin_llcp_activate_llcp(net_nfc_target_handle_s *handle,
 {
        DBG("");
 
-       return false;
+       if (result == NULL)
+               return false;
+
+       if (handle == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (!__neard_plugin_is_valid_target_handle(handle)) {
+               *result = NET_NFC_INVALID_HANDLE;
+               return false;
+       }
+
+       *result = NET_NFC_OK;
+       return true;
 }
 
-static bool neard_plugin_llcp_create_socket(net_nfc_llcp_socket_t *socket,
+static bool neard_plugin_llcp_create_socket(net_nfc_llcp_socket_t *s,
                                        net_nfc_socket_type_e socketType,
                                        uint16_t miu, uint8_t rw,
                                        net_nfc_error_e* result,
-                                       void * user_param)
+                                       void* user_param)
 {
+       int fd;
+       struct neard_plugin_p2p_data *server;
+
        DBG("");
 
-       return false;
+       if (result == NULL)
+               return false;
+
+       if (s == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (socketType != NET_NFC_LLCP_SOCKET_TYPE_CONNECTIONORIENTED) {
+               *result = NET_NFC_NOT_SUPPORTED;
+               return false;
+       }
+
+       fd = socket(AF_NFC, SOCK_STREAM, NFC_SOCKPROTO_LLCP);
+       if (fd < 0) {
+               *result = NET_NFC_OPERATION_FAIL;
+               return false;
+       }
+
+       /* TODO : set these config options for socket */
+//     DBG(" socketType : %d, miu : %d, rw : %d", socketType, miu, rw);
+
+        server = g_try_malloc0(sizeof(struct neard_plugin_p2p_data));
+        if (server == NULL) {
+                close(fd);
+               *result = NET_NFC_ALLOC_FAIL;
+                return false;
+        }
+
+       g_hash_table_insert(server_hash, GINT_TO_POINTER(fd), server);
+
+       *s = fd;
+       *result = NET_NFC_OK;
+
+       return true;
 }
 
 static bool neard_plugin_llcp_bind(net_nfc_llcp_socket_t socket,
                                        uint8_t service_access_point,
                                        net_nfc_error_e* result)
 {
-       DBG("");
+       DBG("service_access_point : %d", service_access_point);
 
-       return false;
+       if (result == NULL)
+               return false;
+
+       /* Note: binding requires service access name, and it is
+        * available in listen call, so binind and listen in 
+        * listen call.
+        */
+       *result = NET_NFC_OK;
+
+       return true;
+}
+
+static gboolean __neard_plugin_p2p_listen_cb(GIOChannel *channel,
+                                               GIOCondition condition,
+                                               gpointer user_data)
+{
+       net_nfc_request_accept_socket_t *message;
+       struct neard_plugin_p2p_data *server = user_data;
+       struct sockaddr_nfc_llcp client_addr;
+       socklen_t client_addr_len;
+       int client_fd;
+
+       DBG("condition 0x%x", condition);
+
+       message = g_try_malloc0(sizeof(net_nfc_request_accept_socket_t));
+        if (message == NULL)
+               return FALSE;
+
+       if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+               DBG("error in listener event");
+               message->length = sizeof(net_nfc_request_accept_socket_t);
+               message->request_type = NET_NFC_MESSAGE_SERVICE_LLCP_SOCKET_ERROR;
+               message->result = NET_NFC_OPERATION_FAIL;
+
+               interface_llcp_event_cb(message, server->user_param);
+
+               return FALSE;
+       }
+
+       client_addr_len = sizeof(client_addr);
+       client_fd = accept(server->socket, (struct sockaddr *) &client_addr,
+                                                       &client_addr_len);
+       if (client_fd < 0) {
+               DBG("accept failed");
+               message->length = sizeof(net_nfc_request_accept_socket_t);
+               message->request_type = NET_NFC_MESSAGE_SERVICE_LLCP_SOCKET_ACCEPTED_ERROR;
+               message->result = NET_NFC_OPERATION_FAIL;
+
+               interface_llcp_event_cb(message, server->user_param);
+
+               return FALSE;
+       }
+
+       server->client_list = g_list_append(server->client_list, &client_fd);
+
+       message->length = sizeof(net_nfc_request_accept_socket_t);
+       message->request_type = NET_NFC_MESSAGE_SERVICE_LLCP_ACCEPT;
+       message->handle = server->handle;
+       message->incomming_socket = client_fd;
+       message->trans_param = server->user_param;
+       message->result = NET_NFC_OK;
+
+       interface_llcp_event_cb(message, server->user_param);
+
+       return TRUE;
 }
 
 static bool neard_plugin_llcp_listen(net_nfc_target_handle_s* handle,
                                        uint8_t* service_access_name,
                                        net_nfc_llcp_socket_t socket,
                                        net_nfc_error_e* result,
-                                       void * user_param)
+                                       void* user_param)
 {
+        struct sockaddr_nfc_llcp addr;
+       struct neard_plugin_p2p_data *server;
+       net_nfc_request_accept_socket_t *message;
+       int err;
+
        DBG("");
 
-       return false;
+       if (result == NULL)
+               return false;
+
+       if (handle == NULL || service_access_name == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (!__neard_plugin_is_valid_target_handle(handle)) {
+               *result = NET_NFC_INVALID_HANDLE;
+               return false;
+       }
+
+       DBG("service_access_name : %s, socket : %d",
+                       (char *)service_access_name, socket);
+
+       memset(&addr, 0, sizeof(struct sockaddr_nfc_llcp));
+       addr.sa_family = AF_NFC;
+       addr.dev_idx = __neard_plugin_get_adapter_id(neard_adp_path);
+       addr.nfc_protocol = NFC_PROTO_NFC_DEP;
+       addr.service_name_len = strlen((char *)service_access_name);
+       strcpy(addr.service_name, (char *)service_access_name);
+
+       /* binding */
+       err = bind(socket, (struct sockaddr *) &addr,
+                       sizeof(struct sockaddr_nfc_llcp));
+       if (err < 0) {
+               if (errno == EADDRINUSE) {
+                       DBG("%s is already bound", addr.service_name);
+                       *result = NET_NFC_OPERATION_FAIL;
+                       return false;
+               }
+
+               DBG("%s bind failed %d", addr.service_name, err);
+
+               message = g_try_malloc0(sizeof(net_nfc_request_accept_socket_t));
+               if (message == NULL)
+                       return FALSE;
+
+               message->length = sizeof(net_nfc_request_accept_socket_t);
+               message->request_type = NET_NFC_MESSAGE_SERVICE_LLCP_SOCKET_ERROR;
+               message->result = NET_NFC_OPERATION_FAIL;
+
+               interface_llcp_event_cb(message, user_param);
+
+               close(socket);
+               *result = NET_NFC_OPERATION_FAIL;
+               return false;
+       }
+
+       /* listening */
+       err = listen(socket, 10);
+       if (err < 0) {
+               DBG("%s listen failed %d", addr.service_name, err);
+
+               message = g_try_malloc0(sizeof(net_nfc_request_accept_socket_t));
+               if (message == NULL)
+                       return FALSE;
+
+               message->length = sizeof(net_nfc_request_accept_socket_t);
+               message->request_type = NET_NFC_MESSAGE_SERVICE_LLCP_SOCKET_ERROR;
+               message->result = NET_NFC_OPERATION_FAIL;
+
+               interface_llcp_event_cb(message, user_param);
+
+               close(socket);
+               *result = NET_NFC_OPERATION_FAIL;
+                return false;
+        }
+
+       server = g_hash_table_lookup(server_hash, GINT_TO_POINTER(socket));
+       if (server == NULL) {
+               *result = NET_NFC_UNKNOWN_ERROR;
+               return false;
+       }
+
+       server->adapter_idx = addr.dev_idx;
+       server->socket = socket;
+       server->handle = handle;
+       server->user_param = user_param;
+
+       server->channel = g_io_channel_unix_new(socket);
+       g_io_channel_set_close_on_unref(server->channel, TRUE);
+
+       server->watch = g_io_add_watch(server->channel,
+                               G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR,
+                               __neard_plugin_p2p_listen_cb,
+                               (gpointer) server);
+       g_io_channel_unref(server->channel);
+
+       *result = NET_NFC_OK;
+       return true;
 }
 
 static bool neard_plugin_llcp_accept(net_nfc_llcp_socket_t socket,
@@ -1014,28 +1501,92 @@ static bool neard_plugin_llcp_accept(net_nfc_llcp_socket_t socket,
 {
        DBG("");
 
-       return false;
+       if (result == NULL)
+               return false;
+
+       *result = NET_NFC_OK;
+       return true;
 }
 
 static bool neard_plugin_llcp_connect_by_url(net_nfc_target_handle_s* handle,
                                        net_nfc_llcp_socket_t socket,
                                        uint8_t* service_access_name,
                                        net_nfc_error_e* result,
-                                       void * user_param)
+                                       void* user_param)
 {
-       DBG("");
+       int err = 0;
+        struct sockaddr_nfc_llcp addr;
+       net_nfc_request_llcp_msg_t *message;
 
-       return false;
+        DBG("");
+
+       if (result == NULL)
+               return false;
+
+       if (handle == NULL || service_access_name == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (!__neard_plugin_is_valid_target_handle(handle)) {
+               *result = NET_NFC_INVALID_HANDLE;
+               return false;
+       }
+
+       memset(&addr, 0, sizeof(struct sockaddr_nfc_llcp));
+       addr.sa_family = AF_NFC;
+       addr.dev_idx =  __neard_plugin_get_adapter_id(neard_adp_path);
+       addr.target_idx = handle->connection_id;
+       addr.nfc_protocol = NFC_PROTO_NFC_DEP;
+       addr.service_name_len = strlen((char *)service_access_name);
+       strcpy(addr.service_name, (char *)service_access_name);
+
+       err = connect(socket, (struct sockaddr *) &addr,
+                       sizeof(struct sockaddr_nfc_llcp));
+       if (err < 0) {
+               DBG("Connect failed  %d", err);
+               *result = NET_NFC_LLCP_INVALID_SOCKET;
+               return false;
+        }
+
+       message = g_try_malloc0(sizeof(net_nfc_request_llcp_msg_t));
+       if (message == NULL) {
+               *result = NET_NFC_ALLOC_FAIL;
+               return false;
+       }
+
+       message->length = sizeof(net_nfc_request_llcp_msg_t);
+       message->request_type = NET_NFC_MESSAGE_SERVICE_LLCP_CONNECT;
+       message->result = NET_NFC_OK;
+
+       interface_llcp_event_cb(message, user_param);
+
+       *result = NET_NFC_OK;
+       return true;
 }
 
 static bool neard_plugin_llcp_connect(net_nfc_target_handle_s* handle,
                                        net_nfc_llcp_socket_t socket,
                                        uint8_t service_access_point,
                                        net_nfc_error_e* result,
-                                       void * user_param)
+                                       void* user_param)
 {
        DBG("");
 
+       if (result == NULL)
+               return false;
+
+       if (handle == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (!__neard_plugin_is_valid_target_handle(handle)) {
+               *result = NET_NFC_INVALID_HANDLE;
+               return false;
+       }
+
+       *result = NET_NFC_NOT_SUPPORTED;
        return false;
 }
 
@@ -1045,55 +1596,200 @@ static bool neard_plugin_llcp_reject(net_nfc_target_handle_s* handle,
 {
        DBG("");
 
+       if (result == NULL)
+               return false;
+
+       if (handle == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (!__neard_plugin_is_valid_target_handle(handle)) {
+               *result = NET_NFC_INVALID_HANDLE;
+               return false;
+       }
+
+       *result = NET_NFC_NOT_SUPPORTED;
        return false;
 }
 
 static bool neard_plugin_llcp_disconnect(net_nfc_target_handle_s* handle,
                                        net_nfc_llcp_socket_t socket,
                                        net_nfc_error_e* result,
-                                       void * user_param)
+                                       void* user_param)
 {
        DBG("");
 
+       if (result == NULL)
+               return false;
+
+       if (handle == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (!__neard_plugin_is_valid_target_handle(handle)) {
+               *result = NET_NFC_INVALID_HANDLE;
+               return false;
+       }
+
+       *result = NET_NFC_NOT_SUPPORTED;
        return false;
 }
 
 static bool neard_plugin_llcp_socket_close(net_nfc_llcp_socket_t socket,
                                        net_nfc_error_e* result)
 {
+       struct neard_plugin_p2p_data *data;
+
        DBG("");
 
-       return false;
+       if (result == NULL)
+               return false;
+
+       data = g_hash_table_lookup(server_hash, GINT_TO_POINTER(socket));
+       if (data != NULL) {
+               __neard_plugin_free_server(GINT_TO_POINTER(socket),
+                                               data, NULL);
+               g_hash_table_remove(server_hash, GINT_TO_POINTER(socket));
+       }
+
+       *result = NET_NFC_OK;
+
+       return true;
 }
 
 static bool neard_plugin_llcp_recv(net_nfc_target_handle_s* handle,
                                        net_nfc_llcp_socket_t socket,
                                        data_s* data, net_nfc_error_e* result,
-                                       void * user_param)
+                                       void* user_param)
 {
+       net_nfc_request_llcp_msg_t *message;
+       uint8_t buffer[128];
+       int bytes_recv;
+
        DBG("");
 
-       return false;
+       if (result == NULL)
+               return false;
+
+       if (handle == NULL || data == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (!__neard_plugin_is_valid_target_handle(handle)) {
+               *result = NET_NFC_INVALID_HANDLE;
+               return false;
+       }
+
+       bytes_recv = recv(socket, buffer, 128, 0);
+       DBG("bytes read %d", bytes_recv);
+
+       if (bytes_recv < 0) {
+               DBG("Could not recv data from socket");
+
+               *result = NET_NFC_LLCP_INVALID_SOCKET;
+               return false;
+       }
+
+       if (bytes_recv == 0) {
+               data->length = 0;
+               *result = NET_NFC_OK;
+               return true;
+       }
+
+       data->length = bytes_recv;
+       memcpy(data->buffer, buffer, data->length);
+
+       message = g_try_malloc0(sizeof(net_nfc_request_llcp_msg_t));
+       if (message == NULL) {
+               *result = NET_NFC_ALLOC_FAIL;
+               return false;
+       }
+
+       message->length = sizeof(net_nfc_request_llcp_msg_t);
+       message->request_type = NET_NFC_MESSAGE_SERVICE_LLCP_RECEIVE;
+       message->result = NET_NFC_OK;
+
+       interface_llcp_event_cb(message, user_param);
+
+       *result = NET_NFC_OK;
+
+       return true;
 }
 
 static bool neard_plugin_llcp_send(net_nfc_target_handle_s* handle,
                                        net_nfc_llcp_socket_t socket,
                                        data_s* data, net_nfc_error_e* result,
-                                       void * user_param)
+                                       void* user_param)
 {
+       net_nfc_request_llcp_msg_t *message;
+       int err;
+
        DBG("");
 
-       return false;
+       if (result == NULL)
+               return false;
+
+       if (handle == NULL || data == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (!__neard_plugin_is_valid_target_handle(handle)) {
+               *result = NET_NFC_INVALID_HANDLE;
+               return false;
+       }
+
+       err = send(socket, data->buffer, data->length, 0);
+       if (err < 0) {
+               DBG("sending failed %d", err);
+               *result = NET_NFC_P2P_SEND_FAIL;
+               return false;
+       }
+
+       DBG("Sent %d bytes", data->length);
+
+       message = g_try_malloc0(sizeof(net_nfc_request_llcp_msg_t));
+       if (message == NULL) {
+               *result = NET_NFC_ALLOC_FAIL;
+               return false;
+       }
+
+       message->length = sizeof(net_nfc_request_llcp_msg_t);
+       message->request_type = NET_NFC_MESSAGE_SERVICE_LLCP_SEND;
+       message->result = NET_NFC_OK;
+
+       interface_llcp_event_cb(message, user_param);
+
+       *result = NET_NFC_OK;
+       return true;
 }
 
 static bool neard_plugin_llcp_recv_from(net_nfc_target_handle_s* handle,
                                        net_nfc_llcp_socket_t socket,
                                        data_s * data,
                                        net_nfc_error_e* result,
-                                       void * user_param)
+                                       void* user_param)
 {
        DBG("");
 
+       if (result == NULL)
+               return false;
+
+       if (handle == NULL || data == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (!__neard_plugin_is_valid_target_handle(handle)) {
+               *result = NET_NFC_INVALID_HANDLE;
+               return false;
+       }
+
+       *result = NET_NFC_NOT_SUPPORTED;
+
        return false;
 }
 
@@ -1102,10 +1798,25 @@ static bool neard_plugin_llcp_send_to(net_nfc_target_handle_s* handle,
                                        data_s* data,
                                        uint8_t service_access_point,
                                        net_nfc_error_e* result,
-                                       void * user_param)
+                                       void* user_param)
 {
        DBG("");
 
+       if (result == NULL)
+               return false;
+
+       if (handle == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (!__neard_plugin_is_valid_target_handle(handle)) {
+               *result = NET_NFC_INVALID_HANDLE;
+               return false;
+       }
+
+       *result = NET_NFC_NOT_SUPPORTED;
+
        return false;
 }
 
@@ -1116,20 +1827,71 @@ static bool neard_plugin_llcp_get_remote_config(
 {
        DBG("");
 
+       if (result == NULL)
+               return false;
+
+       if (handle == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (!__neard_plugin_is_valid_target_handle(handle)) {
+               *result = NET_NFC_INVALID_HANDLE;
+               return false;
+       }
+
+       *result = NET_NFC_NOT_SUPPORTED;
+
        return false;
 }
 
 static bool neard_plugin_llcp_get_remote_socket_info(
                                        net_nfc_target_handle_s* handle,
                                        net_nfc_llcp_socket_t socket,
-                                       net_nfc_llcp_socket_option_s * option,
+                                       net_nfc_llcp_socket_option_s *option,
                                        net_nfc_error_e* result)
 {
        DBG("");
 
-       return false;
+       if (result == NULL)
+               return false;
+
+       if (handle == NULL || option == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       if (!__neard_plugin_is_valid_target_handle(handle)) {
+               *result = NET_NFC_INVALID_HANDLE;
+               return false;
+       }
+
+       /* TODO : get real values */
+        option->miu = 128;
+        option->rw = 1;
+        option->type = NET_NFC_LLCP_SOCKET_TYPE_CONNECTIONORIENTED;
+
+       *result = NET_NFC_OK;
+       return true;
 }
 
+static bool neard_plugin_eedata_register_set(net_nfc_error_e* result,
+                                       uint32_t mode, uint32_t reg_id,
+                                       data_s* data)
+{
+       DBG("");
+
+       if (result == NULL)
+               return false;
+
+       if (data == NULL) {
+               *result = NET_NFC_NULL_PARAMETER;
+               return false;
+       }
+
+       *result = NET_NFC_NOT_SUPPORTED;
+       return false;
+}
 
 NET_NFC_EXPORT_API bool onload(net_nfc_oem_interface_s* iface)
 {
@@ -1137,6 +1899,7 @@ NET_NFC_EXPORT_API bool onload(net_nfc_oem_interface_s* iface)
        iface->deinit = neard_plugin_deinit;
        iface->register_listener = neard_plugin_register_listener;
        iface->unregister_listener = neard_plugin_unregister_listener;
+       iface->support_nfc = neard_plugin_support_nfc;
        iface->check_firmware_version = neard_plugin_check_firmware_version;
        iface->update_firmeware = neard_plugin_update_firmware;
        iface->get_stack_information = neard_plugin_get_stack_information;
@@ -1173,7 +1936,7 @@ NET_NFC_EXPORT_API bool onload(net_nfc_oem_interface_s* iface)
        iface->reject_llcp = neard_plugin_llcp_reject;
         iface->get_remote_config = neard_plugin_llcp_get_remote_config;
        iface->get_remote_socket_info = neard_plugin_llcp_get_remote_socket_info;
+       iface->eedata_register_set = neard_plugin_eedata_register_set;
 
        return true;
 }
-
diff --git a/src/nfc.h b/src/nfc.h
new file mode 100644 (file)
index 0000000..f81ac79
--- /dev/null
+++ b/src/nfc.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2011 Instituto Nokia de Tecnologia
+ *
+ * Authors:
+ *    Lauro Ramos Venancio <lauro.venancio@openbossa.org>
+ *    Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+#ifndef __LINUX_NFC_H
+#define __LINUX_NFC_H
+
+#include <linux/types.h>
+#include <linux/socket.h>
+
+#define NFC_GENL_NAME "nfc"
+#define NFC_GENL_VERSION 1
+
+#define NFC_GENL_MCAST_EVENT_NAME "events"
+
+/**
+ * enum nfc_commands - supported nfc commands
+ *
+ * @NFC_CMD_UNSPEC: unspecified command
+ *
+ * @NFC_CMD_GET_DEVICE: request information about a device (requires
+ *     %NFC_ATTR_DEVICE_INDEX) or dump request to get a list of all nfc devices
+ * @NFC_CMD_DEV_UP: turn on the nfc device
+ *     (requires %NFC_ATTR_DEVICE_INDEX)
+ * @NFC_CMD_DEV_DOWN: turn off the nfc device
+ *     (requires %NFC_ATTR_DEVICE_INDEX)
+ * @NFC_CMD_START_POLL: start polling for targets using the given protocols
+ *     (requires %NFC_ATTR_DEVICE_INDEX and %NFC_ATTR_PROTOCOLS)
+ * @NFC_CMD_STOP_POLL: stop polling for targets (requires
+ *     %NFC_ATTR_DEVICE_INDEX)
+ * @NFC_CMD_GET_TARGET: dump all targets found by the previous poll (requires
+ *     %NFC_ATTR_DEVICE_INDEX)
+ * @NFC_EVENT_TARGETS_FOUND: event emitted when a new target is found
+ *     (it sends %NFC_ATTR_DEVICE_INDEX)
+ * @NFC_EVENT_DEVICE_ADDED: event emitted when a new device is registred
+ *     (it sends %NFC_ATTR_DEVICE_NAME, %NFC_ATTR_DEVICE_INDEX and
+ *     %NFC_ATTR_PROTOCOLS)
+ * @NFC_EVENT_DEVICE_REMOVED: event emitted when a device is removed
+ *     (it sends %NFC_ATTR_DEVICE_INDEX)
+ * @NFC_EVENT_TM_ACTIVATED: event emitted when the adapter is activated in
+ *      target mode.
+ * @NFC_EVENT_DEVICE_DEACTIVATED: event emitted when the adapter is deactivated
+ *      from target mode.
+ */
+enum nfc_commands {
+       NFC_CMD_UNSPEC,
+       NFC_CMD_GET_DEVICE,
+       NFC_CMD_DEV_UP,
+       NFC_CMD_DEV_DOWN,
+       NFC_CMD_DEP_LINK_UP,
+       NFC_CMD_DEP_LINK_DOWN,
+       NFC_CMD_START_POLL,
+       NFC_CMD_STOP_POLL,
+       NFC_CMD_GET_TARGET,
+       NFC_EVENT_TARGETS_FOUND,
+       NFC_EVENT_DEVICE_ADDED,
+       NFC_EVENT_DEVICE_REMOVED,
+       NFC_EVENT_TARGET_LOST,
+       NFC_EVENT_TM_ACTIVATED,
+       NFC_EVENT_TM_DEACTIVATED,
+/* private: internal use only */
+       __NFC_CMD_AFTER_LAST
+};
+#define NFC_CMD_MAX (__NFC_CMD_AFTER_LAST - 1)
+
+/**
+ * enum nfc_attrs - supported nfc attributes
+ *
+ * @NFC_ATTR_UNSPEC: unspecified attribute
+ *
+ * @NFC_ATTR_DEVICE_INDEX: index of nfc device
+ * @NFC_ATTR_DEVICE_NAME: device name, max 8 chars
+ * @NFC_ATTR_PROTOCOLS: nfc protocols - bitwise or-ed combination from
+ *     NFC_PROTO_*_MASK constants
+ * @NFC_ATTR_TARGET_INDEX: index of the nfc target
+ * @NFC_ATTR_TARGET_SENS_RES: NFC-A targets extra information such as NFCID
+ * @NFC_ATTR_TARGET_SEL_RES: NFC-A targets extra information (useful if the
+ *     target is not NFC-Forum compliant)
+ * @NFC_ATTR_TARGET_NFCID1: NFC-A targets identifier, max 10 bytes
+ * @NFC_ATTR_TARGET_SENSB_RES: NFC-B targets extra information, max 12 bytes
+ * @NFC_ATTR_TARGET_SENSF_RES: NFC-F targets extra information, max 18 bytes
+ * @NFC_ATTR_COMM_MODE: Passive or active mode
+ * @NFC_ATTR_RF_MODE: Initiator or target
+ * @NFC_ATTR_IM_PROTOCOLS: Initiator mode protocols to poll for
+ * @NFC_ATTR_TM_PROTOCOLS: Target mode protocols to listen for
+ */
+enum nfc_attrs {
+       NFC_ATTR_UNSPEC,
+       NFC_ATTR_DEVICE_INDEX,
+       NFC_ATTR_DEVICE_NAME,
+       NFC_ATTR_PROTOCOLS,
+       NFC_ATTR_TARGET_INDEX,
+       NFC_ATTR_TARGET_SENS_RES,
+       NFC_ATTR_TARGET_SEL_RES,
+       NFC_ATTR_TARGET_NFCID1,
+       NFC_ATTR_TARGET_SENSB_RES,
+       NFC_ATTR_TARGET_SENSF_RES,
+       NFC_ATTR_COMM_MODE,
+       NFC_ATTR_RF_MODE,
+       NFC_ATTR_DEVICE_POWERED,
+       NFC_ATTR_IM_PROTOCOLS,
+       NFC_ATTR_TM_PROTOCOLS,
+/* private: internal use only */
+       __NFC_ATTR_AFTER_LAST
+};
+#define NFC_ATTR_MAX (__NFC_ATTR_AFTER_LAST - 1)
+
+#define NFC_DEVICE_NAME_MAXSIZE 8
+#define NFC_NFCID1_MAXSIZE 10
+#define NFC_SENSB_RES_MAXSIZE 12
+#define NFC_SENSF_RES_MAXSIZE 18
+#define NFC_GB_MAXSIZE        48
+
+/* NFC protocols */
+#define NFC_PROTO_JEWEL                1
+#define NFC_PROTO_MIFARE       2
+#define NFC_PROTO_FELICA       3
+#define NFC_PROTO_ISO14443     4
+#define NFC_PROTO_NFC_DEP      5
+#define NFC_PROTO_ISO14443_B   6
+
+#define NFC_PROTO_MAX          7
+
+/* NFC communication modes */
+#define NFC_COMM_ACTIVE  0
+#define NFC_COMM_PASSIVE 1
+
+/* NFC RF modes */
+#define NFC_RF_INITIATOR 0
+#define NFC_RF_TARGET    1
+#define NFC_RF_NONE      2
+
+/* NFC protocols masks used in bitsets */
+#define NFC_PROTO_JEWEL_MASK      (1 << NFC_PROTO_JEWEL)
+#define NFC_PROTO_MIFARE_MASK     (1 << NFC_PROTO_MIFARE)
+#define NFC_PROTO_FELICA_MASK    (1 << NFC_PROTO_FELICA)
+#define NFC_PROTO_ISO14443_MASK          (1 << NFC_PROTO_ISO14443)
+#define NFC_PROTO_NFC_DEP_MASK   (1 << NFC_PROTO_NFC_DEP)
+#define NFC_PROTO_ISO14443_B_MASK (1 << NFC_PROTO_ISO14443_B)
+
+struct sockaddr_nfc {
+       sa_family_t sa_family;
+       __u32 dev_idx;
+       __u32 target_idx;
+       __u32 nfc_protocol;
+};
+
+#define NFC_LLCP_MAX_SERVICE_NAME 63
+struct sockaddr_nfc_llcp {
+       sa_family_t sa_family;
+       __u32 dev_idx;
+       __u32 target_idx;
+       __u32 nfc_protocol;
+       __u8 dsap; /* Destination SAP, if known */
+       __u8 ssap; /* Source SAP to be bound to */
+       char service_name[NFC_LLCP_MAX_SERVICE_NAME]; /* Service name URI */;
+       size_t service_name_len;
+};
+
+/* NFC socket protocols */
+#define NFC_SOCKPROTO_RAW      0
+#define NFC_SOCKPROTO_LLCP     1
+#define NFC_SOCKPROTO_MAX      2
+
+#define NFC_HEADER_SIZE 1
+
+#endif /*__LINUX_NFC_H */