summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRavikumar Veeramally <ravikumar.veeramally@linux.intel.com>2011-10-11 15:35:45 +0300
committerMarcel Holtmann <marcel@holtmann.org>2011-10-20 23:54:06 -0700
commit0623f0de2fdcbb672e1b466a8f2df60efbf6cad5 (patch)
treef07acffe1ff6f4310ab344cff5f144a4c414f091
parent7f82c162de340ddeca281b44653a4c31a94af103 (diff)
downloadneard-0623f0de2fdcbb672e1b466a8f2df60efbf6cad5.tar.gz
neard-0623f0de2fdcbb672e1b466a8f2df60efbf6cad5.tar.bz2
neard-0623f0de2fdcbb672e1b466a8f2df60efbf6cad5.zip
ndef: API provided to prepare text ndef record
API provided to prepare text ndef record which is useful to write ndef data on tags.
-rw-r--r--include/ndef.h9
-rw-r--r--src/ndef.c182
2 files changed, 191 insertions, 0 deletions
diff --git a/include/ndef.h b/include/ndef.h
index c4aee9c..559879d 100644
--- a/include/ndef.h
+++ b/include/ndef.h
@@ -26,6 +26,15 @@
struct near_ndef_record;
+struct near_ndef_message {
+ size_t length;
+ size_t offset;
+ uint8_t *data;
+};
+
int near_ndef_parse(struct near_tag *tag, uint8_t *ndef_data, size_t ndef_length);
+struct near_ndef_message *near_ndef_prepare_text_record(char *encoding,
+ char *language_code, char *text);
+
#endif
diff --git a/src/ndef.c b/src/ndef.c
index 31589ff..05a3dbe 100644
--- a/src/ndef.c
+++ b/src/ndef.c
@@ -55,6 +55,23 @@
#define NDEF_MSG_MIN_LENGTH 0x03
+#define RECORD_MB 0x80
+#define RECORD_ME 0x40
+#define RECORD_CF 0x20
+#define RECORD_SR 0x10
+#define RECORD_IL 0x08
+#define RECORD_TNF_EMPTY_SET(val) ((val & ~0x7) | RECORD_TNF_EMPTY)
+#define RECORD_TNF_WKT_SET(val) ((val & ~0x7) | RECORD_TNF_WELLKNOWN)
+#define RECORD_TNF_MIME_SET(val) ((val & ~0x7) | RECORD_TNF_MIME)
+#define RECORD_TNF_URI_SET(val) ((val & ~0x7) | RECORD_TNF_URI)
+#define RECORD_TNF_EXTERNAL_SET(val) ((val & ~0x7) | RECORD_TNF_EXTERNAL)
+#define RECORD_TNF_UKNOWN_SET(val) ((val & ~0x7) | RECORD_TNF_UNKNOWN)
+#define RECORD_TNF_UNCHANGED_SET(val) ((val & ~0x7) | RECORD_TNF_UNCHANGED)
+
+#define NDEF_MSG_SHORT_RECORD_MAX_LENGTH 0xFF
+#define NDEF_TEXT_RECORD_TYPE_NAME_HEX_VALUE 0x54
+#define NDEF_TEXT_RECORD_UTF16_STATUS 0x80
+
enum record_type {
RECORD_TYPE_WKT_SMART_POSTER = 0x01,
RECORD_TYPE_WKT_URI = 0x02,
@@ -109,6 +126,23 @@ struct near_ndef_record {
static DBusConnection *connection = NULL;
+static inline void fillb8(uint8_t *ptr, uint32_t len)
+{
+ (*(uint8_t *)(ptr)) = ((uint8_t)(len));
+}
+
+static inline void fillb16(uint8_t *ptr, uint32_t len)
+{
+ fillb8((ptr), (uint16_t)(len) >> 8);
+ fillb8((uint8_t *)(ptr) + 1, len);
+}
+
+static inline void fillb32(uint8_t *ptr, uint32_t len)
+{
+ fillb16((ptr), (uint32_t)(len) >> 16);
+ fillb16((uint8_t *)(ptr) + 2, (uint32_t)(len));
+}
+
char *__near_ndef_record_get_path(struct near_ndef_record *record)
{
return record->path;
@@ -1100,6 +1134,154 @@ fail:
return -err;
}
+/**
+ * @brief Allocates ndef message struture
+ *
+ * Allocates ndef message structure and fill message header byte,
+ * type length byte, payload length and type name. Offset is payload
+ * first byte (caller of this API can start filling their payload
+ * from offset value).
+ *
+ * @note : caller responsibility to free the input and output
+ * parameters memory.
+ *
+ * @param[in] type_name Record type name
+ * @param[in] payload_len Record payload length
+ *
+ * @return struct near_ndef_message * - Success
+ * NULL - Failure
+ */
+static struct near_ndef_message *ndef_message_alloc(char* type_name,
+ uint32_t payload_len)
+{
+ struct near_ndef_message *msg;
+ uint8_t hdr = 0, type_len, sr_bit;
+
+ msg = g_try_malloc0(sizeof(struct near_ndef_message));
+ if (msg == NULL)
+ return NULL;
+
+ msg->length = 0;
+ msg->offset = 0;
+ msg->length++; /* record header*/
+ msg->length++; /* type name length byte*/
+
+ type_len = (type_name != NULL) ? strlen(type_name) : 0;
+ sr_bit = (payload_len <= NDEF_MSG_SHORT_RECORD_MAX_LENGTH)
+ ? TRUE : FALSE;
+
+ msg->length += (sr_bit == TRUE) ? 1 : 4;
+ msg->length += type_len;
+ msg->length += payload_len;
+
+ msg->data = g_try_malloc0(msg->length);
+ if (msg->data == NULL)
+ goto fail;
+
+ hdr |= RECORD_MB;
+ hdr |= RECORD_ME;
+
+ if (sr_bit == TRUE)
+ hdr |= RECORD_SR;
+
+ hdr = RECORD_TNF_WKT_SET(hdr);
+
+ msg->data[msg->offset++] = hdr;
+ msg->data[msg->offset++] = type_len;
+
+ if (sr_bit == TRUE) {
+ msg->data[msg->offset++] = payload_len;
+ } else {
+ fillb32((msg->data + msg->offset), payload_len);
+ msg->offset += 4;
+ }
+
+ if (type_name != NULL) {
+ memcpy(msg->data + msg->offset, type_name, type_len);
+ msg->offset += type_len;
+ }
+
+ return msg;
+
+fail:
+ near_error("ndef message struct allocation failed");
+ g_free(msg->data);
+ g_free(msg);
+
+ return NULL;
+}
+
+/**
+ * @brief Prepare Text ndef record
+ *
+ * Prepare text ndef record with provided input data and return
+ * ndef message structure (lenght and byte stream) in success or
+ * NULL in failure case.
+ *
+ * @note : caller responsibility to free the input and output
+ * parameters memory.
+ *
+ * @param[in] encoding Encoding (UTF-8 | UTF-16)
+ * @param[in] language_code Language Code
+ * @param[in] text Actual text
+ *
+ * @return struct near_ndef_message * - Success
+ * NULL - Failure
+ */
+struct near_ndef_message *near_ndef_prepare_text_record(char *encoding,
+ char *language_code, char *text)
+{
+ struct near_ndef_message *msg;
+ uint32_t text_len, payload_length;
+ uint8_t code_len, status = 0;
+
+ DBG("");
+
+ /* Validate input parameters*/
+ if (((g_strcmp0(encoding, "UTF-8") != 0) &&
+ (g_strcmp0(encoding, "UTF-16") != 0)) ||
+ (language_code == NULL) ||
+ (text == NULL)) {
+ return NULL;
+ }
+
+ code_len = strlen(language_code);
+ text_len = strlen(text);
+ payload_length = 1 + code_len + text_len;
+
+ msg = ndef_message_alloc("T", payload_length);
+ if (msg == NULL)
+ return NULL;
+
+ if (g_strcmp0(encoding, "UTF-16") == 0)
+ status |= NDEF_TEXT_RECORD_UTF16_STATUS;
+
+ status = status | code_len;
+ msg->data[msg->offset++] = status;
+
+ if (code_len > 0)
+ memcpy(msg->data + msg->offset, language_code, code_len);
+
+ msg->offset += code_len;
+
+ if (text_len > 0)
+ memcpy(msg->data + msg->offset, text, text_len);
+
+ msg->offset += text_len;
+
+ if (msg->offset > msg->length)
+ goto fail;
+
+ return msg;
+
+fail:
+ near_error("text record preparation failed");
+ g_free(msg->data);
+ g_free(msg);
+
+ return NULL;
+}
+
int __near_ndef_init(void)
{
DBG("");