|
评测五 电表蓝牙配置(小项目) 之前申请评测就讲过电力物联网的事,现在电表配的蓝牙功能要符合国网电科院的规定,具体为MAC地址、profile、类型等等诸多要求,效果如下:: ?. _7 k/ v* P
$ z/ j0 Z ]2 ]' F; J( b) L一、设备名
3 T( \5 e8 V2 @0 P. T 设备名这个没要求,可选,规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,
# G; y, x: ]' V" h& |# W$ |图1 电表广播 二、MAC地址9 X5 C8 ]( Q3 T- _# k& ~
MAC有要求,类型为静态随机地址,在app_conf.h修改CFG_IDENTITY_ADDRESS、CFG_BLE_ADDRESS_TYPE均为GAP_STATIC_RANDOM_ADDR,同时要把表地址设进MAC地址,把随机数a_srd_bd_addr设成表地址如上图。
7 E8 X) T4 P. R& m5 G* c/ l图2 MAC要求 / m0 y$ n. _2 g9 k
三、service2 h3 ~& l1 T+ r) F' V. s$ q l
很明显,新建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如下:" k4 j1 c( o5 \3 u3 C
图3 电表通信profile配置 但在短时间内不熟悉情况下很难完成,于是改造原来已存的服务为电表抄表服务,于是在p2p_stm.c的事件回调里PeerToPeer_Event_Handler往UUID=7941dc24-0ee5-a9e0-93f3-a3b50200406e写入DL/T645请求报文,回复报文在UUID=7941dc24-0ee5-a9e0-93f3-a3b50300406e以通知方式发送:; V% |) z( |0 i
- //645报文:起始符68+地址域(6B)+起始符+控制域+数据长度+数据域+CS(1B)+结束符16
5 F7 X9 Z6 b. H) M6 W - uint8_t dlt645FrameReq[50];
4 n, M) b8 `( h' O9 [ - uint8_t dlt645FrameRsp[50];
1 |( J7 a o; q+ K& V5 k - uint8_t i=0;! W P6 x3 h% ?
- uint16_t len=Notification.DataTransfered.Length;
$ Y4 T7 s8 H ~! X - memcpy(dlt645FrameReq,Notification.DataTransfered.pPayload,len);
# A3 V; K+ G* m - if(dlt645FrameReq[0]!=0x68||sum(dlt645FrameReq,len-2)!=dlt645FrameReq[len-2]||dlt645FrameReq[len-1]!=0x16)
7 X9 v; s' f6 V# O. v- P - return 0;
1 y" i* y/ o/ t; q$ d - switch(dlt645FrameReq[8])# M/ Z2 D% x) \( P% i
- {- A3 O6 j# O) V0 G c
- case CMD_READ_ADDR:- p& Z- D! o# _* z; I. k2 [% O0 S
- //P2PS_STM_App_Notification(&Notification);
^5 F* C6 t# o- X! b" v7 N - dlt645FrameRsp[0]=0x68;. T3 H6 s2 h) t
- memcpy(dlt645FrameRsp+1,meterAddr,6);
* @5 r+ D. x/ ?. b5 x - dlt645FrameRsp[7]=0x68;0 K4 f: y6 ~' n9 l T) ?# G# d
- dlt645FrameRsp[8]=CMD_READ_ADDR|0x80;
: w3 s* o" Z2 m/ X' R - dlt645FrameRsp[9]=0x06;
( v+ p5 j' A: m% Q( g - for(i=0;i<6;i++)
4 e3 S% O$ y u2 T/ z$ W/ ~9 I - dlt645FrameRsp[10+i]=meterAddr[i]+0x33;- n* W& L. T% w& y
- dlt645FrameRsp[16]=sum(dlt645FrameRsp,15);
' L1 \. O w( T% S+ {5 m$ o - dlt645FrameRsp[17]=0x16;% d$ P9 _/ d$ I. S5 d- A+ v v
- tBleStatus result = BLE_STATUS_INVALID_PARAMS;
O ?3 n! d6 H2 I' ?( Q3 G' R! G - result = aci_gatt_update_char_value(aPeerToPeerContext.PeerToPeerSvcHdle,' Y( b( D6 v, _1 C" w, j* `
- aPeerToPeerContext.P2PNotifyServerToClientCharHdle,0 h$ P2 x9 n5 c) h3 O* T& x9 ]% v
- 0, /* charValOffset */* p& `: r$ w% D% u
- 18, /* charValueLen */! Z; D9 Z! y- C( T. T, o5 }6 g
- (uint8_t *) dlt645FrameRsp);+ O. m% B2 M+ Y2 q" V; z
- //P2PS_STM_App_Update_Char(P2P_NOTIFY_CHAR_UUID, (uint8_t *)&P2P_Server_App_Context.ButtonControl);
1 {) ^& A- a+ s5 I9 l! @: ^ - break;! T+ U$ v. p3 s; y* w; ]
- default:
3 C8 ?+ F* w! ^1 j4 f+ H/ j - break;
1 `& B0 F t9 y - }
复制代码 这里以抄读表地址为例,请求报文、回复报文依次为:
) t9 g9 [& B+ R( D主站请求:68 AA AA AA AA AA AA 68 13 00 DF 16% } N: s1 s' ]" `3 Q0 n: Y
电表回复:68 11 11 11 11 11 11 68 93 06 44 44 44 44 44 44 67 16
8 W5 Y. h( q' E8 j3 B r$ B* V+ a成功读到表地址为11 11 11 11 11 11:图4 成功读到表地址 / J; u+ d3 O. B @9 t: T3 d& O4 L; W
' y5 d- X, \% \1 @
9 E- Z# Q$ | W6 ?8 Z
" f2 Z9 d0 Z3 a9 }# D7 o: p
: g# w( a" }+ X" N$ r0 q. `# i! m" v5 w0 H5 i6 \
|