1. 前言
上一篇文章了關於微信藍牙外設的廣播數據格式解析,這篇文章將記錄與微信藍牙外設通訊,並且通過微信藍牙外設協議中的數據透傳通道,如何與單片機端自定義通訊。由於項目用到了安卓和微信小程序(Java Script)兩個平臺,本篇文章將記錄微信小程序調試過程。
2. 微信藍牙外設通訊流程
2.1 根據《微信藍牙外設協議1.0.4》 中提到,藍牙 BLE 模擬成流
藍牙設備需暴露兩個特徵值(Characteristics):Write 特徵值,Indication 特徵值。藍牙 設備從 Write 特徵值接受數據,從Indication 特徵值發送數據。 Indication 特徵值類型是 bytes。 這裏我們約定,把一個特徵值一次傳輸的數據,稱爲一幀(不同類型的特徵值一次傳輸的數 據長度是不一樣的)。
上面的意思是,對於上層也就是(微信小程序)來說,需要向設備發送數據,則通Write 特徵,中寫入數據,即可以傳輸到藍牙設備中,而藍牙設備返回數據到上層,則是通過Indication 特徵,而不是Notify 特徵。
並且還提到,通訊中,使用二進制流的形式通訊,而不是文本。
2.2 藍牙設備寫過程
分幀:假設藍牙手環上有 1k 數據,要發給手機微信。由於一個特徵值長度有限(如 20 個字節),顯然需要分多次才能傳輸完成。1k 數據,要分成 1024 字節/ 20 字節 =51 個幀。剩下的 4 個字節,不足一幀(20 個字節),需補齊爲一幀並對剩下的
16 個字節賦 0。總共是 52 幀。
這的意思是,對於大部分的藍牙BLE 設備(不管是微信藍牙BLE外設還是普通BLE 藍牙外設),一般一次性最多傳輸20 byte,
對於超過20個字節的數據,需要多次傳輸。
2.3 藍牙外設與上層通訊協議 -- 藍牙Airsync協議交互
交互過程是一個協作的過程,就像我們訪問業務系統一樣也要先登陸,再初始化後,才能進行正常的業務通信啊。那麼登陸和初始化我們可以理解爲應用控制信令,而後續的數據通信也是應用數據通信。
藍牙Airsync協議使用protobuf技術進行封包和解包,詳見《 Protocolbuffer序列化及其在微信藍牙協議中的應用》。
根據《微信藍牙外設協議1.0.4》提到,通訊包結構由兩部分組成,定長包頭 + 定長包體
其中,定長包頭格式
定長包頭
struct BpFixHead
{
unsigned char bMagicNumber;
unsigned char bVer;
unsigned short nLength;
unsigned short nCmdId;
unsigned short nSeq;
};
變長包體是使用谷歌的Protoalbuf 打包的二進制數據。
2.4 通訊流程
2.4.1 會話約定
a. 設備連上微信之後,需要發送 AuthReq,等收到成功的回包之後,接着還要發送 InitReq,並收到成功的回包之後,才能正常發送數據。如果設備沒有 auth,手機 對設備的所有請求都返回錯誤碼 EEC_needAuth。
b. 當出現解包異常的時候,直接斷開連接。
c. Push 類的包 seq 永遠爲 0。Req 類和 Resp 類的包的 seq 永不爲 0。
d. 服務器可隨時發送 Push 包。
e. 廠商服務器發送的 Push 包(注意 Push 包是沒有回包的,即沒有 PushResp),如果需要設備的回包,需要由廠商自己實現。
具體方法如:廠商發送 RecvDataPush 給設備,設備收到 push 後,向廠商服務器 發送一個 SendDataRequest。這時廠商服務器可知道設備收到了 push,並且可以 從 Req 裏取得設備的迴應數據。
上述流程就是如下圖所示:
會話流程如下:
3. 通訊指令
3.1 命令列表
名稱 |
描敘
|
Auth
|
登錄
|
Init
|
初始化
|
SendData
|
設備發送數據給廠商或微信公衆平臺或微信客戶端。 當 type 爲空或者等於 0 時,表示發送給廠商服務器。 當 type 爲 10001 時,表示發送給微信客戶端 html5 設備會話 界面。 當 type 爲其他時,表示發送給公衆平臺服務器。具體的定義 請看 附錄:微信公衆平臺 proto 文件。舉個例子,type 等於 1 時,表示手環數據。
|
RecvDataPush
|
廠商或微信客戶端或微信公衆平臺發送數據給設備 當 type 爲空或者等於 0 時,表示廠商發送設備。 當 type 爲 10001 時,表示收到微信客戶端 html5 設備會話界 面的數據。 當 type 爲其他時,表示公衆平臺發送給設備。具體的定義請 看 附錄:微信公衆平臺 proto 文件。舉個例子,type 等於 1 時,表示手環數據。
|
3.2 AuthRequest 登錄指令 (摘自 《以藍牙開發的視覺解讀微信Airsync協議》)
微信支持兩種登陸身份認證,加密和不加密。這裏只討論簡單的不加密認證好了。不加密時,我們一般用MAC地址方式登陸,即將AeSine付空值,AuthMethod賦值爲EAM_macNoEncrypt.
Author會收到手機微信的回覆,在加密時收到的是一個用於之後通信的祕鑰,但在不加密是可以忽略。
3.3 InitRequest 初始化通訊指令(摘自 《以藍牙開發的視覺解讀微信Airsync協議》)
初始化的目的是外設生成一個隨機數,以後每次通信後,該數值都會自動加1;另外,在初始化的回覆中,手機微信可以告訴外設手機微信當前的用的手機操作系統的版本、當前時間、微信用戶ID等等。以便於外設記錄用戶的信息。
3.4 SendData 設備發送數據指令
設備和上層可以通過這個還有RecDataPush 當type = 0 時,發送自定義數據。
4. 微信Proto buf 協議
4.1 proto buf 協議簡介
官方文檔給出的定義和描述:
protocol buffers 是一種語言無關、平臺無關、可擴展的序列化結構數據的方法,它可用於(數據)通信協議、數據存儲等。
Protocol Buffers 是一種靈活,高效,自動化機制的結構數據序列化方法-可類比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更爲簡單。
ProtoBuf 是結構數據序列化[1] 方法,可簡單類比於 XML[2],其具有以下特點:
- 語言無關、平臺無關。即 ProtoBuf 支持 Java、C++、Python 等多種語言,支持多個平臺.
- 高效。即比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更爲簡單.
- 擴展性、兼容性好。你可以更新數據結構,而不影響和破壞原有的舊程序.
而微信藍牙協議中的包體就是基於proto buf 協議的,也就是上面的AuthRequset和AuthReponse、 InitRequset和InitResponse 、SendData 和 RecDataPush 都是基於proto buf 協議的。
4.2 微信藍牙外設 proto 文件
syntax = "proto2";
enum EmCmdId
{
ECI_none = 0;
// req: 藍牙設備 -> 微信/廠商服務器
ECI_req_auth = 10001; // 登錄
ECI_req_sendData = 10002; // 藍牙設備發送數據給微信或廠商
ECI_req_init = 10003; // 初始化
// resp:微信/廠商服務器 -> 藍牙設備
ECI_resp_auth = 20001;
ECI_resp_sendData = 20002;
ECI_resp_init = 20003;
// push:微信/廠商服務器 -> 藍牙設備
ECI_push_recvData = 30001; // 微信或廠商發送數據給藍牙設備
ECI_push_switchView = 30002; // 進入/退出界面
ECI_push_switchBackgroud = 30003; // 切換後臺
ECI_err_decode = 29999; // 解密失敗的錯誤碼。注意:這不是 cmdid。爲節省固定包頭大小,這種特殊的錯誤碼放在包頭的 cmdid 字段。
}
enum EmErrorCode
{
EEC_system = -1; // 通用的錯誤
EEC_needAuth = -2; // 設備未登錄
EEC_sessionTimeout = -3; // session 超時,需要重新登錄
EEC_decode = -4; // proto 解碼失敗
EEC_deviceIsBlock = -5; // 設備出現異常,導致被微信臨時性禁止登錄
EEC_serviceUnAvalibleInBackground = -6; // ios 處於後臺模式,無法正常服務
EEC_deviceProtoVersionNeedUpdate = -7; // 設備的 proto 版本過老,需要更新
EEC_phoneProtoVersionNeedUpdate = -8; // 微信客戶端的 proto 版本過老,需要更新
EEC_maxReqInQueue = -9; // 設備發送了多個請求,並且沒有收到回包。微信客戶端請求隊列擁塞。
EEC_userExitWxAccount = -10; // 用戶退出微信帳號。
}
message BaseRequest
{
}
message BaseResponse
{
required int32 ErrCode = 1;
optional string ErrMsg = 2;
}
message BasePush
{
}
// req, resp ========================================
enum EmAuthMethod
{
EAM_md5 = 1; // 設備通過 Md5DeviceTypeAndDeviceId,來通過微信 app 的認證。1. 如果是用 aes 加密,注意設置 AesSign 有值。 2. 如果是沒有加密,注意設置 AesSign 爲空或者長度爲零。
EAM_macNoEncrypt = 2; // 設備通過 mac 地址字段,且沒有加密,來通過微信 app 的認證。
}
// 登錄 ---------------------------------------------
message AuthRequest
{
required BaseRequest BaseRequest = 1;
optional bytes Md5DeviceTypeAndDeviceId = 2; // deviceType 加 deviceId 的 md5,16 字節的二進制數據
required int32 ProtoVersion = 3; // 設備支持的本 proto 文件的版本號,第一個字節表示最小版本,第二個字節表示小版本,第三字節表示大版本。版本號爲 1.0.0 的話,應該填:0x010000;1.2.3 的話,填成 0x010203。
required int32 AuthProto = 4; // 填 1
required EmAuthMethod AuthMethod = 5; // 驗證和加密的方法,見 EmAuthMethod
optional bytes AesSign = 6; // 具體生成方法見文檔
optional bytes MacAddress = 7; // mac 地址,6 位。當設備沒有燒 deviceId 的時候,可使用該 mac 地址字段來通過微信 app 的認證
optional string TimeZone = 10; // 廢棄
optional string Language = 11; // 廢棄
optional string DeviceName = 12; // 廢棄
}
message AuthResponse
{
required BaseResponse BaseResponse = 1;
required bytes AesSessionKey = 2;
}
// 初始化 --------------------------------------------
enum EmInitRespFieldFilter
{
EIRFF_userNickName = 0x1;
EIRFF_platformType = 0x2;
EIRFF_model = 0x4;
EIRFF_os = 0x8;
EIRFF_time = 0x10;
EIRFF_timeZone = 0x20;
EIRFF_timeString = 0x40;
}
// 微信連接上設備時,處於什麼情景
enum EmInitScence
{
EIS_deviceChat = 1; // 聊天
EIS_autoSync = 2; // 自動同步
}
message InitRequest
{
required BaseRequest BaseRequest = 1;
optional bytes RespFieldFilter = 2; // 當一個 bit 被設置就表示要 resp 的某個字段:見EmInitRespFieldFilter。
optional bytes Challenge = 3; // 設備用來驗證手機是否安全。爲設備隨機生成的四個字節。
}
enum EmPlatformType
{
EPT_ios = 1;
EPT_andriod = 2;
EPT_wp = 3;
EPT_s60v3 = 4;
EPT_s60v5 = 5;
EPT_s40 = 6;
EPT_bb = 7;
}
message InitResponse
{
required BaseResponse BaseResponse = 1;
required uint32 UserIdHigh = 2; // 微信用戶 Id 高 32 位
required uint32 UserIdLow = 3; // 微信用戶 Id 低 32 位
optional uint32 ChalleangeAnswer = 4; // 手機回覆設備的挑戰。爲設備生成的字節的 crc32。
optional EmInitScence InitScence = 5; // 微信連接上設備時,處於什麼情景。如果該字段爲空,表示處於 EIS_deviceChat 下。
optional uint32 AutoSyncMaxDurationSecond = 6; // 自動同步最多持續多長,微信就會關閉連接。0xffffffff 表示無限長。
optional string UserNickName = 11; // 微信用戶暱稱
optional EmPlatformType PlatformType = 12; // 手機平臺
optional string Model = 13; // 手機硬件型號
optional string Os = 14; // 手機 os 版本
optional int32 Time = 15; // 手機當前時間
optional int32 TimeZone = 16; // 手機當前時區
optional string TimeString = 17; // 手機當前時間,格式如 201402281005285,具體字段意義爲 2014(年)02(2 月)28(28 號)10(點)05(分鐘)28(秒)5(星期五)。星期一爲 1,星期天爲 7。
}
// 設備發送數據給微信或廠商 ----------------------------
// 設備數據類型
enum EmDeviceDataType
{
EDDT_manufatureSvr = 0; // 廠商自定義數據
EDDT_wxWristBand = 1; // 微信公衆平臺手環數據
EDDT_wxDeviceHtmlChatView = 10001; // 微信客戶端設備 html5 會話界面數據
}
message SendDataRequest
{
required BaseRequest BaseRequest = 1;
required bytes Data = 2;
optional EmDeviceDataType Type = 3; // 數據類型(如廠商自定義數據,或公衆平臺規定的手環數據,或微信客戶端設備 html5 會話界面數據等)。不填,或者等於 0 的時候,表示設備發送廠商自定義數據到廠商服務器。
}
message SendDataResponse
{
required BaseResponse BaseResponse = 1;
optional bytes Data = 2;
}
// push ===================================================
// 微信或廠商發送數據給藍牙設備 ---------------------------
message RecvDataPush
{
required BasePush BasePush = 1;
required bytes Data = 2;
optional EmDeviceDataType Type = 3; // 數據類型(如廠商自定義數據,或公衆平臺規定的手環數據,或微信客戶端設備 html5 會話界面數據等)。不填,或者等於 0 的時候,表示設備收到廠商自定義數據。
}
4.3 微信小程序使用proto buf --- Java Script 上使用proto buf
通過查閱相關資料,發現網上Java Script 平臺谷歌的 proto buf 使用都是在網頁上使用的,在微信小程序中Function 和 eval 相關的動態執行代碼方式都給屏蔽了,以致google官方Protobuf不能正常使用;
最終找到一個大神的大神的開源項目《微信小程序可用的Protobuf(含demo)》,找出微信小程序使用Protobuf的可行方案。
動態解析,而是根據.proto文件生成json文件再手動生成js文件,過程比較複雜。
因此,要在微信小程序上使用微信外設proto buf文件,需要使用這個開源項目。
4.4 安裝和使用微信小程序可以Protobuf 開源項目
4.1 在《微信小程序可用的Protobuf(含demo)》 鏈接中,下載項目代碼,將其中weichatPb文件夾加入到你的小程序項目中。
4.2 在Windows 操作系統中,安裝Nodejs
4.3 到《https://nodejs.org/zh-cn/download/》 Nodejs 官網上,下載安裝包。
4.4 安裝Nodejs.
4.4.1 檢測PATH環境變量是否配置了Node.js,點擊開始=》運行=》輸入"cmd" => 輸入命令"path",輸出如下結果:
PATH=C:\oraclexe\app\oracle\product\10.2.0\server\bin;C:\Windows\system32;
C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;
c:\python32\python;C:\MinGW\bin;C:\Program Files\GTK2-Runtime\lib;
C:\Program Files\MySQL\MySQL Server 5.5\bin;C:\Program Files\nodejs\;
C:\Users\rg\AppData\Roaming\npm
4.4.2 檢查Node.js版本,在控制檯輸入
node --version
如果安裝成功,可以看到,
4.4.3 打開控制檯, 安裝谷歌的proto buf js ,輸入以下命令
npm install -g protobufjs
會出現,
出現問題是,一般情況是因爲代理問題,npm代理和git代理都要設置。首先確認網絡是否需要設置代理。
解決問題方法這篇文章《npm 安裝報錯 rollbackFailedOptional verb npm-session 解決辦法》有提到,
npm換爲國內鏡像cnpm,使用淘寶鏡像作爲下載資源,具體辦法如下,
4.4.4 修改npm的資源鏡像鏈接,輸入以下命令
npm config set registry http://registry.npm.taobao.org
4.4.5 再次安裝protobufjs.
4.4.6 安裝protobufjs 成功後,接着安裝 pbjs需要的庫 命令行執行下“pbjs”
會出現以下,表示安裝成功。O(∩_∩)O哈哈~
C:\Users\69009>pbjs
installing semver@^5.5.0
installing chalk@^2.4.1
installing glob@^7.1.2
installing jsdoc@^3.5.5
installing minimist@^1.2.0
installing [email protected]
installing uglify-js@^3.3.25
installing espree@^3.5.4
installing escodegen@^1.9.1
installing estraverse@^4.2.0
protobuf.js v6.7.0 CLI for JavaScript
Translates between file formats and generates static code.
-t, --target Specifies the target format. Also accepts a path to require a custom target.
json JSON representation
json-module JSON representation as a module
proto2 Protocol Buffers, Version 2
proto3 Protocol Buffers, Version 3
static Static code without reflection (non-functional on its own)
static-module Static code without reflection as a module
-p, --path Adds a directory to the include path.
-o, --out Saves to a file instead of writing to stdout.
--sparse Exports only those types referenced from a main file (experimental).
Module targets only:
-w, --wrap Specifies the wrapper to use. Also accepts a path to require a custom wrapper.
default Default wrapper supporting both CommonJS and AMD
commonjs CommonJS wrapper
amd AMD wrapper
es6 ES6 wrapper (implies --es6)
closure A closure adding to protobuf.roots where protobuf is a global
--dependency Specifies which version of protobuf to require. Accepts any valid module id
-r, --root Specifies an alternative protobuf.roots name.
-l, --lint Linter configuration. Defaults to protobuf.js-compatible rules:
eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars
--es6 Enables ES6 syntax (const/let instead of var)
Proto sources only:
--keep-case Keeps field casing instead of converting to camel case.
Static targets only:
--no-create Does not generate create functions used for reflection compatibility.
--no-encode Does not generate encode functions.
--no-decode Does not generate decode functions.
--no-verify Does not generate verify functions.
--no-convert Does not generate convert functions like from/toObject
--no-delimited Does not generate delimited encode/decode functions.
--no-beautify Does not beautify generated code.
--no-comments Does not output any JSDoc comments.
--force-long Enfores the use of 'Long' for s-/u-/int64 and s-/fixed64 fields.
--force-number Enfores the use of 'number' for s-/u-/int64 and s-/fixed64 fields.
--force-message Enfores the use of message instances instead of plain objects.
usage: pbjs [options] file1.proto file2.json ... (or pipe) other | pbjs [options] -
C:\Users\69009>
4.5 使用pbjs 轉換一下.proto文件
4.5.1 使用文章開始的上面的微信藍牙外設.proto 文件的創建一個.proto 文件。
4.5.1 將wxProtocolBuffers.proto 轉換成對應.json 文件
在控制檯輸入
pbjs -t json wxProtocolBuffers.proto > wxProtocolBuffers.json
4.6 將文件和開源項目拷貝到微信小程序工程目錄下,
然後就可以開始使用了 O(∩_∩)O哈哈~ O(∩_∩)O哈哈~ ,可以開始調試了。
5. 與微信藍牙設備通訊記錄
5.1 使用微信AirSyncDebug.apk 調試日誌
*****************BLE: AFGF4 ******************
***** onTestBroadcastRecord *****
result = true, Has 0xfee7 or standard service in broadcast record
廣播包:02 01 06 05 02 E7 FE E0 FF 09 FF FF FF F3 3F 31 F3 FF 3F 0D 09 41 46 47 46 34 20 20 20 20 20 20 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
***** onTestManufatureData *****
resut= true, 廣播包中 manufacture specific data 字段中MAC地址校驗成功.
***** onDiscoverService *****
result = true, DiscoverService success
Discovered Services
ServiceUUID: 00001800-0000-1000-8000-00805f9b34fb
ServiceUUID: 0000fee7-0000-1000-8000-00805f9b34fb
ServiceUUID: 0000ffe0-0000-1000-8000-00805f9b34fb
***** onTestHasWeChatService *****
result = true, has WeChatService or standard service
***** onTestHasIndicateCharacteristic *****
result = true, has WeChat Indicate Characteristic
***** onTestHasWriteCharacteristic *****
result = true, has Wechat Write Characteristic
***** onTestHasReadCharacteristic *****
result = true, Has WeChat read characteristic
***** onTestWriteCharacteristicPermisson *****
result = true, has Write permission
***** onTestIndicateCharacteristicPermisson *****
result = true, has Indication permission
***** onTestReadCharacteristicPermisson *****
result = true, Read Characteristic is read able
***** onTestStartIndicating *****
result = true, can Start Indicate
***** onConnected *****
result = true, connected
------onDataReceived------
data length = 20
data dump = FE 01 00 1A 27 11 00 05 0A 00 18 84 80 04 20 01 28 02 3A 06
data receive seq = 1
------onDataReceived------
data length = 6
data dump = F3 3F 31 F3 FF 3F
data receive seq = 2
***** onTestRecvAuthReqtWhenStartedIndicating *****
result = true, received auth request pack
***** onTestIsValidAuthReqPack *****
result = true, is a valid auth request pack
AuthRequestPack: FE 01 00 1A 27 11 00 05 0A 00 18 84 80 04 20 01 28 02 3A 06 F3 3F 31 F3 FF 3F
has BaseRequest
no Md5DeviceTypeAndDeviceId field!
has MacAddress field, Mac Address = F3 3F 31 F3 FF 3F
MacAddress BitLength = 48bit
Mac Address from broadcast record = F3:3F:31:F3:FF:3F
Mac address checkout success
has ProtoVersion field, ProtoVersion = 65540
has AuthProto field, AuthProto = 1
has AuthMethod field, AuthMethod = EAM_macNoEncrypt
no AesSign field!
**** send auth response ****
data len = 14
data dump = FE 01 00 0E 4E 21 00 05 0A 02 08 00 12 00
------onDataReceived------
data length = 20
data dump = FE 01 00 1C 27 13 00 06 0A 00 1A 10 00 01 02 03 04 05 06 07
data receive seq = 3
------onDataReceived------
data length = 8
data dump = 08 09 0A 0B 0C 0D 0E 0F
data receive seq = 4
***** onTestRecvInitReqPack *****
result = true, received init request pack
***** onTestIsValidInitReqPack *****
result = true, valid init request pack: has BaseRequest
has Challenge field, Challenge = 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
**** send init request response ****
data len = 25
data dump = FE 01 00 19 4E 23 00 06 0A 02 08 00 10 B4 24 18 F8 AC 01 20 88 C5 BB F6 0C
5.2 微信小程序調試日誌
5.2.1 藍牙連接日誌 -- O(∩_∩)O哈哈~連接成功
5.2.2 登錄日誌
2019-10-24 21:48:06:833: 接收長度 = 20, 數據 = FE01001A271100010A0018848004200128023A06
util.js:73 2019-10-24 21:48:06:833: 當前接收總長度 = 20
util.js:73 2019-10-24 21:48:06:833: 微信協議數據總長度 = 26
util.js:73 2019-10-24 21:48:06:834: 接收長度 = 6, 數據 = 45014DFFFF0C
util.js:73 2019-10-24 21:48:06:834: 當前接收總長度 = 26
util.js:73 2019-10-24 21:48:06:835: 接收完整一包完成,開始處理數據
util.js:73 2019-10-24 21:48:06:835: 接收完整一包數據 = FE01001A271100010A0018848004200128023A0645014DFFFF0C
util.js:73 2019-10-24 21:48:06:836: 微信協議登錄驗證 = FE01001A271100010A0018848004200128023A0645014DFFFF0C
util.js:73 2019-10-24 21:48:06:836: packet.protobuf = 0A0018848004200128023A0645014DFFFF0C
util.js:73 2019-10-24 21:48:06:841: Test Is Valid Auth ReqPack = {"BaseRequest":{},"ProtoVersion":65540,"AuthProto":1,"AuthMethod":"EAM_macNoEncrypt","MacAddress":"RQFN//8M"}
util.js:73 2019-10-24 21:48:06:841: MAac Address = 45:01:4D:FF:FF:0C:
util.js:73 2019-10-24 21:48:06:843: send auth response = FE0100124E2100010A06080012024F4B1200
util.js:73 2019-10-24 21:48:06:844: 發送數據 = FE0100124E2100010A06080012024F4B1200
util.js:73 2019-10-24 21:48:07:70: 發送成功
通過比較可以發現,與AirSyncDebug 解析一樣。
5.2.3 初始化通訊日誌
019-10-24 21:48:07:70: 接收長度 = 20, 數據 = FE01001C271300020A001A100001020304050607
util.js:73 2019-10-24 21:48:07:71: 當前接收總長度 = 20
util.js:73 2019-10-24 21:48:07:71: 微信協議數據總長度 = 28
util.js:73 2019-10-24 21:48:07:134: 接收長度 = 8, 數據 = 08090A0B0C0D0E0F
util.js:73 2019-10-24 21:48:07:134: 當前接收總長度 = 28
util.js:73 2019-10-24 21:48:07:134: 接收完整一包完成,開始處理數據
util.js:73 2019-10-24 21:48:07:135: 接收完整一包數據 = FE01001C271300020A001A10000102030405060708090A0B0C0D0E0F
util.js:73 2019-10-24 21:48:07:135: 微信協議設備初始化通訊 = FE01001C271300020A001A10000102030405060708090A0B0C0D0E0F
util.js:73 2019-10-24 21:48:07:135: packet.protobuf = 0A001A10000102030405060708090A0B0C0D0E0F
util.js:73 2019-10-24 21:48:07:136: Test Recv InitReq Pack = {"BaseRequest":{},"Challenge":"AAECAwQFBgcICQoLDA0ODw=="}
util.js:73 2019-10-24 21:48:07:136: Challenage = 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
util.js:73 2019-10-24 21:48:07:137: send init request response = FE0100164E2300020A06080012024F4B100018002000
util.js:73 2019-10-24 21:48:07:137: 發送數據 = FE0100164E2300020A06080012024F4B10001800
util.js:73 2019-10-24 21:48:07:350: 發送成功
util.js:73 2019-10-24 21:48:07:350: 發送數據 = 2000
util.js:73 2019-10-24 21:48:07:581: 發送成功
通過比較可以發現,與AirSyncDebug 解析一樣。
通過上述步驟,登錄 -》 初始化通訊 -》 成功後,就可以開始正常與藍牙設備進行通訊了。
5.2.4 使用微信外設藍牙模塊,通過微信AirSync 協議透傳通道與單片機通訊 - 日誌
19-10-24 21:48:09:789: 讀卡器協議包 = 33008001a928
util.js:73 2019-10-24 21:48:09:790: 發送數據 = FE010014753100000A00120633008001A9281800
util.js:73 2019-10-24 21:48:10:69: 發送成功
util.js:73 2019-10-24 21:48:10:217: 接收長度 = 20, 數據 = FE010023271200030A0012143300810FB9001804
util.js:73 2019-10-24 21:48:10:217: 當前接收總長度 = 20
util.js:73 2019-10-24 21:48:10:217: 微信協議數據總長度 = 35
util.js:73 2019-10-24 21:48:10:218: 接收長度 = 15, 數據 = 004F4190FD632800000C787718914E
util.js:73 2019-10-24 21:48:10:218: 當前接收總長度 = 35
util.js:73 2019-10-24 21:48:10:218: 接收完整一包完成,開始處理數據
util.js:73 2019-10-24 21:48:10:219: 接收完整一包數據 = FE010023271200030A0012143300810FB9001804004F4190FD632800000C787718914E
util.js:73 2019-10-24 21:48:10:219: Test Is Valid Send Data Request = {"BaseRequest":{},"Data":"MwCBD7kAGAQAT0GQ/WMoAAAMeHc=","Type":"EDDT_wxDeviceHtmlChatView"}
util.js:73 2019-10-24 21:48:10:219: data = 3300810FB9001804004F4190FD632800000C7877
util.js:73 2019-10-24 21:48:10:220: 微信協議通道 = FE010023271200030A0012143300810FB9001804004F4190FD632800000C787718914E
通過上述日記,我的微信小程序終於可以與微信藍牙外設,正常收發數據了,^_^
今天是1024 節,節日快樂,終於把這篇博客寫完了。
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████ ┃+
* ┃ ┃ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃
* ┃ ┃ + + + +
* ┃ ┃ Code is far away from bug with the animal protecting
* ┃ ┃ + 神獸保佑,代碼無bug
* ┃ ┃
* ┃ ┃ +
* ┃ ┗━━━┓ + +
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*
* @author chenxi
* @date 2019-10-24 21:59:45
*/
參考大神文章:
https://github.com/Zhang19910325/protoBufferForWechat
https://www.cnblogs.com/Free-Thinker/p/5559803.html
https://blog.csdn.net/yueqian_scut/article/details/47606599