FireBLE/BASS

来自Firefly wiki
跳转至: 导航搜索

Introduction

battery server use internal adc Interface Implementation of the battery test.Because of BLE is Widely used in Battery low power consumption environment,to test battery is a very necessary operation.

battery server profile

 /// Full BAS Database Description - Used to add attributes into the database
 const struct atts_desc bas_att_db[BAS_IDX_NB] =
 {
     // Battery Service Declaration
     [BAS_IDX_SVC]                  =   {ATT_DECL_PRIMARY_SERVICE, PERM(RD, ENABLE), sizeof(bas_svc),
                                         sizeof(bas_svc), (uint8_t *)&bas_svc},
 
     // Battery Level Characteristic Declaration
     [BAS_IDX_BATT_LVL_CHAR]        =   {ATT_DECL_CHARACTERISTIC, PERM(RD, ENABLE), sizeof(bas_batt_level_char),
                                         sizeof(bas_batt_level_char), (uint8_t *)&bas_batt_level_char},
     // Battery Level Characteristic Value
     [BAS_IDX_BATT_LVL_VAL]         =   {ATT_CHAR_BATTERY_LEVEL, PERM(RD, ENABLE), sizeof(uint8_t),
                                         0, NULL},
     // Battery Level Characteristic - Client Characteristic Configuration Descriptor
     [BAS_IDX_BATT_LVL_NTF_CFG]     =   {ATT_DESC_CLIENT_CHAR_CFG, PERM(RD, ENABLE)|PERM(WR, ENABLE), sizeof(uint16_t),
                                         0, NULL},
     // Battery Level Characteristic - Characteristic Presentation Format Descriptor
     [BAS_IDX_BATT_LVL_PRES_FMT]    =   {ATT_DESC_CHAR_PRES_FORMAT, PERM(RD, ENABLE), sizeof(struct prf_char_pres_fmt),
                                         0, NULL},
 };

After declaration the Server and Characteristic,it declaration a Characteristic value to read the battery level,other,Server declaration a Characteristic Descriptor to configure Characteristic notifiable,and send battery level Every once in a while.

   #if (BLE_BATT_SERVER)
   bass_init();
   #endif // (BLE_BATT_SERVER)
 void bass_init(void)
 {
     // Reset the find me target environment
     memset(&bass_env, 0, sizeof(bass_env));
 	
 	// Register BASS task into kernel
     task_bass_desc_register();
 
     // Go to IDLE state
     ke_state_set(TASK_BASS, BASS_DISABLED);
 }

System will check if BLE_BATT_SETVER has been defined,when defined system will Init bass,include init bass_env,the TASK_BASS register and so on.

 /// Specifies the message handler structure for every input state.
 const struct ke_state_handler bass_state_handler[BASS_STATE_MAX] =
 {
     [BASS_DISABLED]       = KE_STATE_HANDLER(bass_disabled),
     [BASS_IDLE]           = KE_STATE_HANDLER(bass_idle),
     [BASS_CONNECTED]      = KE_STATE_HANDLER(bass_connected),
 };
 /// Disabled State handler definition.
 const struct ke_msg_handler bass_disabled[] =
 {
     {BASS_CREATE_DB_REQ,            (ke_msg_func_t) bass_create_db_req_handler}
 };
 
 /// Idle State handler definition.
 const struct ke_msg_handler bass_idle[] =
 {
     {BASS_ENABLE_REQ,               (ke_msg_func_t) bass_enable_req_handler}
 };
 static int bass_create_db_req_handler(ke_msg_id_t const msgid,
                                       struct bass_create_db_req const *param,
                                       ke_task_id_t const dest_id,
                                       ke_task_id_t const src_id)
 {
     // Service content flag
     uint8_t cfg_flag = BAS_CFG_FLAG_MANDATORY_MASK;
     // Status
     uint8_t status = PRF_ERR_OK;
     // Counter
     uint8_t i;
     // Battery Level characteristic value permissions
     uint16_t perm;
     // Battery Level characteristic value properties
     uint8_t prop;
 
     // Save profile id
     bass_env.con_info.prf_id = TASK_BASS;
 
     // Check number of BAS instances
     if (param->bas_nb <= BASS_NB_BAS_INSTANCES_MAX)
     {
         // Save number of BAS
         bass_env.bas_nb = param->bas_nb;
 
         for (i = 0; ((i < param->bas_nb) && (status == PRF_ERR_OK)); i++)
         {
             // Save database configuration
             bass_env.features[i] = param->features[i];
 
             // Check if notifications are supported
             if (bass_env.features[i] == BAS_BATT_LVL_NTF_SUP)
             {
                 cfg_flag |= BAS_CFG_FLAG_NTF_SUP_MASK;
             }
 
             // Check if multiple instances
             if (bass_env.bas_nb > 1)
             {
                 cfg_flag |= BAS_CFG_FLAG_MTP_BAS_MASK;
             }
 
             //Create BAS in the DB
             status = atts_svc_create_db(&bass_env.shdl[i], (uint8_t *)&cfg_flag, BAS_IDX_NB, NULL,
                                         dest_id, &bas_att_db[0]);
 
             //Disable the service and set optional features
             if (status == PRF_ERR_OK)
             {
                 //Disable service
                 status = attsdb_svc_set_permission(bass_env.shdl[i], PERM(SVC, DISABLE));
 
                 //Set optional properties and permissions
                 if (bass_env.features[i] == BAS_BATT_LVL_NTF_SUP)
                 {
                     prop = ATT_CHAR_PROP_RD | ATT_CHAR_PROP_NTF;
                     perm = PERM(RD, ENABLE) | PERM(NTF, ENABLE);
 
                     attsdb_att_partial_value_update(bass_env.shdl[i] + BAS_IDX_BATT_LVL_CHAR, 0, 1, &prop);
                     attsdb_att_set_permission(bass_env.shdl[i] + BAS_IDX_BATT_LVL_VAL, perm);
                 }
             }
 
             // Reset configuration flag
             cfg_flag = BAS_CFG_FLAG_MANDATORY_MASK;
         }
 
         if (status == PRF_ERR_OK)
         {
             //If we are here, database has been fulfilled with success, go to idle state
             ke_state_set(TASK_BASS, BASS_IDLE);
         }
     }
     else
     {
         status = PRF_ERR_INVALID_PARAM;
     }
 
     // Send confirmation to application
     struct bass_create_db_cfm * cfm = KE_MSG_ALLOC(BASS_CREATE_DB_CFM, src_id, TASK_BASS,
                                                    bass_create_db_cfm);
     cfm->status = status;
     ke_msg_send(cfm);
 
     return (KE_MSG_CONSUMED);
 }

when Client has configure notify to Battery Level characteristic,it will recive the battery level of device.