# IEEE 802.15.1
###### tags: `IEEE`
[origin: IEEE standard 802.15.1, 2002 - Wireless Medium Access Control (MAC)and Physical Layer (PHY) Specifications for Wireless Personal Area Networks (WPANs)](http://www.diegm.uniud.it/tonello/MATERIAL/STANDARDS/802.15.1/802.15.1-2002.pdf)
### background
* the idea of **WPAN** and **piconet**
:::success
**Why WPAN?**
WPAN的提出,可追溯到電腦的轉變,從本來的桌上電腦縮小化、多樣化,衍伸到PDA、MP3、掌上型遊戲機、數位相機、行動電話等。因此進入「一人多機」的時代後,也就逐漸形成另一種需求,「多機」之間需要一個便捷的傳輸、溝通、交換網路,因此有了WPAN。
:::


:::success
**why is bluetooth is solution to WPAN?**
1998年,創始者 Ericsson 與 Nokia、IBM、東芝(Toshiba) 及 Intel組成了技術性組織(SIG),希望能建立一個短距離無線通信技術,就是藍牙技術的前身。希望透過藍牙簡化短距離設備間的通訊,進一步達成更多無線通信的應用,而不需要被 WLAN 所侷限。

:::

:::success
**compare to others protocal, still have the future?**
迄今,藍牙技術已經應用到超過3萬個 SIG聯盟技術成員的82億件產品之中,且繼續上升中,所以我認為還是很有未來且很難被取代。
:::
### feature
* low power consumption
* short range transfer
* 2.4G ISM band
* 79 physical channels, each 1MHz
* 8 slaves
* frequence hopping, 1600 times per second
* FH-TDD-TDMA transmit method
* new feature, **bluetooth low energy** comming out
* Transmitting rate 720Kbps, up to 48Mbps now
* Intergrate with LANs
## structure


## connection (Baseband Layer)

:::success
Why inquiry and paging?
藍芽屬於Radio access network,因此在空氣中可以監聽到所訊號,因此要建立連線需要先使其同步,再交換雙方身份(你是誰?你有收到我的訊息嘛?),以確保連線的穩定性。
:::
### Frequency Hopping

:::success
Why Frequency Hopping?

起初是作為戰爭通訊的用途,防止"竊聽"與"干擾"的手段之一,現在則沿用此技術作為無線通訊技術的必備協定之一。
:::
### inquiry
在 Bluetooth 裝置還<font color="red">未進入連線狀態之前</font>,並不隸屬於任何 Piconet 網路的成員,也<font color="red">未與任何 Master 之間的時序達到同步,並且跳頻順序也不相同</font>,因此,Master 裝置必須利用特殊的方法,才能執行 Inquiry 與 Paging 呼叫。Master 執行 Inquiry 程序的特殊方法,是利用某些特定頻道(ISM 頻段79個頻道中的32頻道)來廣播 ID 封包。
<font color="red">Inquiry 呼叫程序</font>一開始是由 Master 裝置進入 Inquiry 狀態,準備詢問是否有新的裝置欲加入 Piconet 網路;同時某些裝置啟動電源,也準備加入網路運作而進入 Inquiry Scan 狀態,聆聽廣播ID封包。
接下來,Master 裝置在特殊頻道上發送 ID 封包,該封包含著 Inquiry Access Code;相對地,Slave 裝置也由特殊頻道上收到 ID 封包,知道這是 Master 邀請加入網路的查詢訊號,便進入 Inquiry Response 狀態,並於隨後發送『跳頻同步封包』(FHS 封包)給 Master 裝置,FHS 封包內包含著 Slave 裝置本身的 BD_ADDR(Bluetooth Device Address)、原始時序(Native Clock)與裝置類別(Class of Device)訊息。由於同一時間可能有許多裝置被叫醒(Wake-up),所以在此採用隨機時間,以減少回應 FHS 封包時碰撞的機會,如果某一裝置的 FHS 封包和其它裝置碰撞,則必須回到 Inquiry Scan 狀態,等待下一個 ID 封包。
Master 裝置也許會在收到一個以上的 FHS 封包後,便進入 Page 狀態,執行下一個 Page 程序。同樣地,Slave 裝置在成功發送 FHS 封包後,也會進入 Page Scan 狀態。這裡特別要注意的是,Master 裝置是週期性的進入 Inquiry 狀態,詢問是否有新的裝置欲加入網路,因此所接收到個別裝置的 FHS 封包也會累積起來。

### paging
在呼叫Paging時,同樣是使用到 ISM 頻段上的 32 個特殊頻道。<font color="red">Master 裝置進入 Page 狀態後,可能已收到若干個裝置回應的 FHS 封包,此時必須分別針對每一個裝置做 Paging 的處理。</font>Master 裝置針對每一 Slave 的 BD_ADDR 來計算Page FHS(Frequency-Hopping Sequence),並以 ID 封包回應給 Slave 裝置,ID 封包內包含著 Slave DAC(Device Access Code)的 LAP 位址。
Slave 裝置在 Page Scan 狀態下收到 Master 的 ID 封包後,便進入 Slave Response 狀態,同時也回應相同的 DAC ID 封包給 Master 裝置。接下來,Master 裝置收到 Slave 的 DAC ID 封包後進入 Master Response 狀態,利用下一個 Master-to-Slave 時槽發送一個 FHS 封包給 Slave,此 FHS 封包包含有 Master 裝置的 BD_ADDR、以及即時的 Bluetooth 時序的值。緊接著,Slave 裝置回應一個 DAC ID 封包給 Master,表示有收到 FHS 封包。而 Master 也回應一個 ID 封包給 Slave,表示歡迎加入 Piconet 行列。
<font color="red">從此 Slave 擁有 Master 裝置的 BD_ADDR 與 CLKN,可以計算出 Master 的跳頻順序以及時序的同步,藉此進入連線狀態(Connection State)。同時 Master 也分配一個 AM_ADDR 位址給該 Slave,爾後便利用此位址來通訊,此裝置也正式成為 Piconet 的成員。</font>然而 Master 裝置會連續向欲加入網路的成員做 Page Procedure,一直到全部完成或逾時,才回到連結狀態。
### packet format

### access code
* channel access code: identifies a piconet.
* device access code: used for special signalling procedures, e.g., paging and response to paging.
* inquiry access code: used to discover which other Bluetooth units are in range or group.
<font color="red">In short, The different access code types use different Lower Address Parts (LAPs) to construct the sync word.</font>
### header

* AM_ADDR: 3-bit active member address
* TYPE: 4-bit type code
* ID packet
* NULL pakcet
* POLL packet
* FHS pakcet
* SCO packet
* ACL packet .etc
* FLOW: 1-bit flow control
* ARQN: 1-bit acknowledge indication
* SEQN: 1-bit sequence number
* HEC: 8-bit header error check
### payload
In the payload, two fields are
distinguished: the **SCO type** (synchronous) with voice field , and the **ACL type** (asynchronous) with data field.
:::success
Why ACL and SOC?
SCO連接建立後, Master和Slave會運用固定的time slot傳送資料,而其他的裝置不能用此連線的time slot來傳送資料。SCO提供了64kbps的傳輸速度,封包也不會重傳,針對於時間同步要求很高的資料,像是語音通話等。
ACL支援對稱及不對稱連線(可以一對一、一對多)。當實體通道沒有保留time slot給SCO Link時,ACL Link可佔用任何time slot進行封包交換。如果系統需要SCO Link,ACL Link則會空出time slot以供SCO連線使用。並且ACL封包可做到錯誤檢查並且資料重送,因此不需要高度同步。
:::
## Link between Master and Slave(LMP)
LMP messages are used for **link setup, security, and control**. They are transferred in the payload instead of L2CAP. Moreover, Link Manager messages have higher priority than user data. This means that if the Link Manager needs to send a message, it shall not be delayed by the L2CAP traffic, although it can be delayed by many retransmissions of individual baseband packets.
* **link setup**: pairing
* **security**: link key and encryption
* **control**: Timing accuracy and mode selection .etc 族繁不及備載


## Protocol Multiplexing(L2CAP)


* RFCOMM(Radio Frequency Communication):主要功能是模擬 RS-232 serial port。因此 RFCOMM 上層可以連接 PPP(Point-to-Point Protocol)並透過 PPP 協定連結到其它通訊軟體,由此L2CAP, 只要透過RECOMM Layer連接到 Internet 網路。
* TCS(Telephone Control Specification):在 Bluetooth 裝置之間建立語音與資料通訊所需的呼叫控制命令(Call Control Signalling),使 Bluetooth 裝置能與傳統的電話設備相結合。因此,透過 TCS 協定便可連結一般有線電話或行動電話。
* SDP(Service Discovery Protocol):當裝置進入新的網路範圍時,必須搜尋新的環境是否能給予服務。當Client進入新的網路時,即由 SDP 尋找 Server 所能提供的服務類型;而當Client離開網路時,SDP 也能偵測出該網路所提供的服務已經不存在。(Like Handover in Wireless Network)
* Voice:一般語音傳輸都是利用同步傳輸(SCO),如果針對封包式(經過壓縮處理)的語音,也可透過 L2CAP 來利用非同步傳輸(ACL)。



## Bluetooth programming
suitable platform: Raspberry Pi
https://www.instructables.com/Control-Bluetooth-LE-Devices-From-A-Raspberry-Pi/
Example: rfcomm-server.c
```c=
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
int main(int argc, char **argv)
{
struct sockaddr_rc loc_addr = { 0 }, rem_addr = { 0 };
char buf[1024] = { 0 };
int s, client, bytes_read;
socklen_t opt = sizeof(rem_addr);
// allocate socket
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
// bind socket to port 1 of the first available
// local bluetooth adapter
loc_addr.rc_family = AF_BLUETOOTH;
loc_addr.rc_bdaddr = *BDADDR_ANY;
loc_addr.rc_channel = (uint8_t) 1;
bind(s, (struct sockaddr *)&loc_addr, sizeof(loc_addr));
// put socket into listening mode
listen(s, 1);
// accept one connection
client = accept(s, (struct sockaddr *)&rem_addr, &opt);
ba2str( &rem_addr.rc_bdaddr, buf );
fprintf(stderr, "accepted connection from %s\n", buf);
memset(buf, 0, sizeof(buf));
// read data from the client
bytes_read = read(client, buf, sizeof(buf));
if( bytes_read > 0 ) {
printf("received [%s]\n", buf);
}
// close connection
close(client);
close(s);
return 0;
}
```
rfcomm_client.c
```c=
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
int main(int argc, char **argv)
{
struct sockaddr_rc addr = { 0 };
int s, status;
char dest[18] = "01:23:45:67:89:AB";
// allocate a socket
s = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
// set the connection parameters (who to connect to)
addr.rc_family = AF_BLUETOOTH;
addr.rc_channel = (uint8_t) 1;
str2ba( dest, &addr.rc_bdaddr );
// connect to server
status = connect(s, (struct sockaddr *)&addr, sizeof(addr));
// send a message
if( status == 0 ) {
status = write(s, "hello!", 6);
}
if( status < 0 ) perror("uh oh");
close(s);
return 0;
}
```
## IEEE or other journal