"BLE" CC2541 's indicate

Source: Internet
Author: User

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, &notify_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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.