diff options
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | src/ndef.c | 155 | ||||
-rwxr-xr-x | test/push-device | 9 | ||||
-rwxr-xr-x | test/wifi-handover | 58 |
4 files changed, 223 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index 175cf07..fd2bb90 100644 --- a/Makefile.am +++ b/Makefile.am @@ -81,7 +81,7 @@ dist_man_MANS = doc/neard.8 doc/neard.conf.5 doc/nfctool.1 test_scripts = test/disable-adapter test/enable-adapter test/list-adapters \ test/dump-device test/dump-tag test/dump-record \ test/monitor-near test/start-poll test/stop-poll test/write-tag \ - test/push-device test/bt-handover test/handover-agent + test/push-device test/bt-handover test/handover-agent test/wifi-handover if TEST testdir = $(pkglibdir)/test @@ -3273,6 +3273,119 @@ struct near_ndef_message *near_ndef_prepare_wsc_record(char *ssid, return mime; } +static char *get_mime_payload_data(DBusMessageIter iter, + char **payload, int *payload_len) +{ + DBG(""); + + if (!payload || !payload_len) { + near_error("Payload %p payload_len %p", payload, payload_len); + return NULL; + } + + while (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID) { + const char *key; + DBusMessageIter ent_iter; + DBusMessageIter var_iter; + DBusMessageIter arr_iter; + + dbus_message_iter_recurse(&iter, &ent_iter); + dbus_message_iter_get_basic(&ent_iter, &key); + dbus_message_iter_next(&ent_iter); + dbus_message_iter_recurse(&ent_iter, &var_iter); + + if (g_strcmp0(key, "Payload") == 0) { + if (dbus_message_iter_get_arg_type(&var_iter) == + DBUS_TYPE_ARRAY && + dbus_message_iter_get_element_type(&var_iter) == + DBUS_TYPE_BYTE) { + dbus_message_iter_recurse(&var_iter, + &arr_iter); + dbus_message_iter_get_fixed_array( + &arr_iter, payload, + payload_len); + } else { + near_error("Unexpected payload type"); + return NULL; + } + } + dbus_message_iter_next(&iter); + } + + return *payload; +} + +static struct near_ndef_message *near_ndef_prepare_mime_payload_record( + char *type, char *payload, int payload_len) +{ + struct near_ndef_message *mime; + + DBG("Payload %*s", payload_len, payload); + mime = ndef_message_alloc_complete(type, payload_len, NULL, 0, + RECORD_TNF_MIME, TRUE, TRUE); + if (!mime) { + near_error("Failed to alloc NDEF message"); + return NULL; + } + + memcpy(mime->data + mime->offset, payload, payload_len); + + return mime; +} + +#define DE_AUTHENTICATION_TYPE 0x1003 +#define DE_NETWORK_KEY 0x1027 +#define DE_SSID 0x1045 +static void parse_wsc_oob(guint8 *oob_data, guint32 oob_length, + char **ssid, char **passphrase) +{ + guint32 offset = 0; + guint16 de_length, de_type; + guint16 auth_type; + + while (offset < oob_length) { + de_type = near_get_be16(oob_data + offset); + de_length = near_get_be16(oob_data + offset + 2); + + switch(de_type) { + case DE_AUTHENTICATION_TYPE: + auth_type = near_get_be16(oob_data + offset + 4); + DBG("WSC Authentication Type: 0x%02x", + auth_type); + break; + + case DE_SSID: + *ssid = g_try_malloc0(de_length + 1); + if (!*ssid) + break; + + g_snprintf(*ssid, de_length + 1, + "%s", oob_data + offset + 4); + + DBG("SSID: %s", *ssid); + break; + + case DE_NETWORK_KEY: + *passphrase = g_try_malloc0(de_length + 1); + if (!*passphrase) + break; + + g_snprintf(*passphrase, de_length + 1, + "%s", oob_data + offset + 4); + + DBG("Passphrase: %s", *passphrase); + break; + + default: + DBG("Unknown Data Element"); + break; + + } + + offset += 4 + de_length; + } +} + static struct near_ndef_message *build_mime_record(DBusMessage *msg) { DBusMessageIter iter, arr_iter; @@ -3329,6 +3442,48 @@ static struct near_ndef_message *build_mime_record(DBusMessage *msg) g_free(carrier); return mime; + } else if (g_strcmp0(mime_str, "x/nfctl") == 0) { + struct carrier_data *carrier; + char *ssid = NULL, *passphrase = NULL; + char payload[128]; + + carrier = __near_agent_handover_request_data( + HO_AGENT_WIFI, NULL); + if (!carrier) + return NULL; + + parse_wsc_oob(carrier->data, carrier->size, + &ssid, &passphrase); + if (!ssid || !passphrase) + return NULL; + + g_snprintf(payload, 128, + "enZ:wifi association;C:I4:%s:2:%s", + ssid, passphrase); + g_free(ssid); + g_free(passphrase); + + DBG("payload %s", payload); + + return near_ndef_prepare_mime_payload_record( + mime_str, payload, strlen(payload)); + } else { + /* + * Expect data is set in the Payload field of + * message. + */ + DBusMessageIter payload_iter; + char *payload; + int payload_len; + + DBG("mime string %s", mime_str); + dbus_message_iter_recurse(&iter, &payload_iter); + if (!get_mime_payload_data(payload_iter, + &payload, &payload_len)) + return NULL; + + return near_ndef_prepare_mime_payload_record( + mime_str, payload, payload_len); } } diff --git a/test/push-device b/test/push-device index b0b0c55..d1a142d 100755 --- a/test/push-device +++ b/test/push-device @@ -17,6 +17,8 @@ def help_text(): print "e.g. < %s /org/neard/nfc0/device0 Handover bluetooth,wifi >" % (sys.argv[0]) print "e.g. < %s /org/neard/nfc0/device0 StaticHandover bluetooth,wifi >" % (sys.argv[0]) print "e.g. < %s /org/neard/nfc0/device0 MIME wifi_wsc>" % (sys.argv[0]) + print "e.g. < %s /org/neard/nfc0/device0 MIME raw application/xml '<your><xml tags></your>' >" % (sys.argv[0]) + print "e.g. < %s /org/neard/nfc0/device0 WiFiAssociation >" % (sys.argv[0]) sys.exit(1) if len(sys.argv) < 2: @@ -57,5 +59,12 @@ elif len(sys.argv) == 4: help_text() else: help_text() + +elif len(sys.argv) == 3: + if sys.argv[2] in ["WiFiAssociation"]: + device.Push(({ "Type" : "MIME", + "MIME" : "x/nfctl" })) + else: + help_text() else: help_text() diff --git a/test/wifi-handover b/test/wifi-handover new file mode 100755 index 0000000..5bf966c --- /dev/null +++ b/test/wifi-handover @@ -0,0 +1,58 @@ +#!/usr/bin/python + +import os +import sys +import gobject + +import dbus +import dbus.mainloop.glib + +from dbus.lowlevel import MethodCallMessage, HANDLER_RESULT_NOT_YET_HANDLED + +mainloop = gobject.MainLoop() + +def property_changed_adapter(name, value, path): + if name in ["Devices"]: + if (len(value) == 0): + print "Lost device, exiting" + mainloop.quit() + else: + device_path = value[0] + + print "%s is associating with us..." % (device_path) + + device = dbus.Interface(bus.get_object("org.neard", device_path), "org.neard.Device") + device.Push(({ "Type" : "MIME", "MIME" : "x/nfctl"})) + +if __name__ == '__main__': + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + bus = dbus.SystemBus() + + + manager = dbus.Interface(bus.get_object("org.neard", "/"), + "org.neard.Manager") + + properties = manager.GetProperties() + device_path = properties["Adapters"][0] + adapter = dbus.Interface(bus.get_object("org.neard", device_path), + "org.neard.Adapter") + + adapter_properties = adapter.GetProperties() + + for key in adapter_properties.keys(): + if key in ["Polling"]: + if adapter_properties[key] == dbus.Boolean(1): + print "Stoping poll on %s" % (device_path) + adapter.StopPollLoop() + + print "Starting poll on %s" % (device_path) + adapter.StartPollLoop("Initiator") + + bus.add_signal_receiver(property_changed_adapter, + bus_name="org.neard", + dbus_interface="org.neard.Adapter", + signal_name = "PropertyChanged", + path_keyword="path") + + mainloop.run() |