<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/ESA2GJK1DH1K_A/" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
說明
這節說明一下STM32+Air302+Mdebtls以SSL單向認證(不校驗服務器證書)方式連接MQTT服務器.
Air302內部沒有做上SSL,所以只能先使用單片機控制模組連接上TCP服務器,
然后再利用Mdebtls包實現SSL.
注意:受內存影響開發板不能測試此節的程序
用戶需要選擇STM32F103RET6及其以上型號的單片機測試!
提示(單向SSL認證,忽略服務器證書通信過程)
1.TCP客戶端連接上TCP服務器
2.TCP客戶端發送消息(明文消息)給服務器,告訴他自己都支持哪種加密方式(加密套件)
3.TCP服務器返回消息(明文消息)告訴客戶端咱使用的加密套件,當然還有服務器的證書數據
4.TCP客戶端不用程序解析服務器證書,二者直接通過TCP通信協商對稱加密的密碼
5.使用協商好的密碼進行對稱加密通信
反正記住一句話:證書只是驗證是不是真實的服務器,最終二者把數據經過對稱加密然后再通過TCP傳輸.
測試功能(我以外置一塊STM32F103RET6的板子為例)
1.短接BOOT0和3.3V,復位下單片機,目的是不要讓此開發板工作.調整波動開關如下
2.連線如下
圖示白線 : 外置板(PA2) -- 開發板NB-IOT(RX)
圖示白線 : 外置板(PA3) -- 開發板NB-IOT(TX)
圖示紫線 : 外置板(PB2) -- 開發板(PB2) 復位模塊
圖示黑線 : 外置板(GND) -- 開發板(GND) 共地
3.提醒
串口1在程序里面作為了日志打印輸出口,用戶可以監控下自己板子的串口1,查看打印的日志
4.下載此節的單片機程序到自己的板子
5.部分日志說明
程序說明
1.程序中使用Mdebtls這個包完成的SSL
2.關於詳細的移植和簡單使用參見開源教程資料
https://www.cnblogs.com/yangfengwu/category/1566194.html
3.為方便使用,SSL配置程序單獨建立一個文件
4.初始化配置SSL
5.配置發送數據接口
注:咱使用SSL發送的時候使用的是 mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len )
經過SSL底層程序的封裝以后,就會調用咱的發送數據函數.把數據發送出去.
6.配置接收數據接口
在執行SSL通信過程中,SSL的底層會調用這個函數獲取網絡數據.
模塊是使用串口把數據發給單片機,為了適應底層的調用方式,我把模組發來的網絡數據存儲到了環形隊列
7.串口接收分為兩個部分
普通的接收
凡是網絡返回的數據存儲到環形隊列(這也是為了配合SSL底層程序)
8.接下來看下執行步驟, 首先配置模組連接TCP服務器
9.在配置模組還沒SSL握手成功之前都是在普通接收的數組里面獲取的數據
10.初始化和輪訓調用SSL握手函數
注意:其實是調用的mbedtls_ssl_handshake
在輪訓調用mbedtls_ssl_handshake的時候,SSL底層會自動的執行握手協議的發送,接收和解析
發送和接收解析就是使用的這兩個函數
11.SSL握手成功以后發送連接MQTT消息
注:握手成功以后加密已經協商好了,咱只需要把數據傳遞給mbedtls_ssl_write函數
然后底層把數據加密之后通過咱配置的發送數據函數發送出去
12.現在是SSL網絡通信了,網絡數據需要通過SSL解析之后的接口去獲取
12.連接MQTT成功以后調用連接回調
13.發送緩存的MQTT消息自然也需要使用SSL函數發送
細節說明1
需要把heap加大,因為SSL內部使用 malloc 申請內存
細節說明2
1.發送完MQTT數據以后去掉延時等待發送下一條數據
以前都是使用的中斷發送的數據,有可能中斷發送還沒執行完又進來了這個函數.導致數據被覆蓋,導致發送錯誤.
所以在以前的程序中這個變量放在了串口發送數據完成里面.
這次沒有使用串口中斷發送,而是使用的普通的發送函數
究其原因呀,是因為為了節省內存好多數組是共用的,比如上面的 MainBuffer MainBufferCopy
如果這個地方設置了中斷發送,那么在發送完成之前其他地方就不能使用這些數組....
但是我為了省內存,其他地方也使用了這個數組,所以就改為了普通方式發送!
細節說明3
串口2接收數據緩存我定義到了3582,是因為這個NB-IOT模組每兩個字符作為一個16進制
那么即使是返回1024個數據,那么其實是返回 2048個!!!!!
當然只是執行SSL握手的時候返回的數據非常多...因為里面有服務器證書文件
1340*2 + 237*2 = 3154 這種16進制字符串表示的數據確實給單片機帶來了很大的負擔....
提示
為節省內存,程序里面只加入了一個控制繼電器的數據處理.
用戶可以用手機掃碼綁定以后控制繼電器.(需要連接PB1)