* 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>
#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
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)
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)
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 */
{
int t_type;
- DBG("");
+ DBG(" %s", type);
/* TODO tag sub types */
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)
{
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);
}
}
}
+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;
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)
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;
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();
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("");
{
DBG("");
+ if (result == NULL)
+ return false;
+
+ *result = NET_NFC_NOT_SUPPORTED;
+
return false;
}
{
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;
}
{
DBG("");
- if (result == FALSE)
+ if (result == NULL)
return false;
*result = NET_NFC_NOT_SUPPORTED;
{
DBG("");
- if (result == FALSE)
+ if (result == NULL)
return false;
*result = NET_NFC_NOT_SUPPORTED;
return false;
}
- __neard_plugin_make_invalid_target_handle(handle);
+ __neard_plugin_make_invalid_target_handle();
*result = NET_NFC_OK;
return true;
break;
}
- g_free(ndef);
- *real_data_size = len;
+ if (ndef != NULL)
+ g_free(ndef);
+ *real_data_size = len;
*result = NET_NFC_OK;
return true;
}
if (tag == NULL) {
- DBG("target lost");
+ DBG(" not connected");
*result = NET_NFC_NOT_CONNECTED;
return false;
}
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,
{
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,
{
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,
{
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;
}
{
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;
}
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;
}
{
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)
{
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->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;
}
-
--- /dev/null
+/*
+ * 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 */