| |
| Linux IEEE 802.15.4 implementation |
| |
| |
| Introduction |
| ============ |
| The IEEE 802.15.4 working group focuses on standardization of bottom |
| two layers: Medium Access Control (MAC) and Physical (PHY). And there |
| are mainly two options available for upper layers: |
| - ZigBee - proprietary protocol from the ZigBee Alliance |
| - 6LoWPAN - IPv6 networking over low rate personal area networks |
| |
| The linux-wpan project goal is to provide a complete implementation |
| of the IEEE 802.15.4 and 6LoWPAN protocols. IEEE 802.15.4 is a stack |
| of protocols for organizing Low-Rate Wireless Personal Area Networks. |
| |
| The stack is composed of three main parts: |
| - IEEE 802.15.4 layer; We have chosen to use plain Berkeley socket API, |
| the generic Linux networking stack to transfer IEEE 802.15.4 messages |
| and a special protocol over genetlink for configuration/management |
| - MAC - provides access to shared channel and reliable data delivery |
| - PHY - represents device drivers |
| |
| |
| Socket API |
| ========== |
| |
| int sd = socket(PF_IEEE802154, SOCK_DGRAM, 0); |
| ..... |
| |
| The address family, socket addresses etc. are defined in the |
| include/net/af_ieee802154.h header or in the special header |
| in the userspace package (see either http://wpan.cakelab.org/ or the |
| git tree at https://github.com/linux-wpan/wpan-tools). |
| |
| One can use SOCK_RAW for passing raw data towards device xmit function. YMMV. |
| |
| |
| Kernel side |
| ============= |
| |
| Like with WiFi, there are several types of devices implementing IEEE 802.15.4. |
| 1) 'HardMAC'. The MAC layer is implemented in the device itself, the device |
| exports MLME and data API. |
| 2) 'SoftMAC' or just radio. These types of devices are just radio transceivers |
| possibly with some kinds of acceleration like automatic CRC computation and |
| comparation, automagic ACK handling, address matching, etc. |
| |
| Those types of devices require different approach to be hooked into Linux kernel. |
| |
| |
| HardMAC |
| ======= |
| |
| See the header include/net/ieee802154_netdev.h. You have to implement Linux |
| net_device, with .type = ARPHRD_IEEE802154. Data is exchanged with socket family |
| code via plain sk_buffs. On skb reception skb->cb must contain additional |
| info as described in the struct ieee802154_mac_cb. During packet transmission |
| the skb->cb is used to provide additional data to device's header_ops->create |
| function. Be aware that this data can be overridden later (when socket code |
| submits skb to qdisc), so if you need something from that cb later, you should |
| store info in the skb->data on your own. |
| |
| To hook the MLME interface you have to populate the ml_priv field of your |
| net_device with a pointer to struct ieee802154_mlme_ops instance. The fields |
| assoc_req, assoc_resp, disassoc_req, start_req, and scan_req are optional. |
| All other fields are required. |
| |
| |
| SoftMAC |
| ======= |
| |
| The MAC is the middle layer in the IEEE 802.15.4 Linux stack. This moment it |
| provides interface for drivers registration and management of slave interfaces. |
| |
| NOTE: Currently the only monitor device type is supported - it's IEEE 802.15.4 |
| stack interface for network sniffers (e.g. WireShark). |
| |
| This layer is going to be extended soon. |
| |
| See header include/net/mac802154.h and several drivers in |
| drivers/net/ieee802154/. |
| |
| |
| Device drivers API |
| ================== |
| |
| The include/net/mac802154.h defines following functions: |
| - struct ieee802154_dev *ieee802154_alloc_device |
| (size_t priv_size, struct ieee802154_ops *ops): |
| allocation of IEEE 802.15.4 compatible device |
| |
| - void ieee802154_free_device(struct ieee802154_dev *dev): |
| freeing allocated device |
| |
| - int ieee802154_register_device(struct ieee802154_dev *dev): |
| register PHY in the system |
| |
| - void ieee802154_unregister_device(struct ieee802154_dev *dev): |
| freeing registered PHY |
| |
| Moreover IEEE 802.15.4 device operations structure should be filled. |
| |
| Fake drivers |
| ============ |
| |
| In addition there is a driver available which simulates a real device with |
| SoftMAC (fakelb - IEEE 802.15.4 loopback driver) interface. This option |
| provides possibility to test and debug stack without usage of real hardware. |
| |
| See sources in drivers/net/ieee802154 folder for more details. |
| |
| |
| 6LoWPAN Linux implementation |
| ============================ |
| |
| The IEEE 802.15.4 standard specifies an MTU of 127 bytes, yielding about 80 |
| octets of actual MAC payload once security is turned on, on a wireless link |
| with a link throughput of 250 kbps or less. The 6LoWPAN adaptation format |
| [RFC4944] was specified to carry IPv6 datagrams over such constrained links, |
| taking into account limited bandwidth, memory, or energy resources that are |
| expected in applications such as wireless Sensor Networks. [RFC4944] defines |
| a Mesh Addressing header to support sub-IP forwarding, a Fragmentation header |
| to support the IPv6 minimum MTU requirement [RFC2460], and stateless header |
| compression for IPv6 datagrams (LOWPAN_HC1 and LOWPAN_HC2) to reduce the |
| relatively large IPv6 and UDP headers down to (in the best case) several bytes. |
| |
| In Semptember 2011 the standard update was published - [RFC6282]. |
| It deprecates HC1 and HC2 compression and defines IPHC encoding format which is |
| used in this Linux implementation. |
| |
| All the code related to 6lowpan you may find in files: net/6lowpan/* |
| and net/ieee802154/6lowpan/* |
| |
| To setup 6lowpan interface you need (busybox release > 1.17.0): |
| 1. Add IEEE802.15.4 interface and initialize PANid; |
| 2. Add 6lowpan interface by command like: |
| # ip link add link wpan0 name lowpan0 type lowpan |
| 3. Set MAC (if needs): |
| # ip link set lowpan0 address de:ad:be:ef:ca:fe:ba:be |
| 4. Bring up 'lowpan0' interface |