--- /dev/null
+/*
+ * Copyright (c) 2012, Intel Corportation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#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_private.h"
+#include "net_nfc_util_ndef_message.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
+#define NET_NFC_FELICA_PICC_MAX_SIZE 256
+#define NET_NFC_MIFARE_DESFIRE_PICC_MAX_SIZE 2048
+
+/*************************** INTERFACE CALLBACKS *****************************/
+static target_detection_listener_cb interface_target_detection_cb;
+static se_transaction_listener_cb interface_se_transaction_cb;
+static llcp_event_listener_cb interface_llcp_event_cb;
+
+/*************************** INTERFACE START *********************************/
+static bool neard_plugin_init(net_nfc_error_e* result);
+static bool neard_plugin_deinit(void);
+static bool neard_plugin_register_listener(
+ target_detection_listener_cb target_detection_listener,
+ se_transaction_listener_cb se_transaction_listener,
+ llcp_event_listener_cb llcp_event_listener,
+ net_nfc_error_e* result);
+static bool neard_plugin_unregister_listener();
+static bool neard_plugin_check_firmware_version(net_nfc_error_e* result);
+static bool neard_plugin_update_firmware(net_nfc_error_e* result);
+static bool neard_plugin_get_stack_information(
+ net_nfc_stack_information_s* stack_info,
+ net_nfc_error_e* result);
+static bool neard_plugin_configure_discovery(
+ net_nfc_discovery_mode_e mode,
+ net_nfc_event_filter_e config,
+ net_nfc_error_e* result);
+static bool neard_plugin_get_secure_element_list(
+ net_nfc_secure_element_info_s* list,
+ int* count, net_nfc_error_e* result);
+static bool neard_plugin_set_secure_element_mode(
+ net_nfc_secure_element_type_e element_type,
+ net_nfc_secure_element_mode_e mode,
+ net_nfc_error_e* result);
+static bool neard_plugin_connect(net_nfc_target_handle_s* handle,
+ net_nfc_error_e* result);
+static bool neard_plugin_disconnect(net_nfc_target_handle_s* handle,
+ net_nfc_error_e* result);
+static bool neard_plugin_check_ndef(net_nfc_target_handle_s* handle,
+ uint8_t *ndef_card_state,
+ int* max_data_size,
+ int* real_data_size,
+ net_nfc_error_e* result);
+static bool neard_plugin_check_target_presence(net_nfc_target_handle_s* handle,
+ net_nfc_error_e* result);
+static bool neard_plugin_read_ndef(net_nfc_target_handle_s* handle,
+ data_s** data,
+ net_nfc_error_e* result);
+static bool neard_plugin_write_ndef(net_nfc_target_handle_s* handle,
+ data_s* data, net_nfc_error_e* result);
+static bool neard_plugin_make_read_only_ndef(net_nfc_target_handle_s* handle,
+ net_nfc_error_e* result);
+static bool neard_plugin_transceive(net_nfc_target_handle_s* handle,
+ net_nfc_transceive_info_s* info,
+ data_s** data,
+ net_nfc_error_e* result);
+static bool neard_plugin_format_ndef(net_nfc_target_handle_s* handle,
+ data_s* secure_key,
+ net_nfc_error_e* result);
+static bool neard_plugin_exception_handler(void);
+static bool neard_plugin_is_ready(net_nfc_error_e* error);
+
+static bool neard_plugin_llcp_config(net_nfc_llcp_config_info_s *config,
+ net_nfc_error_e *result);
+static bool neard_plugin_llcp_check_llcp(net_nfc_target_handle_s *handle,
+ net_nfc_error_e *result);
+static bool neard_plugin_llcp_activate_llcp(net_nfc_target_handle_s *handle,
+ net_nfc_error_e *result);
+static bool neard_plugin_llcp_create_socket(net_nfc_llcp_socket_t *socket,
+ net_nfc_socket_type_e socketType,
+ uint16_t miu, uint8_t rw,
+ net_nfc_error_e* result,
+ void * user_param);
+static bool neard_plugin_llcp_bind(net_nfc_llcp_socket_t socket,
+ uint8_t service_access_point,
+ net_nfc_error_e* result);
+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);
+static bool neard_plugin_llcp_accept(net_nfc_llcp_socket_t socket,
+ net_nfc_error_e* result);
+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);
+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);
+static bool neard_plugin_llcp_reject(net_nfc_target_handle_s* handle,
+ net_nfc_llcp_socket_t socket,
+ net_nfc_error_e* result);
+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);
+static bool neard_plugin_llcp_socket_close(net_nfc_llcp_socket_t socket,
+ net_nfc_error_e* result);
+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);
+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);
+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);
+static bool neard_plugin_llcp_send_to(net_nfc_target_handle_s* handle,
+ net_nfc_llcp_socket_t socket,
+ data_s* data,
+ uint8_t service_access_point,
+ net_nfc_error_e* result,
+ void * user_param);
+static bool neard_plugin_llcp_get_remote_config(
+ net_nfc_target_handle_s* handle,
+ net_nfc_llcp_config_info_s *config,
+ net_nfc_error_e* result);
+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_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_DAEMON);
+}
+
+static void neard_plugin_log_close(void)
+{
+ closelog();
+}
+
+static void neard_plugin_debug(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ vsyslog(LOG_DEBUG, format, ap);
+ va_end(ap);
+}
+
+/* Target handle related functions */
+static bool __neard_plugin_is_valid_target_handle(
+ net_nfc_target_handle_s *handle)
+{
+ return (current_handle == handle);
+}
+
+static void __neard_plugin_make_valid_target_handle(
+ net_nfc_target_handle_s **handle)
+{
+ 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()
+
+{
+ if (current_handle != NULL) {
+ g_free(current_handle);
+ current_handle = NULL;
+ }
+}
+
+/* neard plugin helper funtions */
+static int __neard_plugin_convert_target_type(const char *type)
+{
+ int t_type;
+
+ DBG(" %s", type);
+
+ /* TODO tag sub types */
+
+ if (type == NULL)
+ return NET_NFC_UNKNOWN_TARGET;
+
+ if (!g_strcmp0(type, "Type 1"))
+ t_type = NET_NFC_JEWEL_PICC;
+ else if (!g_strcmp0(type, "Type 2"))
+ t_type = NET_NFC_MIFARE_ULTRA_PICC;
+ /*
+ NET_NFC_MIFARE_MINI_PICC
+ NET_NFC_MIFARE_1K_PICC
+ NET_NFC_MIFARE_4K_PICC
+ NET_NFC_MIFARE_ULTRA_PICC
+ */
+ else if (!g_strcmp0(type, "Type 3"))
+ t_type = NET_NFC_FELICA_PICC;
+ else if (!g_strcmp0(type, "Type 4"))
+ t_type = NET_NFC_MIFARE_DESFIRE_PICC;
+ else if (!g_strcmp0(type, "Target"))
+ t_type = NET_NFC_NFCIP1_TARGET;
+ else if (!g_strcmp0(type, "Initiator"))
+ t_type = NET_NFC_NFCIP1_INITIATOR;
+ else
+ t_type = NET_NFC_UNKNOWN_TARGET;
+
+ return t_type;
+}
+
+static uint32_t __neard_plugin_get_tag_id(const char *name)
+{
+ uint32_t id;
+ char **s;
+
+ s = g_strsplit(name, "tag", 2);
+ id = atoi(s[1]);
+ g_strfreev(s);
+
+ 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)
+{
+ DBG("");
+
+ if (neard_adp_path) {
+ g_free(neard_adp_path);
+ neard_adp_path = NULL;
+ }
+
+ if (adpName != NULL)
+ neard_adp_path = g_strdup(adpName);
+}
+
+static void __neardal_adp_removed_cb(const char *adpName, void *user_data)
+{
+ DBG("");
+
+ if (neard_adp_path) {
+ g_free(neard_adp_path);
+ neard_adp_path = NULL;
+ }
+}
+
+static void __neardal_adp_prop_changed_cb(char *adpName, char *propName,
+ void *value, void *user_data)
+{
+ DBG(" %s", propName);
+
+ if (!g_strcmp0(propName, "Polling")) {
+ if ((int*) value == 0) {
+ neard_adp_polling = false;
+ DBG(" Stopped");
+ } else {
+ neard_adp_polling = true;
+ 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);
+ }
+}
+
+static void __neardal_tag_found_cb(const char *tagName, void *user_data)
+{
+ DBG("");
+
+ net_nfc_target_handle_s *handle = NULL;
+ net_nfc_request_target_detected_t *tag_detected = NULL;
+
+ if (neardal_get_tag_properties(tagName, &tag) != NEARDAL_SUCCESS)
+ return;
+
+ __neard_plugin_make_valid_target_handle(&handle);
+ if (handle == NULL)
+ goto out_err;
+
+ handle->connection_id = __neard_plugin_get_tag_id(tagName);
+ handle->connection_type = NET_NFC_TAG_CONNECTION;
+
+ tag_detected = g_try_malloc0(sizeof(net_nfc_request_target_detected_t));
+ if (tag_detected == NULL)
+ goto out_err;
+
+ tag_detected->length = sizeof(net_nfc_request_target_detected_t);
+ tag_detected->request_type = NET_NFC_MESSAGE_SERVICE_STANDALONE_TARGET_DETECTED;
+ tag_detected->devType = __neard_plugin_convert_target_type(tag->type);
+ tag_detected->number_of_keys = 0;
+ tag_detected->handle = handle;
+ tag_detected->target_info_values.length = 0;
+
+ if (interface_target_detection_cb != NULL)
+ interface_target_detection_cb(tag_detected, NULL);
+
+ return;
+
+out_err:
+ g_free(tag_detected);
+}
+
+static void __neardal_tag_lost_cb(const char *tagName, void *userdata)
+{
+ DBG("");
+
+ if (tag != NULL) {
+ neardal_free_tag(tag);
+ tag = 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 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;
+ neardal_adapter *neard_adp = NULL;
+ char **adapters = NULL;
+ int len, powered;
+
+ 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)
+ goto out_err;
+
+ if (!(len > 0 && adapters != NULL))
+ goto out_err;
+
+ /* Cache the current/default adapter path */
+ neard_adp_path = g_strdup(adapters[0]);
+ neardal_free_array(&adapters);
+ adapters = NULL;
+
+ /* Get adapters properties */
+ err = neardal_get_adapter_properties(neard_adp_path, &neard_adp);
+ if (err != NEARDAL_SUCCESS)
+ goto out_err;
+
+ if (neard_adp == NULL) {
+ err = NEARDAL_ERROR_DBUS;
+ goto out_err;
+ }
+
+ neard_adp_powered = (neard_adp->powered) ? true : false;
+ neard_adp_polling = (neard_adp->polling) ? true : false;
+ neardal_free_adapter(neard_adp);
+ neard_adp = NULL;
+
+ /* If adpater is not powered on then power it on */
+ if (neard_adp_powered == false) {
+ powered = 1;
+ err = neardal_set_adapter_property(neard_adp_path,
+ NEARD_ADP_PROP_POWERED, (void*) powered);
+ if (err != NEARDAL_SUCCESS)
+ goto out_err;
+
+ neard_adp_powered = true;
+ }
+
+ if (neard_adp_polling == false) {
+ err = neardal_start_poll_loop(neard_adp_path,
+ NEARD_ADP_MODE_DUAL);
+ if (err != NEARDAL_SUCCESS)
+ goto out_err;
+
+ neard_adp_polling = true;
+ }
+
+ return NEARDAL_SUCCESS;
+
+out_err:
+
+ if (adapters)
+ neardal_free_array(&adapters);
+
+ if (neard_adp)
+ neardal_free_adapter(neard_adp);
+
+ return err;
+}
+
+static bool neard_plugin_init(net_nfc_error_e *result)
+{
+ neard_plugin_log_open("neard-plugin");
+
+ DBG("");
+
+ if (neardal_set_cb_adapter_added(
+ __neardal_adp_added_cb, NULL) != NEARDAL_SUCCESS ||
+ neardal_set_cb_adapter_removed(
+ __neardal_adp_removed_cb, NULL) != NEARDAL_SUCCESS ||
+ neardal_set_cb_adapter_property_changed(
+ __neardal_adp_prop_changed_cb, NULL) != NEARDAL_SUCCESS ||
+ neardal_set_cb_tag_found(
+ __neardal_tag_found_cb, NULL) != NEARDAL_SUCCESS ||
+ 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_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;
+
+ return false;
+ }
+
+ if (__neardal_init() != NEARDAL_SUCCESS) {
+ *result = NET_NFC_UNKNOWN_ERROR;
+
+ return false;
+ }
+
+ *result = NET_NFC_OK;
+
+ return true;
+}
+
+static bool neard_plugin_deinit(void)
+{
+ int powered = 0;
+
+ DBG("");
+
+ if (neard_adp_polling == true)
+ neardal_stop_poll(neard_adp_path);
+
+ if (neard_adp_powered == true)
+ neardal_set_adapter_property(neard_adp_path,
+ NEARD_ADP_PROP_POWERED, (void*) powered);
+
+ if (neard_adp_path) {
+ g_free(neard_adp_path);
+ 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();
+
+ return true;
+}
+
+static bool neard_plugin_register_listener(
+ target_detection_listener_cb target_detection_listener,
+ se_transaction_listener_cb se_transaction_listener,
+ llcp_event_listener_cb llcp_event_listener,
+ net_nfc_error_e* result)
+{
+ if (result == NULL)
+ return false;
+
+ DBG("");
+
+ interface_target_detection_cb = target_detection_listener;
+ interface_se_transaction_cb = se_transaction_listener;
+ interface_llcp_event_cb = llcp_event_listener;
+
+ *result = NET_NFC_OK;
+
+ return true;
+}
+
+static bool neard_plugin_unregister_listener()
+{
+ DBG("");
+
+ interface_target_detection_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("");
+
+ if (result == NULL)
+ return false;
+
+ *result = NET_NFC_NOT_SUPPORTED;
+
+ return false;
+}
+
+static bool neard_plugin_update_firmware(net_nfc_error_e* result)
+{
+ DBG("");
+
+ if (result == NULL)
+ return false;
+
+ *result = NET_NFC_NOT_SUPPORTED;
+
+ return false;
+}
+
+static bool neard_plugin_get_stack_information(
+ net_nfc_stack_information_s* stack_info,
+ net_nfc_error_e* result)
+{
+ DBG("");
+
+ if (result == NULL)
+ return false;
+
+ *result = NET_NFC_NOT_SUPPORTED;
+
+ return false;
+}
+
+static bool neard_plugin_configure_discovery(
+ net_nfc_discovery_mode_e mode,
+ net_nfc_event_filter_e config,
+ net_nfc_error_e* result)
+{
+ 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;
+}
+
+static bool neard_plugin_get_secure_element_list(
+ net_nfc_secure_element_info_s* list,
+ int* count, net_nfc_error_e* result)
+{
+ DBG("");
+
+ if (result == NULL)
+ return false;
+
+ *result = NET_NFC_NOT_SUPPORTED;
+
+ return false;
+}
+
+static bool neard_plugin_set_secure_element_mode(
+ net_nfc_secure_element_type_e element_type,
+ net_nfc_secure_element_mode_e mode,
+ net_nfc_error_e* result)
+{
+ DBG("");
+
+ if (result == NULL)
+ return false;
+
+ *result = NET_NFC_NOT_SUPPORTED;
+
+ return false;
+}
+
+static bool neard_plugin_connect(net_nfc_target_handle_s* handle,
+ net_nfc_error_e* result)
+{
+ 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_OK;
+
+ return true;
+}
+
+static bool neard_plugin_disconnect(net_nfc_target_handle_s* handle,
+ net_nfc_error_e* result)
+{
+ DBG("");
+
+ if (result == NULL)
+ return false;
+
+ if (handle == NULL) {
+ *result = NET_NFC_NULL_PARAMETER;
+ return false;
+ }
+
+ __neard_plugin_make_invalid_target_handle();
+ *result = NET_NFC_OK;
+
+ return true;
+}
+
+/* TODO */
+static bool neard_plugin_check_ndef(net_nfc_target_handle_s* handle,
+ uint8_t *ndef_card_state,
+ int* max_data_size,
+ int* real_data_size,
+ net_nfc_error_e* result)
+{
+ char *ndef = NULL;
+ int len = 0;
+
+ DBG("");
+
+ if (result == NULL)
+ return false;
+
+ if (handle == NULL || ndef_card_state == NULL ||
+ max_data_size == NULL || real_data_size == NULL) {
+
+ *result = NET_NFC_NULL_PARAMETER;
+ return false;
+ }
+
+ if (!__neard_plugin_is_valid_target_handle(handle)) {
+ *result = NET_NFC_INVALID_HANDLE;
+ return false;
+ }
+
+ if (tag == NULL) {
+ *result = NET_NFC_UNKNOWN_ERROR;
+ return false;
+ }
+
+ if (neardal_tag_get_rawNDEF(tag->name, &ndef, &len)
+ != NEARDAL_SUCCESS) {
+ *ndef_card_state = 0;
+ *max_data_size = -1;
+ *real_data_size = -1;
+ *result = NET_NFC_TAG_READ_FAILED;
+ }
+
+ if (tag->readOnly)
+ *ndef_card_state = NET_NFC_NDEF_CARD_READ_ONLY;
+ else
+ *ndef_card_state = NET_NFC_NDEF_CARD_READ_WRITE;
+
+ /* TODO get real data */
+ switch (__neard_plugin_convert_target_type(tag->type)) {
+ case NET_NFC_JEWEL_PICC:
+ *max_data_size = NET_NFC_JEWEL_PICC_MAX_SIZE;
+ break;
+
+ case NET_NFC_MIFARE_ULTRA_PICC:
+ *max_data_size = NET_NFC_MIFARE_ULTRA_PICC_MAX_SIZE;;
+ break;
+
+ case NET_NFC_FELICA_PICC:
+ *max_data_size = NET_NFC_FELICA_PICC_MAX_SIZE;
+ break;
+
+ case NET_NFC_MIFARE_DESFIRE_PICC:
+ *max_data_size = NET_NFC_MIFARE_DESFIRE_PICC_MAX_SIZE;
+ break;
+ }
+
+ if (ndef != NULL)
+ g_free(ndef);
+
+ *real_data_size = len;
+ *result = NET_NFC_OK;
+
+ return true;
+}
+
+static bool neard_plugin_check_target_presence(net_nfc_target_handle_s* handle,
+ net_nfc_error_e* result)
+{
+// 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;
+ }
+
+ if (tag == NULL) {
+ DBG(" not connected");
+ *result = NET_NFC_NOT_CONNECTED;
+ return false;
+ }
+
+ *result = NET_NFC_OK;
+
+ return true;
+}
+
+static bool neard_plugin_read_ndef(net_nfc_target_handle_s* handle,
+ data_s** data,
+ net_nfc_error_e* result)
+{
+ char *buffer = NULL;
+ int len = 0;
+
+ 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;
+ }
+
+ *data = g_try_malloc0(sizeof(data_s));
+ if (*data == NULL) {
+ *result = NET_NFC_ALLOC_FAIL;
+ return false;
+ }
+
+ if (neardal_tag_get_rawNDEF(tag->name, &buffer,
+ &len) != NEARDAL_SUCCESS) {
+ g_free(*data);
+ *data = NULL;
+ *result = NET_NFC_TAG_READ_FAILED;
+
+ return false;
+ }
+
+ (*data)->length = len;
+ (*data)->buffer = g_try_malloc0((*data)->length);
+ if ((*data)->buffer == NULL) {
+ g_free(buffer);
+ g_free(*data);
+ *result = NET_NFC_ALLOC_FAIL;
+ return false;
+ }
+
+ memcpy((*data)->buffer, buffer, (*data)->length);
+
+ g_free(buffer);
+
+ *result = NET_NFC_OK;
+
+ return true;
+}
+
+static bool neard_plugin_write_ndef(net_nfc_target_handle_s* handle,
+ data_s* data, net_nfc_error_e* result)
+{
+ neardal_record *record;
+
+ 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;
+ }
+
+ if ((data->buffer == NULL && data->length != 0) ||
+ (data->buffer != NULL && data->length == 0)) {
+ *result = NET_NFC_NULL_PARAMETER;
+ return false;
+ }
+
+ record = g_try_malloc0(sizeof(neardal_record));
+ if (record == NULL) {
+ *result = NET_NFC_ALLOC_FAIL;
+ return false;
+ }
+
+ record->name = g_strdup(tag->records[0]);
+ record->type = g_strdup("Raw");
+ record->rawNDEF = g_try_malloc0(data->length);
+ if (record->rawNDEF == NULL) {
+ neardal_free_record(record);
+ *result = NET_NFC_ALLOC_FAIL;
+ return false;
+ }
+
+ memcpy(record->rawNDEF, data->buffer, data->length);
+ record->rawNDEFSize = data->length;
+
+ if (neardal_tag_write(record) != NEARDAL_SUCCESS) {
+ neardal_free_record(record);
+ *result = NET_NFC_TAG_WRITE_FAILED;
+ return false;
+ }
+
+ neardal_free_record(record);
+ *result = NET_NFC_OK;
+
+ return true;
+}
+
+static bool neard_plugin_make_read_only_ndef(net_nfc_target_handle_s* handle,
+ net_nfc_error_e* result)
+{
+ 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_transceive(net_nfc_target_handle_s* handle,
+ net_nfc_transceive_info_s* info,
+ data_s** data,
+ net_nfc_error_e* result)
+{
+ DBG("");
+
+ return false;
+}
+
+static bool neard_plugin_format_ndef(net_nfc_target_handle_s* handle,
+ data_s* secure_key,
+ net_nfc_error_e* result)
+{
+ DBG("");
+
+ if (result == NULL)
+ return false;
+
+ if (handle == NULL || secure_key == 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_exception_handler(void)
+{
+ DBG("");
+
+ return true;
+}
+
+static bool neard_plugin_is_ready(net_nfc_error_e* result)
+{
+ DBG("");
+
+ if (result == NULL)
+ return false;
+
+ *result = NET_NFC_OK;
+
+ return true;
+}
+
+
+static bool neard_plugin_llcp_config(net_nfc_llcp_config_info_s *config,
+ net_nfc_error_e *result)
+{
+ DBG("");
+
+ if (result == NULL)
+ return false;
+
+ if (config == NULL) {
+ *result = NET_NFC_NULL_PARAMETER;
+ 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,
+ net_nfc_error_e *result)
+{
+ 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;
+ }
+
+ /* 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,
+ net_nfc_error_e *result)
+{
+ 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_OK;
+ return true;
+}
+
+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)
+{
+ int fd;
+ struct neard_plugin_p2p_data *server;
+
+ DBG("");
+
+ 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("service_access_point : %d", service_access_point);
+
+ 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)
+{
+ struct sockaddr_nfc_llcp addr;
+ struct neard_plugin_p2p_data *server;
+ net_nfc_request_accept_socket_t *message;
+ int err;
+
+ 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;
+ }
+
+ 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,
+ net_nfc_error_e* result)
+{
+ DBG("");
+
+ 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)
+{
+ int err = 0;
+ struct sockaddr_nfc_llcp addr;
+ net_nfc_request_llcp_msg_t *message;
+
+ 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)
+{
+ 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_reject(net_nfc_target_handle_s* handle,
+ net_nfc_llcp_socket_t socket,
+ net_nfc_error_e* result)
+{
+ 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)
+{
+ 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("");
+
+ 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)
+{
+ net_nfc_request_llcp_msg_t *message;
+ uint8_t buffer[128];
+ int bytes_recv;
+
+ 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;
+ }
+
+ 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)
+{
+ net_nfc_request_llcp_msg_t *message;
+ int err;
+
+ 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;
+ }
+
+ 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)
+{
+ 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;
+}
+
+static bool neard_plugin_llcp_send_to(net_nfc_target_handle_s* handle,
+ net_nfc_llcp_socket_t socket,
+ data_s* data,
+ uint8_t service_access_point,
+ net_nfc_error_e* result,
+ 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_get_remote_config(
+ net_nfc_target_handle_s* handle,
+ net_nfc_llcp_config_info_s *config,
+ net_nfc_error_e* result)
+{
+ 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_error_e* result)
+{
+ DBG("");
+
+ 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)
+{
+ iface->init = neard_plugin_init;
+ 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;
+ iface->configure_discovery = neard_plugin_configure_discovery;
+ iface->get_secure_element_list = neard_plugin_get_secure_element_list;
+ iface->set_secure_element_mode = neard_plugin_set_secure_element_mode;
+ iface->connect = neard_plugin_connect;
+ iface->disconnect = neard_plugin_disconnect;
+ iface->check_ndef = neard_plugin_check_ndef;
+ iface->check_presence = neard_plugin_check_target_presence;
+ iface->read_ndef = neard_plugin_read_ndef;
+ iface->write_ndef = neard_plugin_write_ndef;
+ iface->make_read_only_ndef = neard_plugin_make_read_only_ndef;
+ iface->transceive = neard_plugin_transceive;
+ iface->format_ndef = neard_plugin_format_ndef;
+ iface->exception_handler = neard_plugin_exception_handler;
+ iface->is_ready = neard_plugin_is_ready;
+
+ iface->config_llcp = neard_plugin_llcp_config;
+ iface->check_llcp_status = neard_plugin_llcp_check_llcp;
+ iface->activate_llcp = neard_plugin_llcp_activate_llcp;
+ iface->create_llcp_socket = neard_plugin_llcp_create_socket;
+ iface->bind_llcp_socket = neard_plugin_llcp_bind;
+ iface->listen_llcp_socket = neard_plugin_llcp_listen;
+ iface->accept_llcp_socket = neard_plugin_llcp_accept;
+ iface->connect_llcp_by_url = neard_plugin_llcp_connect_by_url;
+ iface->connect_llcp = neard_plugin_llcp_connect;
+ iface->disconnect_llcp = neard_plugin_llcp_disconnect;
+ iface->close_llcp_socket = neard_plugin_llcp_socket_close;
+ iface->recv_llcp = neard_plugin_llcp_recv;
+ iface->send_llcp = neard_plugin_llcp_send;
+ iface->recv_from_llcp = neard_plugin_llcp_recv_from;
+ iface->send_to_llcp = neard_plugin_llcp_send_to;
+ 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;
+}