|
评测五 电表蓝牙配置(小项目) 之前申请评测就讲过电力物联网的事,现在电表配的蓝牙功能要符合国网电科院的规定,具体为MAC地址、profile、类型等等诸多要求,效果如下:
" a( U. P8 ]# b/ i8 O 7 ^% c" D, b4 S' L" l4 o5 ~2 K6 U
一、设备名
. E+ P* V5 Q H 设备名这个没要求,可选,规GAP管,在app_ble.c的广播函数Adv_Request把a_LocalName=“Meter”,同时连接后GAP名字也要改,具体Ble_Hci_Gap_Gatt_Init的aci_gap_init的name=“Meter”,同时实际长度APPBLE_GAP_DEVICE_NAME_LENGTH=5,* I# v0 o9 S @; L% N e1 _
图1 电表广播 二、MAC地址* O5 W; S& m' Y0 r( o8 u
MAC有要求,类型为静态随机地址,在app_conf.h修改CFG_IDENTITY_ADDRESS、CFG_BLE_ADDRESS_TYPE均为GAP_STATIC_RANDOM_ADDR,同时要把表地址设进MAC地址,把随机数a_srd_bd_addr设成表地址如上图。
7 N) \" q! R) \1 E* [4 L q( k. E0 x图2 MAC要求
$ n" h x u/ O三、service8 Q8 `4 T* E, q, I: F9 k& ^
很明显,新建profile是最直接的路子,通过aci_gatt_add_service、aci_gatt_add_char、aci_gatt_add_char_desc接口来添加服务、特征、描述符等,详见《AN5289 - Building a Wireless application》6.1 Initialization phase章节描述,比如p2pserver源码在p2p_stm.c里P2PS_STM_Init强函数中。电表蓝牙profile如下:
, r5 `* M) T. D. p; @, C图3 电表通信profile配置 但在短时间内不熟悉情况下很难完成,于是改造原来已存的服务为电表抄表服务,于是在p2p_stm.c的事件回调里PeerToPeer_Event_Handler往UUID=7941dc24-0ee5-a9e0-93f3-a3b50200406e写入DL/T645请求报文,回复报文在UUID=7941dc24-0ee5-a9e0-93f3-a3b50300406e以通知方式发送:1 ?: S7 E: F# ]6 x I1 M1 d
- //645报文:起始符68+地址域(6B)+起始符+控制域+数据长度+数据域+CS(1B)+结束符16
- c% F+ P: O% w - uint8_t dlt645FrameReq[50];
X$ b& H2 ?7 G& s( W" h4 ~ - uint8_t dlt645FrameRsp[50];4 P9 m: Z r4 n% T5 `& G1 c( G
- uint8_t i=0;
3 e2 G- x3 g1 S$ }) t' w - uint16_t len=Notification.DataTransfered.Length;
* y$ }9 S5 u9 c# C5 _5 d - memcpy(dlt645FrameReq,Notification.DataTransfered.pPayload,len);7 u& K" j* l( u' e/ P( z
- if(dlt645FrameReq[0]!=0x68||sum(dlt645FrameReq,len-2)!=dlt645FrameReq[len-2]||dlt645FrameReq[len-1]!=0x16)' W7 e% B0 N: a/ g; V6 b7 Q
- return 0;
# @6 Z* A& n' g - switch(dlt645FrameReq[8])
( ~* R4 x, I. u; A - {
5 s: I# e* t9 ?# i& P: Z/ K- j8 b - case CMD_READ_ADDR:7 S: b( ?! t0 p; v+ X+ h
- //P2PS_STM_App_Notification(&Notification);
* p' G7 @1 k9 S2 @! e' e* y - dlt645FrameRsp[0]=0x68;
, v+ l+ n5 n, x ] - memcpy(dlt645FrameRsp+1,meterAddr,6);
, l. W0 C8 m) b: c( Z. O - dlt645FrameRsp[7]=0x68;+ [" L, X: X: G; T# `
- dlt645FrameRsp[8]=CMD_READ_ADDR|0x80;* h0 H( r4 I5 k! T
- dlt645FrameRsp[9]=0x06;
. U4 \$ S" Q( S' { - for(i=0;i<6;i++)
: E. @; ^" c, ]2 v$ N - dlt645FrameRsp[10+i]=meterAddr[i]+0x33;. R* _- L. _0 }4 I) ?$ v A6 o% e
- dlt645FrameRsp[16]=sum(dlt645FrameRsp,15);
; P1 _9 C1 Y, s/ a! W; F& [2 C& i) { - dlt645FrameRsp[17]=0x16;
" w5 H, `& o5 M/ F - tBleStatus result = BLE_STATUS_INVALID_PARAMS;& y: r) [, h3 ]
- result = aci_gatt_update_char_value(aPeerToPeerContext.PeerToPeerSvcHdle,( J0 i0 t( V" y- C# B, [2 s# P4 M
- aPeerToPeerContext.P2PNotifyServerToClientCharHdle,0 I7 _ ]+ n/ y% J9 |, x
- 0, /* charValOffset */ P& A; @& E. R* K' E; D) S4 f: A- }
- 18, /* charValueLen */
" `% E+ F* O0 J* g. r - (uint8_t *) dlt645FrameRsp);5 q+ ~" }) f( X9 b
- //P2PS_STM_App_Update_Char(P2P_NOTIFY_CHAR_UUID, (uint8_t *)&P2P_Server_App_Context.ButtonControl);
5 y8 ]6 p7 S; C# ?' W7 |$ | - break;& V! e4 f/ M9 J, K( P& v/ {" M7 m
- default:
) K& f& n& D% v- M( M/ i - break;
5 c+ Y% |/ T4 s) d4 A+ U - }
复制代码 这里以抄读表地址为例,请求报文、回复报文依次为:
& g& Z; n A$ z8 @4 M主站请求:68 AA AA AA AA AA AA 68 13 00 DF 16
5 i7 r) f+ l/ p' m$ [' l4 P5 L6 \电表回复:68 11 11 11 11 11 11 68 93 06 44 44 44 44 44 44 67 16
# j' `$ Z7 J) f8 r+ l: @* { N成功读到表地址为11 11 11 11 11 11:图4 成功读到表地址 7 |. ^% T# ?, C3 f1 u1 B9 A
4 F0 R" l$ Y) v d1 h W2 Q
8 ~( {8 C+ x) ^+ T( S8 {/ k; c7 o. {
. w/ {: E2 }; s6 o z, b4 I3 @8 c' w2 R6 I. Q
# @! I3 a$ Z a |