types: Fix build error due to unaligned memory access
authorOlivier Guiter <olivier.guiter@linux.intel.com>
Wed, 9 Jan 2013 12:42:37 +0000 (13:42 +0100)
committerSamuel Ortiz <sameo@linux.intel.com>
Thu, 10 Jan 2013 12:08:59 +0000 (13:08 +0100)
This fix number of build error on architectures that can't handle
unaligned memory access (eg. ARM).

Most of the code was originally written in BlueZ's bluetooth.h.

include/types.h
plugins/nfctype4.c
plugins/snep-core.c
src/bluetooth.c
src/ndef.c
src/tlv.c

index bd5b53d..894b7db 100644 (file)
@@ -22,6 +22,8 @@
 #ifndef __NEAR_TYPES_H
 #define __NEAR_TYPES_H
 
+#include <byteswap.h>
+
 #ifndef        FALSE
 #define        FALSE   (0)
 #endif
 
 typedef int    near_bool_t;
 
+#define near_get_unaligned(ptr)                        \
+({                                             \
+       struct __attribute__((packed)) {        \
+               typeof(*(ptr)) __v;             \
+       } *__p = (typeof(__p)) (ptr);           \
+       __p->__v;                               \
+})
+
+#define near_put_unaligned(val, ptr)           \
+do {                                           \
+       struct __attribute__((packed)) {        \
+               typeof(*(ptr)) __v;             \
+       } *__p = (typeof(__p)) (ptr);           \
+       __p->__v = (val);                       \
+} while (0)
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+static inline uint64_t near_get_le64(const void *ptr)
+{
+       return near_get_unaligned((const uint64_t *) ptr);
+}
+
+static inline uint64_t near_get_be64(const void *ptr)
+{
+       return bswap_64(near_get_unaligned((const uint64_t *) ptr));
+}
+
+static inline uint32_t near_get_le32(const void *ptr)
+{
+       return near_get_unaligned((const uint32_t *) ptr);
+}
+
+static inline uint32_t near_get_be32(const void *ptr)
+{
+       return bswap_32(near_get_unaligned((const uint32_t *) ptr));
+}
+
+static inline uint16_t near_get_le16(const void *ptr)
+{
+       return near_get_unaligned((const uint16_t *) ptr);
+}
+
+static inline uint16_t near_get_be16(const void *ptr)
+{
+       return bswap_16(near_get_unaligned((const uint16_t *) ptr));
+}
+
+static inline void near_put_le64(uint64_t val, const void *ptr)
+{
+       near_put_unaligned(val, (uint64_t *) ptr);
+}
+
+static inline void near_put_be64(uint64_t val, const void *ptr)
+{
+       near_put_unaligned(bswap_64(val), (uint64_t *) ptr);
+}
+
+static inline void near_put_le32(uint32_t val, const void *ptr)
+{
+       near_put_unaligned(val, (uint32_t *) ptr);
+}
+
+static inline void near_put_be32(uint32_t val, const void *ptr)
+{
+       near_put_unaligned(bswap_32(val), (uint32_t *) ptr);
+}
+
+static inline void near_put_le16(uint16_t val, const void *ptr)
+{
+       near_put_unaligned(val, (uint16_t *) ptr);
+}
+
+static inline void near_put_be16(uint16_t val, const void *ptr)
+{
+       near_put_unaligned(bswap_16(val), (uint16_t *) ptr);
+}
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+static inline uint64_t near_get_le64(const void *ptr)
+{
+       return bswap_64(near_get_unaligned((const uint64_t *) ptr));
+}
+
+static inline uint64_t near_get_be64(const void *ptr)
+{
+       return near_get_unaligned((const uint64_t *) ptr);
+}
+
+static inline uint32_t near_get_le32(const void *ptr)
+{
+       return bswap_32(near_get_unaligned((const uint32_t *) ptr));
+}
+
+static inline uint32_t near_get_be32(const void *ptr)
+{
+       return near_get_unaligned((const uint32_t *) ptr);
+}
+
+static inline uint16_t near_get_le16(const void *ptr)
+{
+       return bswap_16(near_get_unaligned((const uint16_t *) ptr));
+}
+
+static inline uint16_t near_get_be16(const void *ptr)
+{
+       return near_get_unaligned((const uint16_t *) ptr);
+}
+
+static inline void near_put_le64(uint64_t val, const void *ptr)
+{
+       near_put_unaligned(bswap_64(val), (uint64_t *) ptr);
+}
+
+static inline void near_put_be64(uint64_t val, const void *ptr)
+{
+       near_put_unaligned(val, (uint64_t *) ptr);
+}
+
+static inline void near_put_le32(uint32_t val, const void *ptr)
+{
+       near_put_unaligned(bswap_32(val), (uint32_t *) ptr);
+}
+
+static inline void near_put_be32(uint32_t val, const void *ptr)
+{
+       near_put_unaligned(val, (uint32_t *) ptr);
+}
+
+static inline void near_put_le16(uint16_t val, const void *ptr)
+{
+       near_put_unaligned(bswap_16(val), (uint16_t *) ptr);
+}
+
+static inline void near_put_be16(uint16_t val, const void *ptr)
+{
+       near_put_unaligned(val, (uint16_t *) ptr);
+}
+#else
+#error "Unknown byte order"
+#endif
+
 #endif
index 538630a..e275a9f 100644 (file)
@@ -74,7 +74,7 @@
 #define T4_ALL_ACCESS          0x00
 #define T4_READ_ONLY           0xFF
 
-#define APDU_STATUS(a) (g_ntohs(*((uint16_t *)(a))))
+#define APDU_STATUS(a) near_get_be16(a)
 
 /* Tag Type 4 version ID */
 static uint8_t iso_appname_v1[] = { 0xd2, 0x76, 0x0, 0x0, 0x85, 0x01, 0x0 };
@@ -365,7 +365,7 @@ static int t4_readbin_NDEF_ID(uint8_t *resp, int length, void *data)
 
        /* Add data to the tag */
        err = near_tag_add_data(cookie->adapter_idx, cookie->target_idx, NULL,
-                               g_ntohs(*((uint16_t *)(resp + NFC_STATUS_BYTE_LEN))));
+                               near_get_be16(resp + NFC_STATUS_BYTE_LEN));
        if (err < 0)
                return t4_cookie_release(err, cookie);
 
index 2155a75..ad84296 100644 (file)
@@ -642,8 +642,8 @@ static int snep_core_response(int fd, struct p2p_snep_put_req_data *req,
 
        /* if GET, we add the Acceptable length */
        if (header.request == SNEP_REQ_GET)
-               *(uint32_t *)(fragment->data + SNEP_REQ_PUT_HEADER_LENGTH)  =
-                                       GUINT32_TO_BE(snep_req_header_length);
+               near_put_be32(snep_req_header_length,
+                               fragment->data + SNEP_REQ_PUT_HEADER_LENGTH);
 
        if (fragmenting == TRUE) {
                memcpy(fragment->data + snep_req_header_length, ndef->data,
index 5c96b2e..51b659b 100644 (file)
 #define OOB_SP_SIZE            16
 #define EIR_SIZE_MAX           255
 
-#define get_unaligned(ptr)                     \
-({                                             \
-       struct __attribute__((packed)) {        \
-               typeof(*(ptr)) __v;             \
-       } *__p = (typeof(__p)) (ptr);           \
-       __p->__v;                               \
-})
-
 struct near_oob_data {
        char *def_adapter;
 
@@ -641,8 +633,7 @@ int __near_bluetooth_parse_oob_record(struct bt_data *data,
                 * the NDEF forum NDEF spec define a payload length as single
                 * byte (and the payload size IS the oob data size).
                 */
-               bt_oob_data_size =
-                       GUINT16_FROM_LE(get_unaligned((uint16_t *) ptr));
+               bt_oob_data_size = near_get_le16(ptr);
                if (bt_oob_data_size > 0xFF)    /* Big Endian */
                        bt_oob_data_size = GUINT16_FROM_BE(bt_oob_data_size);
 
index fa61548..1183280 100644 (file)
@@ -907,8 +907,7 @@ static struct near_ndef_record_header *parse_record_header(uint8_t *rec,
                rec_header->payload_len = rec[offset++];
                header_len++;
        } else {
-               rec_header->payload_len =
-                       g_ntohl(*((uint32_t *)(rec + offset)));
+               rec_header->payload_len = near_get_be32(rec + offset);
                offset += 4;
                header_len += 4;
 
@@ -1260,8 +1259,7 @@ parse_sp_payload(uint8_t *payload, uint32_t length)
                        if (rec_header->payload_len != 4)
                                goto fail;
 
-                       sp_payload->size =
-                               g_ntohl(*((uint32_t *)(payload + offset)));
+                       sp_payload->size = near_get_be32(payload + offset);
                        break;
 
                case RECORD_TYPE_WKT_TYPE:
@@ -1716,7 +1714,7 @@ static struct near_ndef_message *near_ndef_prepare_cr_message(uint16_t cr_id)
                return NULL;
 
        /* Prepare ac message */
-       *(uint16_t *)(cr_msg->data + cr_msg->offset) = g_htons(cr_id);
+       near_put_be16(cr_id, cr_msg->data + cr_msg->offset);
 
        return cr_msg;
 }
@@ -2177,7 +2175,8 @@ static struct near_ndef_ho_payload *parse_ho_payload(enum record_type rec_type,
                        }
 
                        ho_payload->collision_record =
-                               g_ntohs(*((uint16_t *)(payload + offset)));
+                                       near_get_be16(payload + offset);
+
                        break;
 
                case RECORD_TYPE_WKT_ALTERNATIVE_CARRIER:
@@ -2526,7 +2525,7 @@ int near_ndef_record_length(uint8_t *ndef_in, size_t ndef_in_length)
        if (RECORD_SR_BIT(hdr) == 1) {
                ndef_size += ndef_in[offset++];
        } else {
-               ndef_size += g_ntohl(*((uint32_t *)(ndef_in + offset)));
+               ndef_size += near_get_be32(ndef_in + offset);
                offset += 4;
 
                if (offset >= ndef_in_length)
index cc6d5a3..b6829f2 100644 (file)
--- a/src/tlv.c
+++ b/src/tlv.c
@@ -32,7 +32,7 @@ uint16_t near_tlv_length(uint8_t *tlv)
        if (tlv[0] == TLV_NULL || tlv[0] == TLV_END)
                length = 0;
        else if (tlv[1] == 0xff)
-               length = g_ntohs(*(uint16_t *)(tlv + 2));
+               length = near_get_be16(tlv + 2);
        else
                length = tlv[1];