├── LICENSE ├── mainline-3.10.y ├── 0004-Fixed-incomplete-type-of-struct-in6_addr.patch └── 0002-Fixed-frame-parsing.patch ├── mainline-3.11.y ├── 0004-Fixed-incomplete-type-of-struct-in6_addr.patch └── 0002-Fixed-frame-parsing.patch ├── mainline-3.12.y ├── 0004-Fixed-incomplete-type-of-struct-in6_addr.patch └── 0002-Fixed-frame-parsing.patch ├── README.md └── rpi-3.10.y ├── 0002-Fixed-frame-parsing.patch └── 0001-Added-XBee-driver-support.patch /LICENSE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mainline-3.10.y/0004-Fixed-incomplete-type-of-struct-in6_addr.patch: -------------------------------------------------------------------------------- 1 | From 65695d81357b068afaf589d258bf5f2e58974a75 Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Taveira?= 3 | Date: Sun, 5 Jan 2014 16:53:49 +0000 4 | Subject: [PATCH 4/4] Fixed incomplete type of struct in6_addr 5 | 6 | --- 7 | net/ipv6/rpl/nl_policy.c | 1 + 8 | 1 file changed, 1 insertion(+) 9 | 10 | diff --git a/net/ipv6/rpl/nl_policy.c b/net/ipv6/rpl/nl_policy.c 11 | index cebcfba..b2a58b3 100644 12 | --- a/net/ipv6/rpl/nl_policy.c 13 | +++ b/net/ipv6/rpl/nl_policy.c 14 | @@ -17,6 +17,7 @@ 15 | #include 16 | #include 17 | #include 18 | +#include 19 | 20 | #define NLA_RPL_RANK NLA_U16 21 | 22 | -- 23 | 1.8.3.2 24 | 25 | -------------------------------------------------------------------------------- /mainline-3.11.y/0004-Fixed-incomplete-type-of-struct-in6_addr.patch: -------------------------------------------------------------------------------- 1 | From 66e74ff95389cb12f007f2da1d50a125dd7e8697 Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Taveira?= 3 | Date: Sun, 5 Jan 2014 16:53:49 +0000 4 | Subject: [PATCH 4/4] Fixed incomplete type of struct in6_addr 5 | 6 | --- 7 | net/ipv6/rpl/nl_policy.c | 1 + 8 | 1 file changed, 1 insertion(+) 9 | 10 | diff --git a/net/ipv6/rpl/nl_policy.c b/net/ipv6/rpl/nl_policy.c 11 | index cebcfba..b2a58b3 100644 12 | --- a/net/ipv6/rpl/nl_policy.c 13 | +++ b/net/ipv6/rpl/nl_policy.c 14 | @@ -17,6 +17,7 @@ 15 | #include 16 | #include 17 | #include 18 | +#include 19 | 20 | #define NLA_RPL_RANK NLA_U16 21 | 22 | -- 23 | 1.8.3.2 24 | 25 | -------------------------------------------------------------------------------- /mainline-3.12.y/0004-Fixed-incomplete-type-of-struct-in6_addr.patch: -------------------------------------------------------------------------------- 1 | From add14d9b524aa90a860fa411b6f4d5978e618383 Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Taveira?= 3 | Date: Sun, 5 Jan 2014 16:53:49 +0000 4 | Subject: [PATCH 4/4] Fixed incomplete type of struct in6_addr 5 | 6 | --- 7 | net/ipv6/rpl/nl_policy.c | 1 + 8 | 1 file changed, 1 insertion(+) 9 | 10 | diff --git a/net/ipv6/rpl/nl_policy.c b/net/ipv6/rpl/nl_policy.c 11 | index cebcfba..b2a58b3 100644 12 | --- a/net/ipv6/rpl/nl_policy.c 13 | +++ b/net/ipv6/rpl/nl_policy.c 14 | @@ -17,6 +17,7 @@ 15 | #include 16 | #include 17 | #include 18 | +#include 19 | 20 | #define NLA_RPL_RANK NLA_U16 21 | 22 | -- 23 | 1.8.3.2 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #linux-rpl 2 | 3 | ##**RPL: IPv6 Routing Protocol for Low-Power and Lossy Networks for Linux** 4 | 5 | ### rpl-userspace-tools 6 | Userspace tools to setup, manage, list and check RPL configurations 7 | 8 | https://github.com/joaopedrotaveira/rpl-userspace-tools 9 | 10 | ### rpl-kernel 11 | Kernel patches 12 | 13 | * Mainline 14 | * v3.10 15 | * v3.11 16 | * v3.12 17 | * raspberrypi 3.10.y 18 | 19 | https://github.com/joaopedrotaveira/linux-rpl 20 | 21 | ## Using RPL 22 | 23 | ### Setting up root 24 | ``` 25 | # in root mode, kernel will use iface addr as dodag id 26 | $ sudo ip addr add 2001:aaaa:beef:c0fe::1/64 dev lowpan0 27 | 28 | # setup iface to act as dodag root 29 | $ sudo sysctl -w net.ipv6.conf.lowpan0.rpl_dodag_root=1 30 | 31 | # enable rpl on iface 32 | $ sudo sysctl -w net.ipv6.conf.lowpan0.rpl_enabled=1 33 | ``` 34 | 35 | ### Setting up RPL router 36 | ``` 37 | # enable without rpl-userspace-tools 38 | $ sudo sysctl -w net.ipv6.conf.lowpan0.rpl_enabled=1 39 | ``` 40 | ``` 41 | # enable with rpl-userspace-tools 42 | $ sudo rpl-ctl enable lowpan0 43 | ``` 44 | 45 | ### Disable IPv6 Privacy Extensions 46 | RPL module announces all global IPv6 addresses of RPL enabled iface. It might not be desired to announce 2 or 3 addresses of each node to DAG. 47 | 48 | To disable IPv6 Privacy Extensions: 49 | ``` 50 | $ sudo sysctl -w net.ipv6.conf.all.use_tempaddr = 0 51 | $ sudo sysctl -w net.ipv6.conf.default.use_tempaddr = 0 52 | ``` -------------------------------------------------------------------------------- /mainline-3.12.y/0002-Fixed-frame-parsing.patch: -------------------------------------------------------------------------------- 1 | From 1c1ae0c1ab866896a5910802871d0de12d8d88d3 Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Taveira?= 3 | Date: Sun, 5 Jan 2014 16:14:33 +0000 4 | Subject: [PATCH 2/4] Fixed frame parsing 5 | 6 | --- 7 | net/ieee802154/6lowpan.c | 33 +++++++++++++++++++++++++++------ 8 | 1 file changed, 27 insertions(+), 6 deletions(-) 9 | 10 | diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c 11 | index ff41b4d..6e6d0be 100644 12 | --- a/net/ieee802154/6lowpan.c 13 | +++ b/net/ieee802154/6lowpan.c 14 | @@ -879,16 +879,26 @@ lowpan_process_data(struct sk_buff *skb) 15 | pr_debug("%s first fragment received for tag %d, " 16 | "begin packet reassembly", __func__, tag); 17 | frame = lowpan_alloc_new_frame(skb, len, tag); 18 | - if (!frame) 19 | + if (!frame){ 20 | + pr_debug("%s first fragment received for tag %d, " 21 | + "failed to allow new frame!! len: %d", __func__, tag,len); 22 | goto unlock_and_drop; 23 | + } 24 | } 25 | 26 | /* if payload fits buffer, copy it */ 27 | if (likely((offset * 8 + skb->len) <= frame->length)) 28 | skb_copy_to_linear_data_offset(frame->skb, offset * 8, 29 | skb->data, skb->len); 30 | - else 31 | + else { 32 | + pr_debug("%s it doesnt fit: offset: %d skb->len: %d frame->length: %d" 33 | + "(tag %d)", __func__, offset,skb->len,frame->length, tag); 34 | + 35 | goto unlock_and_drop; 36 | + } 37 | + 38 | + pr_debug("%s assembling: bytes_rcv: %d/%d len: %d" 39 | + "(tag %d)", __func__, frame->bytes_rcv,frame->length, skb->len, tag); 40 | 41 | frame->bytes_rcv += skb->len; 42 | 43 | @@ -1104,15 +1114,26 @@ static int lowpan_set_address(struct net_device *dev, void *p) 44 | return 0; 45 | } 46 | 47 | +//static int lowpan_get_mac_header_length(struct sk_buff *skb) 48 | +//{ 49 | +// /* 50 | +// * Currently long addressing mode is supported only, so the overall 51 | +// * header size is 21: 52 | +// * FC SeqNum DPAN DA SA Sec 53 | +// * 2 + 1 + 2 + 8 + 8 + 0 = 21 54 | +// */ 55 | +// return 21; 56 | +//} 57 | + 58 | static int lowpan_get_mac_header_length(struct sk_buff *skb) 59 | { 60 | /* 61 | - * Currently long addressing mode is supported only, so the overall 62 | + * Currently long addressing mode is supported only, so the overall //FIXME 63 | * header size is 21: 64 | - * FC SeqNum DPAN DA SA Sec 65 | - * 2 + 1 + 2 + 8 + 8 + 0 = 21 66 | + * FC SeqNum DPAN DA SPAN SA Sec 67 | + * 2 + 1 + 2 + 8 + 2 + 8 + 0 = 23 68 | */ 69 | - return 21; 70 | + return 23; 71 | } 72 | 73 | static int 74 | -- 75 | 1.8.3.2 76 | 77 | -------------------------------------------------------------------------------- /mainline-3.11.y/0002-Fixed-frame-parsing.patch: -------------------------------------------------------------------------------- 1 | From 0aaadbf49862890ca0f0c780266801efbf9e7d1c Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Taveira?= 3 | Date: Sun, 5 Jan 2014 16:14:33 +0000 4 | Subject: [PATCH 2/4] Fixed frame parsing 5 | 6 | --- 7 | net/ieee802154/6lowpan.c | 317 ++++++++++++++++++++++++++++++++--------------- 8 | net/ieee802154/6lowpan.h | 20 ++- 9 | 2 files changed, 231 insertions(+), 106 deletions(-) 10 | 11 | diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c 12 | index 3b9d5f2..58ef670 100644 13 | --- a/net/ieee802154/6lowpan.c 14 | +++ b/net/ieee802154/6lowpan.c 15 | @@ -67,39 +67,6 @@ static const u8 lowpan_ttl_values[] = {0, 1, 64, 255}; 16 | 17 | static LIST_HEAD(lowpan_devices); 18 | 19 | -/* 20 | - * Uncompression of linklocal: 21 | - * 0 -> 16 bytes from packet 22 | - * 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet 23 | - * 2 -> 2 bytes from prefix - zeroes + 2 from packet 24 | - * 3 -> 2 bytes from prefix - infer 8 bytes from lladdr 25 | - * 26 | - * NOTE: => the uncompress function does change 0xf to 0x10 27 | - * NOTE: 0x00 => no-autoconfig => unspecified 28 | - */ 29 | -static const u8 lowpan_unc_llconf[] = {0x0f, 0x28, 0x22, 0x20}; 30 | - 31 | -/* 32 | - * Uncompression of ctx-based: 33 | - * 0 -> 0 bits from packet [unspecified / reserved] 34 | - * 1 -> 8 bytes from prefix - bunch of zeroes and 8 from packet 35 | - * 2 -> 8 bytes from prefix - zeroes + 2 from packet 36 | - * 3 -> 8 bytes from prefix - infer 8 bytes from lladdr 37 | - */ 38 | -static const u8 lowpan_unc_ctxconf[] = {0x00, 0x88, 0x82, 0x80}; 39 | - 40 | -/* 41 | - * Uncompression of ctx-base 42 | - * 0 -> 0 bits from packet 43 | - * 1 -> 2 bytes from prefix - bunch of zeroes 5 from packet 44 | - * 2 -> 2 bytes from prefix - zeroes + 3 from packet 45 | - * 3 -> 2 bytes from prefix - infer 1 bytes from lladdr 46 | - */ 47 | -static const u8 lowpan_unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21}; 48 | - 49 | -/* Link local prefix */ 50 | -static const u8 lowpan_llprefix[] = {0xfe, 0x80}; 51 | - 52 | /* private device info */ 53 | struct lowpan_dev_info { 54 | struct net_device *real_dev; /* real WPAN device ptr */ 55 | @@ -191,55 +158,177 @@ lowpan_compress_addr_64(u8 **hc06_ptr, u8 shift, const struct in6_addr *ipaddr, 56 | return rol8(val, shift); 57 | } 58 | 59 | -static void 60 | -lowpan_uip_ds6_set_addr_iid(struct in6_addr *ipaddr, unsigned char *lladdr) 61 | +/* 62 | + * Uncompress address function for source and 63 | + * destination address(non-multicast). 64 | + * 65 | + * address_mode is sam value or dam value. 66 | + */ 67 | +static int 68 | +lowpan_uncompress_addr(struct sk_buff *skb, 69 | + struct in6_addr *ipaddr, 70 | + const u8 address_mode, 71 | + const struct ieee802154_addr *lladdr) 72 | { 73 | - memcpy(&ipaddr->s6_addr[8], lladdr, IEEE802154_ADDR_LEN); 74 | - /* second bit-flip (Universe/Local) is done according RFC2464 */ 75 | - ipaddr->s6_addr[8] ^= 0x02; 76 | + bool fail; 77 | + 78 | + switch (address_mode) { 79 | + case LOWPAN_IPHC_ADDR_00: 80 | + /* for global link addresses */ 81 | + fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); 82 | + break; 83 | + case LOWPAN_IPHC_ADDR_01: 84 | + /* fe:80::XXXX:XXXX:XXXX:XXXX */ 85 | + ipaddr->s6_addr[0] = 0xFE; 86 | + ipaddr->s6_addr[1] = 0x80; 87 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[8], 8); 88 | + break; 89 | + case LOWPAN_IPHC_ADDR_02: 90 | + /* fe:80::ff:fe00:XXXX */ 91 | + ipaddr->s6_addr[0] = 0xFE; 92 | + ipaddr->s6_addr[1] = 0x80; 93 | + ipaddr->s6_addr[11] = 0xFF; 94 | + ipaddr->s6_addr[12] = 0xFE; 95 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[14], 2); 96 | + break; 97 | + case LOWPAN_IPHC_ADDR_03: 98 | + fail = false; 99 | + switch (lladdr->addr_type) { 100 | + case IEEE802154_ADDR_LONG: 101 | + /* fe:80::XXXX:XXXX:XXXX:XXXX 102 | + * \_________________/ 103 | + * hwaddr 104 | + */ 105 | + ipaddr->s6_addr[0] = 0xFE; 106 | + ipaddr->s6_addr[1] = 0x80; 107 | + memcpy(&ipaddr->s6_addr[8], lladdr->hwaddr, 108 | + IEEE802154_ADDR_LEN); 109 | + /* second bit-flip (Universe/Local) 110 | + * is done according RFC2464 111 | + */ 112 | + ipaddr->s6_addr[8] ^= 0x02; 113 | + break; 114 | + case IEEE802154_ADDR_SHORT: 115 | + /* fe:80::ff:fe00:XXXX 116 | + * \__/ 117 | + * short_addr 118 | + * 119 | + * Universe/Local bit is zero. 120 | + */ 121 | + ipaddr->s6_addr[0] = 0xFE; 122 | + ipaddr->s6_addr[1] = 0x80; 123 | + ipaddr->s6_addr[11] = 0xFF; 124 | + ipaddr->s6_addr[12] = 0xFE; 125 | + ipaddr->s6_addr16[7] = htons(lladdr->short_addr); 126 | + break; 127 | + default: 128 | + pr_debug("Invalid addr_type set\n"); 129 | + return -EINVAL; 130 | + } 131 | + break; 132 | + default: 133 | + pr_debug("Invalid address mode value: 0x%x\n", address_mode); 134 | + return -EINVAL; 135 | + } 136 | + 137 | + if (fail) { 138 | + pr_debug("Failed to fetch skb data\n"); 139 | + return -EIO; 140 | + } 141 | + 142 | + lowpan_raw_dump_inline(NULL, "Reconstructed ipv6 addr is:\n", 143 | + ipaddr->s6_addr, 16); 144 | + 145 | + return 0; 146 | } 147 | 148 | -/* 149 | - * Uncompress addresses based on a prefix and a postfix with zeroes in 150 | - * between. If the postfix is zero in length it will use the link address 151 | - * to configure the IP address (autoconf style). 152 | - * pref_post_count takes a byte where the first nibble specify prefix count 153 | - * and the second postfix count (NOTE: 15/0xf => 16 bytes copy). 154 | +/* Uncompress address function for source context 155 | + * based address(non-multicast). 156 | */ 157 | static int 158 | -lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr, 159 | - u8 const *prefix, u8 pref_post_count, unsigned char *lladdr) 160 | +lowpan_uncompress_context_based_src_addr(struct sk_buff *skb, 161 | + struct in6_addr *ipaddr, 162 | + const u8 sam) 163 | { 164 | - u8 prefcount = pref_post_count >> 4; 165 | - u8 postcount = pref_post_count & 0x0f; 166 | - 167 | - /* full nibble 15 => 16 */ 168 | - prefcount = (prefcount == 15 ? 16 : prefcount); 169 | - postcount = (postcount == 15 ? 16 : postcount); 170 | - 171 | - if (lladdr) 172 | - lowpan_raw_dump_inline(__func__, "linklocal address", 173 | - lladdr, IEEE802154_ADDR_LEN); 174 | - if (prefcount > 0) 175 | - memcpy(ipaddr, prefix, prefcount); 176 | - 177 | - if (prefcount + postcount < 16) 178 | - memset(&ipaddr->s6_addr[prefcount], 0, 179 | - 16 - (prefcount + postcount)); 180 | - 181 | - if (postcount > 0) { 182 | - memcpy(&ipaddr->s6_addr[16 - postcount], skb->data, postcount); 183 | - skb_pull(skb, postcount); 184 | - } else if (prefcount > 0) { 185 | - if (lladdr == NULL) 186 | - return -EINVAL; 187 | + switch (sam) { 188 | + case LOWPAN_IPHC_ADDR_00: 189 | + /* unspec address :: 190 | + * Do nothing, address is already :: 191 | + */ 192 | + break; 193 | + case LOWPAN_IPHC_ADDR_01: 194 | + /* TODO */ 195 | + case LOWPAN_IPHC_ADDR_02: 196 | + /* TODO */ 197 | + case LOWPAN_IPHC_ADDR_03: 198 | + /* TODO */ 199 | + netdev_warn(skb->dev, "SAM value 0x%x not supported\n", sam); 200 | + return -EINVAL; 201 | + default: 202 | + pr_debug("Invalid sam value: 0x%x\n", sam); 203 | + return -EINVAL; 204 | + } 205 | + 206 | + lowpan_raw_dump_inline(NULL, 207 | + "Reconstructed context based ipv6 src addr is:\n", 208 | + ipaddr->s6_addr, 16); 209 | + 210 | + return 0; 211 | +} 212 | + 213 | +/* Uncompress function for multicast destination address, 214 | + * when M bit is set. 215 | + */ 216 | +static int 217 | +lowpan_uncompress_multicast_daddr(struct sk_buff *skb, 218 | + struct in6_addr *ipaddr, 219 | + const u8 dam) 220 | +{ 221 | + bool fail; 222 | + 223 | + switch (dam) { 224 | + case LOWPAN_IPHC_DAM_00: 225 | + /* 00: 128 bits. The full address 226 | + * is carried in-line. 227 | + */ 228 | + fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); 229 | + break; 230 | + case LOWPAN_IPHC_DAM_01: 231 | + /* 01: 48 bits. The address takes 232 | + * the form ffXX::00XX:XXXX:XXXX. 233 | + */ 234 | + ipaddr->s6_addr[0] = 0xFF; 235 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); 236 | + fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[11], 5); 237 | + break; 238 | + case LOWPAN_IPHC_DAM_10: 239 | + /* 10: 32 bits. The address takes 240 | + * the form ffXX::00XX:XXXX. 241 | + */ 242 | + ipaddr->s6_addr[0] = 0xFF; 243 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); 244 | + fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[13], 3); 245 | + break; 246 | + case LOWPAN_IPHC_DAM_11: 247 | + /* 11: 8 bits. The address takes 248 | + * the form ff02::00XX. 249 | + */ 250 | + ipaddr->s6_addr[0] = 0xFF; 251 | + ipaddr->s6_addr[1] = 0x02; 252 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[15], 1); 253 | + break; 254 | + default: 255 | + pr_debug("DAM value has a wrong value: 0x%x\n", dam); 256 | + return -EINVAL; 257 | + } 258 | 259 | - /* no IID based configuration if no prefix and no data */ 260 | - lowpan_uip_ds6_set_addr_iid(ipaddr, lladdr); 261 | + if (fail) { 262 | + pr_debug("Failed to fetch skb data\n"); 263 | + return -EIO; 264 | } 265 | 266 | - pr_debug("uncompressing %d + %d => ", prefcount, postcount); 267 | - lowpan_raw_dump_inline(NULL, NULL, ipaddr->s6_addr, 16); 268 | + lowpan_raw_dump_inline(NULL, "Reconstructed ipv6 multicast addr is:\n", 269 | + ipaddr->s6_addr, 16); 270 | 271 | return 0; 272 | } 273 | @@ -702,6 +791,12 @@ lowpan_alloc_new_frame(struct sk_buff *skb, u16 len, u16 tag) 274 | skb_reserve(frame->skb, sizeof(struct ipv6hdr)); 275 | skb_put(frame->skb, frame->length); 276 | 277 | + /* copy the first control block to keep a 278 | + * trace of the link-layer addresses in case 279 | + * of a link-local compressed address 280 | + */ 281 | + memcpy(frame->skb->cb, skb->cb, sizeof(skb->cb)); 282 | + 283 | init_timer(&frame->timer); 284 | /* time out is the same as for ipv6 - 60 sec */ 285 | frame->timer.expires = jiffies + LOWPAN_FRAG_TIMEOUT; 286 | @@ -723,9 +818,9 @@ frame_err: 287 | static int 288 | lowpan_process_data(struct sk_buff *skb) 289 | { 290 | - struct ipv6hdr hdr; 291 | + struct ipv6hdr hdr = {}; 292 | u8 tmp, iphc0, iphc1, num_context = 0; 293 | - u8 *_saddr, *_daddr; 294 | + const struct ieee802154_addr *_saddr, *_daddr; 295 | int err; 296 | 297 | lowpan_raw_dump_table(__func__, "raw skb data dump", skb->data, 298 | @@ -784,16 +879,26 @@ lowpan_process_data(struct sk_buff *skb) 299 | pr_debug("%s first fragment received for tag %d, " 300 | "begin packet reassembly", __func__, tag); 301 | frame = lowpan_alloc_new_frame(skb, len, tag); 302 | - if (!frame) 303 | + if (!frame){ 304 | + pr_debug("%s first fragment received for tag %d, " 305 | + "failed to allow new frame!! len: %d", __func__, tag,len); 306 | goto unlock_and_drop; 307 | + } 308 | } 309 | 310 | /* if payload fits buffer, copy it */ 311 | if (likely((offset * 8 + skb->len) <= frame->length)) 312 | skb_copy_to_linear_data_offset(frame->skb, offset * 8, 313 | skb->data, skb->len); 314 | - else 315 | + else { 316 | + pr_debug("%s it doesnt fit: offset: %d skb->len: %d frame->length: %d" 317 | + "(tag %d)", __func__, offset,skb->len,frame->length, tag); 318 | + 319 | goto unlock_and_drop; 320 | + } 321 | + 322 | + pr_debug("%s assembling: bytes_rcv: %d/%d len: %d" 323 | + "(tag %d)", __func__, frame->bytes_rcv,frame->length, skb->len, tag); 324 | 325 | frame->bytes_rcv += skb->len; 326 | 327 | @@ -828,8 +933,8 @@ lowpan_process_data(struct sk_buff *skb) 328 | if (lowpan_fetch_skb_u8(skb, &iphc1)) 329 | goto drop; 330 | 331 | - _saddr = mac_cb(skb)->sa.hwaddr; 332 | - _daddr = mac_cb(skb)->da.hwaddr; 333 | + _saddr = &mac_cb(skb)->sa; 334 | + _daddr = &mac_cb(skb)->da; 335 | 336 | pr_debug("iphc0 = %02x, iphc1 = %02x\n", iphc0, iphc1); 337 | 338 | @@ -885,10 +990,6 @@ lowpan_process_data(struct sk_buff *skb) 339 | break; 340 | /* Traffic Class and Flow Label are elided */ 341 | case 3: /* 11b */ 342 | - hdr.priority = 0; 343 | - hdr.flow_lbl[0] = 0; 344 | - hdr.flow_lbl[1] = 0; 345 | - hdr.flow_lbl[2] = 0; 346 | break; 347 | default: 348 | break; 349 | @@ -915,10 +1016,18 @@ lowpan_process_data(struct sk_buff *skb) 350 | /* Extract SAM to the tmp variable */ 351 | tmp = ((iphc1 & LOWPAN_IPHC_SAM) >> LOWPAN_IPHC_SAM_BIT) & 0x03; 352 | 353 | - /* Source address uncompression */ 354 | - pr_debug("source address stateless compression\n"); 355 | - err = lowpan_uncompress_addr(skb, &hdr.saddr, lowpan_llprefix, 356 | - lowpan_unc_llconf[tmp], skb->data); 357 | + if (iphc1 & LOWPAN_IPHC_SAC) { 358 | + /* Source address context based uncompression */ 359 | + pr_debug("SAC bit is set. Handle context based source address.\n"); 360 | + err = lowpan_uncompress_context_based_src_addr( 361 | + skb, &hdr.saddr, tmp); 362 | + } else { 363 | + /* Source address uncompression */ 364 | + pr_debug("source address stateless compression\n"); 365 | + err = lowpan_uncompress_addr(skb, &hdr.saddr, tmp, _saddr); 366 | + } 367 | + 368 | + /* Check on error of previous branch */ 369 | if (err) 370 | goto drop; 371 | 372 | @@ -931,23 +1040,14 @@ lowpan_process_data(struct sk_buff *skb) 373 | pr_debug("dest: context-based mcast compression\n"); 374 | /* TODO: implement this */ 375 | } else { 376 | - u8 prefix[] = {0xff, 0x02}; 377 | - 378 | - pr_debug("dest: non context-based mcast compression\n"); 379 | - if (0 < tmp && tmp < 3) { 380 | - if (lowpan_fetch_skb_u8(skb, &prefix[1])) 381 | - goto drop; 382 | - } 383 | - 384 | - err = lowpan_uncompress_addr(skb, &hdr.daddr, prefix, 385 | - lowpan_unc_mxconf[tmp], NULL); 386 | + err = lowpan_uncompress_multicast_daddr( 387 | + skb, &hdr.daddr, tmp); 388 | if (err) 389 | goto drop; 390 | } 391 | } else { 392 | pr_debug("dest: stateless compression\n"); 393 | - err = lowpan_uncompress_addr(skb, &hdr.daddr, lowpan_llprefix, 394 | - lowpan_unc_llconf[tmp], skb->data); 395 | + err = lowpan_uncompress_addr(skb, &hdr.daddr, tmp, _daddr); 396 | if (err) 397 | goto drop; 398 | } 399 | @@ -1016,15 +1116,26 @@ static int lowpan_set_address(struct net_device *dev, void *p) 400 | return 0; 401 | } 402 | 403 | +//static int lowpan_get_mac_header_length(struct sk_buff *skb) 404 | +//{ 405 | +// /* 406 | +// * Currently long addressing mode is supported only, so the overall 407 | +// * header size is 21: 408 | +// * FC SeqNum DPAN DA SA Sec 409 | +// * 2 + 1 + 2 + 8 + 8 + 0 = 21 410 | +// */ 411 | +// return 21; 412 | +//} 413 | + 414 | static int lowpan_get_mac_header_length(struct sk_buff *skb) 415 | { 416 | /* 417 | - * Currently long addressing mode is supported only, so the overall 418 | + * Currently long addressing mode is supported only, so the overall //FIXME 419 | * header size is 21: 420 | - * FC SeqNum DPAN DA SA Sec 421 | - * 2 + 1 + 2 + 8 + 8 + 0 = 21 422 | + * FC SeqNum DPAN DA SPAN SA Sec 423 | + * 2 + 1 + 2 + 8 + 2 + 8 + 0 = 23 424 | */ 425 | - return 21; 426 | + return 23; 427 | } 428 | 429 | static int 430 | diff --git a/net/ieee802154/6lowpan.h b/net/ieee802154/6lowpan.h 431 | index 4b8f917..2869c05 100644 432 | --- a/net/ieee802154/6lowpan.h 433 | +++ b/net/ieee802154/6lowpan.h 434 | @@ -193,10 +193,12 @@ 435 | /* Values of fields within the IPHC encoding second byte */ 436 | #define LOWPAN_IPHC_CID 0x80 437 | 438 | +#define LOWPAN_IPHC_ADDR_00 0x00 439 | +#define LOWPAN_IPHC_ADDR_01 0x01 440 | +#define LOWPAN_IPHC_ADDR_02 0x02 441 | +#define LOWPAN_IPHC_ADDR_03 0x03 442 | + 443 | #define LOWPAN_IPHC_SAC 0x40 444 | -#define LOWPAN_IPHC_SAM_00 0x00 445 | -#define LOWPAN_IPHC_SAM_01 0x10 446 | -#define LOWPAN_IPHC_SAM_10 0x20 447 | #define LOWPAN_IPHC_SAM 0x30 448 | 449 | #define LOWPAN_IPHC_SAM_BIT 4 450 | @@ -230,4 +232,16 @@ 451 | dest = 16 bit inline */ 452 | #define LOWPAN_NHC_UDP_CS_P_11 0xF3 /* source & dest = 0xF0B + 4bit inline */ 453 | 454 | +static inline bool lowpan_fetch_skb(struct sk_buff *skb, 455 | + void *data, const unsigned int len) 456 | +{ 457 | + if (unlikely(!pskb_may_pull(skb, len))) 458 | + return true; 459 | + 460 | + skb_copy_from_linear_data(skb, data, len); 461 | + skb_pull(skb, len); 462 | + 463 | + return false; 464 | +} 465 | + 466 | #endif /* __6LOWPAN_H__ */ 467 | -- 468 | 1.8.3.2 469 | 470 | -------------------------------------------------------------------------------- /rpi-3.10.y/0002-Fixed-frame-parsing.patch: -------------------------------------------------------------------------------- 1 | From 8916ac1c9011c081ca471bbc30b51c9a8be16cab Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Taveira?= 3 | Date: Sun, 5 Jan 2014 16:14:33 +0000 4 | Subject: [PATCH 2/3] Fixed frame parsing 5 | 6 | --- 7 | net/ieee802154/6lowpan.c | 321 +++++++++++++++++++++++++++++++---------------- 8 | net/ieee802154/6lowpan.h | 20 ++- 9 | 2 files changed, 233 insertions(+), 108 deletions(-) 10 | 11 | diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c 12 | index 31b127e..29a7763 100644 13 | --- a/net/ieee802154/6lowpan.c 14 | +++ b/net/ieee802154/6lowpan.c 15 | @@ -67,39 +67,6 @@ static const u8 lowpan_ttl_values[] = {0, 1, 64, 255}; 16 | 17 | static LIST_HEAD(lowpan_devices); 18 | 19 | -/* 20 | - * Uncompression of linklocal: 21 | - * 0 -> 16 bytes from packet 22 | - * 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet 23 | - * 2 -> 2 bytes from prefix - zeroes + 2 from packet 24 | - * 3 -> 2 bytes from prefix - infer 8 bytes from lladdr 25 | - * 26 | - * NOTE: => the uncompress function does change 0xf to 0x10 27 | - * NOTE: 0x00 => no-autoconfig => unspecified 28 | - */ 29 | -static const u8 lowpan_unc_llconf[] = {0x0f, 0x28, 0x22, 0x20}; 30 | - 31 | -/* 32 | - * Uncompression of ctx-based: 33 | - * 0 -> 0 bits from packet [unspecified / reserved] 34 | - * 1 -> 8 bytes from prefix - bunch of zeroes and 8 from packet 35 | - * 2 -> 8 bytes from prefix - zeroes + 2 from packet 36 | - * 3 -> 8 bytes from prefix - infer 8 bytes from lladdr 37 | - */ 38 | -static const u8 lowpan_unc_ctxconf[] = {0x00, 0x88, 0x82, 0x80}; 39 | - 40 | -/* 41 | - * Uncompression of ctx-base 42 | - * 0 -> 0 bits from packet 43 | - * 1 -> 2 bytes from prefix - bunch of zeroes 5 from packet 44 | - * 2 -> 2 bytes from prefix - zeroes + 3 from packet 45 | - * 3 -> 2 bytes from prefix - infer 1 bytes from lladdr 46 | - */ 47 | -static const u8 lowpan_unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21}; 48 | - 49 | -/* Link local prefix */ 50 | -static const u8 lowpan_llprefix[] = {0xfe, 0x80}; 51 | - 52 | /* private device info */ 53 | struct lowpan_dev_info { 54 | struct net_device *real_dev; /* real WPAN device ptr */ 55 | @@ -191,55 +158,177 @@ lowpan_compress_addr_64(u8 **hc06_ptr, u8 shift, const struct in6_addr *ipaddr, 56 | return rol8(val, shift); 57 | } 58 | 59 | -static void 60 | -lowpan_uip_ds6_set_addr_iid(struct in6_addr *ipaddr, unsigned char *lladdr) 61 | +/* 62 | + * Uncompress address function for source and 63 | + * destination address(non-multicast). 64 | + * 65 | + * address_mode is sam value or dam value. 66 | + */ 67 | +static int 68 | +lowpan_uncompress_addr(struct sk_buff *skb, 69 | + struct in6_addr *ipaddr, 70 | + const u8 address_mode, 71 | + const struct ieee802154_addr *lladdr) 72 | { 73 | - memcpy(&ipaddr->s6_addr[8], lladdr, IEEE802154_ADDR_LEN); 74 | - /* second bit-flip (Universe/Local) is done according RFC2464 */ 75 | - ipaddr->s6_addr[8] ^= 0x02; 76 | + bool fail; 77 | + 78 | + switch (address_mode) { 79 | + case LOWPAN_IPHC_ADDR_00: 80 | + /* for global link addresses */ 81 | + fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); 82 | + break; 83 | + case LOWPAN_IPHC_ADDR_01: 84 | + /* fe:80::XXXX:XXXX:XXXX:XXXX */ 85 | + ipaddr->s6_addr[0] = 0xFE; 86 | + ipaddr->s6_addr[1] = 0x80; 87 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[8], 8); 88 | + break; 89 | + case LOWPAN_IPHC_ADDR_02: 90 | + /* fe:80::ff:fe00:XXXX */ 91 | + ipaddr->s6_addr[0] = 0xFE; 92 | + ipaddr->s6_addr[1] = 0x80; 93 | + ipaddr->s6_addr[11] = 0xFF; 94 | + ipaddr->s6_addr[12] = 0xFE; 95 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[14], 2); 96 | + break; 97 | + case LOWPAN_IPHC_ADDR_03: 98 | + fail = false; 99 | + switch (lladdr->addr_type) { 100 | + case IEEE802154_ADDR_LONG: 101 | + /* fe:80::XXXX:XXXX:XXXX:XXXX 102 | + * \_________________/ 103 | + * hwaddr 104 | + */ 105 | + ipaddr->s6_addr[0] = 0xFE; 106 | + ipaddr->s6_addr[1] = 0x80; 107 | + memcpy(&ipaddr->s6_addr[8], lladdr->hwaddr, 108 | + IEEE802154_ADDR_LEN); 109 | + /* second bit-flip (Universe/Local) 110 | + * is done according RFC2464 111 | + */ 112 | + ipaddr->s6_addr[8] ^= 0x02; 113 | + break; 114 | + case IEEE802154_ADDR_SHORT: 115 | + /* fe:80::ff:fe00:XXXX 116 | + * \__/ 117 | + * short_addr 118 | + * 119 | + * Universe/Local bit is zero. 120 | + */ 121 | + ipaddr->s6_addr[0] = 0xFE; 122 | + ipaddr->s6_addr[1] = 0x80; 123 | + ipaddr->s6_addr[11] = 0xFF; 124 | + ipaddr->s6_addr[12] = 0xFE; 125 | + ipaddr->s6_addr16[7] = htons(lladdr->short_addr); 126 | + break; 127 | + default: 128 | + pr_debug("Invalid addr_type set\n"); 129 | + return -EINVAL; 130 | + } 131 | + break; 132 | + default: 133 | + pr_debug("Invalid address mode value: 0x%x\n", address_mode); 134 | + return -EINVAL; 135 | + } 136 | + 137 | + if (fail) { 138 | + pr_debug("Failed to fetch skb data\n"); 139 | + return -EIO; 140 | + } 141 | + 142 | + lowpan_raw_dump_inline(NULL, "Reconstructed ipv6 addr is:\n", 143 | + ipaddr->s6_addr, 16); 144 | + 145 | + return 0; 146 | } 147 | 148 | -/* 149 | - * Uncompress addresses based on a prefix and a postfix with zeroes in 150 | - * between. If the postfix is zero in length it will use the link address 151 | - * to configure the IP address (autoconf style). 152 | - * pref_post_count takes a byte where the first nibble specify prefix count 153 | - * and the second postfix count (NOTE: 15/0xf => 16 bytes copy). 154 | +/* Uncompress address function for source context 155 | + * based address(non-multicast). 156 | */ 157 | static int 158 | -lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr, 159 | - u8 const *prefix, u8 pref_post_count, unsigned char *lladdr) 160 | +lowpan_uncompress_context_based_src_addr(struct sk_buff *skb, 161 | + struct in6_addr *ipaddr, 162 | + const u8 sam) 163 | { 164 | - u8 prefcount = pref_post_count >> 4; 165 | - u8 postcount = pref_post_count & 0x0f; 166 | - 167 | - /* full nibble 15 => 16 */ 168 | - prefcount = (prefcount == 15 ? 16 : prefcount); 169 | - postcount = (postcount == 15 ? 16 : postcount); 170 | - 171 | - if (lladdr) 172 | - lowpan_raw_dump_inline(__func__, "linklocal address", 173 | - lladdr, IEEE802154_ADDR_LEN); 174 | - if (prefcount > 0) 175 | - memcpy(ipaddr, prefix, prefcount); 176 | - 177 | - if (prefcount + postcount < 16) 178 | - memset(&ipaddr->s6_addr[prefcount], 0, 179 | - 16 - (prefcount + postcount)); 180 | - 181 | - if (postcount > 0) { 182 | - memcpy(&ipaddr->s6_addr[16 - postcount], skb->data, postcount); 183 | - skb_pull(skb, postcount); 184 | - } else if (prefcount > 0) { 185 | - if (lladdr == NULL) 186 | - return -EINVAL; 187 | + switch (sam) { 188 | + case LOWPAN_IPHC_ADDR_00: 189 | + /* unspec address :: 190 | + * Do nothing, address is already :: 191 | + */ 192 | + break; 193 | + case LOWPAN_IPHC_ADDR_01: 194 | + /* TODO */ 195 | + case LOWPAN_IPHC_ADDR_02: 196 | + /* TODO */ 197 | + case LOWPAN_IPHC_ADDR_03: 198 | + /* TODO */ 199 | + netdev_warn(skb->dev, "SAM value 0x%x not supported\n", sam); 200 | + return -EINVAL; 201 | + default: 202 | + pr_debug("Invalid sam value: 0x%x\n", sam); 203 | + return -EINVAL; 204 | + } 205 | + 206 | + lowpan_raw_dump_inline(NULL, 207 | + "Reconstructed context based ipv6 src addr is:\n", 208 | + ipaddr->s6_addr, 16); 209 | + 210 | + return 0; 211 | +} 212 | + 213 | +/* Uncompress function for multicast destination address, 214 | + * when M bit is set. 215 | + */ 216 | +static int 217 | +lowpan_uncompress_multicast_daddr(struct sk_buff *skb, 218 | + struct in6_addr *ipaddr, 219 | + const u8 dam) 220 | +{ 221 | + bool fail; 222 | + 223 | + switch (dam) { 224 | + case LOWPAN_IPHC_DAM_00: 225 | + /* 00: 128 bits. The full address 226 | + * is carried in-line. 227 | + */ 228 | + fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); 229 | + break; 230 | + case LOWPAN_IPHC_DAM_01: 231 | + /* 01: 48 bits. The address takes 232 | + * the form ffXX::00XX:XXXX:XXXX. 233 | + */ 234 | + ipaddr->s6_addr[0] = 0xFF; 235 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); 236 | + fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[11], 5); 237 | + break; 238 | + case LOWPAN_IPHC_DAM_10: 239 | + /* 10: 32 bits. The address takes 240 | + * the form ffXX::00XX:XXXX. 241 | + */ 242 | + ipaddr->s6_addr[0] = 0xFF; 243 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); 244 | + fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[13], 3); 245 | + break; 246 | + case LOWPAN_IPHC_DAM_11: 247 | + /* 11: 8 bits. The address takes 248 | + * the form ff02::00XX. 249 | + */ 250 | + ipaddr->s6_addr[0] = 0xFF; 251 | + ipaddr->s6_addr[1] = 0x02; 252 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[15], 1); 253 | + break; 254 | + default: 255 | + pr_debug("DAM value has a wrong value: 0x%x\n", dam); 256 | + return -EINVAL; 257 | + } 258 | 259 | - /* no IID based configuration if no prefix and no data */ 260 | - lowpan_uip_ds6_set_addr_iid(ipaddr, lladdr); 261 | + if (fail) { 262 | + pr_debug("Failed to fetch skb data\n"); 263 | + return -EIO; 264 | } 265 | 266 | - pr_debug("uncompressing %d + %d => ", prefcount, postcount); 267 | - lowpan_raw_dump_inline(NULL, NULL, ipaddr->s6_addr, 16); 268 | + lowpan_raw_dump_inline(NULL, "Reconstructed ipv6 multicast addr is:\n", 269 | + ipaddr->s6_addr, 16); 270 | 271 | return 0; 272 | } 273 | @@ -702,6 +791,12 @@ lowpan_alloc_new_frame(struct sk_buff *skb, u16 len, u16 tag) 274 | skb_reserve(frame->skb, sizeof(struct ipv6hdr)); 275 | skb_put(frame->skb, frame->length); 276 | 277 | + /* copy the first control block to keep a 278 | + * trace of the link-layer addresses in case 279 | + * of a link-local compressed address 280 | + */ 281 | + memcpy(frame->skb->cb, skb->cb, sizeof(skb->cb)); 282 | + 283 | init_timer(&frame->timer); 284 | /* time out is the same as for ipv6 - 60 sec */ 285 | frame->timer.expires = jiffies + LOWPAN_FRAG_TIMEOUT; 286 | @@ -723,9 +818,9 @@ frame_err: 287 | static int 288 | lowpan_process_data(struct sk_buff *skb) 289 | { 290 | - struct ipv6hdr hdr; 291 | + struct ipv6hdr hdr = {}; 292 | u8 tmp, iphc0, iphc1, num_context = 0; 293 | - u8 *_saddr, *_daddr; 294 | + const struct ieee802154_addr *_saddr, *_daddr; 295 | int err; 296 | 297 | lowpan_raw_dump_table(__func__, "raw skb data dump", skb->data, 298 | @@ -784,16 +879,26 @@ lowpan_process_data(struct sk_buff *skb) 299 | pr_debug("%s first fragment received for tag %d, " 300 | "begin packet reassembly", __func__, tag); 301 | frame = lowpan_alloc_new_frame(skb, len, tag); 302 | - if (!frame) 303 | + if (!frame){ 304 | + pr_debug("%s first fragment received for tag %d, " 305 | + "failed to allow new frame!! len: %d", __func__, tag,len); 306 | goto unlock_and_drop; 307 | + } 308 | } 309 | 310 | /* if payload fits buffer, copy it */ 311 | if (likely((offset * 8 + skb->len) <= frame->length)) 312 | skb_copy_to_linear_data_offset(frame->skb, offset * 8, 313 | skb->data, skb->len); 314 | - else 315 | + else { 316 | + pr_debug("%s it doesnt fit: offset: %d skb->len: %d frame->length: %d" 317 | + "(tag %d)", __func__, offset,skb->len,frame->length, tag); 318 | + 319 | goto unlock_and_drop; 320 | + } 321 | + 322 | + pr_debug("%s assembling: bytes_rcv: %d/%d len: %d" 323 | + "(tag %d)", __func__, frame->bytes_rcv,frame->length, skb->len, tag); 324 | 325 | frame->bytes_rcv += skb->len; 326 | 327 | @@ -828,8 +933,8 @@ lowpan_process_data(struct sk_buff *skb) 328 | if (lowpan_fetch_skb_u8(skb, &iphc1)) 329 | goto drop; 330 | 331 | - _saddr = mac_cb(skb)->sa.hwaddr; 332 | - _daddr = mac_cb(skb)->da.hwaddr; 333 | + _saddr = &mac_cb(skb)->sa; 334 | + _daddr = &mac_cb(skb)->da; 335 | 336 | pr_debug("iphc0 = %02x, iphc1 = %02x\n", iphc0, iphc1); 337 | 338 | @@ -885,10 +990,6 @@ lowpan_process_data(struct sk_buff *skb) 339 | break; 340 | /* Traffic Class and Flow Label are elided */ 341 | case 3: /* 11b */ 342 | - hdr.priority = 0; 343 | - hdr.flow_lbl[0] = 0; 344 | - hdr.flow_lbl[1] = 0; 345 | - hdr.flow_lbl[2] = 0; 346 | break; 347 | default: 348 | break; 349 | @@ -915,10 +1016,18 @@ lowpan_process_data(struct sk_buff *skb) 350 | /* Extract SAM to the tmp variable */ 351 | tmp = ((iphc1 & LOWPAN_IPHC_SAM) >> LOWPAN_IPHC_SAM_BIT) & 0x03; 352 | 353 | - /* Source address uncompression */ 354 | - pr_debug("source address stateless compression\n"); 355 | - err = lowpan_uncompress_addr(skb, &hdr.saddr, lowpan_llprefix, 356 | - lowpan_unc_llconf[tmp], skb->data); 357 | + if (iphc1 & LOWPAN_IPHC_SAC) { 358 | + /* Source address context based uncompression */ 359 | + pr_debug("SAC bit is set. Handle context based source address.\n"); 360 | + err = lowpan_uncompress_context_based_src_addr( 361 | + skb, &hdr.saddr, tmp); 362 | + } else { 363 | + /* Source address uncompression */ 364 | + pr_debug("source address stateless compression\n"); 365 | + err = lowpan_uncompress_addr(skb, &hdr.saddr, tmp, _saddr); 366 | + } 367 | + 368 | + /* Check on error of previous branch */ 369 | if (err) 370 | goto drop; 371 | 372 | @@ -931,23 +1040,14 @@ lowpan_process_data(struct sk_buff *skb) 373 | pr_debug("dest: context-based mcast compression\n"); 374 | /* TODO: implement this */ 375 | } else { 376 | - u8 prefix[] = {0xff, 0x02}; 377 | - 378 | - pr_debug("dest: non context-based mcast compression\n"); 379 | - if (0 < tmp && tmp < 3) { 380 | - if (lowpan_fetch_skb_u8(skb, &prefix[1])) 381 | - goto drop; 382 | - } 383 | - 384 | - err = lowpan_uncompress_addr(skb, &hdr.daddr, prefix, 385 | - lowpan_unc_mxconf[tmp], NULL); 386 | + err = lowpan_uncompress_multicast_daddr( 387 | + skb, &hdr.daddr, tmp); 388 | if (err) 389 | goto drop; 390 | } 391 | } else { 392 | pr_debug("dest: stateless compression\n"); 393 | - err = lowpan_uncompress_addr(skb, &hdr.daddr, lowpan_llprefix, 394 | - lowpan_unc_llconf[tmp], skb->data); 395 | + err = lowpan_uncompress_addr(skb, &hdr.daddr, tmp, _daddr); 396 | if (err) 397 | goto drop; 398 | } 399 | @@ -1016,15 +1116,26 @@ static int lowpan_set_address(struct net_device *dev, void *p) 400 | return 0; 401 | } 402 | 403 | +//static int lowpan_get_mac_header_length(struct sk_buff *skb) 404 | +//{ 405 | +// /* 406 | +// * Currently long addressing mode is supported only, so the overall 407 | +// * header size is 21: 408 | +// * FC SeqNum DPAN DA SA Sec 409 | +// * 2 + 1 + 2 + 8 + 8 + 0 = 21 410 | +// */ 411 | +// return 21; 412 | +//} 413 | + 414 | static int lowpan_get_mac_header_length(struct sk_buff *skb) 415 | { 416 | /* 417 | - * Currently long addressing mode is supported only, so the overall 418 | + * Currently long addressing mode is supported only, so the overall //FIXME 419 | * header size is 21: 420 | - * FC SeqNum DPAN DA SA Sec 421 | - * 2 + 1 + 2 + 8 + 8 + 0 = 21 422 | + * FC SeqNum DPAN DA SPAN SA Sec 423 | + * 2 + 1 + 2 + 8 + 2 + 8 + 0 = 23 424 | */ 425 | - return 21; 426 | + return 23; 427 | } 428 | 429 | static int 430 | @@ -1352,9 +1463,9 @@ static inline void lowpan_netlink_fini(void) 431 | } 432 | 433 | static int lowpan_device_event(struct notifier_block *unused, 434 | - unsigned long event, 435 | - void *ptr) 436 | + unsigned long event, void *ptr) 437 | { 438 | + //struct net_device *dev = netdev_notifier_info_to_dev(ptr); 439 | struct net_device *dev = ptr; 440 | LIST_HEAD(del_list); 441 | struct lowpan_dev_record *entry, *tmp; 442 | diff --git a/net/ieee802154/6lowpan.h b/net/ieee802154/6lowpan.h 443 | index 4b8f917..2869c05 100644 444 | --- a/net/ieee802154/6lowpan.h 445 | +++ b/net/ieee802154/6lowpan.h 446 | @@ -193,10 +193,12 @@ 447 | /* Values of fields within the IPHC encoding second byte */ 448 | #define LOWPAN_IPHC_CID 0x80 449 | 450 | +#define LOWPAN_IPHC_ADDR_00 0x00 451 | +#define LOWPAN_IPHC_ADDR_01 0x01 452 | +#define LOWPAN_IPHC_ADDR_02 0x02 453 | +#define LOWPAN_IPHC_ADDR_03 0x03 454 | + 455 | #define LOWPAN_IPHC_SAC 0x40 456 | -#define LOWPAN_IPHC_SAM_00 0x00 457 | -#define LOWPAN_IPHC_SAM_01 0x10 458 | -#define LOWPAN_IPHC_SAM_10 0x20 459 | #define LOWPAN_IPHC_SAM 0x30 460 | 461 | #define LOWPAN_IPHC_SAM_BIT 4 462 | @@ -230,4 +232,16 @@ 463 | dest = 16 bit inline */ 464 | #define LOWPAN_NHC_UDP_CS_P_11 0xF3 /* source & dest = 0xF0B + 4bit inline */ 465 | 466 | +static inline bool lowpan_fetch_skb(struct sk_buff *skb, 467 | + void *data, const unsigned int len) 468 | +{ 469 | + if (unlikely(!pskb_may_pull(skb, len))) 470 | + return true; 471 | + 472 | + skb_copy_from_linear_data(skb, data, len); 473 | + skb_pull(skb, len); 474 | + 475 | + return false; 476 | +} 477 | + 478 | #endif /* __6LOWPAN_H__ */ 479 | -- 480 | 1.8.3.2 481 | 482 | -------------------------------------------------------------------------------- /mainline-3.10.y/0002-Fixed-frame-parsing.patch: -------------------------------------------------------------------------------- 1 | From 131c4a0e01a1e04fcaf775e9af3ef5128a81a912 Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Taveira?= 3 | Date: Sun, 5 Jan 2014 16:14:33 +0000 4 | Subject: [PATCH 2/4] Fixed frame parsing 5 | 6 | --- 7 | net/ieee802154/6lowpan.c | 321 +++++++++++++++++++++++++++++++---------------- 8 | net/ieee802154/6lowpan.h | 20 ++- 9 | 2 files changed, 233 insertions(+), 108 deletions(-) 10 | 11 | diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c 12 | index 55e1fd5..f8d3b2e 100644 13 | --- a/net/ieee802154/6lowpan.c 14 | +++ b/net/ieee802154/6lowpan.c 15 | @@ -67,39 +67,6 @@ static const u8 lowpan_ttl_values[] = {0, 1, 64, 255}; 16 | 17 | static LIST_HEAD(lowpan_devices); 18 | 19 | -/* 20 | - * Uncompression of linklocal: 21 | - * 0 -> 16 bytes from packet 22 | - * 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet 23 | - * 2 -> 2 bytes from prefix - zeroes + 2 from packet 24 | - * 3 -> 2 bytes from prefix - infer 8 bytes from lladdr 25 | - * 26 | - * NOTE: => the uncompress function does change 0xf to 0x10 27 | - * NOTE: 0x00 => no-autoconfig => unspecified 28 | - */ 29 | -static const u8 lowpan_unc_llconf[] = {0x0f, 0x28, 0x22, 0x20}; 30 | - 31 | -/* 32 | - * Uncompression of ctx-based: 33 | - * 0 -> 0 bits from packet [unspecified / reserved] 34 | - * 1 -> 8 bytes from prefix - bunch of zeroes and 8 from packet 35 | - * 2 -> 8 bytes from prefix - zeroes + 2 from packet 36 | - * 3 -> 8 bytes from prefix - infer 8 bytes from lladdr 37 | - */ 38 | -static const u8 lowpan_unc_ctxconf[] = {0x00, 0x88, 0x82, 0x80}; 39 | - 40 | -/* 41 | - * Uncompression of ctx-base 42 | - * 0 -> 0 bits from packet 43 | - * 1 -> 2 bytes from prefix - bunch of zeroes 5 from packet 44 | - * 2 -> 2 bytes from prefix - zeroes + 3 from packet 45 | - * 3 -> 2 bytes from prefix - infer 1 bytes from lladdr 46 | - */ 47 | -static const u8 lowpan_unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21}; 48 | - 49 | -/* Link local prefix */ 50 | -static const u8 lowpan_llprefix[] = {0xfe, 0x80}; 51 | - 52 | /* private device info */ 53 | struct lowpan_dev_info { 54 | struct net_device *real_dev; /* real WPAN device ptr */ 55 | @@ -191,55 +158,177 @@ lowpan_compress_addr_64(u8 **hc06_ptr, u8 shift, const struct in6_addr *ipaddr, 56 | return rol8(val, shift); 57 | } 58 | 59 | -static void 60 | -lowpan_uip_ds6_set_addr_iid(struct in6_addr *ipaddr, unsigned char *lladdr) 61 | +/* 62 | + * Uncompress address function for source and 63 | + * destination address(non-multicast). 64 | + * 65 | + * address_mode is sam value or dam value. 66 | + */ 67 | +static int 68 | +lowpan_uncompress_addr(struct sk_buff *skb, 69 | + struct in6_addr *ipaddr, 70 | + const u8 address_mode, 71 | + const struct ieee802154_addr *lladdr) 72 | { 73 | - memcpy(&ipaddr->s6_addr[8], lladdr, IEEE802154_ADDR_LEN); 74 | - /* second bit-flip (Universe/Local) is done according RFC2464 */ 75 | - ipaddr->s6_addr[8] ^= 0x02; 76 | + bool fail; 77 | + 78 | + switch (address_mode) { 79 | + case LOWPAN_IPHC_ADDR_00: 80 | + /* for global link addresses */ 81 | + fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); 82 | + break; 83 | + case LOWPAN_IPHC_ADDR_01: 84 | + /* fe:80::XXXX:XXXX:XXXX:XXXX */ 85 | + ipaddr->s6_addr[0] = 0xFE; 86 | + ipaddr->s6_addr[1] = 0x80; 87 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[8], 8); 88 | + break; 89 | + case LOWPAN_IPHC_ADDR_02: 90 | + /* fe:80::ff:fe00:XXXX */ 91 | + ipaddr->s6_addr[0] = 0xFE; 92 | + ipaddr->s6_addr[1] = 0x80; 93 | + ipaddr->s6_addr[11] = 0xFF; 94 | + ipaddr->s6_addr[12] = 0xFE; 95 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[14], 2); 96 | + break; 97 | + case LOWPAN_IPHC_ADDR_03: 98 | + fail = false; 99 | + switch (lladdr->addr_type) { 100 | + case IEEE802154_ADDR_LONG: 101 | + /* fe:80::XXXX:XXXX:XXXX:XXXX 102 | + * \_________________/ 103 | + * hwaddr 104 | + */ 105 | + ipaddr->s6_addr[0] = 0xFE; 106 | + ipaddr->s6_addr[1] = 0x80; 107 | + memcpy(&ipaddr->s6_addr[8], lladdr->hwaddr, 108 | + IEEE802154_ADDR_LEN); 109 | + /* second bit-flip (Universe/Local) 110 | + * is done according RFC2464 111 | + */ 112 | + ipaddr->s6_addr[8] ^= 0x02; 113 | + break; 114 | + case IEEE802154_ADDR_SHORT: 115 | + /* fe:80::ff:fe00:XXXX 116 | + * \__/ 117 | + * short_addr 118 | + * 119 | + * Universe/Local bit is zero. 120 | + */ 121 | + ipaddr->s6_addr[0] = 0xFE; 122 | + ipaddr->s6_addr[1] = 0x80; 123 | + ipaddr->s6_addr[11] = 0xFF; 124 | + ipaddr->s6_addr[12] = 0xFE; 125 | + ipaddr->s6_addr16[7] = htons(lladdr->short_addr); 126 | + break; 127 | + default: 128 | + pr_debug("Invalid addr_type set\n"); 129 | + return -EINVAL; 130 | + } 131 | + break; 132 | + default: 133 | + pr_debug("Invalid address mode value: 0x%x\n", address_mode); 134 | + return -EINVAL; 135 | + } 136 | + 137 | + if (fail) { 138 | + pr_debug("Failed to fetch skb data\n"); 139 | + return -EIO; 140 | + } 141 | + 142 | + lowpan_raw_dump_inline(NULL, "Reconstructed ipv6 addr is:\n", 143 | + ipaddr->s6_addr, 16); 144 | + 145 | + return 0; 146 | } 147 | 148 | -/* 149 | - * Uncompress addresses based on a prefix and a postfix with zeroes in 150 | - * between. If the postfix is zero in length it will use the link address 151 | - * to configure the IP address (autoconf style). 152 | - * pref_post_count takes a byte where the first nibble specify prefix count 153 | - * and the second postfix count (NOTE: 15/0xf => 16 bytes copy). 154 | +/* Uncompress address function for source context 155 | + * based address(non-multicast). 156 | */ 157 | static int 158 | -lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr, 159 | - u8 const *prefix, u8 pref_post_count, unsigned char *lladdr) 160 | +lowpan_uncompress_context_based_src_addr(struct sk_buff *skb, 161 | + struct in6_addr *ipaddr, 162 | + const u8 sam) 163 | { 164 | - u8 prefcount = pref_post_count >> 4; 165 | - u8 postcount = pref_post_count & 0x0f; 166 | - 167 | - /* full nibble 15 => 16 */ 168 | - prefcount = (prefcount == 15 ? 16 : prefcount); 169 | - postcount = (postcount == 15 ? 16 : postcount); 170 | - 171 | - if (lladdr) 172 | - lowpan_raw_dump_inline(__func__, "linklocal address", 173 | - lladdr, IEEE802154_ADDR_LEN); 174 | - if (prefcount > 0) 175 | - memcpy(ipaddr, prefix, prefcount); 176 | - 177 | - if (prefcount + postcount < 16) 178 | - memset(&ipaddr->s6_addr[prefcount], 0, 179 | - 16 - (prefcount + postcount)); 180 | - 181 | - if (postcount > 0) { 182 | - memcpy(&ipaddr->s6_addr[16 - postcount], skb->data, postcount); 183 | - skb_pull(skb, postcount); 184 | - } else if (prefcount > 0) { 185 | - if (lladdr == NULL) 186 | - return -EINVAL; 187 | + switch (sam) { 188 | + case LOWPAN_IPHC_ADDR_00: 189 | + /* unspec address :: 190 | + * Do nothing, address is already :: 191 | + */ 192 | + break; 193 | + case LOWPAN_IPHC_ADDR_01: 194 | + /* TODO */ 195 | + case LOWPAN_IPHC_ADDR_02: 196 | + /* TODO */ 197 | + case LOWPAN_IPHC_ADDR_03: 198 | + /* TODO */ 199 | + netdev_warn(skb->dev, "SAM value 0x%x not supported\n", sam); 200 | + return -EINVAL; 201 | + default: 202 | + pr_debug("Invalid sam value: 0x%x\n", sam); 203 | + return -EINVAL; 204 | + } 205 | + 206 | + lowpan_raw_dump_inline(NULL, 207 | + "Reconstructed context based ipv6 src addr is:\n", 208 | + ipaddr->s6_addr, 16); 209 | + 210 | + return 0; 211 | +} 212 | + 213 | +/* Uncompress function for multicast destination address, 214 | + * when M bit is set. 215 | + */ 216 | +static int 217 | +lowpan_uncompress_multicast_daddr(struct sk_buff *skb, 218 | + struct in6_addr *ipaddr, 219 | + const u8 dam) 220 | +{ 221 | + bool fail; 222 | + 223 | + switch (dam) { 224 | + case LOWPAN_IPHC_DAM_00: 225 | + /* 00: 128 bits. The full address 226 | + * is carried in-line. 227 | + */ 228 | + fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16); 229 | + break; 230 | + case LOWPAN_IPHC_DAM_01: 231 | + /* 01: 48 bits. The address takes 232 | + * the form ffXX::00XX:XXXX:XXXX. 233 | + */ 234 | + ipaddr->s6_addr[0] = 0xFF; 235 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); 236 | + fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[11], 5); 237 | + break; 238 | + case LOWPAN_IPHC_DAM_10: 239 | + /* 10: 32 bits. The address takes 240 | + * the form ffXX::00XX:XXXX. 241 | + */ 242 | + ipaddr->s6_addr[0] = 0xFF; 243 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1); 244 | + fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[13], 3); 245 | + break; 246 | + case LOWPAN_IPHC_DAM_11: 247 | + /* 11: 8 bits. The address takes 248 | + * the form ff02::00XX. 249 | + */ 250 | + ipaddr->s6_addr[0] = 0xFF; 251 | + ipaddr->s6_addr[1] = 0x02; 252 | + fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[15], 1); 253 | + break; 254 | + default: 255 | + pr_debug("DAM value has a wrong value: 0x%x\n", dam); 256 | + return -EINVAL; 257 | + } 258 | 259 | - /* no IID based configuration if no prefix and no data */ 260 | - lowpan_uip_ds6_set_addr_iid(ipaddr, lladdr); 261 | + if (fail) { 262 | + pr_debug("Failed to fetch skb data\n"); 263 | + return -EIO; 264 | } 265 | 266 | - pr_debug("uncompressing %d + %d => ", prefcount, postcount); 267 | - lowpan_raw_dump_inline(NULL, NULL, ipaddr->s6_addr, 16); 268 | + lowpan_raw_dump_inline(NULL, "Reconstructed ipv6 multicast addr is:\n", 269 | + ipaddr->s6_addr, 16); 270 | 271 | return 0; 272 | } 273 | @@ -702,6 +791,12 @@ lowpan_alloc_new_frame(struct sk_buff *skb, u16 len, u16 tag) 274 | skb_reserve(frame->skb, sizeof(struct ipv6hdr)); 275 | skb_put(frame->skb, frame->length); 276 | 277 | + /* copy the first control block to keep a 278 | + * trace of the link-layer addresses in case 279 | + * of a link-local compressed address 280 | + */ 281 | + memcpy(frame->skb->cb, skb->cb, sizeof(skb->cb)); 282 | + 283 | init_timer(&frame->timer); 284 | /* time out is the same as for ipv6 - 60 sec */ 285 | frame->timer.expires = jiffies + LOWPAN_FRAG_TIMEOUT; 286 | @@ -723,9 +818,9 @@ frame_err: 287 | static int 288 | lowpan_process_data(struct sk_buff *skb) 289 | { 290 | - struct ipv6hdr hdr; 291 | + struct ipv6hdr hdr = {}; 292 | u8 tmp, iphc0, iphc1, num_context = 0; 293 | - u8 *_saddr, *_daddr; 294 | + const struct ieee802154_addr *_saddr, *_daddr; 295 | int err; 296 | 297 | lowpan_raw_dump_table(__func__, "raw skb data dump", skb->data, 298 | @@ -784,16 +879,26 @@ lowpan_process_data(struct sk_buff *skb) 299 | pr_debug("%s first fragment received for tag %d, " 300 | "begin packet reassembly", __func__, tag); 301 | frame = lowpan_alloc_new_frame(skb, len, tag); 302 | - if (!frame) 303 | + if (!frame){ 304 | + pr_debug("%s first fragment received for tag %d, " 305 | + "failed to allow new frame!! len: %d", __func__, tag,len); 306 | goto unlock_and_drop; 307 | + } 308 | } 309 | 310 | /* if payload fits buffer, copy it */ 311 | if (likely((offset * 8 + skb->len) <= frame->length)) 312 | skb_copy_to_linear_data_offset(frame->skb, offset * 8, 313 | skb->data, skb->len); 314 | - else 315 | + else { 316 | + pr_debug("%s it doesnt fit: offset: %d skb->len: %d frame->length: %d" 317 | + "(tag %d)", __func__, offset,skb->len,frame->length, tag); 318 | + 319 | goto unlock_and_drop; 320 | + } 321 | + 322 | + pr_debug("%s assembling: bytes_rcv: %d/%d len: %d" 323 | + "(tag %d)", __func__, frame->bytes_rcv,frame->length, skb->len, tag); 324 | 325 | frame->bytes_rcv += skb->len; 326 | 327 | @@ -828,8 +933,8 @@ lowpan_process_data(struct sk_buff *skb) 328 | if (lowpan_fetch_skb_u8(skb, &iphc1)) 329 | goto drop; 330 | 331 | - _saddr = mac_cb(skb)->sa.hwaddr; 332 | - _daddr = mac_cb(skb)->da.hwaddr; 333 | + _saddr = &mac_cb(skb)->sa; 334 | + _daddr = &mac_cb(skb)->da; 335 | 336 | pr_debug("iphc0 = %02x, iphc1 = %02x\n", iphc0, iphc1); 337 | 338 | @@ -885,10 +990,6 @@ lowpan_process_data(struct sk_buff *skb) 339 | break; 340 | /* Traffic Class and Flow Label are elided */ 341 | case 3: /* 11b */ 342 | - hdr.priority = 0; 343 | - hdr.flow_lbl[0] = 0; 344 | - hdr.flow_lbl[1] = 0; 345 | - hdr.flow_lbl[2] = 0; 346 | break; 347 | default: 348 | break; 349 | @@ -915,10 +1016,18 @@ lowpan_process_data(struct sk_buff *skb) 350 | /* Extract SAM to the tmp variable */ 351 | tmp = ((iphc1 & LOWPAN_IPHC_SAM) >> LOWPAN_IPHC_SAM_BIT) & 0x03; 352 | 353 | - /* Source address uncompression */ 354 | - pr_debug("source address stateless compression\n"); 355 | - err = lowpan_uncompress_addr(skb, &hdr.saddr, lowpan_llprefix, 356 | - lowpan_unc_llconf[tmp], skb->data); 357 | + if (iphc1 & LOWPAN_IPHC_SAC) { 358 | + /* Source address context based uncompression */ 359 | + pr_debug("SAC bit is set. Handle context based source address.\n"); 360 | + err = lowpan_uncompress_context_based_src_addr( 361 | + skb, &hdr.saddr, tmp); 362 | + } else { 363 | + /* Source address uncompression */ 364 | + pr_debug("source address stateless compression\n"); 365 | + err = lowpan_uncompress_addr(skb, &hdr.saddr, tmp, _saddr); 366 | + } 367 | + 368 | + /* Check on error of previous branch */ 369 | if (err) 370 | goto drop; 371 | 372 | @@ -931,23 +1040,14 @@ lowpan_process_data(struct sk_buff *skb) 373 | pr_debug("dest: context-based mcast compression\n"); 374 | /* TODO: implement this */ 375 | } else { 376 | - u8 prefix[] = {0xff, 0x02}; 377 | - 378 | - pr_debug("dest: non context-based mcast compression\n"); 379 | - if (0 < tmp && tmp < 3) { 380 | - if (lowpan_fetch_skb_u8(skb, &prefix[1])) 381 | - goto drop; 382 | - } 383 | - 384 | - err = lowpan_uncompress_addr(skb, &hdr.daddr, prefix, 385 | - lowpan_unc_mxconf[tmp], NULL); 386 | + err = lowpan_uncompress_multicast_daddr( 387 | + skb, &hdr.daddr, tmp); 388 | if (err) 389 | goto drop; 390 | } 391 | } else { 392 | pr_debug("dest: stateless compression\n"); 393 | - err = lowpan_uncompress_addr(skb, &hdr.daddr, lowpan_llprefix, 394 | - lowpan_unc_llconf[tmp], skb->data); 395 | + err = lowpan_uncompress_addr(skb, &hdr.daddr, tmp, _daddr); 396 | if (err) 397 | goto drop; 398 | } 399 | @@ -1016,15 +1116,26 @@ static int lowpan_set_address(struct net_device *dev, void *p) 400 | return 0; 401 | } 402 | 403 | +//static int lowpan_get_mac_header_length(struct sk_buff *skb) 404 | +//{ 405 | +// /* 406 | +// * Currently long addressing mode is supported only, so the overall 407 | +// * header size is 21: 408 | +// * FC SeqNum DPAN DA SA Sec 409 | +// * 2 + 1 + 2 + 8 + 8 + 0 = 21 410 | +// */ 411 | +// return 21; 412 | +//} 413 | + 414 | static int lowpan_get_mac_header_length(struct sk_buff *skb) 415 | { 416 | /* 417 | - * Currently long addressing mode is supported only, so the overall 418 | + * Currently long addressing mode is supported only, so the overall //FIXME 419 | * header size is 21: 420 | - * FC SeqNum DPAN DA SA Sec 421 | - * 2 + 1 + 2 + 8 + 8 + 0 = 21 422 | + * FC SeqNum DPAN DA SPAN SA Sec 423 | + * 2 + 1 + 2 + 8 + 2 + 8 + 0 = 23 424 | */ 425 | - return 21; 426 | + return 23; 427 | } 428 | 429 | static int 430 | @@ -1352,9 +1463,9 @@ static inline void lowpan_netlink_fini(void) 431 | } 432 | 433 | static int lowpan_device_event(struct notifier_block *unused, 434 | - unsigned long event, 435 | - void *ptr) 436 | + unsigned long event, void *ptr) 437 | { 438 | + //struct net_device *dev = netdev_notifier_info_to_dev(ptr); 439 | struct net_device *dev = ptr; 440 | LIST_HEAD(del_list); 441 | struct lowpan_dev_record *entry, *tmp; 442 | diff --git a/net/ieee802154/6lowpan.h b/net/ieee802154/6lowpan.h 443 | index 4b8f917..2869c05 100644 444 | --- a/net/ieee802154/6lowpan.h 445 | +++ b/net/ieee802154/6lowpan.h 446 | @@ -193,10 +193,12 @@ 447 | /* Values of fields within the IPHC encoding second byte */ 448 | #define LOWPAN_IPHC_CID 0x80 449 | 450 | +#define LOWPAN_IPHC_ADDR_00 0x00 451 | +#define LOWPAN_IPHC_ADDR_01 0x01 452 | +#define LOWPAN_IPHC_ADDR_02 0x02 453 | +#define LOWPAN_IPHC_ADDR_03 0x03 454 | + 455 | #define LOWPAN_IPHC_SAC 0x40 456 | -#define LOWPAN_IPHC_SAM_00 0x00 457 | -#define LOWPAN_IPHC_SAM_01 0x10 458 | -#define LOWPAN_IPHC_SAM_10 0x20 459 | #define LOWPAN_IPHC_SAM 0x30 460 | 461 | #define LOWPAN_IPHC_SAM_BIT 4 462 | @@ -230,4 +232,16 @@ 463 | dest = 16 bit inline */ 464 | #define LOWPAN_NHC_UDP_CS_P_11 0xF3 /* source & dest = 0xF0B + 4bit inline */ 465 | 466 | +static inline bool lowpan_fetch_skb(struct sk_buff *skb, 467 | + void *data, const unsigned int len) 468 | +{ 469 | + if (unlikely(!pskb_may_pull(skb, len))) 470 | + return true; 471 | + 472 | + skb_copy_from_linear_data(skb, data, len); 473 | + skb_pull(skb, len); 474 | + 475 | + return false; 476 | +} 477 | + 478 | #endif /* __6LOWPAN_H__ */ 479 | -- 480 | 1.8.3.2 481 | 482 | -------------------------------------------------------------------------------- /rpi-3.10.y/0001-Added-XBee-driver-support.patch: -------------------------------------------------------------------------------- 1 | From 6358907fdaf926ac6e975390358e29cabf325e0e Mon Sep 17 00:00:00 2001 2 | From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Taveira?= 3 | Date: Sun, 5 Jan 2014 16:12:15 +0000 4 | Subject: [PATCH 1/3] Added XBee driver support 5 | 6 | --- 7 | drivers/net/ieee802154/Kconfig | 4 + 8 | drivers/net/ieee802154/Makefile | 1 + 9 | drivers/net/ieee802154/xbee.c | 4539 +++++++++++++++++++++++++++++++++++++++ 10 | include/uapi/linux/tty.h | 1 + 11 | 4 files changed, 4545 insertions(+) 12 | create mode 100644 drivers/net/ieee802154/xbee.c 13 | 14 | diff --git a/drivers/net/ieee802154/Kconfig b/drivers/net/ieee802154/Kconfig 15 | index 08ae465..acc8eb8 100644 16 | --- a/drivers/net/ieee802154/Kconfig 17 | +++ b/drivers/net/ieee802154/Kconfig 18 | @@ -30,6 +30,10 @@ config IEEE802154_FAKELB 19 | This driver can also be built as a module. To do so say M here. 20 | The module will be called 'fakelb'. 21 | 22 | +config IEEE802154_XBEE 23 | + depends on IEEE802154_DRIVERS && MAC802154 24 | + tristate "Xbee UART driver" 25 | + 26 | config IEEE802154_AT86RF230 27 | depends on IEEE802154_DRIVERS && MAC802154 28 | tristate "AT86RF230/231 transceiver driver" 29 | diff --git a/drivers/net/ieee802154/Makefile b/drivers/net/ieee802154/Makefile 30 | index abb0c08..72899e3 100644 31 | --- a/drivers/net/ieee802154/Makefile 32 | +++ b/drivers/net/ieee802154/Makefile 33 | @@ -1,4 +1,5 @@ 34 | obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o 35 | obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o 36 | +obj-$(CONFIG_IEEE802154_XBEE) += xbee.o 37 | obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o 38 | obj-$(CONFIG_IEEE802154_MRF24J40) += mrf24j40.o 39 | diff --git a/drivers/net/ieee802154/xbee.c b/drivers/net/ieee802154/xbee.c 40 | new file mode 100644 41 | index 0000000..ec349fd 42 | --- /dev/null 43 | +++ b/drivers/net/ieee802154/xbee.c 44 | @@ -0,0 +1,4539 @@ 45 | +/* 46 | + * Xbee: XBee TTY for Xbee RF 868 OEM using 802.15.4 stack 47 | + * 48 | + * Authors: 49 | + * Joao Pedro Taveira 50 | + * 51 | + * This program is free software; you can redistribute it and/or 52 | + * modify it under the terms of the GNU General Public License 53 | + * as published by the Free Software Foundation; either version 54 | + * 2 of the License, or (at your option) any later version. 55 | + */ 56 | + 57 | +/** 58 | + * @file main.c 59 | + * 60 | + * @date Jun 25, 2013 61 | + * @author Joao Pedro Taveira 62 | + */ 63 | + 64 | + 65 | +#ifndef __KERNEL__ 66 | +#include 67 | +#include 68 | +#include 69 | +#include 70 | +#include 71 | +#include 72 | +#include 73 | +#include 74 | +#include 75 | +#include 76 | + 77 | +#include 78 | +#include 79 | +#include 80 | + 81 | +#define BUG() do{exit(1);}while(0); 82 | + 83 | +#ifndef pr_fmt 84 | +#define pr_fmt(fmt) fmt 85 | +#endif 86 | + 87 | +#define KERN_EMERG "emerg: " /* system is unusable */ 88 | +#define KERN_ALERT "alert: " /* action must be taken immediately */ 89 | +#define KERN_CRIT "crit : " /* critical conditions */ 90 | +#define KERN_ERR "error: " /* error conditions */ 91 | +#define KERN_WARNING "warn : " /* warning conditions */ 92 | +#define KERN_NOTICE "notic: " /* normal but significant condition */ 93 | +#define KERN_INFO "info : " /* informational */ 94 | +#define KERN_DEBUG "debug: " /* debug-level messages */ 95 | + 96 | +#define printk printf 97 | + 98 | +#define pr_debug(fmt, ...) \ 99 | + printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) 100 | + 101 | +#define IEEE802154_ADDR_LEN 8 102 | + 103 | +typedef __signed__ char __s8; 104 | +typedef unsigned char __u8; 105 | + 106 | +typedef __signed__ short __s16; 107 | +typedef unsigned short __u16; 108 | + 109 | +typedef __signed__ int __s32; 110 | +typedef unsigned int __u32; 111 | + 112 | +#ifdef __GNUC__ 113 | +__extension__ typedef __signed__ long long __s64; 114 | +__extension__ typedef unsigned long long __u64; 115 | +#else 116 | +typedef __signed__ long long __s64; 117 | +typedef unsigned long long __u64; 118 | +#endif /* __GNUC__ */ 119 | + 120 | +/* 121 | + * Below are truly Linux-specific types that should never collide with 122 | + * any application/library that wants linux/types.h. 123 | + */ 124 | + 125 | +#ifdef __CHECKER__ 126 | +#define __bitwise__ __attribute__((bitwise)) 127 | +#else 128 | +#define __bitwise__ 129 | +#endif 130 | +#ifdef __CHECK_ENDIAN__ 131 | +#define __bitwise __bitwise__ 132 | +#else 133 | +#define __bitwise 134 | +#endif 135 | + 136 | +typedef __u16 __bitwise __le16; 137 | +typedef __u16 __bitwise __be16; 138 | +typedef __u32 __bitwise __le32; 139 | +typedef __u32 __bitwise __be32; 140 | +typedef __u64 __bitwise __le64; 141 | +typedef __u64 __bitwise __be64; 142 | + 143 | +typedef __u16 __bitwise __sum16; 144 | +typedef __u32 __bitwise __wsum; 145 | + 146 | +struct ieee802154_hw_addr_filt { 147 | + __le16 pan_id; /* Each independent PAN selects a unique 148 | + * identifier. This PAN id allows communication 149 | + * between devices within a network using short 150 | + * addresses and enables transmissions between 151 | + * devices across independent networks. 152 | + */ 153 | + __le16 short_addr; 154 | + uint8_t ieee_addr[IEEE802154_ADDR_LEN]; 155 | + uint8_t pan_coord; 156 | +}; 157 | + 158 | +struct ieee802154_dev { 159 | + /* filled by the driver */ 160 | + int extra_tx_headroom; 161 | + uint32_t flags; 162 | + struct device *parent; 163 | + 164 | + /* filled by mac802154 core */ 165 | + struct ieee802154_hw_addr_filt hw_filt; 166 | + void *priv; 167 | + struct wpan_phy *phy; 168 | +}; 169 | + 170 | +#else 171 | +#include 172 | +#include 173 | +#include 174 | +#include 175 | +#include 176 | +#include 177 | +#include 178 | +#include 179 | +#include 180 | +#include 181 | +#include 182 | + 183 | +#define MAX_DATA_SIZE 127 184 | + 185 | +#endif /* __KERNEL__ */ 186 | + 187 | +/* 188 | + * API Operation 189 | + * 190 | + * Start Del 1B Len 2-3B Bytes 4-n Byte n+1 191 | + * +------------+ +-----+------+ +------------+ +------------+ 192 | + * | 0x7E | | MSB | LSB | |API-specifc | | ChkSum 1B | 193 | + * +------------+ +-----+------+ +------------+ +------------+ 194 | + * 195 | + * Escape characters. When sending or receiving a UART data frame, 196 | + * specific data values must be escaped (flagged) so they do not 197 | + * interfere with the data frame sequencing. To escape an 198 | + * interfering data byte, insert 0x7D and follow it with the byte 199 | + * to be escaped XOR’d with 0x20. 200 | + * 201 | + * Data bytes that need to be escaped: 202 | + * 0x7E – Frame Delimiter 203 | + * 0x7D – Escape 204 | + * 0x11 – XON 205 | + * 0x13 – XOFF 206 | + * Example - Raw UART Data Frame (before escaping interfering bytes):  207 | + * 0x7E 0x00 0x02 0x23 0x11 0xCB 208 | + * 0x11 needs to be escaped which results in the following frame:  209 | + * 0x7E 0x00 0x02 0x23 0x7D 0x31 0xCB 210 | + * Note: In the above example, the length of the raw data (excluding 211 | + * the checksum) is 0x0002 and the checksum of the non-escaped data 212 | + * (excluding frame delimiter and length) is calculated as: 213 | + * 0xFF - (0x23 + 0x11) = (0xFF - 0x34) = 0xCB. 214 | + * 215 | + * Length 216 | + * The length field has two-byte value that specifies the number of 217 | + * bytes that will be contained in the frame data field. It does not 218 | + * include the checksum field. 219 | + */ 220 | + 221 | +#define XBEE_SYSFS_STATS 1 222 | + 223 | +#define XBEE_START_DELIM 0x7E 224 | +#define XBEE_ESCAPE 0x7D 225 | +#define XBEE_XON 0x11 226 | +#define XBEE_XOFF 0x13 227 | + 228 | +#define XBEE_ADDR_LEN 8 229 | +#define XBEE_DEFAULT_BROADCAST_RADIUS 1 230 | + 231 | +#define XBEE_MAX_FRAME_ID 0x3F /* 0011 1111 mask */ 232 | +#define XBEE_TRANSMIT_SPLITTED 0x80 /* 1000 0000 mask */ 233 | +#define XBEE_TRANSMIT_PART2 0x40 /* 0100 0000 mask */ 234 | + 235 | +//typedef enum mode { 236 | +// MODE_IDLE, 237 | +// MODE_RX, 238 | +// MODE_TX, 239 | +// MODE_CMD, 240 | +// MODE_SLEEP 241 | +//} xbee_pro_mode_t; 242 | + 243 | +typedef enum recv_state { 244 | + RECV_STATE_WAIT_START_DELIM, 245 | + RECV_STATE_WAIT_MSB, 246 | + RECV_STATE_WAIT_LSB, 247 | + RECV_STATE_WAIT_DATA, 248 | + RECV_STATE_WAIT_CHECKSUM 249 | +} xbee_recv_state_t; 250 | + 251 | +enum motes { 252 | + NOT_SUPPORTED_MOTE = -1, 253 | + UNKNOWN_MOTE = 0, 254 | + XBEE_XB08_DP_MOTE = 1, 255 | + HM_TRP_433D_MOTE, 256 | + HM_TRP_868D_MOTE, 257 | + MAX_MOTE 258 | +}; 259 | + 260 | +struct xbee_device { 261 | + /* Relative devices */ 262 | +#ifdef __KERNEL__ 263 | + struct tty_struct *tty; 264 | + struct ieee802154_dev *dev; 265 | + int device_driver; 266 | +#else 267 | + int tty_fd; 268 | + const char *tty_path; 269 | +#endif 270 | + 271 | +#ifdef __KERNEL__ 272 | + struct mutex mutex; 273 | +#else 274 | + pthread_mutex_t mutex; 275 | +#endif /* __KERNEL__ */ 276 | + uint8_t frame_id_counter; 277 | + 278 | + int escaped_mode; 279 | +// xbee_pro_mode_t mode; 280 | + 281 | + /* Command (rx) processing */ 282 | + uint16_t recv_data_size; 283 | + unsigned int recv_data_offset; 284 | + int recv_data_escape_next; 285 | + uint8_t *recv_data; 286 | + int recv_state; 287 | + uint8_t recv_data_sum; 288 | + 289 | + wait_queue_head_t wq; 290 | + struct workqueue_struct *frames_workqueue; 291 | + 292 | +#ifndef __KERNEL__ 293 | + int rx_thread_running; 294 | + int rx_thread_end; 295 | + pthread_t rx_thread_tid; 296 | +#endif /* !__KERNEL__ */ 297 | + 298 | + u8 dev_addr[IEEE802154_ADDR_LEN]; 299 | + u16 pan_id; 300 | + //u8 rf_max_payload; 301 | + 302 | +}; 303 | + 304 | +static u8 global_lqi = 0; 305 | + 306 | +#define FRAME_TYPE_AT_CMD 0x08 307 | +#define FRAME_TYPE_AT_CMD_QUEUE 0x09 308 | +#define FRAME_TYPE_TRANSMIT_REQ 0x10 309 | +#define FRAME_TYPE_EXPLICIT_ADDR_CMD 0x11 310 | +#define FRAME_TYPE_REMOTE_AT_CMD_REQ 0x17 311 | +#define FRAME_TYPE_AT_CMD_RESP 0x88 312 | +#define FRAME_TYPE_TRANSMIT_STATUS2 0x89 313 | +#define FRAME_TYPE_MODEM_STATUS 0x8A 314 | +#define FRAME_TYPE_TRANSMIT_STATUS1 0x8B 315 | +#define FRAME_TYPE_RECEIVE_PACKET 0x90 316 | +#define FRAME_TYPE_EXPLICIT_RX_INDICATOR 0x91 317 | +#define FRAME_TYPE_NODE_ID_INDICATOR 0x95 318 | +#define FRAME_TYPE_REMOTE_CMD_RESP 0x97 319 | + 320 | +#define FRAME_TYPE_RAW_TRANSMIT_REQ 0x20 /* simple RAW packet */ 321 | +#define FRAME_TYPE_RAW_RECEIVE FRAME_TYPE_RAW_TRANSMIT_REQ 322 | +#define FRAME_TYPE_RAW_TRANSMIT_STATUS 0xA0 /* RAW packet send completion */ 323 | + 324 | +#define TRANSMIT_OPTION_DISABLE_ACK(x) (x | 0x01) 325 | +#define TRANSMIT_OPTION_ENABLE_ACK(x) (x & ~0x01) 326 | + 327 | +#define TRANSMIT_OPTION_DISABLE_ROUTE_DISCOVERY(x) (x | 0x02) 328 | +#define TRANSMIT_OPTION_ENABLE_ROUTE_DISCOVERY(x) (x & ~0x02) 329 | + 330 | +typedef char at_command_t[2]; 331 | +typedef char at_command_param_t[4]; 332 | + 333 | +typedef struct api_generic { 334 | + uint8_t api_id; 335 | +} api_frame_generic_t; 336 | + 337 | +typedef struct at_cmd { 338 | + uint8_t api_id; 339 | + uint8_t frame_id; 340 | + at_command_t at_command; 341 | + at_command_param_t parameter_value; 342 | + uint8_t parameter_value_len; 343 | +} api_frame_at_cmd_t; 344 | + 345 | +typedef struct at_cmd_queue { 346 | + uint8_t api_id; 347 | + uint8_t frame_id; 348 | + at_command_t at_command; 349 | + at_command_param_t parameter_value; 350 | + uint8_t parameter_value_len; 351 | +} api_frame_at_cmd_queue_t; 352 | + 353 | +typedef struct transmit_req { 354 | + uint8_t api_id; 355 | + uint8_t frame_id; 356 | + uint8_t dst_addr[XBEE_ADDR_LEN]; // 0x000000000000FFFF - Broadcast address 357 | + uint16_t reserved; // 0xFFFE 358 | + uint8_t brd_radius; 359 | + uint8_t options; // bit 0: disable ACK bit 1: Dont Attempt route Disc 360 | + uint8_t *payload; 361 | + uint8_t payload_len; 362 | +} api_frame_transmit_req_t; 363 | + 364 | +typedef struct raw_packet { 365 | + uint8_t api_id; 366 | + union { 367 | + uint8_t frame_id; 368 | + uint8_t lqi; 369 | + }; 370 | + uint8_t *payload; 371 | + uint8_t payload_len; 372 | +} api_frame_raw_packet_t; 373 | + 374 | +typedef struct explicit_addr_cmd { 375 | + uint8_t api_id; 376 | + uint8_t frame_id; 377 | + uint8_t dst_addr[XBEE_ADDR_LEN]; // 0x000000000000FFFF - Broadcast address 378 | + uint16_t reserved; // 0xFFFE 379 | + uint8_t src_endpoint; 380 | + uint8_t dst_endpoint; 381 | + uint16_t cluster_id; 382 | + uint16_t profile_id; 383 | + uint8_t brd_radius; 384 | + uint8_t options; // bit 0: disable ACK bit 1: Dont Attempt route Disc 385 | + uint8_t *payload; 386 | + uint8_t payload_len; 387 | +} api_frame_explicit_addr_cmd_t; 388 | + 389 | +typedef struct remote_at_cmd_req { 390 | + uint8_t api_id; 391 | + uint8_t frame_id; 392 | + uint8_t dst_addr[XBEE_ADDR_LEN]; // 0x000000000000FFFF - Broadcast address 393 | + uint16_t reserved; // 0xFFFE 394 | + uint8_t remote_options; // 0x02 - Apply changes on remote. (If not set, AC command must be sent before changes will take effect.) All other bits must be set to 0. 395 | + at_command_t at_command; 396 | + at_command_param_t parameter_value; 397 | + uint8_t parameter_value_len; 398 | +} api_frame_remote_at_cmd_req_t; 399 | + 400 | +typedef struct at_cmd_resp { 401 | + uint8_t api_id; 402 | + uint8_t frame_id; 403 | + at_command_t at_command; 404 | + uint8_t cmd_status; // 0 = OK; 1 = ERROR; 2 = Invalid Command; 3 = Invalid Parameter 405 | + at_command_param_t cmd_data; 406 | + uint8_t cmd_data_len; 407 | +} api_frame_at_cmd_resp_t; 408 | + 409 | +typedef struct modem_status { 410 | + uint8_t api_id; 411 | + uint8_t status; 412 | + // 0x00: Hardware reset 413 | + // 0x01: Watchdog timer reset 414 | + // 0x0B: Network woke up 415 | + // 0x0C: Network went to sleep 416 | +} api_frame_modem_status_t; 417 | + 418 | +typedef struct transmit_status { 419 | + uint8_t api_id; 420 | + uint8_t frame_id; 421 | + uint16_t reserved; // 0xFFFE 422 | + uint8_t transmit_retry_count; // #transmission retries took place 423 | + uint8_t delivery_status; 424 | + // 0x00 = Success 425 | + // 0x01 = MAC ACK Failure 426 | + // 0x15 = Invalid destination endpoint 427 | + // 0x21 = Network ACK Failure 428 | + // 0x25 = Route Not Found 429 | + uint8_t discovery_status; 430 | + // 0x00 = No Discovery Overhead 431 | + // 0x02 = Route Discovery 432 | +} api_frame_transmit_status1_t; 433 | + 434 | +typedef struct transmit_status2 { 435 | + uint8_t api_id; 436 | + uint8_t frame_id; 437 | + uint8_t delivery_status; 438 | + // 0x00 - Success, no errors were detected on transmission. 439 | + // 0x01 - An expected MAC acknowledgment never occurred. 440 | + // 0x02 - CCA failure. 441 | + // 0x03 - Transmission was purged because it was attempted before the stack was up. 442 | + // 0x04 - Physical error occurred on the interface with the WiFi transceiver. 443 | + // 0x18 - No Buffers. 444 | + // 0x03 - Packet was purged without being transmitted. 445 | + // 0x21 - An expected network acknowledgment never occurred. 446 | + // 0x22 - Not joined to network. 447 | + // 0x23 - Self-addressed. 448 | + // 0x24 - Address not found. 449 | + // 0x25 - Route not found. 450 | + // 0x26 - Broadcast relay was not heard. 451 | + // 0x2B - Invalid Binding Table Index. 452 | + // 0x2C - Invalid Endpoint. 453 | + // 0x31 - A software error occurred. 454 | + // 0x32 - Resource Error. 455 | + // 0x74 - Data payload too large. 456 | + // 0x76 - Attempt to create a client socket failed. 457 | + // 0xBB - Key not authorized. 458 | +} api_frame_transmit_status2_t; 459 | + 460 | +typedef struct raw_transmit_status { 461 | + uint8_t api_id; 462 | + uint8_t frame_id; 463 | + uint8_t retries; 464 | + uint8_t delivery_status; 465 | +} api_frame_raw_transmit_status_t; 466 | + 467 | +typedef struct receive_packet { 468 | + uint8_t api_id; 469 | + uint8_t src_addr[XBEE_ADDR_LEN]; 470 | + uint16_t reserved; // 0xFFFE 471 | + uint8_t options; // 0x01 - Packet Acknowledged; 0x02 - Packet was a broadcast packet 472 | + uint8_t *payload; 473 | + uint8_t payload_len; 474 | +} api_frame_receive_packet_t; 475 | + 476 | +typedef struct explicit_rx_indicator { 477 | + uint8_t api_id; 478 | + uint8_t src_addr[XBEE_ADDR_LEN]; 479 | + uint16_t reserved; // 0xFFFE 480 | + uint8_t src_endpoint; 481 | + uint8_t dst_endpoint; 482 | + uint16_t cluster_id; 483 | + uint16_t profile_id; 484 | + uint8_t options; // 0x01 - Packet Acknowledged; 0x02 - Packet was a broadcast packet 485 | + uint8_t *payload; 486 | + uint8_t payload_len; 487 | +} api_frame_explicit_rx_indicator_t; 488 | + 489 | +typedef struct node_id_indicator { 490 | + uint8_t api_id; 491 | + uint8_t sender_addr[XBEE_ADDR_LEN]; // 64bit addr sender 492 | + uint16_t sender_short_addr; // 16bit addr senders 493 | + uint8_t options; // 0x01 - Packet Acknowledged; 0x02 - Packet was a broadcast packet 494 | + uint16_t src_short_addr; // Set to the 16-bit network address of the remote. Set to 0xFFFE if unknown. 495 | + uint8_t src_addr[XBEE_ADDR_LEN]; 496 | + unsigned char *ni_string; 497 | + uint16_t parent_short_addr; 498 | +} api_frame_node_id_indicator_t; 499 | + 500 | +typedef struct remote_cmd_resp { 501 | + uint8_t api_id; 502 | + uint8_t frame_id; 503 | + uint8_t src_addr[XBEE_ADDR_LEN]; 504 | + uint16_t reserved; // 0xFFFE 505 | + at_command_t at_command; 506 | + uint8_t cmd_status; // 0 = OK; 1 = ERROR; 2 = Invalid Command; 3 = Invalid Parameter 507 | + at_command_param_t cmd_data; 508 | + uint8_t cmd_data_len; 509 | +} api_frame_remote_cmd_resp_t; 510 | + 511 | +typedef struct xbee_api_frame { 512 | + uint16_t len; 513 | + uint8_t api_id; 514 | + uint8_t *raw_data; 515 | + union api_cmd_data_union { 516 | + api_frame_generic_t api_generic; 517 | + api_frame_at_cmd_t at_cmd; 518 | + api_frame_at_cmd_queue_t at_cmd_queue; 519 | + api_frame_transmit_req_t transmit_req; 520 | + api_frame_explicit_addr_cmd_t explitcit_addr_cmd; 521 | + api_frame_remote_at_cmd_req_t remote_at_cmd_req; 522 | + api_frame_at_cmd_resp_t at_cmd_resp; 523 | + api_frame_modem_status_t modem_status; 524 | + api_frame_transmit_status1_t transmit_status; 525 | + api_frame_transmit_status2_t transmit_status2; 526 | + api_frame_receive_packet_t receive_packet; 527 | + api_frame_explicit_rx_indicator_t explicit_rx_indicator; 528 | + api_frame_node_id_indicator_t node_id_indicator; 529 | + api_frame_remote_cmd_resp_t remote_cmd_resp; 530 | + 531 | + api_frame_raw_packet_t raw_packet; 532 | + api_frame_raw_transmit_status_t raw_transmit_status; 533 | + } *api_data; 534 | + uint8_t checksum; 535 | + 536 | +#ifdef __KERNEL__ 537 | + struct completion complete; 538 | + struct mutex mutex; 539 | +#else 540 | + pthread_cond_t complete; 541 | + pthread_mutex_t mutex; 542 | +#endif 543 | + struct xbee_api_frame *response; 544 | + 545 | +} _api_frame_t; 546 | + 547 | +/* 548 | + * TTY Helpers 549 | + */ 550 | + 551 | +#ifndef __KERNEL__ 552 | + 553 | +/* 554 | + * functions from: 555 | + * http://stackoverflow.com/questions/6947413/how-to-open-read-and-write-from-serial-port-in-c 556 | + */ 557 | + 558 | +static int set_interface_attribs(int fd, int speed, int parity) { 559 | + struct termios tty; 560 | + memset(&tty, 0, sizeof tty); 561 | + if (tcgetattr(fd, &tty) != 0) { 562 | + printk(KERN_ERR "%s(): error %d from tcgetattr", __func__, errno); 563 | + return -1; 564 | + } 565 | + 566 | + cfsetospeed(&tty, speed); 567 | + cfsetispeed(&tty, speed); 568 | + 569 | + tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit chars 570 | + // disable IGNBRK for mismatched speed tests; otherwise receive break 571 | + // as \000 chars 572 | + tty.c_iflag &= ~IGNBRK; // ignore break signal 573 | + tty.c_lflag = 0; // no signaling chars, no echo, 574 | + // no canonical processing 575 | + tty.c_oflag = 0; // no remapping, no delays 576 | + tty.c_cc[VMIN] = 0; // read doesn't block 577 | + tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout 578 | + 579 | + tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl 580 | + 581 | + tty.c_cflag |= (CLOCAL | CREAD); // ignore modem controls, 582 | + // enable reading 583 | + tty.c_cflag &= ~(PARENB | PARODD); // shut off parity 584 | + tty.c_cflag |= parity; 585 | + tty.c_cflag &= ~CSTOPB; 586 | + tty.c_cflag &= ~CRTSCTS; 587 | + 588 | + if (tcsetattr(fd, TCSANOW, &tty) != 0) { 589 | + printk(KERN_ERR "%s(): error %d from tcsetattr", __func__, errno); 590 | + return -1; 591 | + } 592 | + return 0; 593 | +} 594 | + 595 | +static void 596 | +set_blocking (int fd, int should_block) 597 | +{ 598 | + struct termios tty; 599 | + memset(&tty, 0, sizeof tty); 600 | + if (tcgetattr(fd, &tty) != 0) { 601 | + printk(KERN_ERR "%s(): error %d from tggetattr", __func__, errno); 602 | + return; 603 | + } 604 | + 605 | + tty.c_cc[VMIN] = should_block ? 1 : 0; 606 | + tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout 607 | + 608 | + if (tcsetattr(fd, TCSANOW, &tty) != 0) 609 | + printk(KERN_ERR "%s(): error %d setting term attributes", __func__, 610 | + errno); 611 | +} 612 | + 613 | + 614 | +/* 615 | + * XBee Dev helpers 616 | + */ 617 | +static 618 | +struct xbee_device *xbee_device_new() 619 | +{ 620 | + struct xbee_device *xbee_dev; 621 | +#ifdef __KERNEL__ 622 | + xbee_dev = kzalloc(sizeof(struct xbee_device),GFP_KERNEL); 623 | +#else 624 | + xbee_dev = calloc(1,sizeof(struct xbee_device)); 625 | +#endif 626 | + if(!xbee_dev) 627 | + { 628 | + printk(KERN_ERR "%s(): unable to allocate memory\n", __func__); 629 | + BUG(); 630 | + } 631 | + xbee_dev->escaped_mode = 1; 632 | + xbee_dev->frame_id_counter = 1; 633 | + xbee_dev->recv_state = RECV_STATE_WAIT_START_DELIM; 634 | +// xbee_dev->rf_max_payload = 100; 635 | + 636 | +#ifdef __KERNEL__ 637 | + mutex_init(&xbee_dev->mutex); 638 | +#else 639 | + pthread_mutex_init(&xbee_dev->mutex,NULL); 640 | +#endif 641 | + 642 | + return xbee_dev; 643 | +} 644 | + 645 | +static 646 | +void xbee_device_release(struct xbee_device *xbee_dev) 647 | +{ 648 | + if(!xbee_dev) 649 | + { 650 | + printk(KERN_ERR "%s: xbee_dev NULL pointer\n", __func__); 651 | + BUG(); 652 | + } 653 | + if(xbee_dev->recv_data) 654 | + { 655 | +#ifdef __KERNEL__ 656 | + kfree(xbee_dev->recv_data); 657 | +#else 658 | + free(xbee_dev->recv_data); 659 | +#endif 660 | + xbee_dev->recv_data = NULL; 661 | + } 662 | + 663 | +#ifndef __KERNEL__ 664 | + pthread_mutex_destroy(&xbee_dev->mutex); 665 | +#endif 666 | + 667 | +#ifndef __KERNEL__ 668 | + if(xbee_dev->tty_fd>0) 669 | + { 670 | + close(xbee_dev->tty_fd); 671 | + } 672 | +#endif 673 | + 674 | +#ifdef __KERNEL__ 675 | + kfree(xbee_dev); 676 | +#else 677 | + free(xbee_dev); 678 | +#endif 679 | + xbee_dev = NULL; 680 | +} 681 | + 682 | +#endif /* !__KERNEL__ */ 683 | + 684 | +#ifdef __KERNEL__ 685 | +#ifdef XBEE_SYSFS_STATS 686 | +typedef struct xbee_mac_stat { 687 | + int defined; 688 | + u8 addr[XBEE_ADDR_LEN]; 689 | + unsigned long last_update; // in jiffies 690 | + u8 last_lqi; 691 | +} xbee_mac_stat_t; 692 | + 693 | +#define XBEE_MOTE_MAXCOUNT 256 694 | +typedef struct xbee_mac_stats { 695 | + struct mutex mutex; 696 | + xbee_mac_stat_t mote[XBEE_MOTE_MAXCOUNT]; 697 | +} xbee_stats_t; 698 | + 699 | +static xbee_stats_t *stats = NULL; 700 | + 701 | +int xbee_addr_equals(u8 addr1[XBEE_ADDR_LEN], u8 addr2[XBEE_ADDR_LEN]) 702 | +{ 703 | + int i = 0; 704 | + for(i=0;imote[i]; 719 | + if(!mac_stat->defined) 720 | + { 721 | + memcpy(mac_stat->addr,addr, XBEE_ADDR_LEN); 722 | + mac_stat->defined = 1; 723 | + break; 724 | + } else if(xbee_addr_equals(addr,mac_stat->addr)){ 725 | + break; 726 | + } 727 | + } 728 | + return mac_stat; 729 | +} 730 | + 731 | +int xbee_stat_update_lqi(u8 addr[XBEE_ADDR_LEN], u8 lqi) 732 | +{ 733 | + xbee_mac_stat_t *mac_stat = NULL; 734 | + mutex_lock(&stats->mutex); 735 | + mac_stat = xbee_stat_get_unsafe(addr); 736 | + if(mac_stat) 737 | + { 738 | + mac_stat->last_lqi = lqi; 739 | + mac_stat->last_update = jiffies; 740 | + } 741 | + mutex_unlock(&stats->mutex); 742 | + return 0; 743 | +} 744 | + 745 | +static const char * 746 | +eui64_address_to_str(uint8_t addr[XBEE_ADDR_LEN],char eui64_addr_str[24]); 747 | + 748 | +#define XBEE_LQI_TABLE_MAX_LEN 4096 749 | + 750 | +static ssize_t 751 | +xbee_stat_get_lqi_table(char str[XBEE_LQI_TABLE_MAX_LEN]) 752 | +{ 753 | + ssize_t count = 0; 754 | + ssize_t len = 0; 755 | + int i = 0; 756 | + unsigned long now = jiffies; 757 | + unsigned long diff = 0; 758 | + xbee_mac_stat_t *mac_stat = NULL; 759 | + char eui64_addr_str[24] = {}; 760 | + mutex_lock(&stats->mutex); 761 | + for(i = 0;imote[i]; 764 | + if(mac_stat && mac_stat->defined) 765 | + { 766 | + diff = (long) now - (long) mac_stat->last_update; 767 | + count = sprintf(str+len,"%s\t%6ld ms\t%3d (0x%02X)\n",eui64_address_to_str(mac_stat->addr,eui64_addr_str),diff * 1000 / HZ, mac_stat->last_lqi,mac_stat->last_lqi); 768 | + len += count; 769 | + } 770 | + } 771 | + mutex_unlock(&stats->mutex); 772 | + return len; 773 | +} 774 | + 775 | +static int xbee_stats_init(void){ 776 | + stats = kzalloc(sizeof(xbee_stats_t),GFP_KERNEL); 777 | + if(!stats) 778 | + return -ENOMEM; 779 | + mutex_init(&stats->mutex); 780 | + return 0; 781 | +} 782 | + 783 | +static int xbee_stats_tini(void) { 784 | + if(stats) 785 | + kfree(stats); 786 | + return 0; 787 | +} 788 | + 789 | +#endif 790 | +#endif 791 | + 792 | +static uint8_t 793 | +_xbee_device_gen_frame_id(struct xbee_device *xbee_dev) 794 | +{ 795 | + uint8_t frame_id; 796 | + if(!xbee_dev) 797 | + return 0; 798 | +#ifdef __KERNEL__ 799 | + mutex_lock(&xbee_dev->mutex); 800 | +#else 801 | + pthread_mutex_lock(&xbee_dev->mutex); 802 | +#endif 803 | + frame_id = xbee_dev->frame_id_counter = (xbee_dev->frame_id_counter+1)%XBEE_MAX_FRAME_ID; 804 | + if(frame_id == 0) 805 | + { 806 | + frame_id = xbee_dev->frame_id_counter = 1; 807 | + } 808 | +#ifdef __KERNEL__ 809 | + mutex_unlock(&xbee_dev->mutex); 810 | +#else 811 | + pthread_mutex_unlock(&xbee_dev->mutex); 812 | +#endif 813 | + return frame_id; 814 | +} 815 | + 816 | + 817 | +static int escape_required(uint8_t c); 818 | + 819 | +#ifndef __KERNEL__ 820 | +static int 821 | +xbee_device_write_to_phy(struct xbee_device *xbee_dev, unsigned char *buf, unsigned int len) 822 | +{ 823 | + int i = 0; 824 | + uint8_t raw_byte = 0; 825 | + uint8_t escape_value = XBEE_ESCAPE; 826 | + unsigned char *raw_data = (unsigned char *) buf; 827 | + for(i = 0;i 2 && xbee_dev->escaped_mode && escape_required(raw_byte)) 830 | + { 831 | + //printf("%02X ",XBEE_ESCAPE); 832 | + write(xbee_dev->tty_fd,&escape_value,1); 833 | + raw_byte = raw_byte^0x20; 834 | + } 835 | + write(xbee_dev->tty_fd,&raw_byte,1); 836 | + //printf("%02X ",raw_byte); 837 | + } 838 | + printf("\n"); 839 | + return len; 840 | +} 841 | + 842 | +static int 843 | +xbee_device_init(struct xbee_device *xbee_dev) 844 | +{ 845 | + if(!xbee_dev) 846 | + { 847 | + printk(KERN_ERR "%s: xbee_dev NULL pointer\n", __func__); 848 | + BUG(); 849 | + } 850 | +#ifndef __KERNEL__ 851 | + if((xbee_dev->tty_fd = open(xbee_dev->tty_path,O_RDWR | O_NOCTTY | O_SYNC)) < 0) 852 | + { 853 | + printk(KERN_ERR "%s: error opening tty %s: %s\n", __func__, xbee_dev->tty_path,strerror(errno)); 854 | + return -1; 855 | + } 856 | + 857 | + set_interface_attribs (xbee_dev->tty_fd, B9600, 0); // set speed to 115,200 bps, 8n1 (no parity) 858 | + set_blocking (xbee_dev->tty_fd, 0); // set no blocking 859 | +#endif /* !__KERNEL__ */ 860 | + return 0; 861 | +} 862 | +#endif /* !__KERNEL__ */ 863 | + 864 | +#ifdef __KERNEL__ 865 | + 866 | +#define XBEE_FRAME_MAX_SIZE 255 867 | + 868 | +static struct mote_id { 869 | + int type; 870 | + u8 id[4]; 871 | + char *description; 872 | +} mote_ids[4] = { 873 | + { 874 | + .type = XBEE_XB08_DP_MOTE, 875 | + .id = {0x00,0x06,0x00,0x00}, 876 | + .description = "XBee 868 point to multi-point (868MHz for EU market)", 877 | + }, 878 | + { 879 | + .type = HM_TRP_433D_MOTE, 880 | + .id = {0xFF,0xFF,0x00,0x43}, 881 | + .description = "HM-TRP Series 100mW Transceiver modules (HM-TRP-433D)", 882 | + }, 883 | + { 884 | + .type = HM_TRP_868D_MOTE, 885 | + .id = {0xFF,0xFF,0x00,0x86}, 886 | + .description = "HM-TRP Series 100mW Transceiver modules (HM-TRP-868D)", 887 | + }, 888 | + { 889 | + .type = NOT_SUPPORTED_MOTE, 890 | + .id = {0x00,0x00,0x00,0x00}, 891 | + .description = "Not supported device", 892 | + }, 893 | +}; 894 | + 895 | +int mote_id_equals(u8 id1[4], u8 id2[4]){ 896 | + int i = 0; 897 | + for(i=0;i<4;i++){ 898 | + if(id1[i] != id2[i]) 899 | + return 0; 900 | + } 901 | + return 1; 902 | +} 903 | + 904 | +static int 905 | +xbee_api_at_command_read_u32(struct xbee_device *xbee_dev, const char cmdid[3], uint8_t value[4]); 906 | + 907 | +static int 908 | +xbee_device_get_type(struct xbee_device *xbee_dev){ 909 | + int mote_type = UNKNOWN_MOTE; 910 | + u8 mote_id[4] = {0}; 911 | + int i = 0; 912 | + int err = 0; 913 | + mutex_lock(&xbee_dev->mutex); 914 | + mote_type = xbee_dev->device_driver; 915 | + mutex_unlock(&xbee_dev->mutex); 916 | + if(mote_type != UNKNOWN_MOTE){ 917 | + return mote_type; 918 | + } 919 | + err = xbee_api_at_command_read_u32(xbee_dev,"DD",mote_id); 920 | + if(err) { 921 | + printk(KERN_ERR "%s: error getting device type\n", __func__); 922 | + return err; 923 | + } 924 | + else { 925 | + print_hex_dump_bytes("xbee_device_get_type(): device type: ", DUMP_PREFIX_NONE, mote_id, 4); 926 | + } 927 | + while(mote_type != NOT_SUPPORTED_MOTE){ 928 | + mote_type = mote_ids[i].type; 929 | + //printk(KERN_INFO "%s: checking type: %d: %s\n", __func__,mote_ids[i].type,mote_ids[i].description); 930 | + //print_hex_dump_bytes("xbee_device_get_type(): checking: ", DUMP_PREFIX_NONE, mote_ids[i].id, 4); 931 | + if(mote_id_equals(mote_ids[i].id,mote_id) || mote_type == NOT_SUPPORTED_MOTE){ 932 | + mutex_lock(&xbee_dev->mutex); 933 | + xbee_dev->device_driver = mote_type; 934 | + mutex_unlock(&xbee_dev->mutex); 935 | + printk(KERN_INFO "xbee: found mote: %s\n", mote_ids[i].description); 936 | + break; 937 | + } 938 | + i++; 939 | + } 940 | + return mote_type; 941 | +} 942 | + 943 | +static int 944 | +xbee_device_write_to_phy(struct xbee_device *xbee_dev, unsigned char *buf, unsigned int len){ 945 | + struct tty_struct *tty; 946 | + unsigned int sent = 0; 947 | + 948 | + int i = 0; 949 | + u8 raw_byte = 0; 950 | + u8 escape_value = XBEE_ESCAPE; 951 | + unsigned char *raw_data = (unsigned char *) buf; 952 | + 953 | + BUG_ON(!xbee_dev); 954 | + tty = xbee_dev->tty; 955 | + if (!tty) 956 | + return -ENODEV; 957 | + 958 | + /* Debug info */ 959 | + pr_debug("%s(): %d bytes frame\n", __func__, len); 960 | +#ifdef DEBUG 961 | + print_hex_dump_bytes("send_pending_data ", DUMP_PREFIX_NONE, 962 | + buf, len); 963 | +#endif 964 | + 965 | + pr_debug("%s(): sending %d\n", __func__,len); 966 | + for(i = 0;i 0 && xbee_dev->escaped_mode && escape_required(raw_byte)) 969 | + { 970 | + if (tty->driver->ops->write(tty, &escape_value,1) != 1) { 971 | + printk(KERN_ERR "%s: device write failed\n", __func__); 972 | + return -1; 973 | + } 974 | + raw_byte = raw_byte^0x20; 975 | + } 976 | + if (tty->driver->ops->write(tty, &raw_byte,1) != 1) { 977 | + printk(KERN_ERR "%s: device write failed\n", __func__); 978 | + return -1; 979 | + } 980 | + sent++; 981 | + } 982 | + return sent; 983 | +} 984 | +#endif /* __KERNEL__ */ 985 | + 986 | +static _api_frame_t *temporary_frames_list[1000] = {}; 987 | +static int 988 | +_api_frame_should_wait_response(_api_frame_t *api_frame); 989 | + 990 | +static int 991 | +xbee_device_add_pendent_req(struct xbee_device *xbee_dev, _api_frame_t *api_frame) 992 | +{ 993 | + int index = 0; 994 | + 995 | + if(xbee_dev == NULL) 996 | + { 997 | + printk(KERN_ERR "%s: xbee_dev NULL pointer\n", __func__); 998 | + BUG(); 999 | + } 1000 | + if(api_frame == NULL) 1001 | + { 1002 | + printk(KERN_ERR "%s: api_frame NULL pointer\n", __func__); 1003 | + BUG(); 1004 | + } 1005 | + 1006 | +#ifdef __KERNEL__ 1007 | + //if (mutex_lock_interruptible(&xbee_dev->mutex)) 1008 | + // return -EINTR; 1009 | + mutex_lock(&xbee_dev->mutex); 1010 | +#else 1011 | + if(pthread_mutex_lock(&xbee_dev->mutex)) 1012 | + return -EINTR; 1013 | +#endif 1014 | + 1015 | + index = _api_frame_should_wait_response(api_frame); 1016 | + temporary_frames_list[index] = api_frame; 1017 | + 1018 | +#ifdef __KERNEL__ 1019 | + mutex_unlock(&xbee_dev->mutex); 1020 | +#else 1021 | + pthread_mutex_unlock(&xbee_dev->mutex); 1022 | +#endif 1023 | + 1024 | + return 0; 1025 | +} 1026 | + 1027 | +static int 1028 | +xbee_device_remove_pendent_req(struct xbee_device *xbee_dev, _api_frame_t *api_frame) 1029 | +{ 1030 | + int index = 0; 1031 | + 1032 | + if(xbee_dev == NULL) 1033 | + { 1034 | + printk(KERN_ERR "%s: xbee_dev NULL pointer\n", __func__); 1035 | + BUG(); 1036 | + } 1037 | + if(api_frame == NULL) 1038 | + { 1039 | + printk(KERN_ERR "%s: api_frame NULL pointer\n", __func__); 1040 | + BUG(); 1041 | + } 1042 | + 1043 | + pr_debug("%s(): removing pendent req\n", __func__); 1044 | + 1045 | +#ifdef __KERNEL__ 1046 | + if (mutex_lock_interruptible(&xbee_dev->mutex)) 1047 | + return -EINTR; 1048 | +#else 1049 | + if(pthread_mutex_lock(&xbee_dev->mutex)) 1050 | + return -EINTR; 1051 | +#endif 1052 | + 1053 | + index = _api_frame_should_wait_response(api_frame); 1054 | + if(index) 1055 | + temporary_frames_list[index] = NULL; 1056 | + 1057 | +#ifdef __KERNEL__ 1058 | + mutex_unlock(&xbee_dev->mutex); 1059 | +#else 1060 | + pthread_mutex_unlock(&xbee_dev->mutex); 1061 | +#endif 1062 | + 1063 | + return 0; 1064 | +} 1065 | + 1066 | +static int 1067 | +_api_frame_should_signal_pendent(_api_frame_t *api_frame); 1068 | +static void 1069 | +_api_frame_print(_api_frame_t *api_frame); 1070 | + 1071 | +static int 1072 | +xbee_device_signal_pendent_req(struct xbee_device *xbee_dev, _api_frame_t *api_frame_response) 1073 | +{ 1074 | + int index = 0; 1075 | + _api_frame_t *api_frame_req = NULL; 1076 | + 1077 | + if(xbee_dev == NULL) 1078 | + { 1079 | + printk(KERN_ERR "%s: xbee_dev NULL pointer\n", __func__); 1080 | + BUG(); 1081 | + } 1082 | + if(api_frame_response == NULL) 1083 | + { 1084 | + printk(KERN_ERR "%s: api_frame NULL pointer\n", __func__); 1085 | + BUG(); 1086 | + } 1087 | + 1088 | +#ifdef __KERNEL__ 1089 | + if (mutex_lock_interruptible(&xbee_dev->mutex)) 1090 | + return -EINTR; 1091 | +#else 1092 | + if(pthread_mutex_lock(&xbee_dev->mutex)) 1093 | + return -EINTR; 1094 | +#endif 1095 | + 1096 | + index = _api_frame_should_signal_pendent(api_frame_response); 1097 | + api_frame_req = temporary_frames_list[index]; 1098 | + 1099 | + if(api_frame_req != NULL) 1100 | + { 1101 | + pr_debug("%s(): api_frame found...\n", __func__); 1102 | + _api_frame_print(api_frame_req); 1103 | +#ifndef __KERNEL__ 1104 | + pthread_mutex_lock(&api_frame_req->mutex); 1105 | +#endif 1106 | + api_frame_req->response = api_frame_response; 1107 | +#ifndef __KERNEL__ 1108 | + pthread_cond_signal(&api_frame_req->complete); 1109 | + pthread_mutex_unlock(&api_frame_req->mutex); 1110 | +#else 1111 | + complete(&api_frame_req->complete); 1112 | +#endif 1113 | + } 1114 | + else 1115 | + { 1116 | + printk(KERN_DEBUG "%s: api_frame NOT found: %d\n", __func__,index); 1117 | + } 1118 | + 1119 | + temporary_frames_list[index] = NULL; 1120 | + 1121 | +#ifdef __KERNEL__ 1122 | + mutex_unlock(&xbee_dev->mutex); 1123 | +#else 1124 | + pthread_mutex_unlock(&xbee_dev->mutex); 1125 | +#endif 1126 | + 1127 | + return 0; 1128 | +} 1129 | + 1130 | +/* 1131 | + * Debug helpers 1132 | + */ 1133 | + 1134 | +#ifdef DEBUG 1135 | +static const char * 1136 | +xbee_recv_state_str(int recv_state) 1137 | +{ 1138 | + switch(recv_state) 1139 | + { 1140 | + case RECV_STATE_WAIT_START_DELIM: 1141 | + return "RECV_STATE_WaitStartDelim"; 1142 | + break; 1143 | + case RECV_STATE_WAIT_MSB: 1144 | + return "RECV_STATE_WaitMSB"; 1145 | + break; 1146 | + case RECV_STATE_WAIT_LSB: 1147 | + return "RECV_STATE_WaitLSB"; 1148 | + break; 1149 | + case RECV_STATE_WAIT_DATA: 1150 | + return "RECV_STATE_WaitData"; 1151 | + break; 1152 | + case RECV_STATE_WAIT_CHECKSUM: 1153 | + return "RECV_STATE_WaitCheckSum"; 1154 | + break; 1155 | + default: 1156 | + return "RECV_STATE_Unknown"; 1157 | + break; 1158 | + } 1159 | + return "RECV_STATE_Unknown"; 1160 | +} 1161 | +#endif /* DEBUG */ 1162 | + 1163 | +static int 1164 | +at_command_get_parameter_len(_api_frame_t *api_frame) 1165 | +{ 1166 | + int at_parameter_len = 0; 1167 | + if(!api_frame) 1168 | + return 0; 1169 | + switch(api_frame->api_id){ 1170 | + case FRAME_TYPE_AT_CMD: 1171 | + at_parameter_len = api_frame->len-4; 1172 | + break; 1173 | + case FRAME_TYPE_AT_CMD_QUEUE: 1174 | + at_parameter_len = api_frame->len-4; 1175 | + break; 1176 | + case FRAME_TYPE_REMOTE_AT_CMD_REQ: 1177 | + at_parameter_len = api_frame->len-15; 1178 | + break; 1179 | + case FRAME_TYPE_AT_CMD_RESP: 1180 | + at_parameter_len = api_frame->len-5; 1181 | + break; 1182 | + case FRAME_TYPE_REMOTE_CMD_RESP: 1183 | + at_parameter_len = api_frame->len-15; 1184 | + break; 1185 | + default: 1186 | + return 0; 1187 | + } 1188 | + return at_parameter_len; 1189 | +} 1190 | + 1191 | +#ifdef DEBUG 1192 | +static const char * 1193 | +at_command_get_parameter_str(_api_frame_t *api_frame,char *str_aux) 1194 | +{ 1195 | + uint8_t *at_data = NULL; 1196 | + int wrote_bytes = 0; 1197 | + int at_parameter_len = 0; 1198 | + int i = 0; 1199 | + if(!api_frame) 1200 | + return ""; 1201 | + at_parameter_len = at_command_get_parameter_len(api_frame); 1202 | + switch(api_frame->api_id){ 1203 | + case FRAME_TYPE_AT_CMD: 1204 | + at_data = (uint8_t *) api_frame->api_data->at_cmd.parameter_value; 1205 | + break; 1206 | + case FRAME_TYPE_AT_CMD_QUEUE: 1207 | + at_data = (uint8_t *) api_frame->api_data->at_cmd_queue.parameter_value; 1208 | + break; 1209 | + case FRAME_TYPE_REMOTE_AT_CMD_REQ: 1210 | + at_data = (uint8_t *) api_frame->api_data->remote_at_cmd_req.parameter_value; 1211 | + break; 1212 | + case FRAME_TYPE_AT_CMD_RESP: 1213 | + at_data = (uint8_t *) api_frame->api_data->at_cmd_resp.cmd_data; 1214 | + break; 1215 | + case FRAME_TYPE_REMOTE_CMD_RESP: 1216 | + at_data = (uint8_t *) api_frame->api_data->remote_cmd_resp.cmd_data; 1217 | + break; 1218 | + default: 1219 | + return ""; 1220 | + } 1221 | + for(i=0;ilen = frame_len; 1268 | +#ifdef __KERNEL__ 1269 | + api_data = kzalloc(data_len,GFP_KERNEL); 1270 | +#else 1271 | + api_data = calloc(data_len,sizeof(uint8_t)); 1272 | +#endif 1273 | + if(!api_data) 1274 | + { 1275 | + printk(KERN_ERR "%s(): unable to allocate memory to api_data\n", __func__); 1276 | + _api_frame_free(api_frame); 1277 | + api_frame = NULL; 1278 | + BUG(); 1279 | + } 1280 | + 1281 | + api_frame->api_data = (union api_cmd_data_union*) api_data; 1282 | + 1283 | +#ifdef __KERNEL__ 1284 | + mutex_init(&api_frame->mutex); 1285 | +#else 1286 | + pthread_mutex_init(&api_frame->mutex,NULL); 1287 | +#endif 1288 | + 1289 | +#ifdef __KERNEL__ 1290 | + init_completion(&api_frame->complete); 1291 | +#else 1292 | + pthread_cond_init(&api_frame->complete,NULL); 1293 | +#endif 1294 | + 1295 | + api_frame->response = NULL; 1296 | + 1297 | + return api_frame; 1298 | +} 1299 | + 1300 | +static uint8_t * 1301 | +_api_frame_to_raw(_api_frame_t *api_frame, uint16_t *p_len) 1302 | +{ 1303 | + uint8_t *raw_data = NULL; 1304 | + uint8_t frame_sum = 0; 1305 | + int raw_offset = 0; 1306 | + int i = 0; 1307 | + uint16_t raw_data_len = 1 /* start delim */ + 2 /* 16 bit length */; 1308 | + if(!api_frame) 1309 | + { 1310 | + printk(KERN_ERR "%s(): invalid frame\n", __func__); 1311 | + BUG(); 1312 | + } 1313 | + if(!p_len) 1314 | + { 1315 | + printk(KERN_ERR "%s(): invalid len pointer\n", __func__); 1316 | + BUG(); 1317 | + } 1318 | + 1319 | + /* Compute buffer length */ 1320 | + switch(api_frame->api_id) 1321 | + { 1322 | + // Requests 1323 | + case FRAME_TYPE_AT_CMD: 1324 | + raw_data_len += 1 /* frame type */ + 1 /* frame id */ + 2 /* at command */; 1325 | + raw_data_len += api_frame->api_data->at_cmd.parameter_value_len; 1326 | + break; 1327 | + case FRAME_TYPE_AT_CMD_QUEUE: 1328 | + raw_data_len += 1 /* frame type */ + 1 /* frame id */ + 2 /* at command */; 1329 | + raw_data_len += api_frame->api_data->at_cmd_queue.parameter_value_len; 1330 | + break; 1331 | + case FRAME_TYPE_TRANSMIT_REQ: 1332 | + raw_data_len += 1 /* frame type */ + 1 /* frame id */; 1333 | + raw_data_len += 8 /* dst addr */ + 2 /* reserved */; 1334 | + raw_data_len += 1 /* bcast radius */ + 1 /* options */; 1335 | + raw_data_len += api_frame->api_data->transmit_req.payload_len; 1336 | + break; 1337 | + case FRAME_TYPE_RAW_TRANSMIT_REQ: 1338 | + raw_data_len += 1 /* frame type */ + 1 /* frame id */; 1339 | + raw_data_len += api_frame->api_data->raw_packet.payload_len; 1340 | + break; 1341 | + case FRAME_TYPE_EXPLICIT_ADDR_CMD: 1342 | + raw_data_len += 1 /* frame type */ + 1 /* frame id */; 1343 | + raw_data_len += 8 /* dst addr */ + 2 /* reserved */; 1344 | + raw_data_len += 1 /* src endpoint */ + 1 /* dst endpoint */; 1345 | + raw_data_len += 2 /* clusterID */ + 2 /* profile ID*/; 1346 | + raw_data_len += 1 /* bcast radius */ + 1 /* options */; 1347 | + raw_data_len += api_frame->api_data->explitcit_addr_cmd.payload_len; 1348 | + break; 1349 | + case FRAME_TYPE_REMOTE_AT_CMD_REQ: 1350 | + raw_data_len += 1 /* frame type */ + 1 /* frame id */; 1351 | + raw_data_len += 8 /* dst addr */ + 2 /* reserved */; 1352 | + raw_data_len += 1 /* remote command options */ + 2 /* at command */; 1353 | + raw_data_len += api_frame->api_data->remote_at_cmd_req.parameter_value_len; 1354 | + break; 1355 | + 1356 | + // Responses 1357 | + case FRAME_TYPE_AT_CMD_RESP: 1358 | + break; 1359 | + case FRAME_TYPE_MODEM_STATUS: 1360 | + break; 1361 | + case FRAME_TYPE_TRANSMIT_STATUS1: 1362 | + break; 1363 | + case FRAME_TYPE_TRANSMIT_STATUS2: 1364 | + break; 1365 | + case FRAME_TYPE_RAW_TRANSMIT_STATUS: 1366 | + break; 1367 | + case FRAME_TYPE_RECEIVE_PACKET: 1368 | + break; 1369 | + case FRAME_TYPE_EXPLICIT_RX_INDICATOR: 1370 | + break; 1371 | + case FRAME_TYPE_NODE_ID_INDICATOR: 1372 | + break; 1373 | + case FRAME_TYPE_REMOTE_CMD_RESP: 1374 | + break; 1375 | + default: 1376 | + printk(KERN_WARNING "%s(): Unknown Type (0x%02X)\n", __func__,api_frame->api_id); 1377 | + break; 1378 | + return NULL; 1379 | + } 1380 | + raw_data_len += 1 /* checksum */; 1381 | + 1382 | +#ifdef __KERNEL__ 1383 | + raw_data = kzalloc(raw_data_len*sizeof(uint8_t),GFP_KERNEL); 1384 | +#else 1385 | + raw_data = calloc(raw_data_len,sizeof(uint8_t)); 1386 | +#endif 1387 | + if(!raw_data) 1388 | + { 1389 | + printk(KERN_ERR "%s(): unable to allocate memory\n", __func__); 1390 | + return NULL; 1391 | + } 1392 | + 1393 | + *p_len = raw_data_len; 1394 | + 1395 | + raw_data[raw_offset++] = XBEE_START_DELIM; 1396 | + raw_data[raw_offset++] = (raw_data_len-4) >> 8 & 0xFF; 1397 | + raw_data[raw_offset++] = (raw_data_len-4) & 0xFF; 1398 | + 1399 | + /* Fill buffer */ 1400 | + switch(api_frame->api_id) 1401 | + { 1402 | + // Requests 1403 | + case FRAME_TYPE_AT_CMD: 1404 | + raw_data[raw_offset] = api_frame->api_data->at_cmd.api_id; 1405 | + frame_sum += raw_data[raw_offset++]; 1406 | + raw_data[raw_offset] = api_frame->api_data->at_cmd.frame_id; 1407 | + frame_sum += raw_data[raw_offset++]; 1408 | + raw_data[raw_offset] = api_frame->api_data->at_cmd.at_command[0]; 1409 | + frame_sum += raw_data[raw_offset++]; 1410 | + raw_data[raw_offset] = api_frame->api_data->at_cmd.at_command[1]; 1411 | + frame_sum += raw_data[raw_offset++]; 1412 | + for(i=0;iapi_data->at_cmd.parameter_value_len;i++) 1413 | + { 1414 | + raw_data[raw_offset] = api_frame->api_data->at_cmd.parameter_value[i]; 1415 | + frame_sum += raw_data[raw_offset++]; 1416 | + } 1417 | + break; 1418 | + case FRAME_TYPE_AT_CMD_QUEUE: 1419 | + raw_data[raw_offset] = api_frame->api_data->at_cmd_queue.api_id; 1420 | + frame_sum += raw_data[raw_offset++]; 1421 | + raw_data[raw_offset] = api_frame->api_data->at_cmd_queue.frame_id; 1422 | + frame_sum += raw_data[raw_offset++]; 1423 | + raw_data[raw_offset] = api_frame->api_data->at_cmd_queue.at_command[0]; 1424 | + frame_sum += raw_data[raw_offset++]; 1425 | + raw_data[raw_offset] = api_frame->api_data->at_cmd_queue.at_command[1]; 1426 | + frame_sum += raw_data[raw_offset++]; 1427 | + for(i=0;iapi_data->at_cmd_queue.parameter_value_len;i++) 1428 | + { 1429 | + raw_data[raw_offset] = api_frame->api_data->at_cmd_queue.parameter_value[i]; 1430 | + frame_sum += raw_data[raw_offset++]; 1431 | + } 1432 | + break; 1433 | + case FRAME_TYPE_TRANSMIT_REQ: 1434 | + raw_data[raw_offset] = api_frame->api_data->transmit_req.api_id; 1435 | + frame_sum += raw_data[raw_offset++]; 1436 | + raw_data[raw_offset] = api_frame->api_data->transmit_req.frame_id; 1437 | + frame_sum += raw_data[raw_offset++]; 1438 | + for(i=0;iapi_data->transmit_req.dst_addr[i]; 1441 | + frame_sum += raw_data[raw_offset++]; 1442 | + } 1443 | + raw_data[raw_offset] = api_frame->api_data->transmit_req.reserved >> 8 & 0xFF; 1444 | + frame_sum += raw_data[raw_offset++]; 1445 | + raw_data[raw_offset] = api_frame->api_data->transmit_req.reserved & 0xFF; 1446 | + frame_sum += raw_data[raw_offset++]; 1447 | + raw_data[raw_offset] = api_frame->api_data->transmit_req.brd_radius; 1448 | + frame_sum += raw_data[raw_offset++]; 1449 | + raw_data[raw_offset] = api_frame->api_data->transmit_req.options; 1450 | + frame_sum += raw_data[raw_offset++]; 1451 | + 1452 | + for(i=0;iapi_data->transmit_req.payload_len;i++) 1453 | + { 1454 | + raw_data[raw_offset] = api_frame->api_data->transmit_req.payload[i]; 1455 | + frame_sum += raw_data[raw_offset++]; 1456 | + } 1457 | + break; 1458 | + case FRAME_TYPE_RAW_TRANSMIT_REQ: 1459 | + raw_data[raw_offset] = api_frame->api_data->raw_packet.api_id; 1460 | + frame_sum += raw_data[raw_offset++]; 1461 | + raw_data[raw_offset] = api_frame->api_data->raw_packet.frame_id; 1462 | + frame_sum += raw_data[raw_offset++]; 1463 | + for(i=0;iapi_data->raw_packet.payload_len;i++) 1464 | + { 1465 | + raw_data[raw_offset] = api_frame->api_data->raw_packet.payload[i]; 1466 | + frame_sum += raw_data[raw_offset++]; 1467 | + } 1468 | + break; 1469 | + case FRAME_TYPE_EXPLICIT_ADDR_CMD: 1470 | + break; 1471 | + case FRAME_TYPE_REMOTE_AT_CMD_REQ: 1472 | + raw_data[raw_offset] = api_frame->api_data->remote_at_cmd_req.api_id; 1473 | + frame_sum += raw_data[raw_offset++]; 1474 | + raw_data[raw_offset] = api_frame->api_data->remote_at_cmd_req.frame_id; 1475 | + frame_sum += raw_data[raw_offset++]; 1476 | + for(i=0;iapi_data->remote_at_cmd_req.dst_addr[i]; 1479 | + frame_sum += raw_data[raw_offset++]; 1480 | + } 1481 | + raw_data[raw_offset] = api_frame->api_data->remote_at_cmd_req.reserved >> 8 & 0xFF; 1482 | + frame_sum += raw_data[raw_offset++]; 1483 | + raw_data[raw_offset] = api_frame->api_data->remote_at_cmd_req.reserved & 0xFF; 1484 | + frame_sum += raw_data[raw_offset++]; 1485 | + raw_data[raw_offset] = api_frame->api_data->remote_at_cmd_req.remote_options; 1486 | + frame_sum += raw_data[raw_offset++]; 1487 | + raw_data[raw_offset] = api_frame->api_data->remote_at_cmd_req.at_command[0]; 1488 | + frame_sum += raw_data[raw_offset++]; 1489 | + raw_data[raw_offset] = api_frame->api_data->remote_at_cmd_req.at_command[1]; 1490 | + frame_sum += raw_data[raw_offset++]; 1491 | + for(i=0;iapi_data->remote_at_cmd_req.parameter_value_len;i++) 1492 | + { 1493 | + raw_data[raw_offset] = api_frame->api_data->remote_at_cmd_req.parameter_value[i]; 1494 | + frame_sum += raw_data[raw_offset++]; 1495 | + } 1496 | + break; 1497 | + 1498 | + // Responses 1499 | + case FRAME_TYPE_AT_CMD_RESP: 1500 | + break; 1501 | + case FRAME_TYPE_MODEM_STATUS: 1502 | + break; 1503 | + case FRAME_TYPE_TRANSMIT_STATUS1: 1504 | + break; 1505 | + case FRAME_TYPE_TRANSMIT_STATUS2: 1506 | + break; 1507 | + case FRAME_TYPE_RAW_TRANSMIT_STATUS: 1508 | + break; 1509 | + case FRAME_TYPE_RECEIVE_PACKET: 1510 | + break; 1511 | + case FRAME_TYPE_EXPLICIT_RX_INDICATOR: 1512 | + break; 1513 | + case FRAME_TYPE_NODE_ID_INDICATOR: 1514 | + break; 1515 | + case FRAME_TYPE_REMOTE_CMD_RESP: 1516 | + break; 1517 | + default: 1518 | + printk(KERN_WARNING "%s(): Unknown Type (0x%02X)\n", __func__,api_frame->api_id); 1519 | +#ifdef __KERNEL__ 1520 | + kfree(raw_data); 1521 | +#else 1522 | + free(raw_data); 1523 | +#endif 1524 | + *p_len = 0; 1525 | + break; 1526 | + return NULL; 1527 | + } 1528 | + raw_data[raw_offset++] = 0xFF - frame_sum; 1529 | + 1530 | + return raw_data; 1531 | +} 1532 | + 1533 | +static int 1534 | +_api_frame_should_wait_response(_api_frame_t *api_frame) 1535 | +{ 1536 | + switch(api_frame->api_id) 1537 | + { 1538 | + // Requests 1539 | + case FRAME_TYPE_AT_CMD: 1540 | + if(api_frame->api_data->at_cmd.frame_id) 1541 | + return api_frame->api_data->at_cmd.frame_id; 1542 | + break; 1543 | + case FRAME_TYPE_AT_CMD_QUEUE: 1544 | + if(api_frame->api_data->at_cmd_queue.frame_id) 1545 | + return api_frame->api_data->at_cmd_queue.frame_id; 1546 | + break; 1547 | + case FRAME_TYPE_TRANSMIT_REQ: 1548 | + if(api_frame->api_data->transmit_req.frame_id) 1549 | + return api_frame->api_data->transmit_req.frame_id; 1550 | + break; 1551 | + case FRAME_TYPE_RAW_TRANSMIT_REQ: 1552 | + if(api_frame->api_data->raw_packet.frame_id) 1553 | + return api_frame->api_data->raw_packet.frame_id; 1554 | + break; 1555 | + case FRAME_TYPE_EXPLICIT_ADDR_CMD: 1556 | + if(api_frame->api_data->explitcit_addr_cmd.frame_id) 1557 | + return api_frame->api_data->explitcit_addr_cmd.frame_id; 1558 | + break; 1559 | + case FRAME_TYPE_REMOTE_AT_CMD_REQ: 1560 | + if(api_frame->api_data->remote_at_cmd_req.frame_id) 1561 | + return api_frame->api_data->remote_at_cmd_req.frame_id; 1562 | + break; 1563 | + 1564 | + // Responses 1565 | + case FRAME_TYPE_AT_CMD_RESP: 1566 | + break; 1567 | + case FRAME_TYPE_MODEM_STATUS: 1568 | + break; 1569 | + case FRAME_TYPE_TRANSMIT_STATUS1: 1570 | + break; 1571 | + case FRAME_TYPE_TRANSMIT_STATUS2: 1572 | + break; 1573 | + case FRAME_TYPE_RAW_TRANSMIT_STATUS: 1574 | + break; 1575 | + case FRAME_TYPE_RECEIVE_PACKET: 1576 | + break; 1577 | + case FRAME_TYPE_EXPLICIT_RX_INDICATOR: 1578 | + break; 1579 | + case FRAME_TYPE_NODE_ID_INDICATOR: 1580 | + break; 1581 | + case FRAME_TYPE_REMOTE_CMD_RESP: 1582 | + break; 1583 | + default: 1584 | + printk(KERN_WARNING "%s(): Unknown Type (0x%02X)\n", __func__,api_frame->api_id); 1585 | + break; 1586 | + return 0; 1587 | + } 1588 | + return 0; 1589 | +} 1590 | + 1591 | +static int 1592 | +_api_frame_should_signal_pendent(_api_frame_t *api_frame) 1593 | +{ 1594 | + switch(api_frame->api_id) 1595 | + { 1596 | + // Requests 1597 | + case FRAME_TYPE_AT_CMD: 1598 | + break; 1599 | + case FRAME_TYPE_AT_CMD_QUEUE: 1600 | + break; 1601 | + case FRAME_TYPE_TRANSMIT_REQ: 1602 | + break; 1603 | + case FRAME_TYPE_RAW_TRANSMIT_REQ: 1604 | + break; 1605 | + case FRAME_TYPE_EXPLICIT_ADDR_CMD: 1606 | + break; 1607 | + case FRAME_TYPE_REMOTE_AT_CMD_REQ: 1608 | + break; 1609 | + 1610 | + // Responses 1611 | + case FRAME_TYPE_AT_CMD_RESP: 1612 | + if(api_frame->api_data->at_cmd_resp.frame_id) 1613 | + return api_frame->api_data->at_cmd_resp.frame_id; 1614 | + break; 1615 | + case FRAME_TYPE_MODEM_STATUS: 1616 | + return 0; 1617 | + break; 1618 | + case FRAME_TYPE_TRANSMIT_STATUS1: 1619 | + if(api_frame->api_data->transmit_status.frame_id) 1620 | + return api_frame->api_data->transmit_status.frame_id; 1621 | + break; 1622 | + case FRAME_TYPE_TRANSMIT_STATUS2: 1623 | + if(api_frame->api_data->transmit_status2.frame_id) 1624 | + return api_frame->api_data->transmit_status2.frame_id; 1625 | + break; 1626 | + case FRAME_TYPE_RAW_TRANSMIT_STATUS: 1627 | + if(api_frame->api_data->raw_transmit_status.frame_id) 1628 | + return api_frame->api_data->raw_transmit_status.frame_id; 1629 | + break; 1630 | + case FRAME_TYPE_RECEIVE_PACKET: 1631 | + return 0; 1632 | + break; 1633 | + case FRAME_TYPE_EXPLICIT_RX_INDICATOR: 1634 | + return 0; 1635 | + break; 1636 | + case FRAME_TYPE_NODE_ID_INDICATOR: 1637 | + return 0; 1638 | + break; 1639 | + case FRAME_TYPE_REMOTE_CMD_RESP: 1640 | + if(api_frame->api_data->remote_cmd_resp.frame_id) 1641 | + return api_frame->api_data->remote_cmd_resp.frame_id; 1642 | + break; 1643 | + default: 1644 | + printk(KERN_WARNING "%s(): Unknown Type (0x%02X)\n", __func__,api_frame->api_id); 1645 | + break; 1646 | + return 0; 1647 | + } 1648 | + return 0; 1649 | +} 1650 | + 1651 | +static _api_frame_t * 1652 | +_api_frame_parse(uint16_t frame_len, uint8_t *raw_data, uint8_t checksum) 1653 | +{ 1654 | + size_t api_data_size = 0; 1655 | + _api_frame_t *api_frame = NULL; 1656 | + int i = 0; 1657 | + int ni_string_len = 0; 1658 | +#ifdef __KERNEL__ 1659 | + api_frame = kzalloc(sizeof(_api_frame_t),GFP_KERNEL); 1660 | +#else 1661 | + api_frame = calloc(1,sizeof(_api_frame_t)); 1662 | +#endif 1663 | + if(!api_frame) 1664 | + { 1665 | + printk(KERN_ERR "%s(): unable to allocate memory\n", __func__); 1666 | + _api_frame_free(api_frame); 1667 | + BUG(); 1668 | + } 1669 | + 1670 | + api_frame->len = frame_len; 1671 | + api_frame->raw_data = raw_data; 1672 | + api_frame->api_id = *(api_frame->raw_data); 1673 | + api_frame->checksum = checksum; 1674 | + api_frame->response = NULL; 1675 | + 1676 | + switch(api_frame->api_id) 1677 | + { 1678 | + // Requests 1679 | + case FRAME_TYPE_AT_CMD: 1680 | + api_data_size = sizeof(api_frame_at_cmd_t); 1681 | + break; 1682 | + case FRAME_TYPE_TRANSMIT_REQ: 1683 | + api_data_size = sizeof(api_frame_transmit_req_t); 1684 | + break; 1685 | + 1686 | + // Responses 1687 | + case FRAME_TYPE_AT_CMD_RESP: 1688 | + api_data_size = sizeof(api_frame_at_cmd_resp_t); 1689 | + break; 1690 | + case FRAME_TYPE_MODEM_STATUS: 1691 | + api_data_size = sizeof(api_frame_modem_status_t); 1692 | + break; 1693 | + case FRAME_TYPE_TRANSMIT_STATUS1: 1694 | + api_data_size = sizeof(api_frame_transmit_status1_t); 1695 | + break; 1696 | + case FRAME_TYPE_TRANSMIT_STATUS2: 1697 | + api_data_size = sizeof(api_frame_transmit_status2_t); 1698 | + break; 1699 | + case FRAME_TYPE_RAW_TRANSMIT_STATUS: 1700 | + api_data_size = sizeof(api_frame_raw_transmit_status_t); 1701 | + break; 1702 | + case FRAME_TYPE_RECEIVE_PACKET: 1703 | + api_data_size = sizeof(api_frame_receive_packet_t); 1704 | + break; 1705 | + case FRAME_TYPE_EXPLICIT_RX_INDICATOR: 1706 | + api_data_size = sizeof(api_frame_explicit_rx_indicator_t); 1707 | + break; 1708 | + case FRAME_TYPE_NODE_ID_INDICATOR: 1709 | + api_data_size = sizeof(api_frame_node_id_indicator_t); 1710 | + break; 1711 | + case FRAME_TYPE_REMOTE_CMD_RESP: 1712 | + api_data_size = sizeof(api_frame_remote_cmd_resp_t); 1713 | + break; 1714 | + 1715 | + // RAW 1716 | + case FRAME_TYPE_RAW_TRANSMIT_REQ: 1717 | + api_data_size = sizeof(api_frame_raw_packet_t); 1718 | + break; 1719 | + 1720 | + default: 1721 | + printk(KERN_ERR "%s(): unknown or unimplemented parsing: Type: 0x%02X\n", __func__,api_frame->api_id); 1722 | + print_hex_dump_bytes("xbee_net_rx(): ", DUMP_PREFIX_NONE, raw_data,frame_len); 1723 | + api_frame->raw_data = NULL; 1724 | + _api_frame_free(api_frame); 1725 | + return NULL; 1726 | + } 1727 | + 1728 | +#ifdef __KERNEL__ 1729 | + api_frame->api_data = kzalloc(api_data_size,GFP_KERNEL); 1730 | +#else 1731 | + api_frame->api_data = calloc(api_data_size,sizeof(uint8_t)); 1732 | +#endif 1733 | + if(!api_frame->api_data) 1734 | + { 1735 | + printk(KERN_ERR "%s(): unable to allocate memory\n", __func__); 1736 | + api_frame->raw_data = NULL; 1737 | + _api_frame_free(api_frame); 1738 | + BUG(); 1739 | + } 1740 | + switch(api_frame->api_id) 1741 | + { 1742 | + case FRAME_TYPE_AT_CMD: 1743 | + api_frame->api_data->at_cmd.api_id = *(api_frame->raw_data); 1744 | + api_frame->api_data->at_cmd.frame_id = *(api_frame->raw_data+1); 1745 | + api_frame->api_data->at_cmd.at_command[0] = *(api_frame->raw_data+2); 1746 | + api_frame->api_data->at_cmd.at_command[1] = *(api_frame->raw_data+3); 1747 | + api_frame->api_data->at_cmd.parameter_value_len = at_command_get_parameter_len(api_frame); 1748 | + for(i=0;iapi_data->at_cmd.parameter_value_len;i++) 1749 | + { 1750 | + api_frame->api_data->at_cmd.parameter_value[i] = *(api_frame->raw_data+4+i); 1751 | + } 1752 | + break; 1753 | + case FRAME_TYPE_TRANSMIT_REQ: 1754 | + api_frame->api_data->transmit_req.api_id = *(api_frame->raw_data); 1755 | + api_frame->api_data->transmit_req.frame_id = *(api_frame->raw_data+1); 1756 | + memcpy(api_frame->api_data->transmit_req.dst_addr, api_frame->raw_data+2, XBEE_ADDR_LEN); 1757 | + api_frame->api_data->transmit_req.reserved = ((*(api_frame->raw_data+10))<<8)+*(api_frame->raw_data+11); 1758 | + api_frame->api_data->transmit_req.brd_radius = *(api_frame->raw_data+12); 1759 | + api_frame->api_data->transmit_req.options = *(api_frame->raw_data+13); 1760 | + api_frame->api_data->transmit_req.payload = api_frame->raw_data+14; 1761 | + api_frame->api_data->transmit_req.payload_len = api_frame->len-14; 1762 | + break; 1763 | + 1764 | + // Responses 1765 | + case FRAME_TYPE_AT_CMD_RESP: 1766 | + api_frame->api_data->at_cmd_resp.api_id = *(api_frame->raw_data); 1767 | + api_frame->api_data->at_cmd_resp.frame_id = *(api_frame->raw_data+1); 1768 | + api_frame->api_data->at_cmd_resp.at_command[0] = *(api_frame->raw_data+2); 1769 | + api_frame->api_data->at_cmd_resp.at_command[1] = *(api_frame->raw_data+3); 1770 | + api_frame->api_data->at_cmd_resp.cmd_status = *(api_frame->raw_data+4); 1771 | + api_frame->api_data->at_cmd_resp.cmd_data_len = at_command_get_parameter_len(api_frame); 1772 | + for(i=0;iapi_data->at_cmd_resp.cmd_data_len;i++) 1773 | + { 1774 | + api_frame->api_data->at_cmd_resp.cmd_data[i] = *(api_frame->raw_data+5+i); 1775 | + } 1776 | + break; 1777 | + case FRAME_TYPE_MODEM_STATUS: 1778 | + api_frame->api_data->modem_status.api_id = *(api_frame->raw_data); 1779 | + api_frame->api_data->modem_status.status = *(api_frame->raw_data+1); 1780 | + break; 1781 | + case FRAME_TYPE_TRANSMIT_STATUS1: 1782 | + api_frame->api_data->transmit_status.api_id = *(api_frame->raw_data); 1783 | + api_frame->api_data->transmit_status.frame_id = *(api_frame->raw_data+1); 1784 | + api_frame->api_data->transmit_status.reserved = ((*(api_frame->raw_data+2))<<8)+*(api_frame->raw_data+3); 1785 | + api_frame->api_data->transmit_status.transmit_retry_count = *(api_frame->raw_data+4); 1786 | + api_frame->api_data->transmit_status.delivery_status = *(api_frame->raw_data+5); 1787 | + api_frame->api_data->transmit_status.discovery_status = *(api_frame->raw_data+6); 1788 | + break; 1789 | + case FRAME_TYPE_TRANSMIT_STATUS2: 1790 | + api_frame->api_data->transmit_status2.api_id = *(api_frame->raw_data); 1791 | + api_frame->api_data->transmit_status2.frame_id = *(api_frame->raw_data+1); 1792 | + api_frame->api_data->transmit_status2.delivery_status = *(api_frame->raw_data+2); 1793 | + break; 1794 | + case FRAME_TYPE_RECEIVE_PACKET: 1795 | + api_frame->api_data->receive_packet.api_id = *(api_frame->raw_data); 1796 | + memcpy(api_frame->api_data->receive_packet.src_addr, api_frame->raw_data+1, XBEE_ADDR_LEN); 1797 | + api_frame->api_data->receive_packet.reserved = ((*(api_frame->raw_data+9))<<8)+*(api_frame->raw_data+10); 1798 | + api_frame->api_data->receive_packet.options = *(api_frame->raw_data+11); 1799 | + //api_frame->api_data->receive_packet.split_header = *(api_frame->raw_data+12); 1800 | + api_frame->api_data->receive_packet.payload = api_frame->raw_data+12; 1801 | + api_frame->api_data->receive_packet.payload_len = api_frame->len-12; 1802 | + break; 1803 | + case FRAME_TYPE_EXPLICIT_RX_INDICATOR: 1804 | + api_frame->api_data->explicit_rx_indicator.api_id = *(api_frame->raw_data); 1805 | + memcpy(api_frame->api_data->explicit_rx_indicator.src_addr, api_frame->raw_data+1, XBEE_ADDR_LEN); 1806 | + api_frame->api_data->explicit_rx_indicator.reserved = ((*(api_frame->raw_data+9))<<8)+*(api_frame->raw_data+10); 1807 | + api_frame->api_data->explicit_rx_indicator.src_endpoint = *(api_frame->raw_data+11); 1808 | + api_frame->api_data->explicit_rx_indicator.dst_endpoint = *(api_frame->raw_data+12); 1809 | + api_frame->api_data->explicit_rx_indicator.cluster_id = ((*(api_frame->raw_data+13))<<8)+*(api_frame->raw_data+14); 1810 | + api_frame->api_data->explicit_rx_indicator.profile_id = ((*(api_frame->raw_data+15))<<8)+*(api_frame->raw_data+16); 1811 | + api_frame->api_data->explicit_rx_indicator.options = *(api_frame->raw_data+17); 1812 | + api_frame->api_data->explicit_rx_indicator.payload = api_frame->raw_data+18; 1813 | + api_frame->api_data->explicit_rx_indicator.payload_len = api_frame->len-18; 1814 | + break; 1815 | + case FRAME_TYPE_NODE_ID_INDICATOR: 1816 | + api_frame->api_data->node_id_indicator.api_id = *(api_frame->raw_data); 1817 | + memcpy(api_frame->api_data->node_id_indicator.sender_addr, api_frame->raw_data+1, XBEE_ADDR_LEN); 1818 | + api_frame->api_data->node_id_indicator.sender_short_addr = ((*(api_frame->raw_data+9))<<8)+*(api_frame->raw_data+10); 1819 | + api_frame->api_data->node_id_indicator.options = *(api_frame->raw_data+11); 1820 | + api_frame->api_data->node_id_indicator.src_short_addr = ((*(api_frame->raw_data+12))<<8)+*(api_frame->raw_data+13); 1821 | + memcpy(api_frame->api_data->node_id_indicator.src_addr, api_frame->raw_data+14, XBEE_ADDR_LEN); 1822 | + api_frame->api_data->node_id_indicator.ni_string = api_frame->raw_data+22; 1823 | + ni_string_len = strlen((char*)api_frame->api_data->node_id_indicator.ni_string); 1824 | + api_frame->api_data->node_id_indicator.parent_short_addr = ((*(api_frame->raw_data+22+ni_string_len+1))<<8)+*(api_frame->raw_data+23+ni_string_len+1); 1825 | + break; 1826 | + case FRAME_TYPE_REMOTE_CMD_RESP: 1827 | + api_frame->api_data->remote_cmd_resp.api_id = *(api_frame->raw_data); 1828 | + api_frame->api_data->remote_cmd_resp.frame_id = *(api_frame->raw_data+1); 1829 | + memcpy(api_frame->api_data->remote_cmd_resp.src_addr, api_frame->raw_data+2, XBEE_ADDR_LEN); 1830 | + api_frame->api_data->remote_cmd_resp.reserved = ((*(api_frame->raw_data+10))<<8)+*(api_frame->raw_data+11); 1831 | + api_frame->api_data->remote_cmd_resp.at_command[0] = *(api_frame->raw_data+12); 1832 | + api_frame->api_data->remote_cmd_resp.at_command[1] = *(api_frame->raw_data+13); 1833 | + api_frame->api_data->remote_cmd_resp.cmd_status = *(api_frame->raw_data+14); 1834 | + api_frame->api_data->remote_cmd_resp.cmd_data_len = at_command_get_parameter_len(api_frame); 1835 | + for(i=0;iapi_data->remote_cmd_resp.cmd_data_len;i++) 1836 | + { 1837 | + api_frame->api_data->remote_cmd_resp.cmd_data[i] = *(api_frame->raw_data+15+i); 1838 | + } 1839 | + break; 1840 | + 1841 | + // RAW packet 1842 | + // case FRAME_TYPE_RAW_RECEIVE: 1843 | + case FRAME_TYPE_RAW_TRANSMIT_REQ: 1844 | + api_frame->api_data->raw_packet.api_id = *(api_frame->raw_data); 1845 | + api_frame->api_data->raw_packet.frame_id = *(api_frame->raw_data+1); // this is the LQI on RAW received 1846 | + api_frame->api_data->raw_packet.payload = api_frame->raw_data+2; 1847 | + api_frame->api_data->raw_packet.payload_len = api_frame->len-2; 1848 | + break; 1849 | + 1850 | + case FRAME_TYPE_RAW_TRANSMIT_STATUS: 1851 | + api_frame->api_data->raw_transmit_status.api_id = *(api_frame->raw_data); 1852 | + api_frame->api_data->raw_transmit_status.frame_id = *(api_frame->raw_data+1); 1853 | + api_frame->api_data->raw_transmit_status.retries = *(api_frame->raw_data+2); 1854 | + api_frame->api_data->raw_transmit_status.delivery_status = *(api_frame->raw_data+3); 1855 | + break; 1856 | + 1857 | + default: 1858 | + printk(KERN_ERR "%s(): unknown or unimplemented parsing #2: Type: 0x%02X\n", __func__,api_frame->api_id); 1859 | + api_frame->raw_data = NULL; 1860 | + _api_frame_free(api_frame); 1861 | + return NULL; 1862 | + } 1863 | + 1864 | +#ifdef __KERNEL__ 1865 | + mutex_init(&api_frame->mutex); 1866 | +#else 1867 | + pthread_mutex_init(&api_frame->mutex,NULL); 1868 | + pthread_cond_init(&api_frame->complete,NULL); 1869 | +#endif 1870 | + 1871 | +#ifndef __KERNEL__ 1872 | +#ifdef DEBUG 1873 | + printk(KERN_DEBUG "%s(): new frame %"PRIu16" bytes length: cmdID: 0x%02X\n", 1874 | + __func__,api_frame->len,api_frame->api_id); 1875 | +#endif 1876 | +#endif 1877 | + 1878 | + return api_frame; 1879 | +} 1880 | + 1881 | +static void 1882 | +_api_frame_free(_api_frame_t *api_frame) 1883 | +{ 1884 | + if(!api_frame) 1885 | + { 1886 | + printk(KERN_ERR "%s: api frame NULL pointer\n", __func__); 1887 | + BUG(); 1888 | + } 1889 | + 1890 | + if(api_frame->response) 1891 | + { 1892 | + _api_frame_free(api_frame->response); 1893 | + } 1894 | + 1895 | + if(api_frame->api_data) 1896 | + { 1897 | +#ifdef __KERNEL__ 1898 | + kfree(api_frame->api_data); 1899 | +#else 1900 | + free(api_frame->api_data); 1901 | +#endif 1902 | + api_frame->api_data = NULL; 1903 | + } 1904 | + if(api_frame->raw_data) 1905 | + { 1906 | +#ifdef __KERNEL__ 1907 | + kfree(api_frame->raw_data); 1908 | +#else 1909 | + free(api_frame->raw_data); 1910 | +#endif 1911 | + api_frame->raw_data = NULL; 1912 | + } 1913 | + 1914 | +#ifndef __KERNEL__ 1915 | + pthread_mutex_destroy(&api_frame->mutex); 1916 | +#endif 1917 | + 1918 | +#ifndef __KERNEL__ 1919 | + pthread_cond_destroy(&api_frame->complete); 1920 | +#endif 1921 | + 1922 | +#ifdef __KERNEL__ 1923 | + kfree(api_frame); 1924 | +#else 1925 | + free(api_frame); 1926 | +#endif 1927 | + api_frame = NULL; 1928 | +} 1929 | + 1930 | +static void 1931 | +_api_frame_print(_api_frame_t *api_frame) 1932 | +{ 1933 | +#ifdef DEBUG 1934 | + char str_aux[20] = {}; 1935 | + //123456789012345678901234 1936 | + //AA:BB:CC:DD:EE:FF:11:22 1937 | + char eui64_addr_str[24] = {}; 1938 | + int i = 0; 1939 | + 1940 | + if(!api_frame) 1941 | + { 1942 | + printk(KERN_DEBUG "%s: api frame NULL pointer\n", __func__); 1943 | + return; 1944 | + } 1945 | + printk(KERN_DEBUG "%s(): ______________________________________________________\n", __func__); 1946 | + switch(api_frame->api_id) 1947 | + { 1948 | + case FRAME_TYPE_AT_CMD: 1949 | + printk(KERN_DEBUG "%s(): Type: AT Command\n", __func__); 1950 | + printk(KERN_DEBUG "%s(): FrameID: %d\n", __func__,api_frame->api_data->at_cmd.frame_id); 1951 | + printk(KERN_DEBUG "%s(): Command: %c%c\n", __func__,api_frame->api_data->at_cmd.at_command[0],api_frame->api_data->at_cmd.at_command[1]); 1952 | + printk(KERN_DEBUG "%s(): Parameter: %s\n", __func__,at_command_get_parameter_str(api_frame,str_aux)); 1953 | + break; 1954 | + case FRAME_TYPE_AT_CMD_QUEUE: 1955 | + printk(KERN_DEBUG "%s(): AT Command Queue Type\n", __func__); 1956 | + printk(KERN_DEBUG "%s(): FrameID: %d\n", __func__,api_frame->api_data->at_cmd.frame_id); 1957 | + printk(KERN_DEBUG "%s(): Command: %c%c\n", __func__,api_frame->api_data->at_cmd.at_command[0],api_frame->api_data->at_cmd.at_command[1]); 1958 | + printk(KERN_DEBUG "%s(): Parameter: %s\n", __func__,at_command_get_parameter_str(api_frame,str_aux)); 1959 | + break; 1960 | + case FRAME_TYPE_TRANSMIT_REQ: 1961 | + printk(KERN_DEBUG "%s(): Type: Transmit Request\n", __func__); 1962 | + printk(KERN_DEBUG "%s(): FrameID: %d\n", __func__,api_frame->api_data->transmit_req.frame_id); 1963 | + printk(KERN_DEBUG "%s(): Dst Addr: %s\n", __func__,eui64_address_to_str(api_frame->api_data->transmit_req.dst_addr,eui64_addr_str)); 1964 | + printk(KERN_DEBUG "%s(): Reserved: %04X\n", __func__,api_frame->api_data->transmit_req.reserved); 1965 | + printk(KERN_DEBUG "%s(): BroadcastRadius: %d\n", __func__,api_frame->api_data->transmit_req.brd_radius); 1966 | + if(api_frame->api_data->transmit_req.options & 0x01) 1967 | + printk(KERN_DEBUG "%s(): Ack Disabled\n", __func__); 1968 | + if(api_frame->api_data->transmit_req.options & 0x02) 1969 | + printk(KERN_DEBUG "%s(): Don't attempt route Discovery\n", __func__); 1970 | + printk(KERN_DEBUG "%s(): Payload Lenght: %d\n", __func__,api_frame->api_data->transmit_req.payload_len); 1971 | + printk(KERN_DEBUG "%s(): Payload: ", __func__); 1972 | + for(i = 0;iapi_data->transmit_req.payload_len;i++){ 1973 | + printk("%02X ",api_frame->api_data->transmit_req.payload[i]); 1974 | + } 1975 | + printk("\n"); 1976 | + break; 1977 | + case FRAME_TYPE_RAW_PACKET: 1978 | + printk(KERN_DEBUG "%s(): Type: Raw Packet\n", __func__); 1979 | + printk(KERN_DEBUG "%s(): Payload Lenght: %d\n", __func__,api_frame->api_data->raw_packet.payload_len); 1980 | + printk(KERN_DEBUG "%s(): Payload: ", __func__); 1981 | + for(i = 0;iapi_data->raw_packet.payload_len;i++){ 1982 | + printk("%02X ",api_frame->api_data->raw_packet.payload[i]); 1983 | + } 1984 | + printk("\n"); 1985 | + break; 1986 | + case FRAME_TYPE_EXPLICIT_ADDR_CMD: 1987 | + printk(KERN_DEBUG "%s(): Type: Explicit Addressing Command\n", __func__); 1988 | + break; 1989 | + case FRAME_TYPE_REMOTE_AT_CMD_REQ: 1990 | + printk(KERN_DEBUG "%s(): Type: Remote AT Command Request\n", __func__); 1991 | + break; 1992 | + case FRAME_TYPE_AT_CMD_RESP: 1993 | + printk(KERN_DEBUG "%s(): Type: AT Command Response\n", __func__); 1994 | + printk(KERN_DEBUG "%s(): FrameID: %d\n", __func__,api_frame->api_data->at_cmd_resp.frame_id); 1995 | + printk(KERN_DEBUG "%s(): Command: %c%c\n", __func__,api_frame->api_data->at_cmd_resp.at_command[0],api_frame->api_data->at_cmd_resp.at_command[1]); 1996 | + switch(api_frame->api_data->at_cmd_resp.cmd_status) 1997 | + { 1998 | + case 0x00: 1999 | + printk(KERN_DEBUG "%s(): Command Status: OK\n", __func__); 2000 | + break; 2001 | + case 0x01: 2002 | + printk(KERN_DEBUG "%s(): Command Status: Error\n", __func__); 2003 | + break; 2004 | + case 0x02: 2005 | + printk(KERN_DEBUG "%s(): Command Status: Invalid Command\n", __func__); 2006 | + break; 2007 | + case 0x03: 2008 | + printk(KERN_DEBUG "%s(): Command Status: Invalid Parameter\n", __func__); 2009 | + break; 2010 | + default: 2011 | + printk(KERN_DEBUG "%s(): Command Status: Unknown status 0x%02X\n", __func__,api_frame->api_data->at_cmd_resp.cmd_status); 2012 | + break; 2013 | + } 2014 | + if(api_frame->api_data->at_cmd_resp.cmd_data_len) 2015 | + printk(KERN_DEBUG "%s(): Parameter: %s\n", __func__,at_command_get_parameter_str(api_frame,str_aux)); 2016 | + break; 2017 | + case FRAME_TYPE_MODEM_STATUS: 2018 | + printk(KERN_DEBUG "%s(): Type: Modem Status\n", __func__); 2019 | + switch(api_frame->api_data->modem_status.status) 2020 | + { 2021 | + case 0x00: 2022 | + printk(KERN_DEBUG "%s(): Status: Hardware reset\n", __func__); 2023 | + break; 2024 | + case 0x01: 2025 | + printk(KERN_DEBUG "%s(): Status: Watchdog time reset\n", __func__); 2026 | + break; 2027 | + case 0x0B: 2028 | + printk(KERN_DEBUG "%s(): Status: Network Woke Up\n", __func__); 2029 | + break; 2030 | + case 0x0C: 2031 | + printk(KERN_DEBUG "%s(): Status: Network Went To Sleep\n", __func__); 2032 | + break; 2033 | + default: 2034 | + printk(KERN_DEBUG "%s(): Status: Unknown (0x%02X)\n", __func__,api_frame->api_data->modem_status.status); 2035 | + break; 2036 | + } 2037 | + break; 2038 | + case FRAME_TYPE_TRANSMIT_STATUS1: 2039 | + printk(KERN_DEBUG "%s(): Type: Transmit Status\n", __func__); 2040 | + printk(KERN_DEBUG "%s(): FrameID: %d\n", __func__,api_frame->api_data->transmit_status.frame_id); 2041 | + printk(KERN_DEBUG "%s(): Reserved: %04X\n", __func__,api_frame->api_data->transmit_status.reserved); 2042 | + printk(KERN_DEBUG "%s(): Transmit Retry Count: %d\n", __func__,api_frame->api_data->transmit_status.transmit_retry_count); 2043 | + switch(api_frame->api_data->transmit_status.delivery_status) 2044 | + { 2045 | + case 0x00: 2046 | + printk(KERN_DEBUG "%s(): Delivery Status: Success\n", __func__); 2047 | + break; 2048 | + case 0x01: 2049 | + printk(KERN_DEBUG "%s(): Delivery Status: MAC ACK Failure\n", __func__); 2050 | + break; 2051 | + case 0x15: 2052 | + printk(KERN_DEBUG "%s(): Delivery Status: Invalid destination endpoint\n", __func__); 2053 | + break; 2054 | + case 0x21: 2055 | + printk(KERN_DEBUG "%s(): Delivery Status: Network ACK Failure\n", __func__); 2056 | + break; 2057 | + case 0x25: 2058 | + printk(KERN_DEBUG "%s(): Delivery Status: Route Not Found\n", __func__); 2059 | + break; 2060 | + default: 2061 | + printk(KERN_DEBUG "%s(): Delivery Status: Unknown (0x%02X)\n", __func__,api_frame->api_data->transmit_status.delivery_status); 2062 | + break; 2063 | + } 2064 | + switch(api_frame->api_data->transmit_status.discovery_status) 2065 | + { 2066 | + case 0x00: 2067 | + printk(KERN_DEBUG "%s(): Discovery Status: No Discovery Overhead\n", __func__); 2068 | + break; 2069 | + case 0x02: 2070 | + printk(KERN_DEBUG "%s(): Discovery Status: Route Discovery\n", __func__); 2071 | + break; 2072 | + default: 2073 | + printk(KERN_DEBUG "%s(): Discovery Status: Unknown (0x%02X)\n", __func__,api_frame->api_data->transmit_status.discovery_status); 2074 | + break; 2075 | + } 2076 | + break; 2077 | + case FRAME_TYPE_TRANSMIT_STATUS2: 2078 | + printk(KERN_DEBUG "%s(): Type: Transmit Status 2\n", __func__); 2079 | + printk(KERN_DEBUG "%s(): FrameID: %d\n", __func__,api_frame->api_data->transmit_status2.frame_id); 2080 | + switch(api_frame->api_data->transmit_status2.delivery_status) 2081 | + { 2082 | + case 0x00: 2083 | + printk(KERN_DEBUG "%s(): Success, no errors were detected on transmission.\n", __func__); 2084 | + break; 2085 | + case 0x01: 2086 | + printk(KERN_DEBUG "%s(): An expected MAC acknowledgement never occurred.\n", __func__); 2087 | + break; 2088 | + case 0x02: 2089 | + printk(KERN_DEBUG "%s(): CCA failure.\n", __func__); 2090 | + break; 2091 | + case 0x03: 2092 | + printk(KERN_DEBUG "%s(): Transmission was purged because it was attempted before the stack was up.\n", __func__); 2093 | + break; 2094 | + case 0x04: 2095 | + printk(KERN_DEBUG "%s(): Physical error occurred on the interface with the WiFi transceiver.\n", __func__); 2096 | + break; 2097 | + case 0x18: 2098 | + printk(KERN_DEBUG "%s(): No Buffers.\n", __func__); 2099 | + break; 2100 | + case 0x21: 2101 | + printk(KERN_DEBUG "%s(): An expected network acknowledgement never occurred.\n", __func__); 2102 | + break; 2103 | + case 0x22: 2104 | + printk(KERN_DEBUG "%s(): Not joined to network.\n", __func__); 2105 | + break; 2106 | + case 0x23: 2107 | + printk(KERN_DEBUG "%s(): Self-addressed.\n", __func__); 2108 | + break; 2109 | + case 0x24: 2110 | + printk(KERN_DEBUG "%s(): Address not found.\n", __func__); 2111 | + break; 2112 | + case 0x25: 2113 | + printk(KERN_DEBUG "%s(): Route not found.\n", __func__); 2114 | + break; 2115 | + case 0x26: 2116 | + printk(KERN_DEBUG "%s(): Broadcast relay was not heard.\n", __func__); 2117 | + break; 2118 | + case 0x2B: 2119 | + printk(KERN_DEBUG "%s(): Invalid Binding Table Index.\n", __func__); 2120 | + break; 2121 | + case 0x2C: 2122 | + printk(KERN_DEBUG "%s(): Invalid Endpoint.\n", __func__); 2123 | + break; 2124 | + case 0x31: 2125 | + printk(KERN_DEBUG "%s(): A software error occurred.\n", __func__); 2126 | + break; 2127 | + case 0x32: 2128 | + printk(KERN_DEBUG "%s(): Resource Error.\n", __func__); 2129 | + break; 2130 | + case 0x74: 2131 | + printk(KERN_DEBUG "%s(): Data payload too large.\n", __func__); 2132 | + break; 2133 | + case 0x76: 2134 | + printk(KERN_DEBUG "%s(): Attempt to create a client socket failed.\n", __func__); 2135 | + break; 2136 | + case 0xBB: 2137 | + printk(KERN_DEBUG "%s(): Key not authorized.\n", __func__); 2138 | + break; 2139 | + default: 2140 | + printk(KERN_DEBUG "%s(): Delivery Status: Unknown (0x%02X)\n", __func__,api_frame->api_data->transmit_status2.delivery_status); 2141 | + break; 2142 | + } 2143 | + break; 2144 | + case FRAME_TYPE_RECEIVE_PACKET: 2145 | + printk(KERN_DEBUG "%s(): Type: Receive Packet\n", __func__); 2146 | + printk(KERN_DEBUG "%s(): Src Addr: %s\n", __func__,eui64_address_to_str(api_frame->api_data->receive_packet.src_addr,eui64_addr_str)); 2147 | + printk(KERN_DEBUG "%s(): Reserved: %04X\n", __func__,api_frame->api_data->receive_packet.reserved); 2148 | + if(api_frame->api_data->receive_packet.options & 0x01) 2149 | + printk(KERN_DEBUG "%s(): Packet Acknowleged\n", __func__); 2150 | + if(api_frame->api_data->receive_packet.options & 0x02) 2151 | + printk(KERN_DEBUG "%s(): Packet was broadcast packet\n", __func__); 2152 | + printk(KERN_DEBUG "%s(): Payload Lenght: %d\n", __func__,api_frame->api_data->receive_packet.payload_len); 2153 | + printk(KERN_DEBUG "%s(): Payload: ", __func__); 2154 | + for(i = 0;iapi_data->receive_packet.payload_len;i++){ 2155 | + printk("%02X ",api_frame->api_data->receive_packet.payload[i]); 2156 | + } 2157 | + printk("\n"); 2158 | + 2159 | + break; 2160 | + case FRAME_TYPE_EXPLICIT_RX_INDICATOR: 2161 | + printk(KERN_DEBUG "%s(): Type: Explitict RX Indicator\n", __func__); 2162 | + printk(KERN_DEBUG "%s(): Src Addr: %s\n", __func__,eui64_address_to_str(api_frame->api_data->explicit_rx_indicator.src_addr,eui64_addr_str)); 2163 | + printk(KERN_DEBUG "%s(): Reserved: %04X\n", __func__,api_frame->api_data->explicit_rx_indicator.reserved); 2164 | + printk(KERN_DEBUG "%s(): Src Endpoint: 0x%02X\n", __func__,api_frame->api_data->explicit_rx_indicator.src_endpoint); 2165 | + printk(KERN_DEBUG "%s(): Dst Endpoint: 0x%02X\n", __func__,api_frame->api_data->explicit_rx_indicator.dst_endpoint); 2166 | + printk(KERN_DEBUG "%s(): ClusterID: %04X\n", __func__,api_frame->api_data->explicit_rx_indicator.cluster_id); 2167 | + printk(KERN_DEBUG "%s(): ProfileID: %04X\n", __func__,api_frame->api_data->explicit_rx_indicator.profile_id); 2168 | + if(api_frame->api_data->explicit_rx_indicator.options & 0x01) 2169 | + printk(KERN_DEBUG "%s(): Packet Acknowleged\n", __func__); 2170 | + if(api_frame->api_data->explicit_rx_indicator.options & 0x02) 2171 | + printk(KERN_DEBUG "%s(): Packet was broadcast packet\n", __func__); 2172 | + printk(KERN_DEBUG "%s(): Payload Lenght: %d\n", __func__,api_frame->api_data->explicit_rx_indicator.payload_len); 2173 | + printk(KERN_DEBUG "%s(): Payload: ", __func__); 2174 | + for(i = 0;iapi_data->explicit_rx_indicator.payload_len;i++){ 2175 | + printk("%02X ",api_frame->api_data->explicit_rx_indicator.payload[i]); 2176 | + } 2177 | + printk("\n"); 2178 | + 2179 | + break; 2180 | + case FRAME_TYPE_NODE_ID_INDICATOR: 2181 | + printk(KERN_DEBUG "%s(): Type: Node Identification Indicator\n", __func__); 2182 | + printk(KERN_DEBUG "%s(): Sender Addr: %s\n", __func__,eui64_address_to_str(api_frame->api_data->node_id_indicator.sender_addr,eui64_addr_str)); 2183 | + printk(KERN_DEBUG "%s(): Sender Short Addr: %04X\n", __func__,api_frame->api_data->node_id_indicator.sender_short_addr); 2184 | + if(api_frame->api_data->node_id_indicator.options & 0x01) 2185 | + printk(KERN_DEBUG "%s(): Packet Acknowleged\n", __func__); 2186 | + if(api_frame->api_data->node_id_indicator.options & 0x02) 2187 | + printk(KERN_DEBUG "%s(): Packet was broadcast packet\n", __func__); 2188 | + printk(KERN_DEBUG "%s(): Remote Short Addr: %04X\n", __func__,api_frame->api_data->node_id_indicator.src_short_addr); 2189 | + printk(KERN_DEBUG "%s(): Remote Addr: %s\n", __func__,eui64_address_to_str(api_frame->api_data->node_id_indicator.src_addr,eui64_addr_str)); 2190 | + printk(KERN_DEBUG "%s(): Ni: \"%s\"\n", __func__,api_frame->api_data->node_id_indicator.ni_string); 2191 | + printk(KERN_DEBUG "%s(): Remote Short Addr: %04X\n", __func__,api_frame->api_data->node_id_indicator.parent_short_addr); 2192 | + 2193 | + break; 2194 | + case FRAME_TYPE_REMOTE_CMD_RESP: 2195 | + printk(KERN_DEBUG "%s(): Type: Remote Command Response\n", __func__); 2196 | + printk(KERN_DEBUG "%s(): FrameID: %d\n", __func__,api_frame->api_data->remote_cmd_resp.frame_id); 2197 | + printk(KERN_DEBUG "%s(): Src Addr: %s\n", __func__,eui64_address_to_str(api_frame->api_data->remote_cmd_resp.src_addr,eui64_addr_str)); 2198 | + printk(KERN_DEBUG "%s(): Reserved: %04X\n", __func__,api_frame->api_data->remote_cmd_resp.reserved); 2199 | + printk(KERN_DEBUG "%s(): Command: %c%c\n", __func__,api_frame->api_data->remote_cmd_resp.at_command[0],api_frame->api_data->remote_cmd_resp.at_command[1]); 2200 | + switch(api_frame->api_data->remote_cmd_resp.cmd_status) 2201 | + { 2202 | + case 0x00: 2203 | + printk(KERN_DEBUG "%s(): Command Status: OK\n", __func__); 2204 | + break; 2205 | + case 0x01: 2206 | + printk(KERN_DEBUG "%s(): Command Status: Error\n", __func__); 2207 | + break; 2208 | + case 0x02: 2209 | + printk(KERN_DEBUG "%s(): Command Status: Invalid Command\n", __func__); 2210 | + break; 2211 | + case 0x03: 2212 | + printk(KERN_DEBUG "%s(): Command Status: Invalid Parameter\n", __func__); 2213 | + break; 2214 | + default: 2215 | + printk(KERN_DEBUG "%s(): Command Status: Unknown status 0x%02X\n", __func__,api_frame->api_data->remote_cmd_resp.cmd_status); 2216 | + break; 2217 | + } 2218 | + if(api_frame->api_data->remote_cmd_resp.cmd_data_len) 2219 | + printk(KERN_DEBUG "%s(): Parameter: %s\n", __func__,at_command_get_parameter_str(api_frame,str_aux)); 2220 | + 2221 | + break; 2222 | + default: 2223 | + printk(KERN_DEBUG "%s(): Type: Unknown (0x%02X)\n", __func__,api_frame->api_id); 2224 | + break; 2225 | + } 2226 | + 2227 | + printk(KERN_DEBUG "%s(): ______________________________________________________\n", __func__); 2228 | +#endif 2229 | +} 2230 | + 2231 | + 2232 | +/* 2233 | + * Escape helpers 2234 | + */ 2235 | +static int 2236 | +escape_required(uint8_t c) 2237 | +{ 2238 | + return ((XBEE_START_DELIM == c) || 2239 | + (XBEE_ESCAPE == c) || 2240 | + (XBEE_XON == c) || 2241 | + (XBEE_XOFF == c)); 2242 | +} 2243 | +static int 2244 | +unescape_required(uint8_t c) 2245 | +{ 2246 | + return (XBEE_ESCAPE == c); 2247 | +} 2248 | + 2249 | +/* 2250 | + * Received data processing 2251 | + */ 2252 | + 2253 | +static int 2254 | +_api_frame_process_response(_api_frame_t *api_frame) 2255 | +{ 2256 | + if(api_frame == NULL) 2257 | + { 2258 | + printk(KERN_ERR "%s: api_frame NULL pointer\n", __func__); 2259 | + BUG(); 2260 | + } 2261 | + pr_debug("%s(): api_frame request 0x%02X with response 0x%02X\n", __func__,api_frame->api_id,api_frame->response->api_id); 2262 | + switch(api_frame->api_id) 2263 | + { 2264 | + // Requests 2265 | + case FRAME_TYPE_AT_CMD: 2266 | + if(api_frame->response->api_id != FRAME_TYPE_AT_CMD_RESP) 2267 | + { 2268 | + printk(KERN_WARNING "%s: invalid response type: 0x%02X (expected 0x%02X)\n", __func__,api_frame->response->api_id,FRAME_TYPE_AT_CMD_RESP); 2269 | + return -EINVAL; 2270 | + } 2271 | + if(api_frame->response->api_data->at_cmd_resp.cmd_status != 0) 2272 | + { 2273 | + printk(KERN_DEBUG "%s: error issuing AT command: 0x%02X\n", __func__,api_frame->response->api_data->at_cmd_resp.cmd_status); 2274 | + return -EINVAL; 2275 | + } 2276 | + break; 2277 | + case FRAME_TYPE_AT_CMD_QUEUE: 2278 | + if(api_frame->response->api_id != FRAME_TYPE_AT_CMD_RESP) 2279 | + { 2280 | + printk(KERN_WARNING "%s: invalid response type: 0x%02X (expected 0x%02X)\n", __func__,api_frame->response->api_id,FRAME_TYPE_AT_CMD_RESP); 2281 | + return -EINVAL; 2282 | + } 2283 | + if(api_frame->response->api_data->at_cmd_resp.cmd_status != 0) 2284 | + { 2285 | + printk(KERN_DEBUG "%s: error issuing AT command: 0x%02X\n", __func__,api_frame->response->api_data->at_cmd_resp.cmd_status); 2286 | + return -EINVAL; 2287 | + } 2288 | + break; 2289 | + case FRAME_TYPE_TRANSMIT_REQ: 2290 | + if(api_frame->response->api_id != FRAME_TYPE_TRANSMIT_STATUS1 && api_frame->response->api_id != FRAME_TYPE_TRANSMIT_STATUS2) 2291 | + { 2292 | + printk(KERN_WARNING "%s: invalid response type: 0x%02X (expected 0x%02X)\n", __func__,api_frame->response->api_id,FRAME_TYPE_TRANSMIT_STATUS1); 2293 | + return -EINVAL; 2294 | + } 2295 | + if(api_frame->response->api_data->transmit_status.delivery_status) 2296 | + { 2297 | + printk(KERN_DEBUG "%s: error transmitting data: 0x%02X retries: %d disc: 0x%02X\n", __func__, 2298 | + api_frame->response->api_data->transmit_status.delivery_status, 2299 | + api_frame->response->api_data->transmit_status.transmit_retry_count, 2300 | + api_frame->response->api_data->transmit_status.discovery_status); 2301 | + return -EAGAIN; 2302 | + } 2303 | + break; 2304 | + 2305 | + case FRAME_TYPE_RAW_TRANSMIT_REQ: 2306 | + if(api_frame->response->api_id != FRAME_TYPE_RAW_TRANSMIT_STATUS) 2307 | + { 2308 | + printk(KERN_WARNING "%s: invalid response type: 0x%02X (expected 0x%02X)\n", __func__,api_frame->response->api_id,FRAME_TYPE_RAW_TRANSMIT_STATUS); 2309 | + return -EINVAL; 2310 | + } 2311 | + if(api_frame->response->api_data->raw_transmit_status.delivery_status) 2312 | + { 2313 | + printk(KERN_DEBUG "%s: error transmitting data: 0x%02X\n", __func__, 2314 | + api_frame->response->api_data->raw_transmit_status.delivery_status); 2315 | + return -EAGAIN; 2316 | + } 2317 | + break; 2318 | + 2319 | + case FRAME_TYPE_EXPLICIT_ADDR_CMD: 2320 | + if(api_frame->response->api_id != FRAME_TYPE_TRANSMIT_STATUS1 && api_frame->response->api_id != FRAME_TYPE_TRANSMIT_STATUS2) 2321 | + { 2322 | + printk(KERN_WARNING "%s: invalid response type: 0x%02X (expected 0x%02X)\n", __func__,api_frame->response->api_id,FRAME_TYPE_TRANSMIT_STATUS1); 2323 | + return -EINVAL; 2324 | + } 2325 | + if(api_frame->response->api_data->transmit_status.delivery_status) 2326 | + { 2327 | + printk(KERN_DEBUG "%s: error transmitting data: 0x%02X\n", __func__,api_frame->response->api_data->transmit_status.delivery_status); 2328 | + return -EAGAIN; 2329 | + } 2330 | + break; 2331 | + case FRAME_TYPE_REMOTE_AT_CMD_REQ: 2332 | + if(api_frame->response->api_id != FRAME_TYPE_REMOTE_CMD_RESP) 2333 | + { 2334 | + printk(KERN_WARNING "%s: invalid response type: 0x%02X (expected 0x%02X)\n", __func__,api_frame->response->api_id,FRAME_TYPE_REMOTE_CMD_RESP); 2335 | + return -EINVAL; 2336 | + } 2337 | + if(api_frame->response->api_data->remote_cmd_resp.cmd_status != 0) 2338 | + { 2339 | + printk(KERN_DEBUG "%s: error issuing AT command: 0x%02X\n", __func__,api_frame->response->api_data->remote_cmd_resp.cmd_status); 2340 | + return -EINVAL; 2341 | + } 2342 | + break; 2343 | + 2344 | + // Responses 2345 | +// case FRAME_TYPE_AT_CMD_RESP: 2346 | +// return 1; 2347 | +// break; 2348 | +// case FRAME_TYPE_MODEM_STATUS: 2349 | +// return 1; 2350 | +// break; 2351 | +// case FRAME_TYPE_TRANSMIT_STATUS: 2352 | +// return 1; 2353 | +// break; 2354 | +// case FRAME_TYPE_RECEIVE_PACKET: 2355 | +// return 1; 2356 | +// break; 2357 | +// case FRAME_TYPE_EXPLICIT_RX_INDICATOR: 2358 | +// return 1; 2359 | +// break; 2360 | +// case FRAME_TYPE_NODE_ID_INDICATOR: 2361 | +// return 1; 2362 | +// break; 2363 | +// case FRAME_TYPE_REMOTE_CMD_RESP: 2364 | +// return 1; 2365 | +// break; 2366 | + default: 2367 | + printk(KERN_WARNING "%s(): Invalid Request Type (0x%02X)\n", __func__,api_frame->api_id); 2368 | + break; 2369 | + return 0; 2370 | + } 2371 | + return 0; 2372 | +} 2373 | + 2374 | +static void 2375 | +ieee802154_net_rx(struct xbee_device *xbee_dev, _api_frame_t *api_frame); 2376 | + 2377 | +static int 2378 | +_api_frame_process(struct xbee_device *xbee_dev, _api_frame_t *api_frame) 2379 | +{ 2380 | + int ret = 0; 2381 | + if(xbee_dev == NULL) 2382 | + { 2383 | + printk(KERN_ERR "%s: xbee_dev NULL pointer\n", __func__); 2384 | + BUG(); 2385 | + } 2386 | + if(api_frame == NULL) 2387 | + { 2388 | + printk(KERN_ERR "%s: api_frame NULL pointer\n", __func__); 2389 | + BUG(); 2390 | + } 2391 | + 2392 | +#ifdef DEBUG 2393 | + printk(KERN_INFO "%s(): Call process frame\n", __func__); 2394 | +#endif 2395 | + 2396 | + //_api_frame_print(api_frame); 2397 | + 2398 | + if(_api_frame_should_signal_pendent(api_frame)) 2399 | + { 2400 | + xbee_device_signal_pendent_req(xbee_dev,api_frame); 2401 | + } 2402 | + else 2403 | + { 2404 | + //TODO: not pendent request response 2405 | + _api_frame_print(api_frame); 2406 | + 2407 | + //FIXME we should only push to stack the received_packets frames or RAW 2408 | + ieee802154_net_rx(xbee_dev,api_frame); 2409 | + 2410 | + _api_frame_free(api_frame); 2411 | + api_frame = NULL; 2412 | + } 2413 | + 2414 | + return ret; 2415 | +} 2416 | + 2417 | +static int 2418 | +xbee_process_char(struct xbee_device *xbee_dev, unsigned char c) 2419 | +{ 2420 | + _api_frame_t *api_frame = NULL; 2421 | +//#ifdef DEBUG 2422 | +// printk(KERN_INFO "%s(): current state %s\n", __func__, 2423 | +// xbee_recv_state_str(xbee_dev->recv_state)); 2424 | +// 2425 | +// printk(KERN_INFO "%s(): processing %3d (0x%02X)\n", __func__,c,c); 2426 | +//#endif 2427 | + 2428 | + /* Data processing */ 2429 | + switch (xbee_dev->recv_state) { 2430 | + case RECV_STATE_WAIT_START_DELIM: 2431 | + if (XBEE_START_DELIM == c) 2432 | + { 2433 | + xbee_dev->recv_state = RECV_STATE_WAIT_MSB; 2434 | + } 2435 | + break; 2436 | + case RECV_STATE_WAIT_MSB: 2437 | + xbee_dev->recv_data_size = c; 2438 | + xbee_dev->recv_state = RECV_STATE_WAIT_LSB; 2439 | + break; 2440 | + case RECV_STATE_WAIT_LSB: 2441 | + 2442 | + if(xbee_dev->recv_data) 2443 | + { 2444 | + printk(KERN_INFO "%s(): we shouldnt get data buffers here!\n",__func__); 2445 | + } 2446 | + 2447 | + xbee_dev->recv_data_size <<= 8; 2448 | + xbee_dev->recv_data_size += c; 2449 | + xbee_dev->recv_state = RECV_STATE_WAIT_DATA; 2450 | + 2451 | +#ifdef __KERNEL__ 2452 | + xbee_dev->recv_data = kzalloc(xbee_dev->recv_data_size, GFP_KERNEL); 2453 | +#else 2454 | + xbee_dev->recv_data = calloc(xbee_dev->recv_data_size,sizeof(uint8_t)); 2455 | +#endif 2456 | + if (!xbee_dev->recv_data) { 2457 | + printk(KERN_ERR "%s(): unable to allocate memory\n", __func__); 2458 | + xbee_dev->recv_data_size = 0; 2459 | + return -ENOMEM; 2460 | + } 2461 | + 2462 | + xbee_dev->recv_data_offset = 0; 2463 | + xbee_dev->recv_data_sum = 0; 2464 | + 2465 | +#ifndef __KERNEL__ 2466 | +#ifdef DEBUG 2467 | + printk(KERN_INFO "%s(): Got payload length: %"PRIu16"\n", __func__,xbee_dev->recv_data_size); 2468 | +#endif 2469 | +#endif 2470 | + 2471 | + break; 2472 | + case RECV_STATE_WAIT_DATA: 2473 | +//#ifdef DEBUG 2474 | +// printk(KERN_INFO "%s(): processing: index data[%u]\n", __func__,xbee_dev->recv_data_offset); 2475 | +//#endif 2476 | + xbee_dev->recv_data_sum += c; 2477 | + xbee_dev->recv_data[xbee_dev->recv_data_offset++] = c; 2478 | + if(xbee_dev->recv_data_offset == xbee_dev->recv_data_size) 2479 | + { 2480 | + xbee_dev->recv_state = RECV_STATE_WAIT_CHECKSUM; 2481 | + } 2482 | + break; 2483 | + case RECV_STATE_WAIT_CHECKSUM: 2484 | + if(0xFF - xbee_dev->recv_data_sum != c) 2485 | + { 2486 | + printk(KERN_WARNING "%s(): checksum failed: got 0x%02X (expected 0x%02X)\n", __func__,c,0xFF - xbee_dev->recv_data_sum); 2487 | + printk(KERN_WARNING "%s(): Error parsing frame: discarding\n", __func__); 2488 | + printk(KERN_WARNING "%s(): received %d bytes\n", __func__,xbee_dev->recv_data_size); 2489 | + print_hex_dump_bytes("xbee_process_char(): ", DUMP_PREFIX_NONE, xbee_dev->recv_data, xbee_dev->recv_data_size); 2490 | + 2491 | +#ifdef __KERNEL__ 2492 | + if(xbee_dev->recv_data) 2493 | + kfree(xbee_dev->recv_data); 2494 | +#else 2495 | + free(xbee_dev->recv_data); 2496 | +#endif 2497 | + xbee_dev->recv_data = NULL; 2498 | + xbee_dev->recv_data_offset = 0; 2499 | + xbee_dev->recv_data_escape_next = 0; 2500 | + xbee_dev->recv_data_sum = 0; 2501 | + xbee_dev->recv_data_size = 0; 2502 | + } 2503 | + else 2504 | + { 2505 | +#ifdef DEBUG 2506 | + printk(KERN_INFO "%s(): Got valid frame\n", __func__); 2507 | +#endif 2508 | + api_frame = _api_frame_parse(xbee_dev->recv_data_size,xbee_dev->recv_data,c); 2509 | + if(api_frame) 2510 | + { 2511 | + xbee_dev->recv_data = NULL; 2512 | + xbee_dev->recv_data_offset = 0; 2513 | + xbee_dev->recv_data_escape_next = 0; 2514 | + xbee_dev->recv_data_sum = 0; 2515 | + xbee_dev->recv_data_size = 0; 2516 | + if(_api_frame_process(xbee_dev,api_frame)) 2517 | + { 2518 | + printk(KERN_WARNING "%s(): error processing frame\n", __func__); 2519 | + } 2520 | + api_frame = NULL; 2521 | + } 2522 | + else 2523 | + { 2524 | + printk(KERN_WARNING "%s(): Error parsing frame: discarding\n", __func__); 2525 | +#ifdef __KERNEL__ 2526 | + if(xbee_dev->recv_data) 2527 | + kfree(xbee_dev->recv_data); 2528 | +#else 2529 | + free(xbee_dev->recv_data); 2530 | +#endif 2531 | + xbee_dev->recv_data = NULL; 2532 | + xbee_dev->recv_data_offset = 0; 2533 | + xbee_dev->recv_data_escape_next = 0; 2534 | + xbee_dev->recv_data_sum = 0; 2535 | + xbee_dev->recv_data_size = 0; 2536 | + } 2537 | + } 2538 | + 2539 | + xbee_dev->recv_state = RECV_STATE_WAIT_START_DELIM; 2540 | + wake_up(&xbee_dev->wq); 2541 | + 2542 | + break; 2543 | + default: 2544 | + BUG(); //FIXME check if we can reach this point 2545 | + break; 2546 | + } 2547 | + return 0; 2548 | +} 2549 | + 2550 | +static int 2551 | +xbee_receive(struct xbee_device *xbee_dev, const unsigned char *buf, int count) 2552 | +{ 2553 | + uint8_t rx_data = 0; 2554 | + int i = 0; 2555 | + if(xbee_dev == NULL) 2556 | + { 2557 | + printk(KERN_ERR "%s: xbee_dev NULL pointer\n", __func__); 2558 | + BUG(); 2559 | + } 2560 | + if(buf == NULL) 2561 | + { 2562 | + printk(KERN_ERR "%s: buf NULL pointer\n", __func__); 2563 | + BUG(); 2564 | + } 2565 | + for (i=0; i < count; ++i){ 2566 | + rx_data = buf[i]; 2567 | + if(xbee_dev->recv_state != RECV_STATE_WAIT_START_DELIM && xbee_dev->escaped_mode) { 2568 | + if(unescape_required(rx_data)) 2569 | + { 2570 | + xbee_dev->recv_data_escape_next = 1; 2571 | + } 2572 | + else if(xbee_dev->recv_data_escape_next) 2573 | + { 2574 | + xbee_dev->recv_data_escape_next = 0; 2575 | + rx_data = buf[i]^0x20; 2576 | + xbee_process_char(xbee_dev, rx_data); 2577 | + } else { 2578 | + xbee_process_char(xbee_dev, rx_data); 2579 | + } 2580 | + } else { 2581 | + xbee_process_char(xbee_dev, rx_data); 2582 | + } 2583 | + } 2584 | + return 0; 2585 | +} 2586 | + 2587 | +static int 2588 | +xbee_send(struct xbee_device *xbee_dev, _api_frame_t *api_frame) 2589 | +{ 2590 | + int ret = 0; 2591 | +#ifndef __KERNEL__ 2592 | + struct timeval tv = {0,0}; 2593 | + struct timespec waitspec = {0,0}; 2594 | + //pthread_attr_t attr; 2595 | +#endif 2596 | + 2597 | + uint16_t len = 0; 2598 | + uint8_t *raw_frame = NULL; 2599 | + if(xbee_dev == NULL) 2600 | + { 2601 | + printk(KERN_ERR "%s: xbee_dev NULL pointer\n", __func__); 2602 | + BUG(); 2603 | + } 2604 | + if(api_frame == NULL) 2605 | + { 2606 | + printk(KERN_ERR "%s: api_frame NULL pointer\n", __func__); 2607 | + BUG(); 2608 | + } 2609 | + 2610 | + raw_frame = _api_frame_to_raw(api_frame,&len); 2611 | + 2612 | + if(raw_frame == NULL) 2613 | + { 2614 | + printk(KERN_ERR "%s: raw_frame NULL pointer\n", __func__); 2615 | + BUG(); 2616 | + } 2617 | + 2618 | + if(_api_frame_should_wait_response(api_frame)) 2619 | + { 2620 | + xbee_device_add_pendent_req(xbee_dev,api_frame); 2621 | + } 2622 | + 2623 | + if((ret = xbee_device_write_to_phy(xbee_dev,raw_frame,len)) != len) 2624 | + { 2625 | + printk(KERN_ERR "%s: error writing to phy media: ret: %d len: %u\n", __func__,ret,len); 2626 | + BUG(); // FIXME 2627 | + /* 2628 | + * [ 1034.907503] xbee_send: error writing to phy media 2629 | +[ 1034.924140] ------------[ cut here ]------------ 2630 | +[ 1034.928770] kernel BUG at drivers/net/ieee802154/xbee.c:2177! 2631 | +[ 1034.934507] Internal error: Oops - BUG: 0 [#1] PREEMPT ARM 2632 | + 2633 | +Entering kdb (current=0xda84a080, pid 6) Oops: (null) 2634 | +due to oops @ 0xbf1a4ed0 2635 | + 2636 | +Pid: 6, comm: kworker/u:0 2637 | +CPU: 0 Not tainted (3.9.6+ #1) 2638 | +PC is at xbee_send+0x12c/0x854 [xbee] 2639 | +LR is at xbee_send+0x12c/0x854 [xbee] 2640 | +pc : [] lr : [] psr: 60000113 2641 | +sp : da851e90 ip : 60000113 fp : 00000089 2642 | +r10: 0000006f r9 : da850000 r8 : 00000000 2643 | +r7 : 0000006f r6 : d99b49e0 r5 : d8511b40 r4 : da9c2660 2644 | +r3 : 00000000 r2 : c057f344 r1 : c0571a80 r0 : 00000025 2645 | +Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel 2646 | +Control: 00c5387d Table: 1aac0008 DAC: 00000017 2647 | + * 2648 | + */ 2649 | + } else { 2650 | + ret = 0; 2651 | + } 2652 | + 2653 | + if(raw_frame) 2654 | + { 2655 | +#ifdef __KERNEL__ 2656 | + kfree(raw_frame); 2657 | +#else 2658 | + free(raw_frame); 2659 | +#endif 2660 | + raw_frame = NULL; 2661 | + } 2662 | + 2663 | + if(_api_frame_should_wait_response(api_frame)) 2664 | + { 2665 | + //xbee_device_add_pendent_req(xbee_dev,api_frame); 2666 | +#ifdef __KERNEL__ 2667 | + INIT_COMPLETION(api_frame->complete); 2668 | + ret = wait_for_completion_interruptible_timeout( 2669 | + &api_frame->complete, 2670 | + 2 * HZ); 2671 | + if (ret == -ERESTARTSYS){ 2672 | + xbee_device_remove_pendent_req(xbee_dev,api_frame); 2673 | + goto err; 2674 | + } 2675 | + if (ret == 0) { 2676 | + xbee_device_remove_pendent_req(xbee_dev,api_frame); 2677 | + ret = -ETIMEDOUT; 2678 | + goto err; 2679 | + } 2680 | +#else 2681 | + printk(KERN_DEBUG "%s: waiting for response...\n", __func__); 2682 | + gettimeofday(&tv,NULL); 2683 | + waitspec.tv_sec = tv.tv_sec + 5; 2684 | + waitspec.tv_nsec = 0; 2685 | + pthread_mutex_lock(&api_frame->mutex); 2686 | + ret = pthread_cond_timedwait(&api_frame->complete,&api_frame->mutex,&waitspec); 2687 | + if(ret != 0 && ret != ETIMEDOUT){ 2688 | + printk(KERN_ERR "%s: some error occur waiting for status to change: %d", __func__, ret); 2689 | + pthread_mutex_unlock(&api_frame->mutex); 2690 | + goto err; 2691 | + } 2692 | + pthread_mutex_unlock(&api_frame->mutex); 2693 | + if(ret == ETIMEDOUT){ 2694 | + printk(KERN_DEBUG "%s: timeout!!!\n", __func__); 2695 | + goto err; 2696 | + }else{ 2697 | + printk(KERN_DEBUG "%s: response received\n", __func__); 2698 | + } 2699 | +#endif 2700 | + xbee_device_remove_pendent_req(xbee_dev,api_frame); 2701 | + if(!api_frame->response) 2702 | + { 2703 | + printk(KERN_DEBUG "%s: response not available\n", __func__); 2704 | + ret = -EBUSY; 2705 | + goto err; 2706 | + } 2707 | + ret = _api_frame_process_response(api_frame); 2708 | + if(ret) 2709 | + { 2710 | + printk(KERN_DEBUG "%s: error in response\n", __func__); 2711 | + goto err; 2712 | + } 2713 | + } 2714 | + 2715 | + 2716 | +err: 2717 | + pr_debug("%s(): ret: %d\n", __func__,ret); 2718 | + return ret; 2719 | +} 2720 | + 2721 | +/* 2722 | + * Frame API AT Command 2723 | + */ 2724 | + 2725 | +static _api_frame_t * 2726 | +_api_frame_new_at_command(struct xbee_device *xbee_dev,const char cmdid[3]) 2727 | +{ 2728 | + _api_frame_t *api_frame = NULL; 2729 | + api_frame = _api_frame_alloc(4,sizeof(api_frame_at_cmd_t)); 2730 | + if(api_frame == NULL) 2731 | + { 2732 | + printk(KERN_ERR "%s: error creating api_frame\n", __func__); 2733 | + BUG(); 2734 | + } 2735 | + api_frame->api_id = api_frame->api_data->at_cmd.api_id = FRAME_TYPE_AT_CMD; 2736 | + api_frame->api_data->at_cmd.frame_id = _xbee_device_gen_frame_id(xbee_dev); 2737 | + api_frame->api_data->at_cmd.at_command[0] = cmdid[0]; 2738 | + api_frame->api_data->at_cmd.at_command[1] = cmdid[1]; 2739 | + api_frame->api_data->at_cmd.parameter_value_len = 0; 2740 | + return api_frame; 2741 | +} 2742 | + 2743 | +static _api_frame_t * 2744 | +_api_frame_new_at_command_u8(struct xbee_device *xbee_dev,const char cmdid[3],uint8_t arg) 2745 | +{ 2746 | + _api_frame_t *api_frame = NULL; 2747 | + api_frame = _api_frame_alloc(5,sizeof(api_frame_at_cmd_t)); 2748 | + if(api_frame == NULL) 2749 | + { 2750 | + printk(KERN_ERR "%s: error creating api_frame\n", __func__); 2751 | + BUG(); 2752 | + } 2753 | + api_frame->api_id = api_frame->api_data->at_cmd.api_id = FRAME_TYPE_AT_CMD; 2754 | + api_frame->api_data->at_cmd.frame_id = _xbee_device_gen_frame_id(xbee_dev); 2755 | + api_frame->api_data->at_cmd.at_command[0] = cmdid[0]; 2756 | + api_frame->api_data->at_cmd.at_command[1] = cmdid[1]; 2757 | + api_frame->api_data->at_cmd.parameter_value[0] = arg; 2758 | + api_frame->api_data->at_cmd.parameter_value_len = 1; 2759 | + return api_frame; 2760 | +} 2761 | + 2762 | +static _api_frame_t * 2763 | +_api_frame_new_at_command_u16(struct xbee_device *xbee_dev,const char cmdid[3],uint8_t arg[2]) 2764 | +{ 2765 | + _api_frame_t *api_frame = NULL; 2766 | + api_frame = _api_frame_alloc(6,sizeof(api_frame_at_cmd_t)); 2767 | + if(api_frame == NULL) 2768 | + { 2769 | + printk(KERN_ERR "%s: error creating api_frame\n", __func__); 2770 | + BUG(); 2771 | + } 2772 | + api_frame->api_id = api_frame->api_data->at_cmd.api_id = FRAME_TYPE_AT_CMD; 2773 | + api_frame->api_data->at_cmd.frame_id = _xbee_device_gen_frame_id(xbee_dev); 2774 | + api_frame->api_data->at_cmd.at_command[0] = cmdid[0]; 2775 | + api_frame->api_data->at_cmd.at_command[1] = cmdid[1]; 2776 | + api_frame->api_data->at_cmd.parameter_value[0] = arg[0]; 2777 | + api_frame->api_data->at_cmd.parameter_value[1] = arg[1]; 2778 | + api_frame->api_data->at_cmd.parameter_value_len = 2; 2779 | + return api_frame; 2780 | +} 2781 | + 2782 | +static _api_frame_t * 2783 | +_api_frame_new_at_command_u32(struct xbee_device *xbee_dev,const char cmdid[3],uint8_t arg[4]) 2784 | +{ 2785 | + _api_frame_t *api_frame = NULL; 2786 | + api_frame = _api_frame_alloc(8,sizeof(api_frame_at_cmd_t)); 2787 | + if(api_frame == NULL) 2788 | + { 2789 | + printk(KERN_ERR "%s: error creating api_frame\n", __func__); 2790 | + BUG(); 2791 | + } 2792 | + api_frame->api_id = api_frame->api_data->at_cmd.api_id = FRAME_TYPE_AT_CMD; 2793 | + api_frame->api_data->at_cmd.frame_id = _xbee_device_gen_frame_id(xbee_dev); 2794 | + api_frame->api_data->at_cmd.at_command[0] = cmdid[0]; 2795 | + api_frame->api_data->at_cmd.at_command[1] = cmdid[1]; 2796 | + api_frame->api_data->at_cmd.parameter_value[0] = arg[0]; 2797 | + api_frame->api_data->at_cmd.parameter_value[1] = arg[1]; 2798 | + api_frame->api_data->at_cmd.parameter_value[2] = arg[2]; 2799 | + api_frame->api_data->at_cmd.parameter_value[3] = arg[3]; 2800 | + api_frame->api_data->at_cmd.parameter_value_len = 4; 2801 | + return api_frame; 2802 | +} 2803 | + 2804 | +/* 2805 | + * Frame API AT Command - Queue Parameter Value 2806 | + */ 2807 | + 2808 | +static _api_frame_t * 2809 | +_api_frame_new_at_command_queue(struct xbee_device *xbee_dev,const char cmdid[3]) 2810 | +{ 2811 | + _api_frame_t *api_frame = NULL; 2812 | + api_frame = _api_frame_alloc(4,sizeof(api_frame_at_cmd_queue_t)); 2813 | + if(api_frame == NULL) 2814 | + { 2815 | + printk(KERN_ERR "%s: error creating api_frame\n", __func__); 2816 | + BUG(); 2817 | + } 2818 | + api_frame->api_id = api_frame->api_data->at_cmd_queue.api_id = FRAME_TYPE_AT_CMD_QUEUE; 2819 | + api_frame->api_data->at_cmd_queue.frame_id = _xbee_device_gen_frame_id(xbee_dev); 2820 | + api_frame->api_data->at_cmd_queue.at_command[0] = cmdid[0]; 2821 | + api_frame->api_data->at_cmd_queue.at_command[1] = cmdid[1]; 2822 | + api_frame->api_data->at_cmd_queue.parameter_value_len = 0; 2823 | + return api_frame; 2824 | +} 2825 | + 2826 | +static _api_frame_t * 2827 | +_api_frame_new_at_command_queue_u8(struct xbee_device *xbee_dev,const char cmdid[3],uint8_t arg) 2828 | +{ 2829 | + _api_frame_t *api_frame = NULL; 2830 | + api_frame = _api_frame_alloc(5,sizeof(api_frame_at_cmd_queue_t)); 2831 | + if(api_frame == NULL) 2832 | + { 2833 | + printk(KERN_ERR "%s: error creating api_frame\n", __func__); 2834 | + BUG(); 2835 | + } 2836 | + api_frame->api_id = api_frame->api_data->at_cmd_queue.api_id = FRAME_TYPE_AT_CMD_QUEUE; 2837 | + api_frame->api_data->at_cmd_queue.frame_id = _xbee_device_gen_frame_id(xbee_dev); 2838 | + api_frame->api_data->at_cmd_queue.at_command[0] = cmdid[0]; 2839 | + api_frame->api_data->at_cmd_queue.at_command[1] = cmdid[1]; 2840 | + api_frame->api_data->at_cmd_queue.parameter_value[0] = arg; 2841 | + api_frame->api_data->at_cmd_queue.parameter_value_len = 1; 2842 | + return api_frame; 2843 | +} 2844 | + 2845 | +static _api_frame_t * 2846 | +_api_frame_new_at_command_queue_u16(struct xbee_device *xbee_dev,const char cmdid[3],uint8_t arg[2]) 2847 | +{ 2848 | + _api_frame_t *api_frame = NULL; 2849 | + api_frame = _api_frame_alloc(6,sizeof(api_frame_at_cmd_queue_t)); 2850 | + if(api_frame == NULL) 2851 | + { 2852 | + printk(KERN_ERR "%s: error creating api_frame\n", __func__); 2853 | + BUG(); 2854 | + } 2855 | + api_frame->api_id = api_frame->api_data->at_cmd_queue.api_id = FRAME_TYPE_AT_CMD_QUEUE; 2856 | + api_frame->api_data->at_cmd_queue.frame_id = _xbee_device_gen_frame_id(xbee_dev); 2857 | + api_frame->api_data->at_cmd_queue.at_command[0] = cmdid[0]; 2858 | + api_frame->api_data->at_cmd_queue.at_command[1] = cmdid[1]; 2859 | + api_frame->api_data->at_cmd_queue.parameter_value[0] = arg[0]; 2860 | + api_frame->api_data->at_cmd_queue.parameter_value[1] = arg[1]; 2861 | + api_frame->api_data->at_cmd_queue.parameter_value_len = 2; 2862 | + return api_frame; 2863 | +} 2864 | + 2865 | +static _api_frame_t * 2866 | +_api_frame_new_at_command_queue_u32(struct xbee_device *xbee_dev,const char cmdid[3],uint8_t arg[4]) 2867 | +{ 2868 | + _api_frame_t *api_frame = NULL; 2869 | + api_frame = _api_frame_alloc(8,sizeof(api_frame_at_cmd_queue_t)); 2870 | + if(api_frame == NULL) 2871 | + { 2872 | + printk(KERN_ERR "%s: error creating api_frame\n", __func__); 2873 | + BUG(); 2874 | + } 2875 | + api_frame->api_id = api_frame->api_data->at_cmd_queue.api_id = FRAME_TYPE_AT_CMD_QUEUE; 2876 | + api_frame->api_data->at_cmd_queue.frame_id = _xbee_device_gen_frame_id(xbee_dev); 2877 | + api_frame->api_data->at_cmd_queue.at_command[0] = cmdid[0]; 2878 | + api_frame->api_data->at_cmd_queue.at_command[1] = cmdid[1]; 2879 | + api_frame->api_data->at_cmd_queue.parameter_value[0] = arg[0]; 2880 | + api_frame->api_data->at_cmd_queue.parameter_value[1] = arg[1]; 2881 | + api_frame->api_data->at_cmd_queue.parameter_value[2] = arg[2]; 2882 | + api_frame->api_data->at_cmd_queue.parameter_value[3] = arg[3]; 2883 | + api_frame->api_data->at_cmd_queue.parameter_value_len = 4; 2884 | + return api_frame; 2885 | +} 2886 | + 2887 | +/* 2888 | + * Frame API Transmit Request 2889 | + */ 2890 | + 2891 | +static _api_frame_t * 2892 | +_api_frame_new_transmit_request(struct xbee_device *xbee_dev, 2893 | + uint8_t dst_addr[XBEE_ADDR_LEN], uint8_t options, uint8_t *payload, 2894 | + uint16_t payload_len) { 2895 | + _api_frame_t *api_frame = NULL; 2896 | + size_t frame_len = 1 /* frame type */ + 2897 | + 1 /* frameID*/ + 2898 | + XBEE_ADDR_LEN + 2899 | + 2 /* reserved */ + 2900 | + 1 /* broadcast radius */ + 2901 | + 1 /* transmit options */ + 2902 | + payload_len; 2903 | + api_frame = _api_frame_alloc(frame_len,sizeof(api_frame_transmit_req_t)); 2904 | + if (api_frame == NULL ) { 2905 | + printk(KERN_ERR "%s: error creating api_frame\n", __func__); 2906 | + BUG(); 2907 | + } 2908 | + api_frame->api_id = api_frame->api_data->transmit_req.api_id = FRAME_TYPE_TRANSMIT_REQ; 2909 | + api_frame->api_data->transmit_req.frame_id = _xbee_device_gen_frame_id(xbee_dev); 2910 | + memcpy(api_frame->api_data->transmit_req.dst_addr, dst_addr, XBEE_ADDR_LEN); 2911 | + api_frame->api_data->transmit_req.reserved = 0xFFFE; 2912 | + api_frame->api_data->transmit_req.brd_radius = XBEE_DEFAULT_BROADCAST_RADIUS; 2913 | + api_frame->api_data->transmit_req.options = options; 2914 | + api_frame->api_data->transmit_req.payload = payload; 2915 | + api_frame->api_data->transmit_req.payload_len = payload_len; 2916 | + return api_frame; 2917 | +} 2918 | + 2919 | +/* 2920 | + * Frame API IEEE 802.15.4 Raw Packet 2921 | + */ 2922 | + 2923 | +static _api_frame_t * 2924 | +_api_frame_new_raw_packet(struct xbee_device *xbee_dev, uint8_t *payload, uint16_t payload_len) { 2925 | + _api_frame_t *api_frame = NULL; 2926 | + size_t frame_len = 1 /* frame type */ + 2927 | + payload_len; 2928 | + api_frame = _api_frame_alloc(frame_len,sizeof(api_frame_transmit_req_t)); 2929 | + if (api_frame == NULL ) { 2930 | + printk(KERN_ERR "%s: error creating api_frame\n", __func__); 2931 | + BUG(); 2932 | + } 2933 | + api_frame->api_id = api_frame->api_data->raw_packet.api_id = FRAME_TYPE_RAW_TRANSMIT_REQ; 2934 | + api_frame->api_data->raw_packet.frame_id = _xbee_device_gen_frame_id(xbee_dev); 2935 | + api_frame->api_data->raw_packet.payload = payload; 2936 | + api_frame->api_data->raw_packet.payload_len = payload_len; 2937 | + return api_frame; 2938 | +} 2939 | + 2940 | +/* 2941 | + * Frame API Explicit Addressing Command 2942 | + */ 2943 | + 2944 | +//static _api_frame_t * 2945 | +//_api_frame_new_explicit_addressing(struct xbee_device *xbee_dev, 2946 | +// uint8_t dst_addr[XBEE_ADDR_LEN], uint8_t options, uint8_t *payload, 2947 | +// uint16_t payload_len) { 2948 | +// //TODO: _api_frame_new_explicit_addressing: not implemented 2949 | +// return NULL; 2950 | +//} 2951 | + 2952 | +/* 2953 | + * Frame API Remote AT Command Request 2954 | + */ 2955 | + 2956 | +//static _api_frame_t * 2957 | +//_api_frame_new_remote_at_command(struct xbee_device *xbee_dev, 2958 | +// uint8_t dst_addr[XBEE_ADDR_LEN], const char cmdid[3]) { 2959 | +// //TODO: _api_frame_new_remote_at_command_u32: not implemented 2960 | +// return NULL ; 2961 | +//} 2962 | +// 2963 | +//static _api_frame_t * 2964 | +//_api_frame_new_remote_at_command_u8(struct xbee_device *xbee_dev, 2965 | +// uint8_t dst_addr[XBEE_ADDR_LEN], const char cmdid[3], uint8_t arg[1]) { 2966 | +// //TODO: _api_frame_new_remote_at_command_u8: not implemented 2967 | +// return NULL ; 2968 | +//} 2969 | +// 2970 | +//static _api_frame_t * 2971 | +//_api_frame_new_remote_at_command_u16(struct xbee_device *xbee_dev, 2972 | +// uint8_t dst_addr[XBEE_ADDR_LEN], const char cmdid[3], uint8_t arg[2]) { 2973 | +// //TODO: _api_frame_new_remote_at_command_u16: not implemented 2974 | +// return NULL ; 2975 | +//} 2976 | +// 2977 | +//static _api_frame_t * 2978 | +//_api_frame_new_remote_at_command_u32(struct xbee_device *xbee_dev, 2979 | +// uint8_t dst_addr[XBEE_ADDR_LEN], const char cmdid[3], uint8_t arg[4]) { 2980 | +// //TODO: _api_frame_new_remote_at_command_u32: not implemented 2981 | +// return NULL ; 2982 | +//} 2983 | + 2984 | +/* 2985 | + * XBee AT Command Read 32 bit parameter 2986 | + */ 2987 | + 2988 | +static int 2989 | +xbee_api_at_command_read_uN(struct xbee_device *xbee_dev, const char cmdid[3], uint8_t value[4], uint8_t len) 2990 | +{ 2991 | + int ret = 0; 2992 | + int i = 0; 2993 | + _api_frame_t *api_frame = NULL; 2994 | + 2995 | + if (NULL == xbee_dev) { 2996 | + printk(KERN_ERR "%s: wrong xbee device\n", __func__); 2997 | + return -EINVAL; 2998 | + } 2999 | + 3000 | + api_frame = _api_frame_new_at_command(xbee_dev,cmdid); 3001 | + 3002 | + ret = xbee_send(xbee_dev,api_frame); 3003 | + 3004 | + if(ret) 3005 | + { 3006 | + printk(KERN_ERR "%s: error sending API frame: %s: %d\n", __func__,cmdid,ret); 3007 | + goto err; 3008 | + } 3009 | + 3010 | + if(!api_frame->response) 3011 | + { 3012 | + printk(KERN_ERR "%s: response is NULL\n", __func__); 3013 | + ret = -EAGAIN; 3014 | + goto err; 3015 | + } 3016 | + 3017 | + if(api_frame->response->api_data->at_cmd_resp.cmd_data_len != len) 3018 | + { 3019 | + printk(KERN_ERR "%s: invalid response value len\n", __func__); 3020 | + ret = -EAGAIN; 3021 | + goto err; 3022 | + } 3023 | + 3024 | + _api_frame_print(api_frame); 3025 | + if(api_frame && api_frame->response) 3026 | + _api_frame_print(api_frame->response); 3027 | + 3028 | + for(i=0;iresponse->api_data->at_cmd_resp.cmd_data_len;i++) 3029 | + { 3030 | + value[i] = api_frame->response->api_data->at_cmd_resp.cmd_data[i]; 3031 | + } 3032 | + 3033 | + pr_debug("%s(): xbee_send ret: %d\n", __func__,ret); 3034 | + 3035 | +err: 3036 | + if(api_frame) 3037 | + { 3038 | + _api_frame_free(api_frame); 3039 | + } 3040 | + 3041 | + return 0; 3042 | +} 3043 | + 3044 | +static int 3045 | +xbee_api_at_command_read_u8(struct xbee_device *xbee_dev, const char cmdid[3], uint8_t value[1]) 3046 | +{ 3047 | + return xbee_api_at_command_read_uN(xbee_dev,cmdid,value,1); 3048 | +} 3049 | + 3050 | +static int 3051 | +xbee_api_at_command_read_u16(struct xbee_device *xbee_dev, const char cmdid[3], uint8_t value[2]) 3052 | +{ 3053 | + return xbee_api_at_command_read_uN(xbee_dev,cmdid,value,2); 3054 | +} 3055 | + 3056 | +static int 3057 | +xbee_api_at_command_read_u32(struct xbee_device *xbee_dev, const char cmdid[3], uint8_t value[4]) 3058 | +{ 3059 | + return xbee_api_at_command_read_uN(xbee_dev,cmdid,value,4); 3060 | +} 3061 | + 3062 | +#ifndef __KERNEL__ 3063 | +static void 3064 | +dump_hex(uint8_t *buf, int len); 3065 | +#endif 3066 | + 3067 | +//static int 3068 | +//xbee_ieee_address(struct xbee_device *xbee_dev, uint8_t addr[IEEE802154_ADDR_LEN]) 3069 | +////xbee_ieee_address(struct ieee802154_dev *dev, uint8_t addr[IEEE802154_ADDR_LEN]) 3070 | +//{ 3071 | +// //struct xbee_device *xbee_dev = NULL; 3072 | +// 3073 | +//// uint8_t serial_number_high[4] = {}; 3074 | +//// uint8_t serial_number_low[4] = {}; 3075 | +// 3076 | +// int ret = 0; 3077 | +// pr_debug("%s\n", __func__); 3078 | +// 3079 | +// //xbee_dev = dev->priv; 3080 | +// if (NULL == xbee_dev) { 3081 | +// printk(KERN_ERR "%s: wrong phy\n", __func__); 3082 | +// return -EINVAL; 3083 | +// } 3084 | +// 3085 | +// //ret = xbee_api_at_command_read_u32(xbee_dev,"SH",serial_number_high); 3086 | +// ret = xbee_api_at_command_read_u32(xbee_dev,"SH",addr); 3087 | +// if(ret) 3088 | +// { 3089 | +// printk(KERN_ERR "%s: error getting serial high value\n", __func__); 3090 | +// return ret; 3091 | +// } 3092 | +// //dump_hex(serial_number_high, 4); printf("\n"); 3093 | +// 3094 | +// //ret = xbee_api_at_command_read_u32(xbee_dev,"SL",serial_number_low); 3095 | +// ret = xbee_api_at_command_read_u32(xbee_dev,"SL",addr+4); 3096 | +// if(ret) 3097 | +// { 3098 | +// printk(KERN_ERR "%s: error getting serial low value\n", __func__); 3099 | +// return ret; 3100 | +// } 3101 | +// //dump_hex(serial_number_low, 4); printf("\n"); 3102 | +// 3103 | +//#ifndef __KERNEL__ 3104 | +// dump_hex(addr, 8); printf("\n"); 3105 | +//#endif 3106 | +// pr_debug("%s end\n", __func__); 3107 | +// return ret; 3108 | +//} 3109 | + 3110 | +static uint8_t 3111 | +xbee_get_rssi(struct ieee802154_dev *dev) 3112 | +{ 3113 | + struct xbee_device *xbee_dev = NULL; 3114 | + uint8_t result = 0x00; 3115 | + int ret = 0; 3116 | + pr_debug("%s\n", __func__); 3117 | + 3118 | + xbee_dev = dev->priv; 3119 | + if (NULL == xbee_dev) { 3120 | + printk(KERN_ERR "%s: wrong phy\n", __func__); 3121 | + return -EINVAL; 3122 | + } 3123 | + 3124 | + ret = xbee_api_at_command_read_u8(xbee_dev,"DB",&result); 3125 | + if(ret) 3126 | + { 3127 | + printk(KERN_ERR "%s: error getting RSSI value\n", __func__); 3128 | + return ret; 3129 | + } 3130 | + 3131 | + global_lqi = result; 3132 | + 3133 | +#ifndef __KERNEL__ 3134 | + dump_hex(addr, 8); printf("\n"); 3135 | +#endif 3136 | + pr_debug("%s end\n", __func__); 3137 | + return result; 3138 | +} 3139 | + 3140 | +//static uint16_t 3141 | +//xbee_get_pan_id(struct ieee802154_dev *dev) 3142 | +//{ 3143 | +// struct xbee_device *xbee_dev = NULL; 3144 | +// uint8_t at_cmd_result[4] = {0,0,0,0}; 3145 | +// uint16_t result = 0x0000; 3146 | +// int ret = 0; 3147 | +// pr_debug("%s\n", __func__); 3148 | +// 3149 | +// xbee_dev = dev->priv; 3150 | +// if (NULL == xbee_dev) { 3151 | +// printk(KERN_ERR "%s: wrong phy\n", __func__); 3152 | +// return -EINVAL; 3153 | +// } 3154 | +// 3155 | +// ret = xbee_api_at_command_read_u16(xbee_dev,"ID",&at_cmd_result); 3156 | +// if(ret) 3157 | +// { 3158 | +// printk(KERN_ERR "%s: error getting network id value\n", __func__); 3159 | +// return ret; 3160 | +// } 3161 | +//#ifndef __KERNEL__ 3162 | +// dump_hex(addr, 8); printf("\n"); 3163 | +//#endif 3164 | +// result = ((at_cmd_result[0] << 8) & 0xFF00) + (at_cmd_result[1] & 0xFF); 3165 | +// 3166 | +// pr_debug("%s end\n", __func__); 3167 | +// return result; 3168 | +//} 3169 | + 3170 | +static uint8_t 3171 | +xbee_get_dsn(struct ieee802154_dev *dev) 3172 | +{ 3173 | + struct xbee_device *xbee_dev = NULL; 3174 | + uint8_t dsn = 0x00; 3175 | + pr_debug("%s\n", __func__); 3176 | + 3177 | + xbee_dev = dev->priv; 3178 | + if (NULL == xbee_dev) { 3179 | + printk(KERN_ERR "%s: wrong phy\n", __func__); 3180 | + return -EINVAL; 3181 | + } 3182 | + 3183 | +#ifdef __KERNEL__ 3184 | + mutex_lock(&xbee_dev->mutex); 3185 | +#else 3186 | + pthread_mutex_lock(&xbee_dev->mutex); 3187 | +#endif 3188 | + dsn = xbee_dev->frame_id_counter; 3189 | +#ifdef __KERNEL__ 3190 | + mutex_unlock(&xbee_dev->mutex); 3191 | +#else 3192 | + pthread_mutex_unlock(&xbee_dev->mutex); 3193 | +#endif 3194 | + 3195 | + pr_debug("%s end\n", __func__); 3196 | + return dsn; 3197 | +} 3198 | + 3199 | +#ifdef __KERNEL__ 3200 | + 3201 | +/* 3202 | + * MAC802154 parsing functions 3203 | + */ 3204 | + 3205 | +static inline int mac802154_fetch_skb_u8(struct sk_buff *skb, u8 *val) 3206 | +{ 3207 | + if (unlikely(!pskb_may_pull(skb, 1))) 3208 | + return -EINVAL; 3209 | + 3210 | + *val = skb->data[0]; 3211 | + skb_pull(skb, 1); 3212 | + 3213 | + return 0; 3214 | +} 3215 | + 3216 | +static inline int mac802154_fetch_skb_u16(struct sk_buff *skb, u16 *val) 3217 | +{ 3218 | + if (unlikely(!pskb_may_pull(skb, 2))) 3219 | + return -EINVAL; 3220 | + 3221 | + *val = skb->data[0] | (skb->data[1] << 8); 3222 | + skb_pull(skb, 2); 3223 | + 3224 | + return 0; 3225 | +} 3226 | + 3227 | +static inline void mac802154_haddr_copy_swap(u8 *dest, const u8 *src) 3228 | +{ 3229 | + int i; 3230 | + for (i = 0; i < IEEE802154_ADDR_LEN; i++) 3231 | + dest[IEEE802154_ADDR_LEN - i - 1] = src[i]; 3232 | +} 3233 | + 3234 | +static int mac802154_parse_frame_start(struct sk_buff *skb) 3235 | +{ 3236 | + u8 *head = skb->data; 3237 | + u16 fc; 3238 | + 3239 | + if (mac802154_fetch_skb_u16(skb, &fc) || 3240 | + mac802154_fetch_skb_u8(skb, &(mac_cb(skb)->seq))) 3241 | + goto err; 3242 | + 3243 | + pr_debug("fc: %04x dsn: %02x\n", fc, head[2]); 3244 | + 3245 | + mac_cb(skb)->flags = IEEE802154_FC_TYPE(fc); 3246 | + mac_cb(skb)->sa.addr_type = IEEE802154_FC_SAMODE(fc); 3247 | + mac_cb(skb)->da.addr_type = IEEE802154_FC_DAMODE(fc); 3248 | + 3249 | + if (fc & IEEE802154_FC_INTRA_PAN) 3250 | + mac_cb(skb)->flags |= MAC_CB_FLAG_INTRAPAN; 3251 | + 3252 | + if (mac_cb(skb)->da.addr_type != IEEE802154_ADDR_NONE) { 3253 | + if (mac802154_fetch_skb_u16(skb, &(mac_cb(skb)->da.pan_id))) 3254 | + goto err; 3255 | + 3256 | + /* source PAN id compression */ 3257 | + if (mac_cb_is_intrapan(skb)) 3258 | + mac_cb(skb)->sa.pan_id = mac_cb(skb)->da.pan_id; 3259 | + 3260 | + pr_debug("dest PAN addr: %04x\n", mac_cb(skb)->da.pan_id); 3261 | + 3262 | + if (mac_cb(skb)->da.addr_type == IEEE802154_ADDR_SHORT) { 3263 | + u16 *da = &(mac_cb(skb)->da.short_addr); 3264 | + 3265 | + if (mac802154_fetch_skb_u16(skb, da)) 3266 | + goto err; 3267 | + 3268 | + pr_debug("destination address is short: %04x\n", 3269 | + mac_cb(skb)->da.short_addr); 3270 | + } else { 3271 | + if (!pskb_may_pull(skb, IEEE802154_ADDR_LEN)) 3272 | + goto err; 3273 | + 3274 | + mac802154_haddr_copy_swap(mac_cb(skb)->da.hwaddr, 3275 | + skb->data); 3276 | + skb_pull(skb, IEEE802154_ADDR_LEN); 3277 | + 3278 | + pr_debug("destination address is hardware\n"); 3279 | + } 3280 | + } 3281 | + 3282 | + if (mac_cb(skb)->sa.addr_type != IEEE802154_ADDR_NONE) { 3283 | + /* non PAN-compression, fetch source address id */ 3284 | + if (!(mac_cb_is_intrapan(skb))) { 3285 | + u16 *sa_pan = &(mac_cb(skb)->sa.pan_id); 3286 | + 3287 | + if (mac802154_fetch_skb_u16(skb, sa_pan)) 3288 | + goto err; 3289 | + } 3290 | + 3291 | + pr_debug("source PAN addr: %04x\n", mac_cb(skb)->da.pan_id); 3292 | + 3293 | + if (mac_cb(skb)->sa.addr_type == IEEE802154_ADDR_SHORT) { 3294 | + u16 *sa = &(mac_cb(skb)->sa.short_addr); 3295 | + 3296 | + if (mac802154_fetch_skb_u16(skb, sa)) 3297 | + goto err; 3298 | + 3299 | + pr_debug("source address is short: %04x\n", 3300 | + mac_cb(skb)->sa.short_addr); 3301 | + } else { 3302 | + if (!pskb_may_pull(skb, IEEE802154_ADDR_LEN)) 3303 | + goto err; 3304 | + 3305 | + mac802154_haddr_copy_swap(mac_cb(skb)->sa.hwaddr, 3306 | + skb->data); 3307 | + skb_pull(skb, IEEE802154_ADDR_LEN); 3308 | + 3309 | + pr_debug("source address is hardware\n"); 3310 | + } 3311 | + } 3312 | + 3313 | + return 0; 3314 | +err: 3315 | + return -EINVAL; 3316 | +} 3317 | + 3318 | +/* 3319 | + * to bind XBEE RX API frame to a ieee802154_addr 3320 | + * addr_type = IEEE802154_ADDR_LONG (EUI-64 + PanId) 3321 | + * pan_id = network ID (cmd ATID result should be used) 3322 | + * hwaddr = RX EUI-64bit addr from API 3323 | +struct ieee802154_addr { 3324 | + int addr_type; 3325 | + u16 pan_id; 3326 | + union { 3327 | + u8 hwaddr[IEEE802154_ADDR_LEN]; 3328 | + u16 short_addr; 3329 | + }; 3330 | +}; 3331 | + * 3332 | + */ 3333 | + 3334 | +static int mac802154_header_create(struct sk_buff *skb, 3335 | + struct ieee802154_dev *dev, 3336 | + unsigned short type, 3337 | + const void *_daddr, 3338 | + const void *_saddr, 3339 | + unsigned len) 3340 | +{ 3341 | + const struct ieee802154_addr *saddr = _saddr; 3342 | + const struct ieee802154_addr *daddr = _daddr; 3343 | + struct ieee802154_addr dev_addr; 3344 | + struct xbee_device *xbee_dev = dev->priv; 3345 | + int pos = 2; 3346 | + u8 head[MAC802154_FRAME_HARD_HEADER_LEN]; 3347 | + u16 fc; 3348 | + 3349 | + if (!daddr) 3350 | + return -EINVAL; 3351 | + 3352 | + //head[pos++] = mac_cb(skb)->seq; /* DSN/BSN */ /* we should use FrameID here!!!! */ 3353 | + //head[pos++] = xbee_get_dsn(dev); 3354 | + head[pos++] = 0; 3355 | + fc = mac_cb_type(skb); 3356 | + 3357 | + if (!saddr) { 3358 | + //spin_lock_bh(&zbdev->mib_lock); 3359 | + 3360 | +// if (zbdev->short_addr == IEEE802154_ADDR_BROADCAST || 3361 | +// zbdev->short_addr == IEEE802154_ADDR_UNDEF || 3362 | +// zbdev->pan_id == IEEE802154_PANID_BROADCAST) { 3363 | + dev_addr.addr_type = IEEE802154_ADDR_LONG; 3364 | +// 3365 | + // replace here with EUI64 of the hw 3366 | + memcpy(dev_addr.hwaddr, xbee_dev->dev_addr, IEEE802154_ADDR_LEN); 3367 | +// } else { 3368 | +// dev_addr.addr_type = IEEE802154_ADDR_SHORT; 3369 | +// dev_addr.short_addr = zbdev->short_addr; 3370 | +// } 3371 | + 3372 | + dev_addr.pan_id = xbee_dev->pan_id; // network addr ATID? 3373 | + saddr = &dev_addr; 3374 | + 3375 | + //spin_unlock_bh(&zbdev->mib_lock); 3376 | + } 3377 | + 3378 | + if (daddr->addr_type != IEEE802154_ADDR_NONE) { 3379 | + fc |= (daddr->addr_type << IEEE802154_FC_DAMODE_SHIFT); 3380 | + 3381 | + head[pos++] = daddr->pan_id & 0xff; 3382 | + head[pos++] = daddr->pan_id >> 8; 3383 | + 3384 | + if (daddr->addr_type == IEEE802154_ADDR_SHORT) { 3385 | + head[pos++] = daddr->short_addr & 0xff; 3386 | + head[pos++] = daddr->short_addr >> 8; 3387 | + } else { 3388 | + mac802154_haddr_copy_swap(head + pos, daddr->hwaddr); 3389 | + pos += IEEE802154_ADDR_LEN; 3390 | + } 3391 | + } 3392 | + 3393 | + if (saddr->addr_type != IEEE802154_ADDR_NONE) { 3394 | + fc |= (saddr->addr_type << IEEE802154_FC_SAMODE_SHIFT); 3395 | + 3396 | + if ((saddr->pan_id == daddr->pan_id) && 3397 | + (saddr->pan_id != IEEE802154_PANID_BROADCAST)) { 3398 | + /* PANID compression/intra PAN */ 3399 | + fc |= IEEE802154_FC_INTRA_PAN; 3400 | + } else { 3401 | + head[pos++] = saddr->pan_id & 0xff; 3402 | + head[pos++] = saddr->pan_id >> 8; 3403 | + } 3404 | + 3405 | + if (saddr->addr_type == IEEE802154_ADDR_SHORT) { 3406 | + head[pos++] = saddr->short_addr & 0xff; 3407 | + head[pos++] = saddr->short_addr >> 8; 3408 | + } else { 3409 | + mac802154_haddr_copy_swap(head + pos, saddr->hwaddr); 3410 | + pos += IEEE802154_ADDR_LEN; 3411 | + } 3412 | + } 3413 | + 3414 | + head[0] = fc; 3415 | + head[1] = fc >> 8; 3416 | + 3417 | + memcpy(skb_push(skb, pos), head, pos); 3418 | + 3419 | + return pos; 3420 | +} 3421 | + 3422 | +//#define DEBUG 1 3423 | +static int enable_debug = 0; 3424 | + 3425 | +static int 3426 | +ieee802154_hm_trp_xmit(struct ieee802154_dev *dev, struct sk_buff *skb){ 3427 | + struct xbee_device *xbee_dev = NULL; 3428 | + _api_frame_t *api_frame = NULL; 3429 | + 3430 | + struct sk_buff *sskb = NULL; 3431 | + int ret = 0; 3432 | + 3433 | + xbee_dev = dev->priv; 3434 | + if (NULL == xbee_dev) { 3435 | + printk(KERN_ERR "%s: wrong phy\n", __func__); 3436 | + return -EINVAL; 3437 | + } 3438 | + pr_debug("%s(): recv_state: %d\n", __func__, xbee_dev->recv_state); 3439 | + 3440 | + pr_debug("%s(): BEFORE wait\n", __func__); 3441 | + if (wait_event_interruptible_timeout(xbee_dev->wq, 3442 | + xbee_dev->recv_state == RECV_STATE_WAIT_START_DELIM, 3443 | + msecs_to_jiffies(1000)) > 0) { 3444 | + pr_debug("%s(): AFTER wait\n", __func__); 3445 | + } else { 3446 | + ret = -ETIMEDOUT; 3447 | + pr_debug("%s(): TIMEOUT\n", __func__); 3448 | + goto out; 3449 | + } 3450 | + 3451 | + sskb = skb_clone(skb, GFP_ATOMIC); 3452 | + if (sskb) { 3453 | + api_frame = _api_frame_new_raw_packet(xbee_dev,sskb->data,sskb->len); 3454 | + 3455 | + if(api_frame){ 3456 | + _api_frame_print(api_frame); 3457 | + 3458 | + ret = xbee_send(xbee_dev,api_frame); 3459 | + if(ret){ 3460 | + ret = -EAGAIN; 3461 | + if(enable_debug){ 3462 | + print_hex_dump_bytes("ieee802154_serial_xmit(): before parse: ", DUMP_PREFIX_NONE,sskb->data, sskb->len); 3463 | + } 3464 | + } 3465 | + pr_debug("%s: xbee_send ret: %d\n", __func__,ret); 3466 | + _api_frame_free(api_frame); 3467 | + } else { 3468 | + ret = -ENOMEM; 3469 | + printk(KERN_DEBUG "%s: xbee_send ret: %d\n", __func__,ret); 3470 | + } 3471 | + kfree_skb(sskb); 3472 | + } 3473 | +out: 3474 | + pr_debug("%s end\n", __func__); 3475 | + return ret; 3476 | +} 3477 | + 3478 | +static int 3479 | +ieee802154_xbee_xmit(struct ieee802154_dev *dev, struct sk_buff *skb){ 3480 | + u8 broadcast_check = 0x00; 3481 | + u8 xbee_broadcast_addr[XBEE_ADDR_LEN] = {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF}; 3482 | + struct xbee_device *xbee_dev = NULL; 3483 | + _api_frame_t *api_frame = NULL; 3484 | + 3485 | + struct sk_buff *sskb = NULL; 3486 | + int ret = 0; 3487 | + 3488 | + xbee_dev = dev->priv; 3489 | + if (NULL == xbee_dev) { 3490 | + printk(KERN_ERR "%s: wrong phy\n", __func__); 3491 | + return -EINVAL; 3492 | + } 3493 | + pr_debug("%s(): recv_state: %d\n", __func__, xbee_dev->recv_state); 3494 | + 3495 | + pr_debug("%s(): BEFORE wait\n", __func__); 3496 | + if (wait_event_interruptible_timeout(xbee_dev->wq, 3497 | + xbee_dev->recv_state == RECV_STATE_WAIT_START_DELIM, 3498 | + msecs_to_jiffies(1000)) > 0) { 3499 | + pr_debug("%s(): AFTER wait\n", __func__); 3500 | + } else { 3501 | + ret = -ETIMEDOUT; 3502 | + pr_debug("%s(): TIMEOUT\n", __func__); 3503 | + goto out; 3504 | + } 3505 | + 3506 | + sskb = skb_clone(skb, GFP_ATOMIC); 3507 | + if (sskb) { 3508 | + 3509 | +#ifdef DEBUG 3510 | + print_hex_dump_bytes("ieee802154_serial_xmit(): before parse: ", DUMP_PREFIX_NONE, 3511 | + skb->data, skb->len); 3512 | +#endif 3513 | + mac802154_parse_frame_start(sskb); 3514 | + pr_debug("%s(): type: %d\n", __func__, sskb->pkt_type); 3515 | + pr_debug("%s(): mac_len: %d\n", __func__, sskb->mac_len); 3516 | + pr_debug("%s(): len: %d\n", __func__, sskb->len); 3517 | +#ifdef DEBUG 3518 | + print_hex_dump_bytes("ieee802154_serial_xmit(): mac_header: ", DUMP_PREFIX_NONE, 3519 | + sskb->mac_header, sskb->mac_len); 3520 | +#endif 3521 | + 3522 | + pr_debug("%s(): sa.addr_type: %d\n", __func__, mac_cb(sskb)->sa.addr_type); 3523 | +#ifdef DEBUG 3524 | + print_hex_dump_bytes("ieee802154_serial_xmit(): sa.hwaddr: ", DUMP_PREFIX_NONE, 3525 | + mac_cb(sskb)->sa.hwaddr, 8); 3526 | +#endif 3527 | + pr_debug("%s(): da.addr_type: %d\n", __func__, mac_cb(sskb)->da.addr_type); 3528 | +#ifdef DEBUG 3529 | + print_hex_dump_bytes("ieee802154_serial_xmit(): da.hwaddr: ", DUMP_PREFIX_NONE, 3530 | + mac_cb(sskb)->da.hwaddr, 8); 3531 | +#endif 3532 | +#ifdef DEBUG 3533 | + print_hex_dump_bytes("ieee802154_serial_xmit(): data: ", DUMP_PREFIX_NONE, 3534 | + sskb->data, sskb->len); 3535 | +#endif 3536 | + 3537 | + /* 3538 | + * check if da.hwaddr is broadcast (0xFFFFFFFFFFFFFFFF) and 3539 | + * ERRATA: check if da.hwaddr is broadcast (0xFFFF0000000000) and 3540 | + * replace with 0x000000000000FFFF 3541 | + */ 3542 | + if(mac_cb(sskb)->da.hwaddr[0] == 0xFF && 3543 | + mac_cb(sskb)->da.hwaddr[1] == 0xFF && 3544 | + mac_cb(sskb)->da.hwaddr[2] == 0x00 && 3545 | + mac_cb(sskb)->da.hwaddr[3] == 0x00 && 3546 | + mac_cb(sskb)->da.hwaddr[4] == 0x00 && 3547 | + mac_cb(sskb)->da.hwaddr[5] == 0x00 && 3548 | + mac_cb(sskb)->da.hwaddr[6] == 0x00 && 3549 | + mac_cb(sskb)->da.hwaddr[7] == 0x00 3550 | + ){ 3551 | + broadcast_check = 0xFF; 3552 | + } 3553 | + if(broadcast_check == 0xFF){ 3554 | + api_frame = _api_frame_new_transmit_request(xbee_dev,xbee_broadcast_addr,0x00,skb->data,skb->len); 3555 | + //api_frame = _api_frame_new_transmit_request_splited(xbee_dev,xbee_broadcast_addr,0x00,sskb->data,sskb->len); 3556 | + } else { 3557 | + api_frame = _api_frame_new_transmit_request(xbee_dev,xbee_broadcast_addr,0x00,skb->data,skb->len); 3558 | + //api_frame = _api_frame_new_transmit_request_splited(xbee_dev,mac_cb(sskb)->da.hwaddr,0x00,sskb->data,sskb->len); 3559 | + } 3560 | + 3561 | + if(api_frame){ 3562 | + _api_frame_print(api_frame); 3563 | + 3564 | + ret = xbee_send(xbee_dev,api_frame); 3565 | + if(ret){ 3566 | + ret = -EAGAIN; 3567 | + if(enable_debug){ 3568 | + print_hex_dump_bytes("ieee802154_serial_xmit(): before parse: ", DUMP_PREFIX_NONE,skb->data, skb->len); 3569 | + pr_debug("%s(): type: %d\n", __func__, sskb->pkt_type); 3570 | + pr_debug("%s(): mac_len: %d\n", __func__, sskb->mac_len); 3571 | + pr_debug("%s(): len: %d\n", __func__, sskb->len); 3572 | + print_hex_dump_bytes("ieee802154_serial_xmit(): mac_header: ", DUMP_PREFIX_NONE, 3573 | + sskb->mac_header, sskb->mac_len); 3574 | + printk(KERN_DEBUG "%s(): sa.addr_type: %d\n", __func__, mac_cb(sskb)->sa.addr_type); 3575 | + print_hex_dump_bytes("ieee802154_serial_xmit(): sa.hwaddr: ", DUMP_PREFIX_NONE, 3576 | + mac_cb(sskb)->sa.hwaddr, 8); 3577 | + printk(KERN_DEBUG "%s(): da.addr_type: %d\n", __func__, mac_cb(sskb)->da.addr_type); 3578 | + print_hex_dump_bytes("ieee802154_serial_xmit(): da.hwaddr: ", DUMP_PREFIX_NONE, 3579 | + mac_cb(sskb)->da.hwaddr, 8); 3580 | + print_hex_dump_bytes("ieee802154_serial_xmit(): data: ", DUMP_PREFIX_NONE, 3581 | + sskb->data, sskb->len); 3582 | + } 3583 | + 3584 | + } 3585 | + pr_debug("%s: xbee_send ret: %d\n", __func__,ret); 3586 | + _api_frame_free(api_frame); 3587 | + } else { 3588 | + ret = -ENOMEM; 3589 | + printk(KERN_DEBUG "%s: xbee_send ret: %d\n", __func__,ret); 3590 | + } 3591 | + kfree_skb(sskb); 3592 | + } 3593 | +out: 3594 | + pr_debug("%s end\n", __func__); 3595 | + return ret; 3596 | +} 3597 | + 3598 | +static int 3599 | +ieee802154_xmit(struct ieee802154_dev *dev, struct sk_buff *skb){ 3600 | + struct xbee_device *xbee_dev = NULL; 3601 | + int ret = 0; 3602 | + int mote_type = UNKNOWN_MOTE; 3603 | + xbee_dev = dev->priv; 3604 | + if (NULL == xbee_dev) { 3605 | + printk(KERN_ERR "%s: wrong phy\n", __func__); 3606 | + return -EINVAL; 3607 | + } 3608 | + 3609 | + mote_type = xbee_device_get_type(xbee_dev); 3610 | + 3611 | + switch(mote_type){ 3612 | + case XBEE_XB08_DP_MOTE: 3613 | + ret = ieee802154_xbee_xmit(dev,skb); 3614 | + break; 3615 | + case HM_TRP_433D_MOTE: 3616 | + case HM_TRP_868D_MOTE: 3617 | + ret = ieee802154_hm_trp_xmit(dev,skb); 3618 | + break; 3619 | + default: 3620 | + ret = -ENOTSUPP; 3621 | + break; 3622 | + } 3623 | + 3624 | + return ret; 3625 | +} 3626 | + 3627 | +static int 3628 | +ieee802154_xbee_ed(struct ieee802154_dev *dev, u8 *level){ 3629 | + int ret = 0; 3630 | + int mote_type = UNKNOWN_MOTE; 3631 | + struct xbee_device *xbee_dev = NULL; 3632 | + pr_debug("%s\n", __func__); 3633 | + 3634 | + xbee_dev = dev->priv; 3635 | + if (NULL == xbee_dev) { 3636 | + printk(KERN_ERR "%s: wrong phy\n", __func__); 3637 | + return -EINVAL; 3638 | + } 3639 | + 3640 | + mote_type = xbee_device_get_type(xbee_dev); 3641 | + printk(KERN_DEBUG "%s: mote type: %d\n", __func__,mote_type); 3642 | + 3643 | + pr_debug("%s end\n", __func__); 3644 | + return ret; 3645 | +} 3646 | + 3647 | +static int 3648 | +ieee802154_xbee_set_channel(struct ieee802154_dev *dev, int page, int channel){ 3649 | + int ret = 0; 3650 | + struct xbee_device *xbee_dev = NULL; 3651 | + int mote_type = UNKNOWN_MOTE; 3652 | + pr_debug("%s\n", __func__); 3653 | + 3654 | + xbee_dev = dev->priv; 3655 | + if (NULL == xbee_dev) { 3656 | + printk(KERN_ERR "%s: wrong phy\n", __func__); 3657 | + return -EINVAL; 3658 | + } 3659 | + 3660 | + mote_type = xbee_device_get_type(xbee_dev); 3661 | + printk(KERN_DEBUG "%s: mote type: %d\n", __func__,mote_type); 3662 | + 3663 | + pr_debug("%s end\n", __func__); 3664 | + return ret; 3665 | +} 3666 | + 3667 | +static int 3668 | +ieee802154_xbee_start(struct ieee802154_dev *dev){ 3669 | + int ret = 0; 3670 | + struct xbee_device *xbee_dev = NULL; 3671 | + int mote_type = UNKNOWN_MOTE; 3672 | + pr_debug("%s\n", __func__); 3673 | + xbee_dev = dev->priv; 3674 | + if (NULL == xbee_dev) { 3675 | + printk(KERN_ERR "%s: wrong phy\n", __func__); 3676 | + return -EINVAL; 3677 | + } 3678 | + 3679 | + mote_type = xbee_device_get_type(xbee_dev); 3680 | + printk(KERN_DEBUG "%s: mote type: %d\n", __func__,mote_type); 3681 | + 3682 | + pr_debug("%s end\n", __func__); 3683 | + return ret; 3684 | +} 3685 | + 3686 | +static void 3687 | +ieee802154_xbee_stop(struct ieee802154_dev *dev){ 3688 | + //struct xbee_device *xbee_dev = NULL; 3689 | + pr_debug("%s\n", __func__); 3690 | + pr_debug("%s end\n", __func__); 3691 | + return; 3692 | +} 3693 | + 3694 | +static int 3695 | +ieee802154_xbee_address(struct ieee802154_dev *dev, u8 addr[IEEE802154_ADDR_LEN]){ 3696 | + int ret = 0; 3697 | + struct xbee_device *xbee_dev = NULL; 3698 | + int mote_type = UNKNOWN_MOTE; 3699 | + u8 addr_tmp[IEEE802154_ADDR_LEN] = {}; 3700 | + u8 network_id[2] = {}; 3701 | + 3702 | + pr_debug("%s\n", __func__); 3703 | + 3704 | + xbee_dev = dev->priv; 3705 | + if (NULL == xbee_dev) { 3706 | + printk(KERN_ERR "%s: wrong phy\n", __func__); 3707 | + return -EINVAL; 3708 | + } 3709 | + 3710 | + mote_type = xbee_device_get_type(xbee_dev); 3711 | + printk(KERN_DEBUG "%s: mote type: %d\n", __func__,mote_type); 3712 | + 3713 | + ret = xbee_api_at_command_read_u32(xbee_dev,"SH",addr_tmp); 3714 | + if(ret) 3715 | + { 3716 | + printk(KERN_ERR "%s: error getting serial high value\n", __func__); 3717 | + return ret; 3718 | + } 3719 | + ret = xbee_api_at_command_read_u32(xbee_dev,"SL",addr_tmp+4); 3720 | + if(ret) 3721 | + { 3722 | + printk(KERN_ERR "%s: error getting serial low value\n", __func__); 3723 | + return ret; 3724 | + } 3725 | + memcpy(addr,addr_tmp,IEEE802154_ADDR_LEN); 3726 | + memcpy(xbee_dev->dev_addr,addr_tmp,IEEE802154_ADDR_LEN); 3727 | + 3728 | + ret = xbee_api_at_command_read_u16(xbee_dev,"ID",network_id); 3729 | + if(ret) 3730 | + { 3731 | + printk(KERN_ERR "%s: error getting serial low value\n", __func__); 3732 | + return ret; 3733 | + } 3734 | + xbee_dev->pan_id = ((network_id[0] << 8) & 0xFF00) + (network_id[1] & 0xFF); 3735 | + 3736 | + pr_debug("%s end\n", __func__); 3737 | + return ret; 3738 | +} 3739 | + 3740 | +/* 3741 | + * to bind XBEE RX API frame to a ieee802154_addr 3742 | + * addr_type = IEEE802154_ADDR_LONG (EUI-64 + PanId) 3743 | + * pan_id = network ID (cmd ATID result should be used) 3744 | + * hwaddr = RX EUI-64bit addr from API 3745 | +struct ieee802154_addr { 3746 | + int addr_type; 3747 | + u16 pan_id; 3748 | + union { 3749 | + u8 hwaddr[IEEE802154_ADDR_LEN]; 3750 | + u16 short_addr; 3751 | + }; 3752 | +}; 3753 | + * 3754 | + */ 3755 | + 3756 | +struct xbee_rx_work { 3757 | + struct sk_buff *skb; 3758 | + struct work_struct work; 3759 | + struct xbee_device *xbee_dev; 3760 | + uint8_t lqi; 3761 | + bool update_lqi; 3762 | + u8 src_addr[IEEE802154_ADDR_LEN]; 3763 | +}; 3764 | + 3765 | +static void xbee_rx_worker(struct work_struct *work) 3766 | +{ 3767 | + u8 lqi = 0x00; 3768 | + struct xbee_rx_work *rw = container_of(work, struct xbee_rx_work, work); 3769 | + struct sk_buff *skb = rw->skb; 3770 | + 3771 | + if(rw->xbee_dev->device_driver == HM_TRP_433D_MOTE || rw->xbee_dev->device_driver == HM_TRP_868D_MOTE){ 3772 | + lqi = rw->lqi; 3773 | + }else if(rw->xbee_dev->device_driver == XBEE_XB08_DP_MOTE){ 3774 | + lqi = xbee_get_rssi(rw->xbee_dev->dev); 3775 | + pr_debug("%s(): lqi: %d (0x%02X)\n", __func__,lqi,lqi); 3776 | + } 3777 | + ieee802154_rx_irqsafe(rw->xbee_dev->dev, skb, lqi); 3778 | + if(rw->update_lqi) 3779 | + xbee_stat_update_lqi(rw->src_addr,lqi); 3780 | + kfree(rw); 3781 | +} 3782 | + 3783 | +//static void 3784 | +//xbee_net_rx_old(struct xbee_device *xbee_dev, _api_frame_t *api_frame){ 3785 | +// /* zbdev->param1 is LQI 3786 | +// * zbdev->param2 is length of data 3787 | +// * zbdev->data is data itself 3788 | +// */ 3789 | +// struct sk_buff *skb = NULL; 3790 | +// unsigned char *data = NULL; 3791 | +//// struct ieee802154_addr saddr = {}; 3792 | +//// struct ieee802154_addr daddr = {}; 3793 | +// 3794 | +// struct xbee_rx_work *work; 3795 | +// 3796 | +// skb = alloc_skb(api_frame->api_data->receive_packet.payload_len, GFP_ATOMIC); 3797 | +//// skb_reserve(skb,MAC802154_FRAME_HARD_HEADER_LEN); 3798 | +// 3799 | +// data = skb_put(skb, api_frame->api_data->receive_packet.payload_len); 3800 | +// //skb_copy_to_linear_data(skb, api_frame->api_data->receive_packet.payload, api_frame->api_data->receive_packet.payload_len); 3801 | +// //memcpy(skb->data, from, len); 3802 | +// memcpy(data, api_frame->api_data->receive_packet.payload, api_frame->api_data->receive_packet.payload_len); 3803 | +// 3804 | +//// saddr.addr_type = IEEE802154_ADDR_LONG; 3805 | +//// //saddr.pan_id = xbee_dev->pan_id; 3806 | +//// saddr.pan_id = 0x00FF; 3807 | +//// memcpy(saddr.hwaddr,api_frame->api_data->receive_packet.src_addr,IEEE802154_ADDR_LEN); 3808 | +//// 3809 | +//// daddr.addr_type = IEEE802154_ADDR_LONG; 3810 | +//// //daddr.pan_id = xbee_dev->pan_id; 3811 | +//// daddr.pan_id = 0x00FF; 3812 | +//// memcpy(daddr.hwaddr,xbee_dev->dev_addr,IEEE802154_ADDR_LEN); 3813 | +//// 3814 | +//// mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA; 3815 | +//// mac802154_header_create(skb,xbee_dev->dev,0,&daddr,&saddr,0); 3816 | +// 3817 | +// pr_debug("%s(): type: %d\n", __func__, skb->pkt_type); 3818 | +//#ifdef DEBUG 3819 | +// //print_hex_dump_bytes("xbee_net_rx(): ", DUMP_PREFIX_NONE, skb->data, skb->len); 3820 | +// print_hex_dump_bytes("xbee_net_rx(): ", DUMP_PREFIX_NONE, data, skb->len); 3821 | +//#endif 3822 | +// 3823 | +// //skb_trim(skb, api_frame->api_data->receive_packet.payload_len - 2); /* We do not put CRC into the frame */ 3824 | +// 3825 | +// work = kzalloc(sizeof(struct xbee_rx_work), GFP_ATOMIC); 3826 | +// if (!work) 3827 | +// { 3828 | +// kfree_skb(skb); 3829 | +// return; 3830 | +// } 3831 | +// 3832 | +// INIT_WORK(&work->work, xbee_rx_worker); 3833 | +// work->skb = skb; 3834 | +// work->xbee_dev = xbee_dev; 3835 | +// memcpy(work->src_addr,api_frame->api_data->receive_packet.src_addr,IEEE802154_ADDR_LEN); 3836 | +// 3837 | +// queue_work(xbee_dev->frames_workqueue, &work->work); 3838 | +//} 3839 | + 3840 | +static void 3841 | +hm_trp_rx(struct xbee_device *xbee_dev, _api_frame_t *api_frame){ 3842 | + /* zbdev->param1 is LQI 3843 | + * zbdev->param2 is length of data 3844 | + * zbdev->data is data itself 3845 | + */ 3846 | + struct sk_buff *skb = NULL; 3847 | + unsigned char *data = NULL; 3848 | + struct xbee_rx_work *work; 3849 | + 3850 | + skb = alloc_skb(api_frame->api_data->raw_packet.payload_len, GFP_ATOMIC); 3851 | + 3852 | + data = skb_put(skb, api_frame->api_data->raw_packet.payload_len); 3853 | + memcpy(data, api_frame->api_data->raw_packet.payload, api_frame->api_data->raw_packet.payload_len); 3854 | + 3855 | + pr_debug("%s(): type: %d\n", __func__, skb->pkt_type); 3856 | +#ifdef DEBUG 3857 | + print_hex_dump_bytes("hm_trp_net_rx(): ", DUMP_PREFIX_NONE, data, skb->len); 3858 | +#endif 3859 | + 3860 | + work = kzalloc(sizeof(struct xbee_rx_work), GFP_ATOMIC); 3861 | + if (!work) 3862 | + { 3863 | + kfree_skb(skb); 3864 | + return; 3865 | + } 3866 | + 3867 | + INIT_WORK(&work->work, xbee_rx_worker); 3868 | + work->skb = skb; 3869 | + work->xbee_dev = xbee_dev; 3870 | + work->update_lqi = false; // FIXME: THERE'S still MISSING TO SET SOURCE ADDRESS. IT MUST BE EXTRACTED FROM PACKET 3871 | + work->lqi = api_frame->api_data->raw_packet.lqi; 3872 | + queue_work(xbee_dev->frames_workqueue, &work->work); 3873 | +} 3874 | + 3875 | +static void 3876 | +xbee_rx(struct xbee_device *xbee_dev, _api_frame_t *api_frame){ 3877 | + /* zbdev->param1 is LQI 3878 | + * zbdev->param2 is length of data 3879 | + * zbdev->data is data itself 3880 | + */ 3881 | + struct sk_buff *skb = NULL; 3882 | + unsigned char *data = NULL; 3883 | + struct xbee_rx_work *work; 3884 | + 3885 | + skb = alloc_skb(api_frame->api_data->receive_packet.payload_len, GFP_ATOMIC); 3886 | + 3887 | + data = skb_put(skb, api_frame->api_data->receive_packet.payload_len); 3888 | + memcpy(data, api_frame->api_data->receive_packet.payload, api_frame->api_data->receive_packet.payload_len); 3889 | + 3890 | +#ifdef DEBUG 3891 | + //print_hex_dump_bytes("xbee_net_rx(): ", DUMP_PREFIX_NONE, skb->data, skb->len); 3892 | + print_hex_dump_bytes("xbee_net_rx(): ", DUMP_PREFIX_NONE, data, skb->len); 3893 | +#endif 3894 | + 3895 | + work = kzalloc(sizeof(struct xbee_rx_work), GFP_ATOMIC); 3896 | + if (!work) 3897 | + { 3898 | + kfree_skb(skb); 3899 | + return; 3900 | + } 3901 | + 3902 | + INIT_WORK(&work->work, xbee_rx_worker); 3903 | + work->skb = skb; 3904 | + work->xbee_dev = xbee_dev; 3905 | + work->update_lqi = true; 3906 | + memcpy(work->src_addr,api_frame->api_data->receive_packet.src_addr,IEEE802154_ADDR_LEN); 3907 | + queue_work(xbee_dev->frames_workqueue, &work->work); 3908 | +} 3909 | + 3910 | +static void 3911 | +ieee802154_net_rx(struct xbee_device *xbee_dev, _api_frame_t *api_frame){ 3912 | + int mote_type = UNKNOWN_MOTE; 3913 | + if (NULL == xbee_dev) { 3914 | + printk(KERN_ERR "%s: wrong phy\n", __func__); 3915 | + return; 3916 | + } 3917 | + mote_type = xbee_device_get_type(xbee_dev); 3918 | + switch(mote_type){ 3919 | + case XBEE_XB08_DP_MOTE: 3920 | + xbee_rx(xbee_dev,api_frame); 3921 | + break; 3922 | + case HM_TRP_433D_MOTE: 3923 | + case HM_TRP_868D_MOTE: 3924 | + hm_trp_rx(xbee_dev,api_frame); 3925 | + break; 3926 | + default: 3927 | + break; 3928 | + } 3929 | +} 3930 | + 3931 | +/***************************************************************************** 3932 | + * Line discipline interface for IEEE 802.15.4 serial device 3933 | + *****************************************************************************/ 3934 | + 3935 | +static struct ieee802154_ops serial_ops = { 3936 | + .owner = THIS_MODULE, 3937 | + .xmit = ieee802154_xmit, 3938 | + .ed = ieee802154_xbee_ed, 3939 | + .set_channel = ieee802154_xbee_set_channel, 3940 | + .start = ieee802154_xbee_start, 3941 | + .stop = ieee802154_xbee_stop, 3942 | + .ieee_addr = ieee802154_xbee_address, 3943 | +}; 3944 | + 3945 | +/* 3946 | + * The "foo" file where a static variable is read from and written to. 3947 | + */ 3948 | + 3949 | +static ssize_t debug_show(struct kobject *kobj, struct kobj_attribute *attr, 3950 | + char *buf) { 3951 | + return sprintf(buf, "%d\n", enable_debug); 3952 | +} 3953 | + 3954 | +static ssize_t debug_store(struct kobject *kobj, struct kobj_attribute *attr, 3955 | + const char *buf, size_t count) { 3956 | + sscanf(buf, "%d", &enable_debug); 3957 | + return count; 3958 | +} 3959 | + 3960 | +static struct kobj_attribute debug_attribute = __ATTR(debug, 0666, debug_show, debug_store); 3961 | + 3962 | +/* 3963 | + * The "foo" file where a static variable is read from and written to. 3964 | + */ 3965 | +static ssize_t lqi_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { 3966 | + //return sprintf(buf, "%d\n", global_lqi); 3967 | + return xbee_stat_get_lqi_table(buf); 3968 | +} 3969 | + 3970 | +static ssize_t lqi_store(struct kobject *kobj, struct kobj_attribute *attr, 3971 | + const char *buf, size_t count) { 3972 | + return count; 3973 | +} 3974 | + 3975 | +static struct kobj_attribute lqi_attribute = __ATTR(lqi, 0666, lqi_show, lqi_store); 3976 | + 3977 | +/* 3978 | + * Create a group of attributes so that we can create and destory them all 3979 | + * at once. 3980 | + */ 3981 | +static struct attribute *attrs[] = { 3982 | + &lqi_attribute.attr, 3983 | + &debug_attribute.attr, 3984 | + NULL , /* need to NULL terminate the list of attributes */ 3985 | +}; 3986 | + 3987 | +/* 3988 | + * An unnamed attribute group will put all of the attributes directly in 3989 | + * the kobject directory. If we specify a name, a subdirectory will be 3990 | + * created for the attributes with the directory being the name of the 3991 | + * attribute group. 3992 | + */ 3993 | +static struct attribute_group attr_group = { .attrs = attrs, }; 3994 | + 3995 | +static struct kobject *xbee_kobj; 3996 | + 3997 | +/* 3998 | + * Called when a tty is put into ZB line discipline. Called in process context. 3999 | + * Returns 0 on success. 4000 | + */ 4001 | +static int 4002 | +ieee802154_tty_open(struct tty_struct *tty) 4003 | +{ 4004 | + struct xbee_device *xbee_dev = tty->disc_data; 4005 | + struct ieee802154_dev *dev; 4006 | + int err; 4007 | + int retval; 4008 | + 4009 | + pr_debug("Openning ldisc\n"); 4010 | + if (!capable(CAP_NET_ADMIN)) 4011 | + return -EPERM; 4012 | + 4013 | + if (tty->disc_data) 4014 | + return -EBUSY; 4015 | + 4016 | + dev = ieee802154_alloc_device(sizeof(*xbee_dev), &serial_ops); 4017 | + if (!dev) 4018 | + return -ENOMEM; 4019 | + 4020 | + xbee_dev = dev->priv; 4021 | + xbee_dev->dev = dev; 4022 | + 4023 | + xbee_dev->device_driver = UNKNOWN_MOTE; 4024 | + 4025 | + xbee_dev->escaped_mode = 1; 4026 | + xbee_dev->frame_id_counter = 1; 4027 | + xbee_dev->recv_state = RECV_STATE_WAIT_START_DELIM; 4028 | + 4029 | + mutex_init(&xbee_dev->mutex); 4030 | + init_waitqueue_head(&xbee_dev->wq); 4031 | + 4032 | + dev->extra_tx_headroom = 0; 4033 | + /* only 2.4 GHz band */ 4034 | + dev->phy->channels_supported[0] = 0x7fff800; 4035 | + 4036 | + dev->flags = IEEE802154_HW_OMIT_CKSUM|IEEE802154_HW_AACK; 4037 | + 4038 | + dev->parent = tty->dev; 4039 | + 4040 | + xbee_dev->tty = tty_kref_get(tty); 4041 | + 4042 | + tty->disc_data = xbee_dev; 4043 | + tty->receive_room = MAX_DATA_SIZE; 4044 | + 4045 | + /* FIXME: why is this needed. Note don't use ldisc_ref here as the 4046 | + open path is before the ldisc is referencable */ 4047 | + 4048 | + if (tty->ldisc->ops->flush_buffer) 4049 | + tty->ldisc->ops->flush_buffer(tty); 4050 | + tty_driver_flush_buffer(tty); 4051 | + 4052 | + err = ieee802154_register_device(dev); 4053 | + if (err) { 4054 | + printk(KERN_ERR "%s: device register failed\n", __func__); 4055 | + goto out_free; 4056 | + } 4057 | + 4058 | + xbee_dev->frames_workqueue = 4059 | + create_singlethread_workqueue(wpan_phy_name(xbee_dev->dev->phy)); 4060 | + if (!xbee_dev->frames_workqueue) 4061 | + goto out_unregister; 4062 | + 4063 | + /* 4064 | + * Create a simple kobject with the name of "kobject_example", 4065 | + * located under /sys/kernel/ 4066 | + * 4067 | + * As this is a simple directory, no uevent will be sent to 4068 | + * userspace. That is why this function should not be used for 4069 | + * any type of dynamic kobjects, where the name and number are 4070 | + * not known ahead of time. 4071 | + */ 4072 | + xbee_kobj = kobject_create_and_add("xbee", kernel_kobj); 4073 | + if (!xbee_kobj) 4074 | + return -ENOMEM; 4075 | + 4076 | + /* Create the files associated with this kobject */ 4077 | + retval = sysfs_create_group(xbee_kobj, &attr_group); 4078 | + if (retval) 4079 | + kobject_put(xbee_kobj); 4080 | + 4081 | + return 0; 4082 | + 4083 | +out_unregister: 4084 | + ieee802154_unregister_device(xbee_dev->dev); 4085 | + 4086 | +out_free: 4087 | + destroy_workqueue(xbee_dev->frames_workqueue); 4088 | + tty->disc_data = NULL; 4089 | + tty_kref_put(tty); 4090 | + xbee_dev->tty = NULL; 4091 | + 4092 | + ieee802154_free_device(xbee_dev->dev); 4093 | + 4094 | + return err; 4095 | +} 4096 | + 4097 | +/* 4098 | + * Called when the tty is put into another line discipline or it hangs up. We 4099 | + * have to wait for any cpu currently executing in any of the other zb_tty_* 4100 | + * routines to finish before we can call zb_tty_close and free the 4101 | + * zb_serial_dev struct. This routine must be called from process context, not 4102 | + * interrupt or softirq context. 4103 | + */ 4104 | +static void 4105 | +ieee802154_tty_close(struct tty_struct *tty) 4106 | +{ 4107 | + struct xbee_device *xbee_dev; 4108 | + 4109 | + xbee_dev = tty->disc_data; 4110 | + if (NULL == xbee_dev) { 4111 | + printk(KERN_WARNING "%s: match is not found\n", __func__); 4112 | + return; 4113 | + } 4114 | + 4115 | + flush_workqueue(xbee_dev->frames_workqueue); 4116 | + destroy_workqueue(xbee_dev->frames_workqueue); 4117 | + 4118 | + tty->disc_data = NULL; 4119 | + tty_kref_put(tty); 4120 | + xbee_dev->tty = NULL; 4121 | + 4122 | + ieee802154_unregister_device(xbee_dev->dev); 4123 | + 4124 | + tty_ldisc_flush(tty); 4125 | + tty_driver_flush_buffer(tty); 4126 | + 4127 | + ieee802154_free_device(xbee_dev->dev); 4128 | + 4129 | + kobject_put(xbee_kobj); 4130 | +} 4131 | + 4132 | +/* 4133 | + * Called on tty hangup in process context. 4134 | + */ 4135 | +static int 4136 | +ieee802154_tty_hangup(struct tty_struct *tty) 4137 | +{ 4138 | + ieee802154_tty_close(tty); 4139 | + return 0; 4140 | +} 4141 | + 4142 | +/* 4143 | + * Called in process context only. May be re-entered 4144 | + * by multiple ioctl calling threads. 4145 | + */ 4146 | +static int 4147 | +ieee802154_tty_ioctl(struct tty_struct *tty, struct file *file, 4148 | + unsigned int cmd, unsigned long arg) 4149 | +{ 4150 | + struct xbee_device *xbee_dev; 4151 | + 4152 | + pr_debug("cmd = 0x%x\n", cmd); 4153 | + 4154 | + xbee_dev = tty->disc_data; 4155 | + if (NULL == xbee_dev) { 4156 | + pr_debug("match is not found\n"); 4157 | + return -EINVAL; 4158 | + } 4159 | + 4160 | + switch (cmd) { 4161 | + case TCFLSH: 4162 | + return tty_perform_flush(tty, arg); 4163 | + default: 4164 | + /* Try the mode commands */ 4165 | + return tty_mode_ioctl(tty, file, cmd, arg); 4166 | + } 4167 | +} 4168 | + 4169 | + 4170 | +/* 4171 | + * This can now be called from hard interrupt level as well 4172 | + * as soft interrupt level or mainline. 4173 | + */ 4174 | +static void 4175 | +ieee802154_tty_receive(struct tty_struct *tty, const unsigned char *buf, 4176 | + char *cflags, int count) 4177 | +{ 4178 | + struct xbee_device *xbee_dev; 4179 | +// int i = 0; 4180 | + 4181 | + /* Debug info */ 4182 | +#ifdef DEBUG 4183 | + printk(KERN_INFO "%s, received %d bytes\n", __func__, 4184 | + count); 4185 | + print_hex_dump_bytes("ieee802154_tty_receive ", DUMP_PREFIX_NONE, 4186 | + buf, count); 4187 | +#endif 4188 | + 4189 | + /* Actual processing */ 4190 | + xbee_dev = tty->disc_data; 4191 | + if (NULL == xbee_dev) { 4192 | + printk(KERN_ERR "%s(): record for tty is not found\n", 4193 | + __func__); 4194 | + return; 4195 | + } 4196 | + 4197 | + xbee_receive(xbee_dev,buf,count); 4198 | + 4199 | +//out: 4200 | + tty_unthrottle(tty); 4201 | +} 4202 | + 4203 | +/* 4204 | + * Line discipline device structure 4205 | + */ 4206 | +static struct tty_ldisc_ops xbee_ldisc = { 4207 | + .owner = THIS_MODULE, 4208 | + .magic = TTY_LDISC_MAGIC, 4209 | + .name = "ieee802154-ldisc", 4210 | + .open = ieee802154_tty_open, 4211 | + .close = ieee802154_tty_close, 4212 | + .hangup = ieee802154_tty_hangup, 4213 | + .receive_buf = ieee802154_tty_receive, 4214 | + .ioctl = ieee802154_tty_ioctl, 4215 | +}; 4216 | + 4217 | +/***************************************************************************** 4218 | + * Module service routinues 4219 | + *****************************************************************************/ 4220 | + 4221 | +static int __init ieee802154_xbee_init(void) 4222 | +{ 4223 | + printk(KERN_INFO "Initializing XBee/HM-TRP TTY for Xbee RF 868 OEM and HM-TRP interface\n"); 4224 | + 4225 | + xbee_stats_init(); 4226 | + 4227 | + if (tty_register_ldisc(N_IEEE802154, &xbee_ldisc) != 0) { 4228 | + printk(KERN_ERR "%s: line discipline register failed\n", 4229 | + __func__); 4230 | + return -EINVAL; 4231 | + } 4232 | + 4233 | + return 0; 4234 | +} 4235 | + 4236 | +static void __exit ieee802154_xbee_cleanup(void) 4237 | +{ 4238 | + xbee_stats_tini(); 4239 | + if (tty_unregister_ldisc(N_IEEE802154) != 0) 4240 | + printk(KERN_CRIT 4241 | + "failed to unregister XBee line discipline.\n"); 4242 | +} 4243 | + 4244 | +module_init(ieee802154_xbee_init); 4245 | +module_exit(ieee802154_xbee_cleanup); 4246 | + 4247 | +MODULE_LICENSE("GPL"); 4248 | +MODULE_AUTHOR("João Pedro Taveira"); 4249 | +MODULE_AUTHOR("Martijn Kuipers"); 4250 | +MODULE_ALIAS_LDISC(N_IEEE802154); 4251 | + 4252 | +#endif /* __KERNEL__ */ 4253 | + 4254 | +#ifndef __KERNEL__ 4255 | +uint8_t ex36esc[] = {0x7E,0x00,0x02,0x23,0x7D,0x31,0xCB}; 4256 | +uint8_t exTR40esc[] = {0x7E,0x00,0x16,0x10,0x01,0x00,0x7D,0x33,0xA2,0x00,0x40,0x0A,0x01,0x27,0xFF,0xFE,0x00,0x00,0x54,0x78,0x44,0x61,0x74,0x61,0x30,0x41,0x7D,0x33}; 4257 | + 4258 | +uint8_t ex36escexTR40esc[] = {0x7E,0x00,0x02,0x23,0x7D,0x31,0xCB,0x7E,0x00,0x16,0x10,0x01,0x00,0x7D,0x33,0xA2,0x00,0x40,0x0A,0x01,0x27,0xFF,0xFE,0x00,0x00,0x54,0x78,0x44,0x61,0x74,0x61,0x30,0x41,0x7D,0x33}; 4259 | + 4260 | +uint8_t exTR40escError[] = {0x7E,0x00,0x16,0x10,0x01,0x00,0x7D,0x33,0x7E,0x00,0x02,0x23,0x7D,0x31,0xCB,0xA2,0x00,0x40,0x0A,0x01,0x27,0xFF,0xFE,0x00,0x00,0x54,0x78,0x44,0x61,0x74,0x61,0x30,0x41,0x7D,0x33,0x7E,0x00,0x16,0x10,0x01,0x00,0x7D,0x33,0xA2,0x00,0x40,0x0A,0x01,0x27,0xFF,0xFE,0x00,0x00,0x54,0x78,0x44,0x61,0x74,0x61,0x30,0x41,0x7D,0x33}; 4261 | + 4262 | +uint8_t teste2[] = {0x7E,0x00,0x08,0x08,0x03,0x42,0x44,0xAA,0xBB,0xCC,0xDD,0x60}; 4263 | + 4264 | +uint8_t receive_packet[] = {0x7E,0x00,0x13,0x90,0x00,0x00,0x13,0xA2,0x00,0x40,0x52,0x2B,0xAA,0xFF,0xFE,0x01,0x52,0x78,0x44,0x61,0x74,0x61,0x11}; 4265 | + 4266 | +uint8_t at_cmd_response_BD[] = {0x7E,0x00,0x05,0x88,0x01,0x42,0x44,0x00,0xF0}; 4267 | + 4268 | +uint8_t at_cmd_response_SH[] = {0x7E,0x00,0x09,0x88,0x02,0x53,0x48,0x00,0xAA,0xBB,0xCC,0xDD,0xCC}; 4269 | +uint8_t at_cmd_response_SL[] = {0x7E,0x00,0x09,0x88,0x03,0x53,0x4C,0x00,0x11,0x22,0x33,0x44,0x2B}; 4270 | + 4271 | +uint8_t modem_status_hw_reset[] = {0x7E,0x00,0x02,0x8A,0x00,0x75}; 4272 | +uint8_t modem_status_timer_reset[] = {0x7E,0x00,0x02,0x8A,0x01,0x74}; 4273 | +uint8_t modem_status_net_woke_up[] = {0x7E,0x00,0x02,0x8A,0x0B,0x6A}; 4274 | +uint8_t modem_status_net_went2sleep[] = {0x7E,0x00,0x02,0x8A,0x0C,0x69}; 4275 | + 4276 | +uint8_t transmit_status[] = {0x7E,0x00,0x07,0x8B,0x47,0xFF,0xFE,0x00,0x00,0x02,0x2E}; 4277 | + 4278 | +//uint8_t transmit_status2[] = {0x7E,0x00,0x07,0x8B,0x01,0xFF,0xFE,0x00,0x00,0x00,0x76}; 4279 | + 4280 | +uint8_t remote_at_command_resp[] = {0x7E,0x00,0x13,0x97,0x55,0x00,0x13,0xA2,0x00,0x40,0x52,0x2B,0xAA,0xFF,0xFE,0x53,0x4C,0x00,0x40,0x52,0x2B,0xAA,0xF4}; 4281 | + 4282 | +uint8_t node_id_indicator[] = { 4283 | + 0x7E, 4284 | + 0x00,0x1A, 4285 | + 0x95, //1 4286 | + 0x00,0x13,0xA2,0x00,0x40,0x52,0x2B,0xAA, // 8 4287 | + 0x7D,0x7D^0x20,0x84, // 2 4288 | + 0x02, // 1 4289 | + 0x7D,0x7D^0x20,0x84, // 2 4290 | + 0x00,0x13,0xA2,0x00,0x40,0x52,0x2B,0xAA, // 8 4291 | + 0x20,0x00, // 2 4292 | + 0xFF,0xFE, // 2 4293 | + 0x11}; 4294 | + 4295 | +uint8_t explicit_rx_indicator[] = { 4296 | + 0x7E, 4297 | + 0x00,0x18, 4298 | + 0x91, 4299 | + 0x00,0x13,0xA2,0x00,0x40,0x52,0x2B,0xAA, // 8 4300 | + 0xFF,0xFE, 4301 | + 0xE0, 4302 | + 0xE0, 4303 | + 0x22,0x11, 4304 | + 0xC1,0x05, 4305 | + 0x02, 4306 | + 0x52,0x78,0x44,0x61,0x74,0x61, 4307 | + 0x56 4308 | +}; 4309 | + 4310 | + 4311 | +/* 4312 | + * xbee rx thread 4313 | + */ 4314 | + 4315 | +void xbee_rx_sighandler(int sig){ 4316 | + printk(KERN_DEBUG "%s(): signal caught\n",__func__); 4317 | +} 4318 | + 4319 | +void xbee_rx_setup_signals(){ 4320 | + printk(KERN_DEBUG "%s(): called\n",__func__); 4321 | + struct sigaction act; 4322 | + act.sa_handler = xbee_rx_sighandler; 4323 | + act.sa_flags = 0; 4324 | + sigemptyset(&act.sa_mask); 4325 | + sigaddset(&act.sa_mask, SIGINT); 4326 | + sigaddset(&act.sa_mask, SIGQUIT); 4327 | + sigaddset(&act.sa_mask, SIGTERM); 4328 | + sigaction(SIGINT,&act,NULL); 4329 | + sigaction(SIGQUIT,&act,NULL); 4330 | + sigaction(SIGTERM,&act,NULL); 4331 | + 4332 | + struct sigaction act_pipe; 4333 | + act_pipe.sa_handler = xbee_rx_sighandler; 4334 | + act_pipe.sa_flags = 0; 4335 | + sigemptyset(&act_pipe.sa_mask); 4336 | + sigaddset(&act_pipe.sa_mask, SIGPIPE); 4337 | + sigaction(SIGPIPE,&act_pipe,NULL); 4338 | +} 4339 | + 4340 | +static void 4341 | +dump_hex(uint8_t *buf, int len) 4342 | +{ 4343 | + int i = 0; 4344 | + uint8_t raw_byte = 0; 4345 | + unsigned char *data = (unsigned char *) buf; 4346 | + for(i = 0;imutex); 4366 | + running = xbee_dev->rx_thread_running = 1; 4367 | + end = xbee_dev->rx_thread_end; 4368 | + pthread_mutex_unlock(&xbee_dev->mutex); 4369 | + 4370 | + while(running && !end) 4371 | + { 4372 | + fd_set fds; 4373 | + FD_ZERO(&fds); 4374 | + FD_SET(xbee_dev->tty_fd,&fds); 4375 | + struct timeval tv = {1,0}; 4376 | + switch(select(xbee_dev->tty_fd+1,&fds,NULL,NULL,&tv)){ 4377 | + case 0: 4378 | + printk(KERN_DEBUG "%s: timeout.. waiting again\n",__func__); 4379 | + break; 4380 | + case -1: 4381 | + printk(KERN_ERR "%s(): some error occur in select: %s\n",__func__,strerror(errno)); 4382 | + break; 4383 | + default: 4384 | + if(FD_ISSET(xbee_dev->tty_fd,&fds)){ 4385 | + recv_len = read(xbee_dev->tty_fd,rx_buffer,XBEE_MAX_RX_LEN); 4386 | + printk(KERN_DEBUG "%s: some activity in tty: %d bytes read\n",__func__,recv_len); 4387 | + dump_hex(rx_buffer, recv_len); 4388 | + xbee_receive(xbee_dev,rx_buffer,recv_len); 4389 | + } 4390 | + } 4391 | + pthread_mutex_lock(&xbee_dev->mutex); 4392 | + running = xbee_dev->rx_thread_running; 4393 | + end = xbee_dev->rx_thread_end; 4394 | + pthread_mutex_unlock(&xbee_dev->mutex); 4395 | + } 4396 | + 4397 | + printk(KERN_DEBUG "%s: end\n", __func__); 4398 | + pthread_exit(NULL); 4399 | + return NULL; 4400 | +} 4401 | + 4402 | +static int 4403 | +xbee_start_rx_thread(struct xbee_device *xbee_dev){ 4404 | + pthread_attr_t attr; 4405 | + pthread_attr_init(&attr); 4406 | + if(xbee_dev == NULL){ 4407 | + printk(KERN_ERR "%s(): dev is NULL\n",__func__); 4408 | + return -1; 4409 | + } 4410 | + xbee_rx_setup_signals(); 4411 | + printk(KERN_DEBUG "%s(): starting thread\n",__func__); 4412 | + pthread_mutex_lock(&xbee_dev->mutex); 4413 | + if(!xbee_dev->rx_thread_running){ 4414 | + xbee_dev->rx_thread_running = 1; 4415 | + xbee_dev->rx_thread_end = 0; 4416 | + if(pthread_create(&xbee_dev->rx_thread_tid,&attr,xbee_rx_thread,xbee_dev)!= 0) { 4417 | + pthread_mutex_unlock(&xbee_dev->mutex); 4418 | + printk(KERN_ERR "%s(): error launching thread\n",__func__); 4419 | + return -1; 4420 | + } 4421 | + printk(KERN_DEBUG "%s(): thread started\n",__func__); 4422 | + } else { 4423 | + printk(KERN_WARNING "%s(): thread already running\n",__func__); 4424 | + } 4425 | + pthread_mutex_unlock(&xbee_dev->mutex); 4426 | + return 1; 4427 | +} 4428 | + 4429 | +static int 4430 | +xbee_stop_rx_thread(struct xbee_device *xbee_dev){ 4431 | + if(xbee_dev == NULL){ 4432 | + printk(KERN_ERR "%s(): dev is NULL\n",__func__); 4433 | + return -1; 4434 | + } 4435 | + pthread_mutex_lock(&xbee_dev->mutex); 4436 | + xbee_dev->rx_thread_running = 0; 4437 | + xbee_dev->rx_thread_end = 1; 4438 | + pthread_mutex_unlock(&xbee_dev->mutex); 4439 | + printk(KERN_DEBUG "%s(): waiting for rx thread to end\n",__func__); 4440 | + pthread_join(xbee_dev->rx_thread_tid, NULL); 4441 | + printk(KERN_DEBUG "%s(): rx thread ended\n",__func__); 4442 | + return 1; 4443 | +} 4444 | + 4445 | +#endif /* !__KERNEL__ */ 4446 | + 4447 | +#ifndef __KERNEL__ 4448 | +int main(int argc, char *argv[]){ 4449 | + int ret = 0; 4450 | + _api_frame_t *api_frame = NULL; 4451 | + struct xbee_device *xbee_dev = xbee_device_new(); 4452 | + 4453 | + if(argc > 2) 4454 | + { 4455 | + xbee_dev->tty_path = argv[1]; 4456 | + } 4457 | + else 4458 | + { 4459 | + printk(KERN_ERR "Usage: %s |\n",argv[0]); 4460 | + return 1; 4461 | + } 4462 | + 4463 | + if(xbee_device_init(xbee_dev) < 0) 4464 | + { 4465 | + printk(KERN_ERR "%s(): error in init\n",__func__); 4466 | + return 1; 4467 | + } 4468 | + 4469 | + xbee_start_rx_thread(xbee_dev); 4470 | + 4471 | + if(!strcmp("send_TR",argv[2])){ 4472 | + //uint8_t addr[XBEE_ADDR_LEN] = {0x00,0x13,0xA2,0x00,0x40,0x0A,0x01,0x27}; 4473 | + //uint8_t addr[XBEE_ADDR_LEN] = {0x00,0x13,0xA2,0x00,0x40,0x8B,0xBA,0xCD}; 4474 | + //13:A2:00:40:8B:BA:CD:FF 4475 | + uint8_t addr[XBEE_ADDR_LEN] = {0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF}; 4476 | + uint8_t payload[8] = {'T','x','D','a','t','a','0','A'}; 4477 | + 4478 | + xbee_dev->frame_id_counter = 0x01; 4479 | + api_frame = _api_frame_new_transmit_request(xbee_dev,addr,0x00,payload,8); 4480 | + _api_frame_print(api_frame); 4481 | + 4482 | + ret = xbee_send(xbee_dev,api_frame); 4483 | + printk(KERN_DEBUG "%s: xbee_send ret: %d\n", __func__,ret); 4484 | + 4485 | + _api_frame_free(api_frame); 4486 | + 4487 | + } else if(!strcmp("send_ATAP1",argv[2])){ 4488 | + xbee_dev->frame_id_counter = 0x01; 4489 | + api_frame = _api_frame_new_at_command_u8(xbee_dev,"AP",0); 4490 | + _api_frame_print(api_frame); 4491 | + 4492 | + ret = xbee_send(xbee_dev,api_frame); 4493 | + printk(KERN_DEBUG "%s: xbee_send ret: %d\n", __func__,ret); 4494 | + 4495 | + _api_frame_free(api_frame); 4496 | + } else if(!strcmp("addr",argv[2])){ 4497 | + uint8_t addr[XBEE_ADDR_LEN] = {}; 4498 | + xbee_ieee_address(xbee_dev,addr); 4499 | + } else if(!strcmp("receive",argv[2])){ 4500 | + sleep(7); 4501 | + } 4502 | + 4503 | + xbee_stop_rx_thread(xbee_dev); 4504 | + 4505 | +// xbee_receive(xbee_dev,exTR40esc,sizeof(exTR40esc)); 4506 | +// 4507 | +// xbee_receive(xbee_dev,teste2,sizeof(teste2)); 4508 | +// 4509 | +// xbee_receive(xbee_dev,at_cmd_response_BD,sizeof(at_cmd_response_BD)); 4510 | +// 4511 | +// xbee_receive(xbee_dev,at_cmd_response_SH,sizeof(at_cmd_response_SH)); 4512 | +// xbee_receive(xbee_dev,at_cmd_response_SL,sizeof(at_cmd_response_SL)); 4513 | +// 4514 | +// xbee_receive(xbee_dev,modem_status_hw_reset,sizeof(modem_status_hw_reset)); 4515 | +// xbee_receive(xbee_dev,modem_status_timer_reset,sizeof(modem_status_timer_reset)); 4516 | +// xbee_receive(xbee_dev,modem_status_net_woke_up,sizeof(modem_status_net_woke_up)); 4517 | +// xbee_receive(xbee_dev,modem_status_net_went2sleep,sizeof(modem_status_net_went2sleep)); 4518 | +// 4519 | +// xbee_receive(xbee_dev,transmit_status2,sizeof(transmit_status2)); 4520 | +// 4521 | +// xbee_receive(xbee_dev,node_id_indicator,sizeof(node_id_indicator)); 4522 | +// 4523 | +// xbee_receive(xbee_dev,receive_packet,sizeof(receive_packet)); 4524 | +// xbee_receive(xbee_dev,explicit_rx_indicator,sizeof(explicit_rx_indicator)); 4525 | + 4526 | +// uint8_t somecommand1[] = {0x7E ,0x00 ,0x16 ,0x10 ,0x01 ,0x00 ,0x13 ,0xA2 ,0x00 ,0x40 ,0x0A ,0x01 ,0x27 ,0xFF ,0xFE ,0x00 ,0x00 ,0x54 ,0x78 ,0x44 ,0x61 ,0x74 ,0x61 ,0x30 ,0x41 ,0x13 }; 4527 | +// uint8_t somecommand[] = {0x7D, 0x5E ,0x00 ,0x16 ,0x10 ,0x01 ,0x00 ,0x7D, 0x33 ,0xA2 ,0x00 ,0x40 ,0x0A ,0x01 ,0x27 ,0xFF ,0xFE ,0x00 ,0x00 ,0x54 ,0x78 ,0x44 ,0x61 ,0x74 ,0x61 ,0x30 ,0x41 ,0x7D, 0x33 }; 4528 | + 4529 | +// xbee_dev->escaped_mode = 0; 4530 | +// xbee_receive(xbee_dev,somecommand1,sizeof(somecommand1)); 4531 | + 4532 | +// xbee_dev->escaped_mode = 1; 4533 | +// xbee_receive(xbee_dev,somecommand,sizeof(somecommand)); 4534 | + 4535 | +// api_frame = _api_frame_new_at_command(xbee_dev,"NH"); 4536 | +// _api_frame_print(api_frame); 4537 | +// _api_frame_free(api_frame); 4538 | +// 4539 | +// api_frame = _api_frame_new_at_command_u8(xbee_dev,"BD",0x10); 4540 | +// _api_frame_print(api_frame); 4541 | +// _api_frame_free(api_frame); 4542 | +// 4543 | +// uint8_t args[4] = {0xAA,0xBB,0xCC,0xDD}; 4544 | +// api_frame = _api_frame_new_at_command_u32(xbee_dev,"BD",args); 4545 | +// _api_frame_print(api_frame); 4546 | +// _api_frame_free(api_frame); 4547 | +// 4548 | +// uint8_t addr[XBEE_ADDR_LEN] = {0x00,0x13,0xA2,0x00,0x40,0x0A,0x01,0x27}; 4549 | +// uint8_t payload[8] = {'T','x','D','a','t','a','0','A'}; 4550 | +// 4551 | +// xbee_dev->frame_id_counter = 0x01; 4552 | +// api_frame = _api_frame_new_transmit_request(xbee_dev,addr,0x00,payload,8); 4553 | +// _api_frame_print(api_frame); 4554 | +// 4555 | +// ret = xbee_send(xbee_dev,api_frame); 4556 | +// printk(KERN_DEBUG "%s: xbee_send ret: %d\n", __func__,ret); 4557 | + 4558 | +// uint16_t len = 0; 4559 | +// uint8_t *raw_frame = _api_frame_to_raw(api_frame,&len); 4560 | +// int i = 0; 4561 | +// uint8_t raw_byte = 0; 4562 | +// printf("Dump: uint8_t somecommand[] = {"); 4563 | +// unsigned char *data = (unsigned char *) raw_frame; 4564 | +// for(i = 0;iescaped_mode && escape_required(raw_byte)) 4569 | +// { 4570 | +// printf("0x%02X, ",XBEE_ESCAPE); 4571 | +// raw_byte = raw_byte^0x20; 4572 | +// } 4573 | +// printf("0x%02X ",raw_byte); 4574 | +// } 4575 | +// printf("};\n"); 4576 | +// if(raw_frame) free(raw_frame); 4577 | +// _api_frame_free(api_frame); 4578 | + 4579 | + xbee_device_release(xbee_dev); 4580 | + return 0; 4581 | +} 4582 | + 4583 | +#endif /* !__KERNEL__ */ 4584 | diff --git a/include/uapi/linux/tty.h b/include/uapi/linux/tty.h 4585 | index dac199a..96233b1 100644 4586 | --- a/include/uapi/linux/tty.h 4587 | +++ b/include/uapi/linux/tty.h 4588 | @@ -34,5 +34,6 @@ 4589 | #define N_TI_WL 22 /* for TI's WL BT, FM, GPS combo chips */ 4590 | #define N_TRACESINK 23 /* Trace data routing for MIPI P1149.7 */ 4591 | #define N_TRACEROUTER 24 /* Trace data routing for MIPI P1149.7 */ 4592 | +#define N_IEEE802154 25 /* Serial / USB serial IEEE802154.4 devices */ 4593 | 4594 | #endif /* _UAPI_LINUX_TTY_H */ 4595 | -- 4596 | 1.8.3.2 4597 | 4598 | --------------------------------------------------------------------------------