From: Samuel Ortiz Date: Thu, 9 Jun 2011 17:56:11 +0000 (+0200) Subject: ndef: org.neard.Record export X-Git-Tag: 0.1~141 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f52657bb1473dfc158deb95cd8942344350414dc;p=platform%2Fupstream%2Fneard.git ndef: org.neard.Record export Each record will be accesible through that interface, and each tag tracks its own record list. --- diff --git a/doc/target-api.txt b/doc/target-api.txt index 12101b0..753558e 100644 --- a/doc/target-api.txt +++ b/doc/target-api.txt @@ -3,7 +3,7 @@ Target hierarchy Service org.neard Interface org.neard.Target -Object path [variable prefix]/{nfc0,nfc1,...}/target_UID +Object path [variable prefix]/{nfc0}/{target0, target1...} Method dict GetProperties() @@ -45,7 +45,36 @@ Properties string Type [readonly] "Type 4" and "NFC-DEP" This is only valid for tag type targets. - array{dict} Records [readwrite] + array{object} Records [readwrite] - List of NDEF records. + List of NDEF records object paths. This is only valid for tag type targets. + + +Record hierarchy +================ + +Service org.neard +Interface org.neard.Record +Object path [variable prefix]/{nfc0}/{target0}/{record0,record1,...} + +Method dict GetProperties() + + Returns all properties for the record. See the + properties section for available properties. + + Possible Errors: org.neard.Error.DoesNotExist + +Properties boolean SmartPoster [readonly] + + boolean HandOver [readonly] + + string Type [readonly] + + string Language [readonly] + + string Encoding [readonly] + + array{byte} Value [readonly] + + string Representation [readonly] diff --git a/include/dbus.h b/include/dbus.h index 68f4cea..874e016 100644 --- a/include/dbus.h +++ b/include/dbus.h @@ -31,6 +31,7 @@ #define NFC_ADAPTER_INTERFACE NFC_SERVICE ".Adapter" #define NFC_TARGET_INTERFACE NFC_SERVICE ".Target" +#define NFC_RECORD_INTERFACE NFC_SERVICE ".Record" typedef void (* near_dbus_append_cb_t) (DBusMessageIter *iter, void *user_data); diff --git a/include/ndef.h b/include/ndef.h index fa2661e..c4aee9c 100644 --- a/include/ndef.h +++ b/include/ndef.h @@ -22,22 +22,10 @@ #ifndef __NEAR_NDEF_H #define __NEAR_NDEF_H -struct near_ndef_record { - uint8_t tnf; +#include - uint8_t *type; - size_t type_length; +struct near_ndef_record; - uint8_t *payload; - size_t payload_length; -}; - -struct near_ndef { - gboolean smart_poster; - gboolean handover; - - uint32_t n_records; - GList *records; -}; +int near_ndef_parse(struct near_tag *tag, uint8_t *ndef_data, size_t ndef_length); #endif diff --git a/include/tag.h b/include/tag.h index 0d9280b..a8643dd 100644 --- a/include/tag.h +++ b/include/tag.h @@ -26,8 +26,6 @@ #include -#include - #define NFC_HEADER_SIZE 1 #define NEAR_TAG_NFC_TYPE1 0x1 diff --git a/plugins/nfctype2.c b/plugins/nfctype2.c index 214f2de..31e6363 100644 --- a/plugins/nfctype2.c +++ b/plugins/nfctype2.c @@ -137,7 +137,7 @@ static int data_parse(struct type2_tag *tag, uint8_t *data, uint16_t length) case TLV_NDEF: DBG("NDEF found %d bytes long", tlv_length(tlv)); - near_tag_add_ndef(tag->tag, tlv_data(tlv), + near_ndef_parse(tag->tag, tlv_data(tlv), tlv_length(tlv)); break; diff --git a/src/main.c b/src/main.c index 2701964..b6ea0bf 100644 --- a/src/main.c +++ b/src/main.c @@ -145,6 +145,7 @@ int main(int argc, char *argv[]) __near_netlink_init(); __near_target_init(); __near_adapter_init(); + __near_ndef_init(); __near_manager_init(conn); __near_plugin_init(option_plugin, option_noplugin); @@ -159,6 +160,7 @@ int main(int argc, char *argv[]) __near_plugin_cleanup(); __near_manager_cleanup(); + __near_ndef_cleanup(); __near_adapter_cleanup(); __near_target_cleanup(); __near_netlink_cleanup(); diff --git a/src/ndef.c b/src/ndef.c index aeded8f..9acc25a 100644 --- a/src/ndef.c +++ b/src/ndef.c @@ -42,6 +42,16 @@ #define RECORD_TNF_UNKNOWN 0x05 #define RECORD_TNF_UNCHANGED 0x06 +#define RECORD_TNF_WKT_TEXT 'T' +#define RECORD_TNF_WKT_URI 'U' +#define RECORD_TNF_WKT_SIZE 's' +#define RECORD_TNF_WKT_TYPE 't' +#define RECORD_TNF_WKT_SMART_POSTER "Sp" +#define RECORD_TNF_WKT_REC_ACTION "act" +#define RECORD_TNF_WKT_HANDOVER_REQUEST "Hr" +#define RECORD_TNF_WKT_HANDOVER_SELECT "Hs" +#define RECORD_TNF_WKT_HANDOVER_CARRIER "Hc" + #define RECORD_MB(record) (((record)[0] & 0x80) >> 7) #define RECORD_ME(record) (((record)[0] & 0x40) >> 6) #define RECORD_CF(record) (((record)[0] & 0x20) >> 5) @@ -49,11 +59,37 @@ #define RECORD_IL(record) (((record)[0] & 0x8) >> 3) #define RECORD_TNF(record) ((record)[0] & 0x7) -void __near_ndef_destroy(struct near_ndef *ndef) +struct near_ndef_record { + char *path; + + uint8_t tnf; + gboolean smart_poster; + gboolean hand_over; + + uint8_t *type; + size_t type_length; + + uint8_t *payload; + size_t payload_length; +}; + +static DBusConnection *connection = NULL; + +char *__near_ndef_record_get_path(struct near_ndef_record *record) { - + return record->path; +} + +void __near_ndef_record_free(struct near_ndef_record *record) +{ + g_dbus_unregister_interface(connection, record->path, + NFC_RECORD_INTERFACE); + + g_free(record->path); + g_free(record); } + static gboolean record_sp(uint8_t tnf, uint8_t *type, size_t type_length) { DBG("tnf 0x%x type length %zu", tnf, type_length); @@ -140,21 +176,231 @@ static uint8_t record_payload_offset(uint8_t *record, size_t *payload_length) return offset; } -struct near_ndef *__near_ndef_create(uint8_t *ndef_data, size_t ndef_length) +static void append_rtd_text(struct near_ndef_record *record, + DBusMessageIter *dict) { - struct near_ndef *ndef; - struct near_ndef_record *record; - uint8_t *raw_record, payload_offset, type_offset; + uint8_t utf, language_length; + char *encoding, *language, *value; + + DBG(""); + + utf = (record->payload[0] & 0x80) >> 7; + if (utf == 0) + encoding = "UTF-8"; + else + encoding = "UTF-16"; + + DBG("encoding %s", encoding); + + language_length = record->payload[0] & 0x1f; + language = g_strndup((char *)&record->payload[1], language_length); + + DBG("language %s", language); + + value = g_strndup((char *)&record->payload[1 + language_length], + record->payload_length - 1 -language_length); + + DBG("value %s", value); + + near_dbus_dict_append_basic(dict, "Encoding", + DBUS_TYPE_STRING, &encoding); + + near_dbus_dict_append_basic(dict, "Language", + DBUS_TYPE_STRING, &language); + + near_dbus_dict_append_basic(dict, "Representation", + DBUS_TYPE_STRING, &value); + + g_free(language); + g_free(value); +} + +static void append_rtd_uri(struct near_ndef_record *record, + DBusMessageIter *dict) +{ + char *prefix, *value, *uri; + + switch (record->payload[0]) { + case 0x0: + prefix = NULL; + break; + case 0x1: + prefix = "http://www."; + break; + case 0x2: + prefix = "https://www."; + break; + case 0x3: + prefix = "http://"; + break; + case 0x4: + prefix = "https://"; + break; + case 0x5: + prefix = "tel:"; + break; + case 0x6: + prefix = "mailto:"; + break; + case 0x7: + prefix = "ftp://anonymous:anonymous@"; + break; + case 0x8: + prefix = "ftp://ftp."; + break; + case 0x9: + prefix = "ftps://"; + break; + } + + uri = g_strndup((char *)&record->payload[1], + record->payload_length - 1); + value = g_strdup_printf("%s%s", prefix, uri); + + DBG("value %s", value); + + near_dbus_dict_append_basic(dict, "Representation", + DBUS_TYPE_STRING, &value); + + g_free(uri); + g_free(value); +} + +static void append_rtd(struct near_ndef_record *record, DBusMessageIter *dict) +{ + char *type = (char *) record->type; + char *dbus_type = NULL; + + DBG(""); + + if (record->type_length == 1) { + switch (record->type[0]) { + case RECORD_TNF_WKT_TEXT: + dbus_type = "Text"; + append_rtd_text(record, dict); + break; + case RECORD_TNF_WKT_URI: + dbus_type = "URI"; + append_rtd_uri(record, dict); + break; + case RECORD_TNF_WKT_SIZE: + dbus_type = "Size"; + break; + case RECORD_TNF_WKT_TYPE: + dbus_type = "MIME Type"; + break; + } + } else if (record->type_length == 2) { + if (strncmp(type, RECORD_TNF_WKT_SMART_POSTER, 2)) + dbus_type = "Smart Poster"; + if (strncmp(type, RECORD_TNF_WKT_HANDOVER_REQUEST, 2)) + dbus_type = "Hand Over Request"; + if (strncmp(type, RECORD_TNF_WKT_HANDOVER_SELECT, 2)) + dbus_type = "Hand Over Select"; + if (strncmp(type, RECORD_TNF_WKT_HANDOVER_CARRIER, 2)) + dbus_type = "Hand Over Carrier"; + } else if (record->type_length == 3) + if (strncmp(type, RECORD_TNF_WKT_REC_ACTION, 3)) + dbus_type = "Recommended Action"; + + if (dbus_type != NULL) + near_dbus_dict_append_basic(dict, "Type", + DBUS_TYPE_STRING, &dbus_type); + +} + +static void append_record(struct near_ndef_record *record, + DBusMessageIter *dict) +{ + char *type = NULL; + gboolean representable = FALSE; + + if (record->tnf == RECORD_TNF_WELLKNOWN) + return append_rtd(record, dict); + + switch (record->tnf) { + case RECORD_TNF_EMPTY: + type = "Empty"; + + case RECORD_TNF_MIME: + type = "MIME"; + representable = TRUE; + + case RECORD_TNF_URI: + type = "URI"; + representable = TRUE; + case RECORD_TNF_EXTERNAL: + type = "NFC Forum External"; + case RECORD_TNF_UNKNOWN: + type = "Unknown"; + case RECORD_TNF_UNCHANGED: + type = "Unchanged"; + + } + + near_dbus_dict_append_basic(dict, "Type", + DBUS_TYPE_STRING, &type); + + if (representable == TRUE) { + char *value; + + value = g_strndup((char *)record->payload, + record->payload_length); + + near_dbus_dict_append_basic(dict, "Representation", + DBUS_TYPE_STRING, &value); - ndef = g_try_malloc0(sizeof(struct near_ndef)); - if (ndef == NULL) + g_free(value); + } +} + +static DBusMessage *get_properties(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + struct near_ndef_record *record = data; + DBusMessage *reply; + DBusMessageIter array, dict; + + DBG("conn %p", conn); + + reply = dbus_message_new_method_return(msg); + if (reply == NULL) return NULL; - ndef->n_records = 0; + dbus_message_iter_init_append(reply, &array); + + near_dbus_dict_open(&array, &dict); + + near_dbus_dict_append_basic(&dict, "SmartPoster", + DBUS_TYPE_BOOLEAN, &record->smart_poster); + + near_dbus_dict_append_basic(&dict, "HandOver", + DBUS_TYPE_BOOLEAN, &record->hand_over); + + append_record(record, &dict); + + near_dbus_dict_close(&array, &dict); + + return reply; +} + +static GDBusMethodTable record_methods[] = { + { "GetProperties", "", "a{sv}", get_properties }, + { }, +}; + +int near_ndef_parse(struct near_tag *tag, + uint8_t *ndef_data, size_t ndef_length) +{ + struct near_ndef_record *record; + uint8_t *raw_record, payload_offset, type_offset; + gboolean smart_poster; + raw_record = ndef_data; while (1) { uint8_t mb, me, sr, tnf, il; + uint32_t n_records, target_idx, adapter_idx; size_t i, type_length; mb = RECORD_MB(raw_record); @@ -164,13 +410,11 @@ struct near_ndef *__near_ndef_create(uint8_t *ndef_data, size_t ndef_length) tnf = RECORD_TNF(raw_record); DBG("Record MB 0x%x ME 0x%x SR 0x%x IL 0x%x TNF 0x%x", mb, me, sr, il, tnf); - if (ndef->n_records == 0 && mb != 1) - return NULL; - type_offset = record_type_offset(raw_record, &type_length); - ndef->smart_poster = record_sp(tnf, raw_record + type_offset, type_length); - if (ndef->smart_poster == TRUE) { + smart_poster = record_sp(tnf, raw_record + type_offset, + type_length); + if (smart_poster == TRUE) { size_t payload_length; DBG("Smart Poster"); @@ -183,10 +427,8 @@ struct near_ndef *__near_ndef_create(uint8_t *ndef_data, size_t ndef_length) } record = g_try_malloc0(sizeof(struct near_ndef_record)); - if (record == NULL) { - __near_ndef_destroy(ndef); - return NULL; - } + if (record == NULL) + return -ENOMEM; record->tnf = tnf; @@ -196,11 +438,25 @@ struct near_ndef *__near_ndef_create(uint8_t *ndef_data, size_t ndef_length) type_offset = record_type_offset(raw_record, &record->type_length); record->type = raw_record + type_offset; + record->smart_poster = smart_poster; + + n_records = __near_tag_n_records(tag); + target_idx = near_tag_get_target_idx(tag); + adapter_idx = near_tag_get_adapter_idx(tag); + record->path = g_strdup_printf("%s/nfc%d/target%d/record%d", + NFC_PATH, adapter_idx, target_idx, + n_records); + for (i = 0; i < record->payload_length; i++) DBG("Payload[%d] %c 0x%x", i, record->payload[i], record->payload[i]); - ndef->n_records += 1; - ndef->records = g_list_append(ndef->records, record); + DBG("Record path %s", record->path); + __near_tag_add_record(tag, record); + + g_dbus_register_interface(connection, record->path, + NFC_RECORD_INTERFACE, + record_methods, NULL, + NULL, record, NULL); if (me == 1) break; @@ -208,5 +464,18 @@ struct near_ndef *__near_ndef_create(uint8_t *ndef_data, size_t ndef_length) raw_record = record->payload + record->payload_length; } - return ndef; + return 0; +} + +int __near_ndef_init(void) +{ + DBG(""); + + connection = near_dbus_get_connection(); + + return 0; +} + +void __near_ndef_cleanup(void) +{ } diff --git a/src/near.h b/src/near.h index 2edfd6b..7483b56 100644 --- a/src/near.h +++ b/src/near.h @@ -102,8 +102,18 @@ void __near_target_remove(uint32_t target_idx); int __near_target_init(void); void __near_target_cleanup(void); +#include + +int __near_ndef_init(void); +void __near_ndef_cleanup(void); +void __near_ndef_record_free(struct near_ndef_record *record); +char *__near_ndef_record_get_path(struct near_ndef_record *record); + #include +void __near_tag_append_records(struct near_tag *tag, DBusMessageIter *iter); +uint32_t __near_tag_n_records(struct near_tag *tag); +int __near_tag_add_record(struct near_tag *tag, struct near_ndef_record *record); struct near_tag *__near_tag_new(uint32_t adapter_idx, uint32_t target_idx, size_t data_length); void __near_tag_free(struct near_tag *tag); @@ -124,8 +134,3 @@ void __near_netlink_cleanup(void); int __near_plugin_init(const char *pattern, const char *exclude); void __near_plugin_cleanup(void); - -#include - -void __near_ndef_destroy(struct near_ndef *ndef); -struct near_ndef *__near_ndef_create(uint8_t *ndef_data, size_t ndef_length); diff --git a/src/tag.c b/src/tag.c index 446435a..8bf6bb7 100644 --- a/src/tag.c +++ b/src/tag.c @@ -45,11 +45,29 @@ struct near_tag { size_t data_length; uint8_t *data; - GList *ndef_list; + uint32_t n_records; + GList *records; }; static GList *driver_list = NULL; +void __near_tag_append_records(struct near_tag *tag, DBusMessageIter *iter) +{ + GList *list; + + for (list = tag->records; list; list = list->next) { + struct near_ndef_record *record = list->data; + char *path; + + path = __near_ndef_record_get_path(record); + if (path == NULL) + continue; + + dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, + &path); + } +} + static int tag_initialize(struct near_tag *tag, uint32_t adapter_idx, uint32_t target_idx, size_t data_length) @@ -58,6 +76,7 @@ static int tag_initialize(struct near_tag *tag, tag->adapter_idx = adapter_idx; tag->target_idx = target_idx; + tag->n_records = 0; if (data_length > 0) { tag->data_length = data_length; @@ -87,10 +106,35 @@ struct near_tag *__near_tag_new(uint32_t adapter_idx, uint32_t target_idx, size_ void __near_tag_free(struct near_tag *tag) { + GList *list; + + for (list = tag->records; list; list = list->next) { + struct near_ndef_record *record = list->data; + + __near_ndef_record_free(record); + } + + g_list_free(tag->records); g_free(tag->data); g_free(tag); } +uint32_t __near_tag_n_records(struct near_tag *tag) +{ + return tag->n_records; +} + +int __near_tag_add_record(struct near_tag *tag, + struct near_ndef_record *record) +{ + DBG(""); + + tag->n_records++; + tag->records = g_list_append(tag->records, record); + + return 0; +} + int near_tag_set_uid(struct near_tag *tag, uint8_t *uid, size_t uid_length) { if (uid_length > TAG_UID_MAX_LEN) @@ -122,19 +166,6 @@ uint32_t near_tag_get_target_idx(struct near_tag *tag) return tag->target_idx; } -int near_tag_add_ndef(struct near_tag *tag, uint8_t *ndef_data, size_t ndef_length) -{ - struct near_ndef *ndef; - - ndef = __near_ndef_create(ndef_data, ndef_length); - if (ndef == NULL) - return -ENOMEM; - - tag->ndef_list = g_list_append(tag->ndef_list, ndef); - - return 0; -} - int near_tag_driver_register(struct near_tag_driver *driver) { DBG(""); diff --git a/src/target.c b/src/target.c index a641e3a..43e9008 100644 --- a/src/target.c +++ b/src/target.c @@ -190,6 +190,18 @@ static const char *type2string(enum near_target_type type) return NULL; } +static void append_records(DBusMessageIter *iter, void *user_data) +{ + struct near_target *target = user_data; + + DBG(""); + + if (target->tag == NULL) + return; + + __near_tag_append_records(target->tag, iter); +} + static DBusMessage *get_properties(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -217,10 +229,14 @@ static DBusMessage *get_properties(DBusConnection *conn, near_dbus_dict_append_array(&dict, "Protocols", DBUS_TYPE_STRING, append_protocols, target); - if (target->type == NEAR_TARGET_TYPE_TAG) + if (target->type == NEAR_TARGET_TYPE_TAG) { near_dbus_dict_append_array(&dict, "TagType", DBUS_TYPE_STRING, append_tag_type, target); + near_dbus_dict_append_array(&dict, "Records", + DBUS_TYPE_OBJECT_PATH, append_records, target); + } + near_dbus_dict_close(&array, &dict); return reply; diff --git a/test/dump-record b/test/dump-record new file mode 100755 index 0000000..37d6573 --- /dev/null +++ b/test/dump-record @@ -0,0 +1,31 @@ +#!/usr/bin/python + +import sys +import dbus + +def extract_list(list): + val = "[" + for i in list: + val += " " + str(i) + val += " ]" + return val + +bus = dbus.SessionBus() + +record = dbus.Interface(bus.get_object("org.neard", sys.argv[1]), + "org.neard.Record") + +properties = record.GetProperties() + +print "[ %s ]" % (sys.argv[1]) + +for key in properties.keys(): + if key in ["SmartPoster", "HandOver"]: + if properties[key] == dbus.Boolean(1): + val = "true" + else: + val = "false" + else: + val = str(properties[key]) + + print " %s = %s" % (key, val) \ No newline at end of file diff --git a/test/dump-target b/test/dump-target new file mode 100755 index 0000000..416e609 --- /dev/null +++ b/test/dump-target @@ -0,0 +1,54 @@ +#!/usr/bin/python + +import sys +import dbus + +bus = dbus.SessionBus() + +def extract_list(list): + val = "[" + for i in list: + val += " " + str(i) + val += " ]" + + return val + +def extract_record(key, list): + for i in list: + record = dbus.Interface(bus.get_object("org.neard", i), + "org.neard.Record") + + properties = record.GetProperties() + print " Record = [ %s ]" % (str(i)) + + for key in properties.keys(): + if key in ["SmartPoster", "HandOver"]: + if properties[key] == dbus.Boolean(1): + val = "true" + else: + val = "false" + else: + val = str(properties[key]) + + print " %s = %s" % (key, val) + + +target = dbus.Interface(bus.get_object("org.neard", sys.argv[1]), + "org.neard.Target") + +properties = target.GetProperties() + +print "[ %s ]" % (sys.argv[1]) + +for key in properties.keys(): + if key in ["TagType"]: + val = extract_list(properties[key]) + print " %s = %s" % (key, val) + elif key in ["Type"]: + val = str(properties[key]) + print " %s = %s" % (key, val) + + if key in ["Records"]: + extract_record(key, properties[key]) + +