# Wireless Lab 1
* 實驗環境
* 硬體版本 : Raspberry Pi 3 Model B+
* 作業系統 : Raspbian 2018-06-27
* LoRa : SX1276晶片
* 實驗目標
* 使用ABP模式傳輸資料
* 並用MQTT取得資料後解碼
###### tags: `Wireless`
## :star: 實驗結果
1. 跑完ABP傳輸模式的流程,傳輸資料時分別使用`Confirm Data`和`Unconfirm Data`,截圖樹莓派上的結果,應該會有一個是有ACK一個是沒有ACK的。
2. 傳輸資料後用MQTT查看,並用base64解密截圖。
3. **以組為單位(一個人上傳即可)**,將這些截圖結果貼成一個word檔案,命名為`wireless-lab1-groupxx.docx`,並上傳到LMS作業區。
## ABP模式送出 (send_ttn.py)
這份程式主要修改來自 [jeroennijhof](https://github.com/jeroennijhof/LoRaWAN) 的程式碼
* 將[實驗程式碼](https://github.com/Ox7FFFFFFF/Wireless-Lab1)載下來
```shell
$ git clone https://github.com/Ox7FFFFFFF/Wireless-Lab1
```
* 程式資料夾
<i class="fa fa-folder-open"></i> LoRaWAN - 與LoRaWAN相關的程式
<i class="fa fa-folder-open"></i> SX127x - 控制晶片的SPI程式
<i class="fa fa-file-text"></i> send_ttn.py - 資料送出 (主程式)
<i class="fa fa-file-text"></i> config.json - Activated [DevAddr, NwkSKey, AppSKey]配置
* 程式流程
```flow
st=>start: Start
tx=>operation: MODE.TX
send=>operation: send message
tx_done=>operation: TX_DONE
rx=>operation: MODE.RXSINGLE
read=>operation: Read downlink payload
save=>operation: Save fCnt to config.json
cond=>condition: MIC check vaild
rx_done=>operation: RX_DONE
drop=>opertion: pass message
success=>operation: Success
fail=>operation: Fail
e=>end: End
st->tx->send->tx_done->tx_done->rx->rx_done->read->cond
cond(yes)->success->save
cond(no)->fail->save
save->e
```
1. 將devAddr,nwkSKey,appSKey填入`config.json`中,各組別的key在[這裡](https://docs.google.com/spreadsheets/d/1m-1YNfDqTG7ANa1yWgwECjDgPu3QftA0OFzzmewLcI0/edit#gid=958303526)
```json
{
"//":"請填寫自己組別對應的內容"
"appskey": "ede9e85656d0632a2fd197cddecb8ebf",
"devaddr": "06bdb47f",
"fCnt": 0,
"nwskey": "1917da8b8be11daf804c700298720299"
}
```
3. 調整`send_ttn.py`主要參數
* Frequency
* Spreading Factor
* Bandwidth
``` python=114
# Setup
lora.set_mode(MODE.SLEEP)
lora.set_dio_mapping([1,0,0,0,0,0])
lora.set_freq(AS923.FREQ1)
lora.set_spreading_factor(SF.SF7)
lora.set_bw(BW.BW125)
lora.set_pa_config(pa_select=1)
lora.set_pa_config(max_power=0x0F, output_power=0x0E)
lora.set_sync_word(0x34)
lora.set_rx_crc(True)
```
4. fCnt 要隨著傳輸次數增加,Server端收到小於目前記錄的fCnt將會丟棄封包不處理。
```python=56
def send(self):
global fCnt
lorawan = LoRaWAN.new(nwskey, appskey)
message = "HELLO WORLD!"
# 資料打包,fCnt+1
lorawan.create(MHDR.CONF_DATA_UP, {'devaddr': devaddr,
'fcnt': fCnt, 'data': list(map(ord, message)) })
print("fCnt: ",fCnt)
print("Send Message: ",message)
fCnt = fCnt+1
self.write_payload(lorawan.to_raw())
self.set_mode(MODE.TX)
```
5. 當切換到`MODE.TX`時,送出uplink之後會跳到`on_tx_done`
```python=21
def on_tx_done(self):
print("TxDone\n")
# 切換到rx
self.set_mode(MODE.STDBY)
self.clear_irq_flags(TxDone=1)
self.set_mode(MODE.SLEEP)
self.set_dio_mapping([0,0,0,0,0,0])
self.set_invert_iq(1)
self.reset_ptr_rx()
sleep(1)
self.set_mode(MODE.RXSINGLE)
```
6. 當接收到downlink時,會跳到`on_rx_done`
```python=
def on_rx_done(self):
global RxDone
RxDone = any([self.get_irq_flags()[s] for s in ['rx_done']])
print("RxDone")
self.clear_irq_flags(RxDone=1)
# 讀取 payload
payload = self.read_payload(nocheck=True)
lorawan = LoRaWAN.new(nwskey, appskey)
lorawan.read(payload)
print("get mic: ",lorawan.get_mic())
print("compute mic: ",lorawan.compute_mic())
print("valid mic: ",lorawan.valid_mic())
# 檢查mic
if lorawan.valid_mic():
print("ACK: ",lorawan.get_mac_payload().get_fhdr().get_fctrl()>>5&0x01)
print("direction: ",lorawan.get_direction())
print("devaddr: ",''.join(format(x, '02x') for x in lorawan.get_devaddr()))
write_config()
else:
print("Wrong MIC")
```
7. 執行`send_ttn.py`
```shell
$ python3 send_ttn.py
```

* MIC(Message Integrity Check):
* 用來確認這個資料是不是自己的
* ACK(Acknowledge):
* 因為傳送的資料格式是`MHDR.CONF_DATA_UP`,所以Downlink中會有ACK回應
* Direction:
* Uplink : 0
* Downlink : 1
* devaddr
* 也可以確認一下devaddr看是不是自己的,採用[Little-Endian](https://zh.wikipedia.org/wiki/%E5%AD%97%E8%8A%82%E5%BA%8F),比對的時候要倒過來看
## 使用MQTT查看傳輸到Server的資料
1. 請先安裝 [MQTT BOX](https://www.microsoft.com/zh-tw/p/mqttbox/9nblggh55jzg?activetab=pivot:overviewtab)
2. 新增 MQTT Client

3. 輸入 MQTT server 資訊

* MQTT Client Name : `隨便取`
* Protocol : `mqtts/tls`
* Username : `engineer`
* Host : `mqtt.hscc.csie.ncu.edu.tw:1883`
* SSL/TLS Certificate Type : `CA signed server ceritificate`
* Password : `nculoraserver`
4. 新增 Subscriber,並按下subscribe

* 主要格式為`application/[applicationID]/device/[devEUI]/rx`
* applicationID : 3
* devEUI : 就是分配到的EUI
* rx : server端收到的
5. 送出訊息後查看,`data`使用base64加密,所以要查看原始資料需要用base64解密

6. [base64解密](https://www.base64decode.org/)
