|
评测五 电表蓝牙配置(小项目) 之前申请评测就讲过电力物联网的事,现在电表配的蓝牙功能要符合国网电科院的规定,具体为MAC地址、profile、类型等等诸多要求,效果如下:
1 g6 d F- Z1 s& L" I & e: c- Y: v6 s: q2 U
一、设备名$ r! f* w* ]! Z. w' f. V1 C) M+ B1 I
设备名这个没要求,可选,规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,% w7 u& ?) M' w% w! C
图1 电表广播 二、MAC地址
% q" Q0 j* v" e, l+ H( Q MAC有要求,类型为静态随机地址,在app_conf.h修改CFG_IDENTITY_ADDRESS、CFG_BLE_ADDRESS_TYPE均为GAP_STATIC_RANDOM_ADDR,同时要把表地址设进MAC地址,把随机数a_srd_bd_addr设成表地址如上图。7 z: G- A0 ]% j* X
图2 MAC要求 5 g6 A( S+ A9 c* N% b V6 }7 r
三、service, P& O& {5 d5 V+ L R+ G
很明显,新建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如下:
% P+ o, }4 }& e8 _3 z3 e8 n图3 电表通信profile配置 但在短时间内不熟悉情况下很难完成,于是改造原来已存的服务为电表抄表服务,于是在p2p_stm.c的事件回调里PeerToPeer_Event_Handler往UUID=7941dc24-0ee5-a9e0-93f3-a3b50200406e写入DL/T645请求报文,回复报文在UUID=7941dc24-0ee5-a9e0-93f3-a3b50300406e以通知方式发送:
& e) W4 n6 P! u9 K U5 {- _8 v2 A- //645报文:起始符68+地址域(6B)+起始符+控制域+数据长度+数据域+CS(1B)+结束符16: T4 y* P7 v& Q2 c
- uint8_t dlt645FrameReq[50];
! ^! s2 Y) l# ~. g' }7 Q3 `5 i! X - uint8_t dlt645FrameRsp[50];
+ m" w; e& E5 G2 e - uint8_t i=0;' ?, r) W( P/ m1 n& u' a8 G
- uint16_t len=Notification.DataTransfered.Length;8 s3 C. m4 R0 U. o6 C
- memcpy(dlt645FrameReq,Notification.DataTransfered.pPayload,len);
& b% N7 n" [) q9 ~ - if(dlt645FrameReq[0]!=0x68||sum(dlt645FrameReq,len-2)!=dlt645FrameReq[len-2]||dlt645FrameReq[len-1]!=0x16)
- T1 \7 o$ @; Q- Z _' P, K0 } - return 0;' ?, k8 ]) M+ s: x$ ]
- switch(dlt645FrameReq[8])# N' U+ {/ H$ z7 y) n! a
- {, |4 T) Y3 d7 V5 |
- case CMD_READ_ADDR:" z. r( m; e* N( V8 e$ _+ w
- //P2PS_STM_App_Notification(&Notification);
3 k+ d$ N+ s% J3 V/ X - dlt645FrameRsp[0]=0x68;
. H( o8 y U" [6 z1 L - memcpy(dlt645FrameRsp+1,meterAddr,6);
M" {5 k% f1 R5 b0 X$ G* w p - dlt645FrameRsp[7]=0x68;% h$ e2 a+ z4 B; t" n- e% M
- dlt645FrameRsp[8]=CMD_READ_ADDR|0x80;
) a' j' i0 x* c% } - dlt645FrameRsp[9]=0x06;/ {9 H* ~9 g: W, F9 O) X3 L; V; _
- for(i=0;i<6;i++)
$ Y0 g, `, f- W7 ]8 `, x0 t - dlt645FrameRsp[10+i]=meterAddr[i]+0x33;% o8 ]0 F# W+ n0 I3 ^% M- K7 P
- dlt645FrameRsp[16]=sum(dlt645FrameRsp,15);/ i) j9 k' b: g, g" ?; ]
- dlt645FrameRsp[17]=0x16;( u1 ]1 c; y- E: V* R, W$ N/ N% ?
- tBleStatus result = BLE_STATUS_INVALID_PARAMS;
2 Q0 E5 L. L. B9 ? - result = aci_gatt_update_char_value(aPeerToPeerContext.PeerToPeerSvcHdle,$ ~/ s6 b( r- t& C; o" J; }
- aPeerToPeerContext.P2PNotifyServerToClientCharHdle,6 w' p3 d6 k( x5 Z& v0 C
- 0, /* charValOffset */& m* J4 \' j5 e, g5 v
- 18, /* charValueLen */' Q1 I# {" B+ j1 B* X+ g- a$ u" ^
- (uint8_t *) dlt645FrameRsp);
8 Y; x1 s6 P/ u9 F( d' p+ n - //P2PS_STM_App_Update_Char(P2P_NOTIFY_CHAR_UUID, (uint8_t *)&P2P_Server_App_Context.ButtonControl);
$ S$ }' Q6 q4 A% ]6 q: O* Q% D' s - break;2 T, y; d5 _. Y0 b6 y2 l* h4 Z
- default:
: C/ q8 o3 A6 ^/ k o - break;- x# F* j( W( {, ~8 [8 U* d
- }
复制代码 这里以抄读表地址为例,请求报文、回复报文依次为:
* j8 z& F5 D" N8 ~8 A, t4 f主站请求:68 AA AA AA AA AA AA 68 13 00 DF 16
' W. {4 j# w. ~) X/ C% K0 w4 |电表回复:68 11 11 11 11 11 11 68 93 06 44 44 44 44 44 44 67 16; A A' I* ~+ U( d
成功读到表地址为11 11 11 11 11 11:图4 成功读到表地址 & y' E: w. L& _& j
7 {9 }8 b" ~; ?) D# P' J9 y
, \4 z+ P( ^/ {) ^% p
3 Q# i" D+ J& a3 C7 w" D$ U2 T
/ i( a: B* J% ]% j. z/ m; F
. s: ]. {6 p- Z |