如何編寫簡易物聯網串列埠閘道器

2021-10-01 10:47:13 字數 4692 閱讀 5111

(3)socket通訊

(4)資料的加密

(5)從main函式開始

5、編寫stm32端

本文為《搭建物聯網基礎通訊框架系列教程》之《編寫物聯網串列埠閘道器》。

預備知識:linux串列埠的配置和讀寫,參考連線

樹莓派3b作為閘道器,當然您也可以用其它嵌入式開發板甚至是linux虛擬機器替代。

底層硬體採用stm32f103,或者其它帶有串列埠外設的mcu。

加密庫採用openssl,加密方式為rsa,aes。

開發語言為c++。

與樹莓派連線的節點作為資料匯集節點,用usb串列埠與樹莓派連線,樹莓派閘道器將資料進行加密,打包成我們自定義的資料報,傳送到我們自己搭建的雲平台。

class

cgateway

;

這裡的socket我進行了簡單的封裝,方便後邊的使用。

建立新的執行緒

1、建立新的執行緒

因為我們需要監聽stm32是否有資料傳送到閘道器,同時又要監聽是否有使用者的控制命令下發到stm32,因此我們需要需要再啟動乙個執行緒用於監聽是否有資料傳送到串列埠,而我們的主線程/程序則負責監聽socket是否有資料可讀。

當然,這個執行緒我們只是先設計出來,並不會馬上建立它。

-----------串列埠監聽執行緒的設計-----------

class

cgateway

;class

cmythread_listenusart

:public cbasethread

;

-----------串列埠監聽執行緒的執行函式-----------

void cmythread_listenusart::

run()if

(buf[0]

=='#'

) count +

= n;

} m_pgateway-

>

postsensordata

(sensordata);}

}}

pkt_sensordata 是自定義的感測器資料報,字元』#『作為資料幀的起始訊號

串列埠的配置

2、串列埠的配置

-----------串列埠類的設計-----------

//串列埠類配置出錯資訊的巨集定義

#define error_cfg_bauderate 0x01

#define error_cfg_databits 0x02

#define error_cfg_partity 0x04

#define error_cfg_stopbits 0x08

#define error_cfg_flowctrl_hw 0x10

#define error_cfg_flowctrl_sw 0x20

class

cserial

;

具體的配置參照linux系統庫中結構體中的變數配置即可,參考連線。

struct termios

;

這部分我們交給主線程/程序去做

-----------閘道器類的run()函式-----------

void cgateway::

run(

) size +

= n;if(

atol

(head.length)==0

&& size > pkt_len_head)if(

atol

(head.length)

>

0&& size >=

atol

(head.length)

)memcpy

(buf,

&buf[

atoi

(head.length)

], size -

atoi

(head.length));

size -

=atoi

(head.length)

;bzero

(&head, pkt_len_head);}

}}

我們不斷去獲取socket中的資料,在這裡我並沒有去設定socket的非阻塞屬性,因此如果socket沒有資料,程式將阻塞在readdata函式。思路就是:如果資料緩衝區的資料長度》=資料報頭的長度,我們就開始接收資料報體,將資料報包體完整接收後,我們根據資料報頭的資料報型別字段,將不同資料報交給對應的處理函式進行處理。

網路安全的基本操作是用【非對稱加密】加密【對稱加密】,然後用對稱加密進行會話。在這我們也採用這樣的邏輯。

rsa的初始化

這一部分設計到rsa加密api的基本使用(其實就是幾個函式),首先讀取公鑰配置檔案,然後生成rsa金鑰。

bool cgateway::

_initrsakey

(const

char

* path)

/* 讀取公鑰pem,pubkey格式pem使用pem_read_rsa_pubkey函式 */if(

(m_rsa =

pem_read_rsapublickey

(fp,

null

,null

,null))

==null

)else

fclose

(fp)

;return

true

;}

aes的初始化

網路安全的基本操作是用【非對稱加密】加密【對稱加密】,然後用對稱加密進行

bool cgateway::

_initaeskey

(en_pkt_cipherdisbt& en_cipherdisbt)if(

aes_set_encrypt_key((

const

unsigned

char

*)cipherdisbt.aes_userkey,16*

8,&m_key_en)!=0

)elseif(

aes_set_decrypt_key((

const

unsigned

char

*)cipherdisbt.aes_userkey,16*

8,&m_key_de)!=0

)else

memcpy

(m_ivec, cipherdisbt.aes_ivec,16)

;_sendauthcheckpkt()

;return

true

;}

pkt_cipherdisbt 定義如下

typedef

struct

pkt_cipherdisbt;

aes_ivec:

在每一次的aes加密和解密中會用到,當然您也可以在收發雙方約定好,每次加密解密只用userkey,ivec設定為0。

aes_userkey:

用於生成aes加密金鑰和解密金鑰。

int

main()

建立串列埠物件

tcp位址類的初始化需要更改為您使用伺服器的ip位址和埠

建立閘道器類物件,啟動閘道器類。

-----------閘道器類的建構函式-----------

cgateway::

cgateway

(cserial* pserial, csockaddr& serveraddr)if(

_initrsakey

("./public.pem")!=

true

) m_ptdlistenusart =

null

;}

當收到會話金鑰分發資料報時,我們之前設計的串列埠線程類就可以開始工作了

void cgateway::

_recvcipherdisbtpkt

(void

* pdata,

int len)if(

!m_ptdlistenusart)

}

樹莓派端的關鍵**我們就編寫完了

因為作為測試,在stm32端的**我做很複雜的功能,只是一些基本的配置和操作。

void

usart1_init

(u32 baudrate)

void

lightadc_init

(void

)

void

task_recvcmd

(unsigned

char

* p)

else

if(p[0]

==0xd0

&&(u8)p[1]

==0x01

)}

void

task_updatedata

(void

)}

int

main()

return0;

}

首先對系統初始化,隨後不間斷每隔2s上發一次感測器的資料。

物聯網閘道器

物聯網閘道器zlan5144j上海卓嵐推出的mqtt json轉modbus物聯網閘道器。支援以mqtt的方式連線雲端伺服器,支援可以介面話配置,自主採集modbus儀表 645儀表的資料,轉化為json格式上發雲端伺服器。支援100個左右的採集資料點。同時它有可以作為普通的透傳的串列埠伺服器和mo...

物聯網閘道器

9 24v的寬電壓的高質量電源設計提供了更好的工業環境適應性 可配備的導軌安裝配件適合導軌安裝。它整合了modbus tcp閘道器功能,可以方便地實現modbus rtu協議轉化為modbus tcp協議。rs232介面支援全雙工 不間斷通訊 rs485內嵌485防雷保護。對於使用虛擬串列埠的使用者...

lora物聯網閘道器

1.功能特點 1 通訊距離遠。實測距離為 表1.zlan9700 9743通訊距離 測試環境 測試距離 無遮擋通訊 8km左右 城市道路直線傳播 6km左右 城市有建築遮擋環境 1km左右 建築物內 穿5層樓板 2 zlan9743具備多功能的lora轉乙太網功能,實現lora轉tcp ip。2.1...