This post was last modified: September 12, 2016, 03:34.
First, Introduction
This article takes simplebleperipheral as an example of how to use indicate instructions in your project.
Second, the experimental platform
Protocol stack version: ble-cc254x-1.4.0
Compiler software: IAR 8.20.2
Hardware platform: Smart RF Development Board
three , Copyright Notice
Bo-master: Sweet Big melon
Statement: Water do not forget to dig well people, reproduced please indicate the source.
Original address: Http://blog.csdn.net/feilusia
Contact information: [Email protected]
Melon ble CC2541 Group: 127442605
Melon ble CC2640 Group: 557278427
Java 0 Basic Starter Exchange Group: 541462902
the Stm8/stm32 group of the Melon single-chip computer: 164311667
Iv. introduction Indicate
1. What is indicate?
Indicate is translated as "indication", which is how the server sends data to the client.
2. What is the difference between it and notify?
It uses more than notify to answer a step, such as:
Note: The mode of communication "indicate", which is answered, is more suitable for reliable communication mode.
3, indicate switch how to open, close?
That is, 0x0002 writes to the CCC bit with the attribute value of "indicate", then the instruction is opened; if 0x0000 is written, the instruction is closed.
Note: If you write 0x0001 to the CCC bit of the attribute value "indicate", it is useless.
V. Purpose of the experiment
By pressing the "center" key of the five keys to send the indicate data to Btool, the "indicate" and "reply" process is printed with the PC's serial port tool.
VI. Add CHAR7 (simplegattprofile.c ) with attribute indicate
1, modify the macro definition of simpleGATTprofile.h
2. Add CHAR7 UUID
Characteristic 7 uuid:0xfff7const uint8 simpleprofilechar7uuid[att_bt_uuid_size] ={ lo_uint16 (SIMPLEPROFILE_ CHAR7_UUID), Hi_uint16 (Simpleprofile_char7_uuid)};
3. Add char7 Setting Properties
Simple profile characteristic 7 Properties static uint8 simpleprofilechar7props = Gatt_prop_indicate; Characteristic 7 Value static uint8 Simpleprofilechar7[simpleprofile_char7_len] = {0}; Simple profiles characteristic 7 Configuration each client have its own //instantiation of the client characteristic Configuration. Reads of the //Client characteristic configuration only shows the configuration for //That Client and writes onl Y affect the configuration of that client. Static gattcharcfg_t Simpleprofilechar7config[gatt_max_num_conn]; Simple profile characteristic 7 User Description static uint8 simpleprofilechar7userdesp[17] = "characteristic 7\0 ";
4. Property sheet Modification
1) Modify the size of the property sheet
#define Servapp_num_attr_supported 25
Depends on how many properties the attribute table has
2) Modify the property sheet
Characteristic 7 Declaration { {att_bt_uuid_size, characteruuid}, Gatt_permit_read, 0, &simpleprofilechar7props }, //characteristic Value 7 { {att_bt_uuid_size, Simpleprofilechar7uuid}, 0, 0, simpleProfileChar7 }, //Characteristic 7 configuration { {att_bt_uuid_size, clientcharcfguuid}, Gatt_permit_read | Gatt_permit_write, 0, (uint8 *) Simpleprofilechar7config }, //characteristic 7 User Description { {att_bt_uuid_size, charuserdescuuid}, Gatt_permit_read, 0, Simpleprofilechar7userdesp
5. Modifying parameter Functions
1) Add in Simpleprofile_setparameter
Case SIMPLEPROFILE_CHAR7: if (len = = Simpleprofile_char7_len) { VOID osal_memcpy (SIMPLEPROFILECHAR7, Value, Simpleprofile_char7_len); } else { ret = bleinvalidrange; } Break
2) Add in Simpleprofile_getparameter
Case SIMPLEPROFILE_CHAR7: VOID osal_memcpy (value, SIMPLEPROFILECHAR7, Simpleprofile_char7_len); Break
6. Modify read-write eigenvalue function
1) Add in SIMPLEPROFILE_READATTRCB
Case SIMPLEPROFILE_CHAR7_UUID: *plen = Simpleprofile_char7_len; VOID osal_memcpy (PValue, Pattr->pvalue, Simpleprofile_char7_len); Break
The above additions are actually useless, but as unified as CHAR4.
2) Modify in SIMPLEPROFILE_WRITEATTRCB
Case Gatt_client_char_cfg_uuid:if (Pattr->handle = = Simpleprofileattrtbl[attrtbl_char4_ccc_idx].handle) CHAR4 NOTIFY {//bloodpressure notifications status = Gattservapp_processcccwritereq (Connhand Le, Pattr, pValue, Len, offset, gatt_client_cfg_notify); } else if (Pattr->handle = = Simpleprofileattrtbl[attrtbl_char6_ccc_idx].handle)//char6 NOTIFY { Bloodpressure Notifications status = Gattservapp_processcccwritereq (Connhandle, pattr, PValue, Len, Offset, gatt_client_cfg_notify); } else if (Pattr->handle = = simpleprofileattrtbl[attrtbl_char7_ccc_idx].handle)//char7 indicate { Bloodpressure Indications status = Gattservapp_processcccwritereq (Connhandle, pattr, PValue, Len, Offset, gatt_client_cfg_iNdicate); } else {status = Att_err_invalid_handle; } break;
Note that each of the notify and indicate attributes here needs to be added with a corresponding code, otherwise the CCC switch will not open up.
3) Add CHAR7 to the CCC offset values in the attribute table macro
#define ATTRTBL_CHAR7_CCC_IDX 23
Note: Other notify, indicate attributes such as CHAR4 and CHAR6 are added by themselves. Only CHAR7 is added here.
7, modify the Simpleprofile_addservice
bstatus_t Simpleprofile_addservice (UInt32 services) { uint8 status = SUCCESS; Initialize Client characteristic Configuration attributes gattservapp_initcharcfg (Invalid_connhandle, Simpleprofilechar4config); Gattservapp_initcharcfg (Invalid_connhandle, simpleprofilechar6config); Gattservapp_initcharcfg (Invalid_connhandle, simpleprofilechar7config); Register with link DB to receive link status change callback VOID Linkdb_register (SIMPLEPROFILE_HANDLECONNSTATUSCB ); if (Services & Simpleprofile_service) { //Register GATT attribute list and CBs with GATT Server APP St ATUs = Gattservapp_registerservice (Simpleprofileattrtbl, gatt_num_attrs (SIMPLEPROFILEATTRTBL), & SIMPLEPROFILECBS); } return (status);}
8, modify the SIMPLEPROFILE_HANDLECONNSTATUSCB
static void Simpleprofile_handleconnstatuscb (UInt16 connhandle, uint8 changetype) { //Make sure this is not loopback Connection if (connhandle! = Loopback_connhandle) { //Reset Client Char Config if connection has dropped
if ((changetype = = linkdb_status_update_removed) | | ((changetype = = linkdb_status_update_stateflags) && (!linkdb_up (Connhandle))) ) { gattservapp_initcharcfg (connhandle, simpleprofilechar4config); Gattservapp_initcharcfg (Connhandle, simpleprofilechar6config); Gattservapp_initcharcfg (Connhandle, Simpleprofilechar7config);}}
9. When modifying the application layer, initialize the part of the feature value
{Uint8 charValue1 = 1; Uint8 charValue2 = 2; Uint8 charValue3 = 3; Uint8 charValue4 = 4; Uint8 Charvalue5[simpleprofile_char5_len] = {1, 2, 3, 4, 5}; Uint8 Charvalue6[simpleprofile_char6_len] = {1, 2, 3, 4, 5}; Uint8 Charvalue7[simpleprofile_char7_len] = {1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5,}; Simpleprofile_setparameter (simpleprofile_char1, sizeof (uint8), &charvalue1); Simpleprofile_setparameter (simpleprofile_char2, sizeof (uint8), &charvalue2); Simpleprofile_setparameter (SIMPLEPROFILE_CHAR3, sizeof (uint8), &charvalue3); Simpleprofile_setparameter (SIMPLEPROFILE_CHAR4, sizeof (uint8), &charvalue4); Simpleprofile_setparameter (SIMPLEPROFILE_CHAR5, Simpleprofile_char5_len, charValue5); Simpleprofile_setparameter (SIMPLEPROFILE_CHAR6, Simpleprofile_char6_len, CharValue6); Simpleprofile_setparameter (SIMPLEPROFILE_CHAR7, Simpleprofile_char7_len, CharValue7);}
Seven, write indicate function
1. Add CHAR7 value in the attribute table with the offset values of the macro (SIMPLEGATTPROFILE.C)
#define Attrtbl_char7_value_idx
2. Add indicate indicator function (SIMPLEGATTPROFILE.C)
Name:simplegattprofile_char7 _indicate//introduce: Data//parameter:connhandle indicating len length: Connection handle//PValue: Data to be notified, range 0~simpleprofile_ch Ar7_len, up to 20 bytes//LEN: The length of the data to be notified//taskId: The Id//return:none of the task to be returned to when answering//************* bstatus_t Simplegattprofile_char7_indicate ( UInt16 Connhandle, Uint8 *pvalue, Uint8 len, uint8 taskId) {atthandlevalueind_t indi; UInt16 value; Value = Gattservapp_readcharcfg (Connhandle, simpleprofilechar7config);//read out the values of CCC if (value & Gatt_client_cfg_indic ATE)//Determine if the notification switch is turned on, then send data {indi.handle = Simpleprofileattrtbl[attrtbl_char7_value_idx].handle; Indi.len = Len; osal_memcpy (Indi.value, PValue, Len); Data Return (Gatt_indication (Connhandle, &indi, FALSE, taskId)); } return (FAILURE);}
3. Declaring functions (simpleGATTprofile.h)
//name: Simplegattprofile_char7_indicate //introduce: data indicating len length//parameter: connhandle: Connection handle // PValue: Data to be notified, range 0~simpleprofile_char7_len, up to 20 bytes / LEN: The length of the data to be notified// TaskId: The id//of the task to be returned to when answering return: none //****************************************************************************** bStatus _t simplegattprofile_char7_indicate (uint16 connhandle, uint8 *pvalue, Uint8 len, uint8 taskId);
Viii. sending data at the application layer using indicate (in simplebleperipheral.c)
1, key processing office Simplebleperipheral_handlekeys Add
if (keys & hal_key_sw_5) { uint16 notify_handle; Uint8 *p = buf[20]; Uint8 status; Gaprole_getparameter (Gaprole_connhandle, ¬ify_handle); Get connection Handle for (uint8 i = 0; i < i++) //write a 20-byte test buffer for data { * (p+i) = i; } Status = Simplegattprofile_char7_indicate (Notify_handle, p, simplebleperipheral_taskid); if (status = = SUCCESS) { npi_printstring ("Indicate is seccess to send!\r\n"); } else { npi_printstring ("Indicate is fail to send!\r\n"); } }
Status is success, indicating that the host has written 0x0002 to CHAR7 CCC, opened the indicator switch. The status is not success for reasons such as no connection, no open indication switch, and so on.
When the Simplegattprofile_char7_indicate function is called, the last parameter simplebleperipheral_taskid is the task ID returned by the indicate answer. So the indicate response is returned to the application layer.
The Gatt_indication function description has the following comment:
* If The return status from this function is SUCCESS, the calling * Application task would receive an osal gatt_msg _event message. * The type of the message would be att_handle_value_cfm.
Indicates that the event for indicate is Gatt_msg_event (which is used below) and that the message type is att_handle_value_cfm.
2. Add gatt_msg_event event with Application Layer event handler function
/********************************************************************* * @fn Simplebleperipheral_ PROCESSOSALMSG * * @brief process an incoming task message. * @param pmsg-message to process * * @return N One */static void simplebleperipheral_processosalmsg (osal_event_hdr_t *pmsg) { switch (pmsg->event) { //#if defined (CC2540_MINIDK) case Key_change: Simplebleperipheral_handlekeys ((((keychange_t *) PMSG)- >state, ((keychange_t *) PMSG)->keys); break; #endif//#if defined (CC2540_MINIDK) case gatt_msg_event: indication_processgattmsg ((gattmsgevent_t *) PMSG); break; Default: //do not break ; }}
Because this event is transmitted from the bottom, it is sent to the system message processing place.
So add a indicate message handler here.
3. Define a indicate message processing function
/********************************************************************* * @fn indication_processgattmsg * * @ Brief Process GATT messages * * @return none */static void Indication_processgattmsg (gattmsgevent_t *pmsg) {
npi_printstring ("indication_processgattmsg\r\n");}
4. Declaring the indicate message handler function
static void Indication_processgattmsg (gattmsgevent_t *pmsg);
Nine, the experimental results
1, Btool and Smart RF connection, press the "center" key of the five-direction button
The display error is normal because the indication switch is not open at this time.
2. Turn on the indicator switch
Method One (host-side open indicator switch):
0X003A is the char7 of the CCC eigenvalue handle, write 0x0002 open the indicator switch.
Method Two (open the indication switch from the machine side):
Gattservapp_writecharcfg (Connhandle, Simpleprofilechar7config, 0x0002);
It is not recommended to open this switch from the machine side itself, should try to ensure that the host to control from the machine.
3, and then press the five-button "center" key to send indicate data
Look at the serial tool:
"Indicate is seccess to send!" Represents smart RF send indicate data sent successfully.
"Indication_processgattmsg" means that the reply message returned by Btool arrives at the application tier.
See Btool:
Received 20 bytes of data from Smart RF.
So, the experiment is successful ~
"BLE" CC2541 's indicate