espblufi.lua 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. --[[
  2. @module espblufi
  3. @summary espblufi esp blufi 蓝牙配网(注意:初版暂不支持加密功能!!!!!!!!)
  4. @version 1.0
  5. @date 2025.07.01
  6. @author Dozingfiretruck
  7. @usage
  8. -- 此为Blufi 配网库
  9. -- BluFi 配网指南:https://www.espressif.com/sites/default/files/documentation/esp32_bluetooth_networking_user_guide_cn.pdf
  10. -- 安卓测试APP下载地址:https://github.com/EspressifApp/EspBlufiForAndroid/releases
  11. -- 安卓APP源码下载地址:https://github.com/EspressifApp/EspBlufiForAndroid
  12. -- IOS测试APP下载地址:https://apps.apple.com/cn/app/espblufi/id1450614082
  13. -- IOSAPP源码下载地址:https://github.com/EspressifApp/EspBlufiForiOS
  14. -- 小程序测试:微信搜索小程序:ESP Config
  15. -- 小程序源码下载地址:https://github.com/EspressifApps/ESP-Config-WeChat
  16. -- 注意:初版暂不支持加密功能!!!!!!!!
  17. -- 用法实例
  18. local espblufi = require("espblufi")
  19. local function espblufi_callback(event,data)
  20. if event == espblufi.EVENT_STA_INFO then
  21. for i, v in pairs(data) do
  22. print(i,v)
  23. end
  24. elseif event == espblufi.EVENT_SOFTAP_INFO then
  25. for i, v in pairs(data) do
  26. print(i,v)
  27. end
  28. elseif event == espblufi.EVENT_CUSTOM_DATA then
  29. espblufi.send_custom_data(data)
  30. end
  31. end
  32. sys.taskInit(function()
  33. local bluetooth_device = bluetooth.init()
  34. espblufi.init(bluetooth_device, espblufi_callback)
  35. espblufi.start()
  36. while 1 do
  37. sys.wait(1000)
  38. end
  39. end)
  40. ]]
  41. local espblufi = {}
  42. local sys = require "sys"
  43. local BLUFI_TOPIC = "espblufi"
  44. local BTC_BLUFI_GREAT_VER = 0x01 --Version + Subversion
  45. local BTC_BLUFI_SUB_VER = 0x03 --Version + Subversion
  46. local BTC_BLUFI_VERSION = ((BTC_BLUFI_GREAT_VER<<8)|BTC_BLUFI_SUB_VER) --Version + Subversion
  47. -- packet type
  48. local BLUFI_TYPE_MASK = 0x03
  49. local BLUFI_TYPE_SHIFT = 0
  50. local BLUFI_SUBTYPE_MASK = 0xFC
  51. local BLUFI_SUBTYPE_SHIFT = 2
  52. local function BLUFI_GET_TYPE(type) return ((type) & BLUFI_TYPE_MASK) end
  53. local function BLUFI_GET_SUBTYPE(type) return (((type) & BLUFI_SUBTYPE_MASK) >>BLUFI_SUBTYPE_SHIFT) end
  54. local function BLUFI_BUILD_TYPE(type,subtype) return (((type) & BLUFI_TYPE_MASK) | ((subtype)<<BLUFI_SUBTYPE_SHIFT)) end
  55. local BLUFI_TYPE_CTRL = 0x0
  56. local BLUFI_TYPE_CTRL_SUBTYPE_ACK = 0x00
  57. local BLUFI_TYPE_CTRL_SUBTYPE_SET_SEC_MODE = 0x01
  58. local BLUFI_TYPE_CTRL_SUBTYPE_SET_WIFI_OPMODE = 0x02
  59. local BLUFI_TYPE_CTRL_SUBTYPE_CONN_TO_AP = 0x03
  60. local BLUFI_TYPE_CTRL_SUBTYPE_DISCONN_FROM_AP = 0x04
  61. local BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_STATUS = 0x05
  62. local BLUFI_TYPE_CTRL_SUBTYPE_DEAUTHENTICATE_STA = 0x06
  63. local BLUFI_TYPE_CTRL_SUBTYPE_GET_VERSION = 0x07
  64. local BLUFI_TYPE_CTRL_SUBTYPE_DISCONNECT_BLE = 0x08
  65. local BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_LIST = 0x09
  66. local BLUFI_TYPE_DATA = 0x1
  67. local BLUFI_TYPE_DATA_SUBTYPE_NEG = 0x00
  68. local BLUFI_TYPE_DATA_SUBTYPE_STA_BSSID = 0x01
  69. local BLUFI_TYPE_DATA_SUBTYPE_STA_SSID = 0x02
  70. local BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD = 0x03
  71. local BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID = 0x04
  72. local BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD = 0x05
  73. local BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM = 0x06
  74. local BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE = 0x07
  75. local BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL = 0x08
  76. local BLUFI_TYPE_DATA_SUBTYPE_USERNAME = 0x09
  77. local BLUFI_TYPE_DATA_SUBTYPE_CA = 0x0a
  78. local BLUFI_TYPE_DATA_SUBTYPE_CLIENT_CERT = 0x0b
  79. local BLUFI_TYPE_DATA_SUBTYPE_SERVER_CERT = 0x0c
  80. local BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY = 0x0d
  81. local BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY = 0x0e
  82. local BLUFI_TYPE_DATA_SUBTYPE_WIFI_REP = 0x0f
  83. local BLUFI_TYPE_DATA_SUBTYPE_REPLY_VERSION = 0x10
  84. local BLUFI_TYPE_DATA_SUBTYPE_WIFI_LIST = 0x11
  85. local BLUFI_TYPE_DATA_SUBTYPE_ERROR_INFO = 0x12
  86. local BLUFI_TYPE_DATA_SUBTYPE_CUSTOM_DATA = 0x13
  87. local BLUFI_TYPE_DATA_SUBTYPE_STA_MAX_CONN_RETRY = 0x14
  88. local BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_END_REASON = 0x15
  89. local BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_RSSI = 0x16
  90. local function BLUFI_TYPE_IS_CTRL(type) return (BLUFI_GET_TYPE((type)) == BLUFI_TYPE_CTRL) end
  91. local function BLUFI_TYPE_IS_DATA(type) return (BLUFI_GET_TYPE((type)) == BLUFI_TYPE_DATA) end
  92. -- packet frame control
  93. local BLUFI_FC_ENC_MASK = 0x01
  94. local BLUFI_FC_CHECK_MASK = 0x02
  95. local BLUFI_FC_DIR_MASK = 0x04
  96. local BLUFI_FC_REQ_ACK_MASK = 0x08
  97. local BLUFI_FC_FRAG_MASK = 0x10
  98. local BLUFI_FC_ENC = 0x01
  99. local BLUFI_FC_CHECK = 0x02
  100. local BLUFI_FC_DIR_P2E = 0x00
  101. local BLUFI_FC_DIR_E2P = 0x04
  102. local BLUFI_FC_REQ_ACK = 0x08
  103. local BLUFI_FC_FRAG = 0x10
  104. local BLUFI_SEQUENCE_ERROR = 0x00
  105. local BLUFI_CHECKSUM_ERROR = 0x01
  106. local BLUFI_DECRYPT_ERROR = 0x02
  107. local BLUFI_ENCRYPT_ERROR = 0x03
  108. local BLUFI_INIT_SECURITY_ERROR = 0x04
  109. local BLUFI_DH_MALLOC_ERROR = 0x05
  110. local BLUFI_DH_PARAM_ERROR = 0x06
  111. local BLUFI_READ_PARAM_ERROR = 0x07
  112. local BLUFI_MAKE_PUBLIC_ERROR = 0x08
  113. local BLUFI_DATA_FORMAT_ERROR = 0x09
  114. local BLUFI_CALC_MD5_ERROR = 0x0a
  115. local BLUFI_WIFI_SCAN_FAIL = 0x0b
  116. local BLUFI_MSG_STATE_ERROR = 0x0c
  117. local BLUFI_OPMODE_NULL = 0x00
  118. local BLUFI_OPMODE_STA = 0x01
  119. local BLUFI_OPMODE_SOFTAP = 0x02
  120. local BLUFI_OPMODE_SOFTAPSTA = 0x03
  121. local BLUFI_STA_CONN_SUCCESS = 0x00
  122. local BLUFI_STA_CONN_FAIL = 0x01
  123. local BLUFI_STA_CONNECTING = 0x02
  124. local BLUFI_STA_NO_IP = 0x03
  125. local BLUFI_BLE_STATE_DISCONN = 0x00
  126. local BLUFI_BLE_STATE_CONNED = 0x01
  127. local BLUFI_WLAN_STATE_DISCONN = 0x00
  128. local BLUFI_WLAN_STATE_CONNING = 0x01
  129. local BLUFI_WLAN_STATE_CONNED = 0x02
  130. local BLUFI_SEQUENCE_ERROR = 0x00
  131. local BLUFI_CHECKSUM_ERROR = 0x01
  132. local BLUFI_DECRYPT_ERROR = 0x02
  133. local BLUFI_ENCRYPT_ERROR = 0x03
  134. local BLUFI_INIT_SECURITY_ERROR = 0x04
  135. local BLUFI_DH_MALLOC_ERROR = 0x05
  136. local BLUFI_DH_PARAM_ERROR = 0x06
  137. local BLUFI_READ_PARAM_ERROR = 0x07
  138. local BLUFI_MAKE_PUBLIC_ERROR = 0x08
  139. local BLUFI_DATA_FORMAT_ERROR = 0x09
  140. local BLUFI_CALC_MD5_ERROR = 0x0a
  141. local BLUFI_WIFI_SCAN_FAIL = 0x0b
  142. local BLUFI_MSG_STATE_ERROR = 0x0c
  143. local function BLUFI_FC_IS_ENC(fc) return ((fc) & BLUFI_FC_ENC_MASK) ~= 0 end
  144. local function BLUFI_FC_IS_CHECK(fc) return ((fc) & BLUFI_FC_CHECK_MASK) ~= 0 end
  145. local function BLUFI_FC_IS_REQ_ACK(fc) return ((fc) & BLUFI_FC_REQ_ACK_MASK) ~= 0 end
  146. local function BLUFI_FC_IS_FRAG(fc) return ((fc) & BLUFI_FC_FRAG_MASK) ~= 0 end
  147. local BLUFI_PROTOCOL_DATA = "BLUFI_PROTOCOL_DATA"
  148. local BLUFI_TASK_EXIT = "BLUFI_TASK_EXIT"
  149. local espblufi_uuid_service = "0xFFFF"
  150. local espblufi_uuid2device = "0xFF01"
  151. local espblufi_uuid2mobile = "0xFF02"
  152. local espblufi_att_db = {
  153. string.fromHex(espblufi_uuid_service),
  154. {string.fromHex(espblufi_uuid2device),ble.WRITE,},
  155. {string.fromHex(espblufi_uuid2mobile),ble.NOTIFY|ble.READ}
  156. }
  157. local blufi_env = {ble_device=nil,callback=nil,isfrag=nil,
  158. ble_state = BLUFI_BLE_STATE_DISCONN,
  159. wlan_state = BLUFI_WLAN_STATE_DISCONN,
  160. opmode = BLUFI_OPMODE_NULL,
  161. recv_seq=0,send_seq=0,sec_mode=0,
  162. softap_conn_num = 0,
  163. softap_auth_mode=0,
  164. softap_max_conn_num=0,
  165. softap_channel = nil,
  166. sta_max_conn_retry = nil,
  167. sta_conn_end_reason = nil,
  168. sta_ssid=nil,sta_passwd=nil,
  169. softap_ssid=nil,softap_passwd=nil}
  170. local blufi_hdr = {type=nil,fc=nil,seq=nil,data_len=nil,data=nil}
  171. espblufi.EVENT_STA_INFO = 0x01
  172. espblufi.EVENT_SOFTAP_INFO = 0x02
  173. espblufi.EVENT_CUSTOM_DATA = 0x03
  174. sys.subscribe("WLAN_AP_INC", function(state, mac)
  175. if state == "CONNECTED" then
  176. blufi_env.softap_conn_num = blufi_env.softap_conn_num+1
  177. elseif state == "DISCONNECTED" and blufi_env.softap_conn_num>0 then
  178. blufi_env.softap_conn_num = blufi_env.softap_conn_num-1
  179. end
  180. end)
  181. local function blufi_crc_checksum(data)
  182. return crypto.crc16("IBM",data)
  183. end
  184. local function blufi_send_encap(blufi_hdr_send)
  185. local send_data = string.char(blufi_hdr_send.type,blufi_hdr_send.fc,blufi_hdr_send.seq,#blufi_hdr_send.data) .. blufi_hdr_send.data
  186. if BLUFI_TYPE_IS_CTRL(blufi_hdr_send.type) then
  187. blufi_hdr_send.fc = blufi_hdr_send.fc|BLUFI_FC_CHECK
  188. send_data = send_data .. blufi_crc_checksum(send_data)
  189. end
  190. blufi_env.send_seq = blufi_env.send_seq + 1
  191. blufi_env.ble_device:write_notify({uuid_service=string.fromHex(espblufi_uuid_service),uuid_characteristic=string.fromHex(espblufi_uuid2mobile)},send_data)
  192. end
  193. local function btc_blufi_send_encap(type,data)
  194. if blufi_env.ble_state == BLUFI_BLE_STATE_DISCONN then
  195. return
  196. end
  197. local blufi_hdr_send = {type=type,fc=0,seq=blufi_env.send_seq,data=data}
  198. blufi_send_encap(blufi_hdr_send)
  199. end
  200. local function btc_blufi_wifi_conn_report(sta_conn_state)
  201. local data = string.char(blufi_env.opmode,blufi_env.wlan_state,blufi_env.softap_conn_num)
  202. local wlan_info = wlan.getInfo()
  203. if wlan_info then
  204. if wlan_info.bssid then
  205. data = data .. string.char(BLUFI_TYPE_DATA_SUBTYPE_STA_BSSID,6) .. string.fromHex(wlan_info.bssid)
  206. end
  207. if wlan_info.rssi then
  208. data = data .. string.char(BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_RSSI,1,wlan_info.rssi%256)
  209. end
  210. end
  211. if blufi_env.sta_ssid then
  212. data = data .. string.char(BLUFI_TYPE_DATA_SUBTYPE_STA_SSID,#blufi_env.sta_ssid) .. blufi_env.sta_ssid
  213. end
  214. if blufi_env.sta_passwd then
  215. data = data .. string.char(BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD,#blufi_env.sta_passwd) .. blufi_env.sta_passwd
  216. end
  217. if blufi_env.softap_ssid then
  218. data = data .. string.char(BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID,#blufi_env.softap_ssid) .. blufi_env.softap_ssid
  219. end
  220. if blufi_env.softap_passwd then
  221. data = data .. string.char(BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD,#blufi_env.softap_passwd) .. blufi_env.softap_passwd
  222. end
  223. if blufi_env.softap_authmode then
  224. data = data .. string.char(BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE,1) .. blufi_env.softap_authmode
  225. end
  226. if blufi_env.softap_max_conn_num then
  227. data = data .. string.char(BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM,1) .. blufi_env.softap_max_conn_num
  228. end
  229. if blufi_env.softap_channel then
  230. data = data .. string.char(BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL,1) .. blufi_env.softap_channel
  231. end
  232. if blufi_env.sta_max_conn_retry then
  233. data = data .. string.char(BLUFI_TYPE_DATA_SUBTYPE_STA_MAX_CONN_RETRY,1) .. blufi_env.sta_max_conn_retry
  234. end
  235. if blufi_env.sta_conn_end_reason then
  236. data = data .. string.char(BLUFI_TYPE_DATA_SUBTYPE_STA_CONN_END_REASON,1) .. blufi_env.sta_conn_end_reason
  237. end
  238. btc_blufi_send_encap(BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_WIFI_REP), data);
  239. end
  240. local function btc_blufi_send_wifi_list(results)
  241. local data = ""
  242. for k,v in pairs(results) do data = data .. string.char(#v["ssid"]+1,v["rssi"]%256) .. v["ssid"] end
  243. btc_blufi_send_encap(BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_WIFI_LIST),data)
  244. end
  245. local function btc_blufi_send_ack(seq)
  246. btc_blufi_send_encap(BLUFI_BUILD_TYPE(BLUFI_TYPE_CTRL, BLUFI_TYPE_CTRL_SUBTYPE_ACK),string.char(seq))
  247. end
  248. local function btc_blufi_send_error_info(state)
  249. btc_blufi_send_encap(BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_ERROR_INFO),string.char(state))
  250. end
  251. local function btc_blufi_send_custom_data(data)
  252. btc_blufi_send_encap(BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_CUSTOM_DATA),data)
  253. end
  254. local SEC_TYPE_DH_PARAM_LEN = 0x00
  255. local SEC_TYPE_DH_PARAM_DATA = 0x01
  256. local SEC_TYPE_DH_P = 0x02
  257. local SEC_TYPE_DH_G = 0x03
  258. local SEC_TYPE_DH_PUBLIC = 0x04
  259. local blufi_sec = {dh_param_len=0}
  260. local function blufi_dh_negotiate_data_handler(data)
  261. if #data<3 then
  262. btc_blufi_send_error_info(BLUFI_DATA_FORMAT_ERROR)
  263. end
  264. local type = data:byte(1)
  265. if type == SEC_TYPE_DH_PARAM_LEN then
  266. blufi_sec.dh_param_len = ((data:byte(2)<<8)|data:byte(3));
  267. -- print("dh_param_len",blufi_sec.dh_param_len)
  268. elseif type == SEC_TYPE_DH_PARAM_DATA then
  269. -- print("SEC_TYPE_DH_PARAM_DATA")
  270. if #data < (blufi_sec.dh_param_len + 1) then
  271. btc_blufi_send_error_info(BLUFI_DH_PARAM_ERROR);
  272. return;
  273. end
  274. -- 秘钥待实现,功能需要mbedtls引出c接口
  275. btc_blufi_send_error_info(BLUFI_INIT_SECURITY_ERROR);
  276. elseif type == SEC_TYPE_DH_P then
  277. print("SEC_TYPE_DH_P")
  278. elseif type == SEC_TYPE_DH_G then
  279. print("SEC_TYPE_DH_G")
  280. elseif type == SEC_TYPE_DH_PUBLIC then
  281. print("SEC_TYPE_DH_PUBLIC")
  282. end
  283. end
  284. local function btc_blufi_protocol_handler(parse_data)
  285. local target_data_len = 0
  286. local parse_data_len = #parse_data
  287. if parse_data_len<4 then return end
  288. blufi_hdr.type,blufi_hdr.fc,blufi_hdr.seq,blufi_hdr.data_len = string.unpack('<BBBB',parse_data)
  289. if BLUFI_FC_IS_CHECK(blufi_hdr.fc) then
  290. target_data_len = blufi_hdr.data_len + 4 + 2 -- // Data + (Type + Frame Control + Sequence Number + Data Length) + Checksum
  291. else
  292. target_data_len = blufi_hdr.data_len + 4 -- Data + (Type + Frame Control + Sequence Number + Data Length)
  293. end
  294. -- print("target_data_len",target_data_len,"parse_data_len",parse_data_len)
  295. if target_data_len ~= parse_data_len then
  296. return
  297. end
  298. if blufi_hdr.seq ~= blufi_env.recv_seq then
  299. return
  300. end
  301. blufi_env.recv_seq = blufi_env.recv_seq + 1
  302. if BLUFI_FC_IS_ENC(blufi_hdr.fc) then
  303. -- 解密功能需要mbedtls引出c接口
  304. end
  305. if BLUFI_FC_IS_CHECK(blufi_hdr.fc) and crypto then
  306. -- 需要app配合调试,暂时不强制校验
  307. local checksum = blufi_crc_checksum()
  308. end
  309. if BLUFI_FC_IS_REQ_ACK(blufi_hdr.fc) then
  310. btc_blufi_send_ack(blufi_hdr.seq)
  311. end
  312. if blufi_hdr.data_len and blufi_hdr.data_len>0 then
  313. if blufi_env.isfrag then
  314. blufi_hdr.data = blufi_hdr.data .. parse_data:sub(5)
  315. else
  316. blufi_hdr.data = parse_data:sub(5)
  317. end
  318. end
  319. if BLUFI_FC_IS_FRAG(blufi_hdr.fc) then
  320. blufi_env.isfrag = true
  321. return
  322. else
  323. blufi_env.isfrag = false
  324. end
  325. -- print(blufi_hdr.type,blufi_hdr.fc,blufi_hdr.seq,blufi_hdr.data_len)
  326. -- print(blufi_hdr.data,blufi_hdr.data:toHex())
  327. local blufi_type = BLUFI_GET_TYPE(blufi_hdr.type)
  328. local blufi_subtype = BLUFI_GET_SUBTYPE(blufi_hdr.type)
  329. if blufi_type == BLUFI_TYPE_CTRL then
  330. if blufi_subtype == BLUFI_TYPE_CTRL_SUBTYPE_ACK then
  331. elseif blufi_subtype == BLUFI_TYPE_CTRL_SUBTYPE_SET_SEC_MODE then
  332. blufi_env.sec_mode = blufi_hdr.data;
  333. elseif blufi_subtype == BLUFI_TYPE_CTRL_SUBTYPE_SET_WIFI_OPMODE then
  334. blufi_env.opmode = blufi_hdr.data:byte(1)
  335. elseif blufi_subtype == BLUFI_TYPE_CTRL_SUBTYPE_CONN_TO_AP then
  336. blufi_env.callback(espblufi.EVENT_STA_INFO,
  337. {ssid=blufi_env.sta_ssid,password=blufi_env.sta_passwd})
  338. wlan.connect(blufi_env.sta_ssid, blufi_env.sta_passwd)
  339. blufi_env.wlan_state = BLUFI_WLAN_STATE_CONNING
  340. local results = sys.waitUntil("IP_READY",3000)
  341. if results then blufi_env.wlan_state = BLUFI_WLAN_STATE_CONNED
  342. else blufi_env.wlan_state = BLUFI_WLAN_STATE_DISCONN end
  343. btc_blufi_wifi_conn_report()
  344. elseif blufi_subtype == BLUFI_TYPE_CTRL_SUBTYPE_DISCONN_FROM_AP then
  345. wlan.disconnect()
  346. elseif blufi_subtype == BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_STATUS then
  347. btc_blufi_wifi_conn_report()
  348. elseif blufi_subtype == BLUFI_TYPE_CTRL_SUBTYPE_DEAUTHENTICATE_STA then
  349. -- print("BLUFI_TYPE_CTRL_SUBTYPE_DEAUTHENTICATE_STA")
  350. elseif blufi_subtype == BLUFI_TYPE_CTRL_SUBTYPE_GET_VERSION then
  351. btc_blufi_send_encap(BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_REPLY_VERSION), string.char(BTC_BLUFI_GREAT_VER,BTC_BLUFI_SUB_VER))
  352. elseif blufi_subtype == BLUFI_TYPE_CTRL_SUBTYPE_DISCONNECT_BLE then
  353. blufi_env.ble_device:disconnect()
  354. elseif blufi_subtype == BLUFI_TYPE_CTRL_SUBTYPE_GET_WIFI_LIST then
  355. wlan.scan()
  356. sys.waitUntil("WLAN_SCAN_DONE", 15000)
  357. local results = wlan.scanResult()
  358. if results and #results>0 then
  359. btc_blufi_send_wifi_list(results)
  360. else
  361. btc_blufi_send_error_info(BLUFI_WIFI_SCAN_FAIL)
  362. end
  363. end
  364. elseif blufi_type == BLUFI_TYPE_DATA then
  365. if blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_NEG then
  366. local data = blufi_dh_negotiate_data_handler(blufi_hdr.data)
  367. if data then
  368. btc_blufi_send_encap(BLUFI_BUILD_TYPE(BLUFI_TYPE_DATA, BLUFI_TYPE_DATA_SUBTYPE_NEG),data)
  369. end
  370. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_STA_BSSID then
  371. blufi_env.sta_bssid = blufi_hdr.data
  372. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_STA_SSID then
  373. blufi_env.sta_ssid = blufi_hdr.data
  374. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_STA_PASSWD then
  375. blufi_env.sta_passwd = blufi_hdr.data
  376. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_SSID then
  377. blufi_env.softap_ssid = blufi_hdr.data
  378. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_PASSWD then
  379. blufi_env.softap_passwd = blufi_hdr.data
  380. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_MAX_CONN_NUM then
  381. blufi_env.softap_max_conn_num = blufi_hdr.data:byte(1)
  382. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_AUTH_MODE then
  383. blufi_env.softap_auth_mode = blufi_hdr.data:byte(1)
  384. blufi_env.callback(espblufi.EVENT_SOFTAP_INFO,
  385. {ssid=blufi_env.softap_ssid,password=blufi_env.softap_passwd,})
  386. wlan.createAP(blufi_env.softap_ssid, blufi_env.softap_passwd,nil,nil,blufi_env.softap_max_channel,{max_conn = blufi_env.softap_max_conn_num})
  387. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_SOFTAP_CHANNEL then
  388. blufi_env.softap_max_channel = blufi_hdr.data:byte(1)
  389. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_USERNAME then
  390. -- print("BLUFI_TYPE_DATA_SUBTYPE_USERNAME")
  391. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_CA then
  392. -- print("BLUFI_TYPE_DATA_SUBTYPE_CA")
  393. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_CLIENT_CERT then
  394. -- print("BLUFI_TYPE_DATA_SUBTYPE_CLIENT_CERT")
  395. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_SERVER_CERT then
  396. -- print("BLUFI_TYPE_DATA_SUBTYPE_SERVER_CERT")
  397. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY then
  398. -- print("BLUFI_TYPE_DATA_SUBTYPE_CLIENT_PRIV_KEY")
  399. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY then
  400. -- print("BLUFI_TYPE_DATA_SUBTYPE_SERVER_PRIV_KEY")
  401. elseif blufi_subtype == BLUFI_TYPE_DATA_SUBTYPE_CUSTOM_DATA then
  402. blufi_env.callback(espblufi.EVENT_CUSTOM_DATA,blufi_hdr.data)
  403. end
  404. else
  405. return
  406. end
  407. end
  408. local function espblufi_task()
  409. while true do
  410. local result, event, data = sys.waitUntil(BLUFI_TOPIC)
  411. if result then
  412. if event == BLUFI_PROTOCOL_DATA then
  413. btc_blufi_protocol_handler(data)
  414. elseif event == BLUFI_TASK_EXIT then
  415. break
  416. end
  417. end
  418. end
  419. end
  420. local function espblufi_ble_callback(ble_device, ble_event, ble_param)
  421. if ble_event == ble.EVENT_CONN then
  422. blufi_env.ble_state = BLUFI_BLE_STATE_CONNED
  423. elseif ble_event == ble.EVENT_DISCONN then
  424. blufi_env.ble_state = BLUFI_BLE_STATE_DISCONN
  425. elseif ble_event == ble.EVENT_WRITE then
  426. sys.publish(BLUFI_TOPIC,BLUFI_PROTOCOL_DATA,ble_param.data)
  427. end
  428. end
  429. --[[
  430. 初始化espblufi
  431. @api espblufi.init(bluetooth_device,espblufi_callback,local_name)
  432. @userdata bluetooth_device 蓝牙设备对象
  433. @function 事件回调函数
  434. @number 蓝牙名,可选,默认为"BLUFI_xxx",xxx为设备型号(因为esp的配网测试app默认过滤蓝牙名称为BLUFI_开头的设备进行显示,可手动修改)
  435. @usage
  436. espblufi.init(espblufi_callback)
  437. ]]
  438. function espblufi.init(bluetooth_device,espblufi_callback,local_name)
  439. if not bluetooth or not ble or not wlan then
  440. log.error("need bluetooth ble and wlan")
  441. return
  442. end
  443. if bluetooth_device == nil or type(bluetooth_device) ~= "userdata" then
  444. log.error("bluetooth_device is nil")
  445. return
  446. end
  447. if not espblufi_callback then
  448. log.error("espblufi_callback is nil")
  449. return
  450. else
  451. blufi_env.callback = espblufi_callback
  452. end
  453. if not local_name then
  454. local_name = "BLUFI_"..rtos.bsp()
  455. end
  456. wlan.init()
  457. local ble_device = bluetooth_device:ble(espblufi_ble_callback)
  458. ble_device:gatt_create(espblufi_att_db)
  459. ble_device:adv_create({
  460. adv_data = {{ble.FLAGS,string.char(0x06)},{ble.COMPLETE_LOCAL_NAME, local_name}},
  461. })
  462. blufi_env.ble_device = ble_device
  463. return
  464. end
  465. --[[
  466. 开始配网
  467. @api espblufi.start()
  468. @usage
  469. espblufi.start()
  470. ]]
  471. function espblufi.start()
  472. sys.taskInit(espblufi_task)
  473. blufi_env.ble_device:adv_start()
  474. end
  475. --[[
  476. 停止配网
  477. @api espblufi.stop()
  478. @usage
  479. espblufi.stop()
  480. ]]
  481. function espblufi.stop()
  482. blufi_env.ble_device:adv_stop()
  483. sys.publish(BLUFI_TOPIC,BLUFI_TASK_EXIT)
  484. end
  485. function espblufi.deinit()
  486. end
  487. --[[
  488. 发送自定义数据,一般用于接收到客户端发送的自定义命令后进行回复
  489. @api espblufi.send_custom_data(data)
  490. @string 回复的数据包内容
  491. @usage
  492. espblufi.send_custom_data(data)
  493. ]]
  494. function espblufi.send_custom_data(data)
  495. btc_blufi_send_custom_data(data)
  496. end
  497. return espblufi