ndef: Workaround buggy Android 4.1 BT handover implementation
authorSzymon Janc <szymon.janc@tieto.com>
Wed, 31 Oct 2012 11:22:22 +0000 (12:22 +0100)
committerSamuel Ortiz <sameo@linux.intel.com>
Wed, 14 Nov 2012 10:36:11 +0000 (11:36 +0100)
Some implementations (e.g. Android 4.1) stores the data_size in big
endian but NDEF forum spec (BT Secure Simple Pairing) requires a little
endian. At the same time, the NDEF forum NDEF spec define a payload
length as single byte (and the payload size IS the oob data size).
So we check the first byte to determine if we have a big or little
endian size.

src/ndef.c

index aeb4273..e9da81e 100644 (file)
@@ -1357,6 +1357,20 @@ fail:
        return NULL;
 }
 
+static void correct_eir_len(struct bt_data *data)
+{
+       /*
+        * Android 4.1 BUG - OOB EIR length should be in LE, but is in BE.
+        * Fortunately payload length is 1 byte so this can be detected and
+        * corrected before sending it to handover agent.
+        */
+       if (data->data[0] == 0) {
+               DBG("EIR length in BE");
+               data->data[0] = data->data[1];
+               data->data[1] = 0;
+       }
+}
+
 static struct near_ndef_mime_payload *
 parse_mime_type(struct near_ndef_record *record, uint8_t *ndef_data,
                size_t ndef_length, size_t offset, uint32_t payload_length,
@@ -1385,6 +1399,8 @@ parse_mime_type(struct near_ndef_record *record, uint8_t *ndef_data,
                data.type = BT_MIME_V2_1;
                data.size = record->header->payload_len;
                memcpy(data.data, ndef_data + offset, data.size);
+
+               correct_eir_len(&data);
        } else if (strcmp(mime->type, BT_MIME_STRING_2_0) == 0) {
                mime->handover.carrier_type = NEAR_CARRIER_BLUETOOTH;
                data.type = BT_MIME_V2_0;