自定义服务和特征号示例

yangzh · 454次点击 · 2023-08-28

实际使用中,我们经常会修改服务号和特征值号,这里以SDK中simple_server为例子,介绍修改方法

现在想修改成如下的服务特征:

image.png


1)找到simple_server.h文件

这个是原示例对应的服务的UUID

#define ATT_SVC_SIMPLE_SERVER_SERVICE {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}
#define ATT_SVC_SIMPLE_SERVER_CHAC1   0x5F01
#define ATT_SVC_SIMPLE_SERVER_CHAC2   {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}

现在修改成如下新的UUID

#define ATT_SVC_SIMPLE_SERVER_SERVICE                                                                  \
    {                                                                                                  \
        0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00 \
    }
#define ATT_SVC_SIMPLE_SERVER_CHAC1                                                                    \
    {                                                                                                  \
        0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0xdc, 0x00, 0x00 \
    }
#define ATT_SVC_SIMPLE_SERVER_CHAC2                                                                    \
    {                                                                                                  \
        0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x02, 0xdc, 0x00, 0x00 \
    }


2)找到simple_server.c文件

同时修改

/// Full SIMPLE_SERVER Database Description - Used to add attributes into the database
const struct attm_desc_128 simple_server_att_db[SIMPLE_SERVER_IDX_NB] =
{
    // Service Declaration
    [SIMPLE_SERVER_IDX_SVC]               =   {ATT_16_TO_128_ARRAY(ATT_DECL_PRIMARY_SERVICE),  PERM(RD, ENABLE), 0, 0},

    // Characteristic Declaration
    [SIMPLE_SERVER_IDX_DEMO_CHAR1]        =   {ATT_16_TO_128_ARRAY(ATT_DECL_CHARACTERISTIC),   PERM(RD, ENABLE), 0, 0},
    // Characteristic Value
    [SIMPLE_SERVER_IDX_DEMO_VAL1]         =   {ATT_SVC_SIMPLE_SERVER_CHAC1,    PERM(WRITE_REQ, ENABLE) | PERM(NTF, ENABLE) | PERM(IND, ENABLE),  PERM(RI, ENABLE) | PERM(UUID_LEN, UUID_128), SIMPLE_SERVER_MAX_CHAC_LEN},
    // Characteristic - Client Characteristic Configuration Descriptor
    [SIMPLE_SERVER_IDX_DEMO_NTF_CFG]     =   {ATT_16_TO_128_ARRAY(ATT_DESC_CLIENT_CHAR_CFG),  PERM(RD, ENABLE)|PERM(WRITE_REQ, ENABLE), 0, 0},

    // Characteristic Declaration
    [SIMPLE_SERVER_IDX_DEMO_CHAR2]        =   {ATT_16_TO_128_ARRAY(ATT_DECL_CHARACTERISTIC),   PERM(RD, ENABLE), 0, 0},
    // Characteristic Value
    [SIMPLE_SERVER_IDX_DEMO_VAL2]         =   {ATT_SVC_SIMPLE_SERVER_CHAC2,    PERM(RD, ENABLE) | PERM(WRITE_REQ, ENABLE), PERM(RI, ENABLE) | PERM(UUID_LEN, UUID_128), SIMPLE_SERVER_MAX_CHAC_LEN},
};


3)app_simple_sever.c文件找到如下函数,屏蔽其内容

static int simple_server_timeout_timer_handler(ke_msg_id_t const msgid,
                                               void const *param,
                                               ke_task_id_t const dest_id,
                                               ke_task_id_t const src_id)
{
    // log_debug("%s@%d\n", __func__, __LINE__);
    // uint8_t ntf_data[] = "SIMPLE_SERVER_SEND_NTF_CMD";
    // ke_timer_set(SIMPLE_SERVER_TIMEOUT_TIMER, TASK_APP, 500);
    // // Allocate the message
    // struct simple_server_send_ntf_cmd * cmd = KE_MSG_ALLOC_DYN(SIMPLE_SERVER_SEND_NTF_CMD,
    //                                             prf_get_task_from_id(TASK_ID_SIMPLE_SERVER),
    //                                             TASK_APP,
    //                                             simple_server_send_ntf_cmd,
    //                                             sizeof(ntf_data));
    // cmd->conidx = app_simple_server_env.conidx;
    // cmd->length = sizeof(ntf_data);
    // memcpy(cmd->value, ntf_data, sizeof(ntf_data));
    // // Send the message
    // ke_msg_send(cmd);
    return (KE_MSG_CONSUMED);
}


4)定义发送接口函数,在main.c中

#include "app_simple_server.h"       // Application Module Definitions
#include "simple_server_task.h"               // health thermometer functions
#include "prf.h"               // health thermometer functions
#include "ke_event.h"


uint8_t ntf_data[500] = {0};

void send_to_app(uint8_t *data,uint8_t length)
{
   
    log_debug("%s@%d\n", __func__, __LINE__);
    //uint8_t ntf_data[] = "SIMPLE_SERVER_SEND_NTF_CMD";
        memcpy(ntf_data,data,length);
       
    // Allocate the message
    struct simple_server_send_ntf_cmd * cmd = KE_MSG_ALLOC_DYN(SIMPLE_SERVER_SEND_NTF_CMD,
                                                prf_get_task_from_id(TASK_ID_SIMPLE_SERVER),
                                                TASK_APP,
                                                simple_server_send_ntf_cmd,
                                                sizeof(ntf_data));
    cmd->conidx = app_simple_server_env.conidx;
    cmd->length = length;
    memcpy(cmd->value, ntf_data, length);
    // Send the message
    ke_msg_send(cmd);

        log_debug_array_ex("ntf_data\n",ntf_data, length);
}


5)我们示例是APP发送什么数据,设备回复什么数据

__STATIC int gattc_write_req_ind_handler(ke_msg_id_t const msgid, struct gattc_write_req_ind const *param,
                                         ke_task_id_t const dest_id, ke_task_id_t const src_id)
{
    struct gattc_write_cfm *cfm;
    uint8_t att_idx = 0;
    uint8_t conidx = KE_IDX_GET(src_id);
    // retrieve handle information
    uint8_t status = simple_server_get_att_idx(param->handle, &att_idx);
    log_debug("%s handle:%d(idx:%d).\n", __func__, param->handle, att_idx);

    // If the attribute has been found, status is GAP_ERR_NO_ERROR
    if (status == GAP_ERR_NO_ERROR)
    {
        struct simple_server_env_tag *simple_server_env = PRF_ENV_GET(SIMPLE_SERVER, simple_server);

        // Only update configuration if value for stop or notification enable
        if (att_idx == SIMPLE_SERVER_IDX_DEMO_NTF_CFG)
        {
            // Extract value before check
            uint16_t ntf_cfg = co_read16p(&param->value[0]);
            if ((ntf_cfg == PRF_CLI_STOP_NTFIND) || (ntf_cfg == PRF_CLI_START_NTF) || (ntf_cfg == PRF_CLI_START_IND))
            {
                // Conserve information in environment
                simple_server_env->ntf_cfg[conidx] = ntf_cfg;
            }
            // Inform APP of configuration change
            struct simple_server_demo_ntf_cfg_ind *ind = KE_MSG_ALLOC(SIMPLE_SERVER_NTF_CFG_IND,
                                                                      prf_dst_task_get(&(simple_server_env->prf_env), conidx), dest_id,
                                                                      simple_server_demo_ntf_cfg_ind);
            ind->conidx = conidx;
            ind->ntf_cfg = simple_server_env->ntf_cfg[conidx];

            ke_msg_send(ind);
        }
        else if (att_idx == SIMPLE_SERVER_IDX_DEMO_VAL1 || att_idx == SIMPLE_SERVER_IDX_DEMO_VAL2)
        {
            log_debug("Offset:%2d. ", param->offset);

            // send fron app
            extern void send_to_app(uint8_t * data, uint8_t length);    //增加接口
            send_to_app((uint8_t *)(param->value), param->length);      //调用  

            log_debug_array_ex("write data", param->value, param->length);
        }
        else
        {
            status = PRF_APP_ERROR;
        }
    }

    // Send write response
    cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm);
    cfm->handle = param->handle;
    cfm->status = status;
    ke_msg_send(cfm);

    return (KE_MSG_CONSUMED);
}


6)测试结果

image.png


被收藏 1  ∙  1 赞  
加入收藏
点赞
0 回复  
善言善语 (您需要 登录 后才能回复 没有账号 ?)

请先登录网站