summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2011-04-27 19:42:33 +0200
committerMarcel Holtmann <marcel@holtmann.org>2011-10-20 23:54:02 -0700
commit8882c274c2ad577ded3b49484596a7f0e23469a5 (patch)
tree60d0a9add3d907616d16b9e11f25169daaf2dcaa
parent5b920d58254a888afaa02c85e86ecd017716332c (diff)
downloadneard-8882c274c2ad577ded3b49484596a7f0e23469a5.tar.gz
neard-8882c274c2ad577ded3b49484596a7f0e23469a5.tar.bz2
neard-8882c274c2ad577ded3b49484596a7f0e23469a5.zip
target: Target add/remove API initial implementation
-rw-r--r--include/dbus.h1
-rw-r--r--src/near.h9
-rw-r--r--src/target.c168
3 files changed, 178 insertions, 0 deletions
diff --git a/include/dbus.h b/include/dbus.h
index 25ec137..68f4cea 100644
--- a/include/dbus.h
+++ b/include/dbus.h
@@ -30,6 +30,7 @@
#define NFC_MANAGER_PATH "/"
#define NFC_ADAPTER_INTERFACE NFC_SERVICE ".Adapter"
+#define NFC_TARGET_INTERFACE NFC_SERVICE ".Target"
typedef void (* near_dbus_append_cb_t) (DBusMessageIter *iter,
void *user_data);
diff --git a/src/near.h b/src/near.h
index 3f3df68..8921bbd 100644
--- a/src/near.h
+++ b/src/near.h
@@ -73,7 +73,16 @@ int __near_adapter_init(void);
void __near_adapter_cleanup(void);
struct near_target;
+
+enum near_target_type {
+ NEAR_TARGET_TYPE_TAG = 0,
+ NEAR_TARGET_TYPE_DEVICE = 1,
+};
+
const char *__near_target_get_path(struct near_target *target);
+int __near_target_add(guint32 adapter_idx, guint32 target_idx,
+ guint32 protocols, enum near_target_type type);
+void __near_target_remove(guint32 target_idx);
int __near_target_init(void);
void __near_target_cleanup(void);
diff --git a/src/target.c b/src/target.c
index 553c809..95a5700 100644
--- a/src/target.c
+++ b/src/target.c
@@ -23,12 +23,39 @@
#include <config.h>
#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <glib.h>
+
+#include <gdbus.h>
+
+#include <linux/nfc.h>
+
#include "near.h"
struct near_target {
char *path;
+
+ guint32 idx;
+ guint32 adapter_idx;
+ guint32 protocols;
+ enum near_target_type type;
};
+static DBusConnection *connection = NULL;
+
+static GHashTable *target_hash;
+
+static void free_target(gpointer data)
+{
+ struct near_target *target = data;
+
+ g_free(target->path);
+ g_free(target);
+}
+
const char *__near_target_get_path(struct near_target *target)
{
@@ -40,14 +67,155 @@ const char *__near_target_get_path(struct near_target *target)
return target->path;
}
+static void append_protocols(DBusMessageIter *iter, void *user_data)
+{
+ struct near_target *target = user_data;
+ const char *str;
+
+ DBG("protocols 0x%x", target->protocols);
+
+ if (target->protocols & NFC_PROTO_FELICA) {
+ str = "Felica";
+
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &str);
+ }
+
+ if (target->protocols & NFC_PROTO_MIFARE) {
+ str = "MIFARE";
+
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &str);
+ }
+
+ if (target->protocols & NFC_PROTO_JEWEL) {
+ str = "Jewel";
+
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &str);
+ }
+
+ if (target->protocols & NFC_PROTO_ISO14443_4) {
+ str = "ISO-DEP";
+
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &str);
+ }
+
+ if (target->protocols & NFC_PROTO_NFC_DEP) {
+ str = "NFC-DEP";
+
+ dbus_message_iter_append_basic(iter,
+ DBUS_TYPE_STRING, &str);
+ }
+}
+
+static DBusMessage *get_properties(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct near_adapter *target = data;
+ DBusMessage *reply;
+ DBusMessageIter array, dict;
+
+ DBG("conn %p", conn);
+
+ reply = dbus_message_new_method_return(msg);
+ if (reply == NULL)
+ return NULL;
+
+ dbus_message_iter_init_append(reply, &array);
+
+ near_dbus_dict_open(&array, &dict);
+
+ near_dbus_dict_append_array(&dict, "Protocols",
+ DBUS_TYPE_STRING, append_protocols, target);
+
+ near_dbus_dict_close(&array, &dict);
+
+ return reply;
+}
+
+static DBusMessage *set_property(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ DBG("conn %p", conn);
+
+ return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+
+static GDBusMethodTable target_methods[] = {
+ { "GetProperties", "", "a{sv}", get_properties },
+ { "SetProperty", "sv", "", set_property },
+ { },
+};
+
+static GDBusSignalTable target_signals[] = {
+ { "PropertyChanged", "sv" },
+ { }
+};
+
+int __near_target_add(guint32 adapter_idx, guint32 target_idx,
+ guint32 protocols, enum near_target_type type)
+{
+ struct near_target *target;
+
+ if (g_hash_table_lookup(target_hash,
+ GINT_TO_POINTER(target_idx)) != NULL)
+ return -EEXIST;
+
+ target = g_try_malloc0(sizeof(struct near_target));
+ if (target == NULL)
+ return -ENOMEM;
+
+ target->path = g_strdup_printf("%s/nfc%d/target%d", NFC_PATH,
+ adapter_idx, target_idx);
+ if (target->path == NULL) {
+ g_free(target);
+ return -ENOMEM;
+ }
+
+ target->idx = target_idx;
+ target->adapter_idx = adapter_idx;
+ target->protocols = protocols;
+ target->type = type;
+
+ g_hash_table_insert(target_hash, GINT_TO_POINTER(target_idx), target);
+
+ DBG("connection %p", connection);
+
+ g_dbus_register_interface(connection, target->path,
+ NFC_TARGET_INTERFACE,
+ target_methods, target_signals,
+ NULL, target, NULL);
+
+ return 0;
+}
+
+void __near_target_remove(guint32 target_idx)
+{
+ struct near_target *target;
+
+ target = g_hash_table_lookup(target_hash, GINT_TO_POINTER(target_idx));
+ if (target == NULL)
+ return;
+
+ free_target(target);
+}
+
int __near_target_init(void)
{
DBG("");
+ target_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, free_target);
+
return 0;
}
void __near_target_cleanup(void)
{
DBG("");
+
+ g_hash_table_destroy(target_hash);
+ target_hash = NULL;
}