summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRavi kumar Veeramally <ravikumar.veeramally@linux.intel.com>2013-02-08 14:01:49 +0200
committerSamuel Ortiz <sameo@linux.intel.com>2013-02-11 09:29:26 +0100
commitd6d3b7dcd47291322804f838974953363f2a9a11 (patch)
treed337d0eed03927cb15c44594e517c0733dc5627f /src
parent9e926fbc38ae53388f628c65f72f0da14cd8f5c8 (diff)
downloadneard-d6d3b7dcd47291322804f838974953363f2a9a11.tar.gz
neard-d6d3b7dcd47291322804f838974953363f2a9a11.tar.bz2
neard-d6d3b7dcd47291322804f838974953363f2a9a11.zip
agent: Add an extra parameter to the handover registration agent api
Current handover registration apis does not support for carrier specific registration. Added an extra parameter (carrier type) to RegisterHandoverAgent and UnregisterHandoverAgent. This is an initial patch for wifi handover agent registration. WiFi NDEF message handling will be supported soon.
Diffstat (limited to 'src')
-rw-r--r--src/agent.c196
-rw-r--r--src/bluetooth.c4
-rw-r--r--src/main.c2
-rw-r--r--src/manager.c48
-rw-r--r--src/ndef.c10
-rw-r--r--src/near.h35
6 files changed, 215 insertions, 80 deletions
diff --git a/src/agent.c b/src/agent.c
index 79c2cc9..b7a1521 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -40,6 +40,7 @@
static DBusConnection *connection = NULL;
static GHashTable *ndef_app_hash;
+static GHashTable *ho_agent_hash;
struct near_ndef_agent {
char *sender;
@@ -48,6 +49,13 @@ struct near_ndef_agent {
guint watch;
};
+struct near_handover_agent {
+ enum ho_agent_carrier carrier;
+ guint watch;
+ char *sender;
+ char *path;
+};
+
static void ndef_agent_free(gpointer data)
{
DBusMessage *message;
@@ -223,10 +231,6 @@ int __near_agent_ndef_unregister(const char *sender, const char *path,
return 0;
}
-static guint handover_agent_watch = 0;
-static gchar *handover_agent_path = NULL;
-static gchar *handover_agent_sender = NULL;
-
static enum carrier_power_state string2cps(const char *state)
{
if (strcasecmp(state, "active") == 0)
@@ -241,6 +245,17 @@ static enum carrier_power_state string2cps(const char *state)
return CPS_UNKNOWN;
}
+static enum ho_agent_carrier string2carrier(const char *carrier)
+{
+ if (strcasecmp(carrier, NEAR_HANDOVER_AGENT_BLUETOOTH) == 0)
+ return HO_AGENT_BT;
+
+ if (strcasecmp(carrier, NEAR_HANDOVER_AGENT_WIFI) == 0)
+ return HO_AGENT_WIFI;
+
+ return HO_AGENT_UNKNOWN;
+}
+
static struct carrier_data *parse_reply(DBusMessage *reply)
{
DBusMessageIter args;
@@ -374,20 +389,22 @@ static void prepare_bt_data(DBusMessage *message, struct carrier_data *data)
}
struct carrier_data *__near_agent_handover_request_data(
+ enum ho_agent_carrier carrier,
struct carrier_data *data)
{
DBusMessage *message;
DBusMessage *reply;
DBusError error;
struct carrier_data *data_reply;
+ struct near_handover_agent *agent = NULL;
- DBG("agent %s", handover_agent_path ? : "not present");
-
- if (handover_agent_path == NULL)
+ agent = g_hash_table_lookup(ho_agent_hash,
+ GINT_TO_POINTER(carrier));
+ if (agent == NULL)
return NULL;
- message = dbus_message_new_method_call(handover_agent_sender,
- handover_agent_path, NFC_HANDOVER_AGENT_INTERFACE,
+ message = dbus_message_new_method_call(agent->sender,
+ agent->path, NFC_HANDOVER_AGENT_INTERFACE,
"RequestOOB");
if (message == NULL)
return NULL;
@@ -420,19 +437,20 @@ struct carrier_data *__near_agent_handover_request_data(
return data_reply;
}
-int __near_agent_handover_push_data(struct carrier_data *data)
+int __near_agent_handover_push_data(enum ho_agent_carrier carrier,
+ struct carrier_data *data)
{
DBusMessage *message;
DBusMessage *reply;
DBusError error;
+ struct near_handover_agent *agent = NULL;
- DBG("agent %s", handover_agent_path ? : "not present");
-
- if (handover_agent_path == NULL)
+ agent = g_hash_table_lookup(ho_agent_hash, GINT_TO_POINTER(carrier));
+ if (agent == NULL)
return -ESRCH;
- message = dbus_message_new_method_call(handover_agent_sender,
- handover_agent_path, NFC_HANDOVER_AGENT_INTERFACE,
+ message = dbus_message_new_method_call(agent->sender,
+ agent->path, NFC_HANDOVER_AGENT_INTERFACE,
"PushOOB");
if (message == NULL)
return -ENOMEM;
@@ -461,88 +479,147 @@ int __near_agent_handover_push_data(struct carrier_data *data)
return -EIO;
}
-static void handover_agent_free(void)
+static void handover_agent_free(gpointer data)
{
- if (handover_agent_watch > 0) {
- g_dbus_remove_watch(connection, handover_agent_watch);
- handover_agent_watch = 0;
- }
+ struct near_handover_agent *agent = data;
+
+ if (agent == NULL)
+ return;
+
+ g_free(agent->sender);
+ agent->sender = NULL;
- g_free(handover_agent_sender);
- handover_agent_sender = NULL;
+ g_free(agent->path);
+ agent->path = NULL;
- g_free(handover_agent_path);
- handover_agent_path = NULL;
+ if (agent->watch == 0)
+ return;
+
+ g_dbus_remove_watch(connection, agent->watch);
+ agent->watch = 0;
}
static void handover_agent_disconnect(DBusConnection *conn, void *data)
{
+ struct near_handover_agent *agent = data;
+
DBG("data %p", data);
- handover_agent_watch = 0;
+ if (agent == NULL)
+ return;
- handover_agent_free();
+ switch (agent->carrier) {
+ case HO_AGENT_BT:
+ /* start watching for legacy bluez */
+ __near_bluetooth_legacy_start();
+ break;
- /* start watching for legacy bluez */
- __near_bluetooth_legacy_start();
+ case HO_AGENT_WIFI:
+ case HO_AGENT_UNKNOWN:
+ break;
+ }
+
+ handover_agent_free(agent);
}
-static void handover_agent_release(void)
+static void handover_agent_release(gpointer key, gpointer data,
+ gpointer user_data)
{
+ struct near_handover_agent *agent = data;
DBusMessage *message;
- if (handover_agent_watch == 0)
+ if (agent == NULL || agent->watch == 0)
return;
- message = dbus_message_new_method_call(handover_agent_sender,
- handover_agent_path,
- "org.neard.HandoverAgent",
- "Release");
+ message = dbus_message_new_method_call(agent->sender, agent->path,
+ "org.neard.HandoverAgent",
+ "Release");
if (message != NULL)
g_dbus_send_message(connection, message);
-
- handover_agent_free();
}
-int __near_agent_handover_register(const char *sender, const char *path)
+static int create_handover_agent(const char *sender, const char *path,
+ enum ho_agent_carrier carrier)
{
- DBG("sender %s path %s", sender, path);
-
- if (handover_agent_path != NULL)
- return -EEXIST;
+ struct near_handover_agent *agent;
- handover_agent_watch = g_dbus_add_disconnect_watch(connection, sender,
- handover_agent_disconnect, NULL, NULL);
- if (handover_agent_watch == 0)
+ agent = g_try_malloc0(sizeof(struct near_handover_agent));
+ if (agent == NULL)
return -ENOMEM;
- handover_agent_sender = g_strdup(sender);
- handover_agent_path = g_strdup(path);
+ agent->sender = g_strdup(sender);
+ agent->path = g_strdup(path);
+ agent->carrier = carrier;
+ agent->watch = g_dbus_add_disconnect_watch(connection, sender,
+ handover_agent_disconnect, agent, NULL);
+
+ g_hash_table_insert(ho_agent_hash, GINT_TO_POINTER(carrier), agent);
- /* stop watching for legacy bluez */
- __near_bluetooth_legacy_stop();
+ DBG("handover agent registered");
+
+ switch (agent->carrier) {
+ case HO_AGENT_BT:
+ /* stop watching for legacy bluez */
+ __near_bluetooth_legacy_stop();
+ break;
+
+ case HO_AGENT_WIFI:
+ case HO_AGENT_UNKNOWN:
+ break;
+ }
return 0;
}
-int __near_agent_handover_unregister(const char *sender, const char *path)
+int __near_agent_handover_register(const char *sender, const char *path,
+ const char *carrier)
{
- DBG("sender %s path %s", sender, path);
+ struct near_handover_agent *agent;
+ enum ho_agent_carrier ho_carrier;
+
+ DBG("sender %s path %s carrier %s", sender, path, carrier);
+
+ ho_carrier = string2carrier(carrier);
- if (handover_agent_path == NULL)
+ if (ho_carrier == HO_AGENT_UNKNOWN)
+ return -EINVAL;
+
+ agent = g_hash_table_lookup(ho_agent_hash, GINT_TO_POINTER(ho_carrier));
+ if (agent != NULL)
+ return -EEXIST;
+
+ return create_handover_agent(sender, path, ho_carrier);
+}
+
+int __near_agent_handover_unregister(const char *sender, const char *path,
+ const char *carrier)
+{
+ struct near_handover_agent *agent;
+ enum ho_agent_carrier ho_carrier;
+
+ DBG("sender %s path %s carrier %s", sender, path, carrier);
+
+ ho_carrier = string2carrier(carrier);
+ agent = g_hash_table_lookup(ho_agent_hash, GINT_TO_POINTER(ho_carrier));
+ if (agent == NULL)
return -ESRCH;
- handover_agent_free();
+ if (strcmp(agent->path, path) != 0 ||
+ strcmp(agent->sender, sender) != 0)
+ return -ESRCH;
- /* start watching for legacy bluez */
- __near_bluetooth_legacy_start();
+ g_hash_table_remove(ho_agent_hash, GINT_TO_POINTER(ho_carrier));
return 0;
}
-near_bool_t __near_agent_handover_registered(void)
+near_bool_t __near_agent_handover_registered(enum ho_agent_carrier carrier)
{
- return handover_agent_path != NULL ? TRUE : FALSE;
+ struct near_handove_agent *agent = NULL;
+
+ agent = g_hash_table_lookup(ho_agent_hash, GINT_TO_POINTER(carrier));
+
+ return agent != NULL ? TRUE : FALSE;
}
int __near_agent_init(void)
@@ -556,6 +633,9 @@ int __near_agent_init(void)
ndef_app_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, ndef_agent_free);
+ ho_agent_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, handover_agent_free);
+
return 0;
}
@@ -566,7 +646,9 @@ void __near_agent_cleanup(void)
g_hash_table_destroy(ndef_app_hash);
ndef_app_hash = NULL;
- handover_agent_release();
+ g_hash_table_foreach(ho_agent_hash, handover_agent_release, NULL);
+ g_hash_table_destroy(ho_agent_hash);
+ ho_agent_hash = NULL;
dbus_connection_unref(connection);
}
diff --git a/src/bluetooth.c b/src/bluetooth.c
index 72fd81f..57163aa 100644
--- a/src/bluetooth.c
+++ b/src/bluetooth.c
@@ -1051,7 +1051,7 @@ static void bt_connect(DBusConnection *conn, void *data)
{
DBG("connection %p with %p", conn, data);
- if (__near_agent_handover_registered() == TRUE) {
+ if (__near_agent_handover_registered(HO_AGENT_BT) == TRUE) {
DBG("Agent already registered");
return;
}
@@ -1089,7 +1089,7 @@ static void bt_disconnect(DBusConnection *conn, void *user_data)
static int bt_prepare_handlers(DBusConnection *conn)
{
- if (__near_agent_handover_registered() == TRUE)
+ if (__near_agent_handover_registered(HO_AGENT_BT) == TRUE)
return 0;
watch = g_dbus_add_service_watch(bt_conn, BLUEZ_SERVICE,
diff --git a/src/main.c b/src/main.c
index dea9995..656d329 100644
--- a/src/main.c
+++ b/src/main.c
@@ -208,8 +208,8 @@ int main(int argc, char *argv[])
__near_adapter_init();
__near_ndef_init();
__near_manager_init(conn);
- __near_bluetooth_init();
__near_agent_init();
+ __near_bluetooth_init();
__near_plugin_init(option_plugin, option_noplugin);
diff --git a/src/manager.c b/src/manager.c
index 66383a5..536cf94 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -136,17 +136,29 @@ void __near_manager_adapter_remove(uint32_t idx)
static DBusMessage *register_handover_agent(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- const char *sender, *path;
+ DBusMessageIter iter;
+ const char *sender, *path, *carrier;
int err;
DBG("conn %p", conn);
sender = dbus_message_get_sender(msg);
- dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID);
+ if (dbus_message_iter_init(msg, &iter) == FALSE)
+ return __near_error_invalid_arguments(msg);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
+ return __near_error_invalid_arguments(msg);
+
+ dbus_message_iter_get_basic(&iter, &path);
+ dbus_message_iter_next(&iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return __near_error_invalid_arguments(msg);
+
+ dbus_message_iter_get_basic(&iter, &carrier);
- err = __near_agent_handover_register(sender, path);
+ err = __near_agent_handover_register(sender, path, carrier);
if (err < 0)
return __near_error_failed(msg, -err);
@@ -156,17 +168,29 @@ static DBusMessage *register_handover_agent(DBusConnection *conn,
static DBusMessage *unregister_handover_agent(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- const char *sender, *path;
+ DBusMessageIter iter;
+ const char *sender, *path, *carrier;
int err;
DBG("conn %p", conn);
sender = dbus_message_get_sender(msg);
- dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
- DBUS_TYPE_INVALID);
+ if (dbus_message_iter_init(msg, &iter) == FALSE)
+ return __near_error_invalid_arguments(msg);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
+ return __near_error_invalid_arguments(msg);
+
+ dbus_message_iter_get_basic(&iter, &path);
+ dbus_message_iter_next(&iter);
+
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return __near_error_invalid_arguments(msg);
+
+ dbus_message_iter_get_basic(&iter, &carrier);
- err = __near_agent_handover_unregister(sender, path);
+ err = __near_agent_handover_unregister(sender, path, carrier);
if (err < 0)
return __near_error_failed(msg, -err);
@@ -245,11 +269,11 @@ static const GDBusMethodTable manager_methods[] = {
GDBUS_ARGS({"name", "s"}, {"value", "v"}),
NULL, set_property) },
{ GDBUS_METHOD("RegisterHandoverAgent",
- GDBUS_ARGS({ "path", "o" }), NULL,
- register_handover_agent) },
+ GDBUS_ARGS({ "path", "o" }, { "type", "s"}),
+ NULL, register_handover_agent) },
{ GDBUS_METHOD("UnregisterHandoverAgent",
- GDBUS_ARGS({ "path", "o" }), NULL,
- unregister_handover_agent) },
+ GDBUS_ARGS({ "path", "o" }, { "type", "s"}),
+ NULL, unregister_handover_agent) },
{ GDBUS_METHOD("RegisterNDEFAgent",
GDBUS_ARGS({"path", "o"}, {"type", "s"}),
NULL, register_ndef_agent) },
diff --git a/src/ndef.c b/src/ndef.c
index 0b5f354..48c1282 100644
--- a/src/ndef.c
+++ b/src/ndef.c
@@ -1414,9 +1414,10 @@ parse_mime_type(struct near_ndef_record *record, uint8_t *ndef_data,
else
data.state = CPS_UNKNOWN;
- if (__near_agent_handover_registered() == TRUE) {
+ if (__near_agent_handover_registered(HO_AGENT_BT) == TRUE) {
if (action == TRUE) {
- err = __near_agent_handover_push_data(&data);
+ err = __near_agent_handover_push_data(HO_AGENT_BT,
+ &data);
} else if (reply != NULL) {
*reply = near_ndef_prepare_handover_record("Hs",
record, NEAR_CARRIER_BLUETOOTH, &data);
@@ -1855,8 +1856,9 @@ struct near_ndef_message *near_ndef_prepare_handover_record(char *type_name,
}
if (carriers & NEAR_CARRIER_BLUETOOTH) {
- if (__near_agent_handover_registered() == TRUE) {
- local = __near_agent_handover_request_data(remote);
+ if (__near_agent_handover_registered(HO_AGENT_BT) == TRUE) {
+ local = __near_agent_handover_request_data(HO_AGENT_BT,
+ remote);
} else {
/* Retrieve the bluetooth settings */
uint16_t props = near_get_carrier_properties(record,
diff --git a/src/near.h b/src/near.h
index c152436..8733eb8 100644
--- a/src/near.h
+++ b/src/near.h
@@ -178,6 +178,29 @@ void __near_plugin_cleanup(void);
#define OOB_PROPS_COD 0x08
#define OOB_PROPS_SP (OOB_PROPS_SP_HASH | OOB_PROPS_SP_RANDOM)
+/* Handover Agent Carrier Types */
+#define NEAR_HANDOVER_AGENT_BLUETOOTH "bluetooth"
+#define NEAR_HANDOVER_AGENT_WIFI "wifi"
+
+/* near_ndef_handover_carrier*/
+#define NEAR_CARRIER_EMPTY 0x00
+#define NEAR_CARRIER_BLUETOOTH 0x01 /* bit 0 */
+#define NEAR_CARRIER_WIFI 0x02 /* bit 1 */
+#define NEAR_CARRIER_UNKNOWN 0x80 /* Bit 7 */
+
+enum carrier_power_state {
+ CPS_INACTIVE = 0x00,
+ CPS_ACTIVE = 0x01,
+ CPS_ACTIVATING = 0x02,
+ CPS_UNKNOWN = 0x03,
+};
+
+enum ho_agent_carrier {
+ HO_AGENT_BT = 0x00,
+ HO_AGENT_WIFI = 0x01,
+ HO_AGENT_UNKNOWN = 0xFF
+};
+
struct carrier_data {
uint8_t type;
uint8_t size;
@@ -199,13 +222,17 @@ int __near_agent_ndef_register(const char *sender, const char *path,
const char *record_type);
int __near_agent_ndef_unregister(const char *sender, const char *path,
const char *record_type);
-int __near_agent_handover_register(const char *sender, const char *path);
-int __near_agent_handover_unregister(const char *sender, const char *path);
-near_bool_t __near_agent_handover_registered(void);
+int __near_agent_handover_register(const char *sender, const char *path,
+ const char *carrier);
+int __near_agent_handover_unregister(const char *sender, const char *path,
+ const char *carrier);
+near_bool_t __near_agent_handover_registered(enum ho_agent_carrier carrier);
struct carrier_data *__near_agent_handover_request_data(
+ enum ho_agent_carrier carrier,
+ struct carrier_data *data);
+int __near_agent_handover_push_data(enum ho_agent_carrier carrier,
struct carrier_data *data);
-int __near_agent_handover_push_data(struct carrier_data *data);
int __near_agent_init(void);
void __near_agent_cleanup(void);