蓝牙BLE-DA14683自定义蓝牙数据收发服务代码

版权声明:转载请注明出处。技术交流加微信:life5270 https://blog.csdn.net/JaLLs/article/details/84558112
/*
 * user_service.c
 *
 *  Created on: 2018年11月26日
 *      Author: Jim
 */


/**
 ****************************************************************************************
 * contact me by wechat: life5270
 * @file user_service.c
 *
 * @brief user_tx_rx Service sample implementation
 *
 * Copyright (C) 2015 Dialog Semiconductor.
 * This computer program includes Confidential, Proprietary Information
 * of Dialog Semiconductor. All Rights Reserved.
 *
 ****************************************************************************************
 */

#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include "stdio.h"
#include "osal.h"
#include "ble_att.h"
#include "ble_bufops.h"
#include "ble_common.h"
#include "ble_gatt.h"
#include "ble_gatts.h"
#include "ble_storage.h"
#include "ble_uuid.h"
#include "svc_defines.h"
#include "svc_types.h"
#include "user_service.h"


#define UUID_TX_RX_SERVICE                  (0x1840)
#define UUID_TX_RX_CHARACTER                (0x2907)


static const uint8_t read_test[] = {
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05
};

static void user_sev_read_cb(ble_service_t *svc, uint16_t conn_idx)
{
        read_date_cfm(svc, conn_idx, ATT_ERROR_OK, read_test);
}

static void user_sev_recieve_cb(ble_service_t *svc, uint16_t conn_idx, \
        const uint8_t *value,uint8_t length)
{

       // printf("value[0]:%x\r\n",value[0]);
      //  printf("value[1]:%x\r\n",value[1]);
       // printf("value[2]:%x\r\n",value[2]);
       // printf("value[3]:%x\r\n",value[3]);

        /*if you use WRITE NO RESPONSE,DO NOT USE THIS*/
       // write_date_response(svc, conn_idx, ATT_ERROR_OK);

        service_send_date(svc, conn_idx, value,length);
        // notify other clients that data has recieved
        //OS_TASK_NOTIFY(ble_peripheral_task_handle, CTS_SET_TIME_NOTIF, eSetBits);
}


static const user_service_callbacks_t user_callbacks = {
        .read_date_cb = user_sev_read_cb,
        .recieve_date_cb = user_sev_recieve_cb,
};





typedef struct {
        ble_service_t svc;
        // callbacks
        const user_service_callbacks_t *cb;
        // handles
        uint16_t user_val_h;
        uint16_t user_ccc_h;
} user_service_t;



static void do_user_read(user_service_t *user_svc, const ble_evt_gatts_read_req_t *evt)
{
        if (!user_svc->cb || !user_svc->cb->read_date_cb) {
                ble_gatts_read_cfm(evt->conn_idx, evt->handle, ATT_ERROR_READ_NOT_PERMITTED, 0, NULL);
                return;
        }

        // Ask client for data information
        user_svc->cb->read_date_cb(&user_svc->svc, evt->conn_idx);

        // callback executed properly, will be replied
}



static att_error_t do_user_write(user_service_t *user_svc, uint16_t conn_idx, uint16_t offset,
                                                        uint16_t length, const uint8_t *value)
{
        if (offset) {
                return ATT_ERROR_ATTRIBUTE_NOT_LONG;
        }

        if (!user_svc->cb || !user_svc->cb->recieve_date_cb) {
                return ATT_ERROR_WRITE_NOT_PERMITTED;
        }

        user_svc->cb->recieve_date_cb(&user_svc->svc, conn_idx, value,length);
        printf("1111\r\n");
        return ATT_ERROR_OK;
}

static att_error_t do_user_ccc_write(user_service_t *user_svc, uint16_t conn_idx, uint16_t offset,
                                                                uint16_t length, const uint8_t *value)
{
        uint16_t ccc;

        if (offset) {
                return ATT_ERROR_ATTRIBUTE_NOT_LONG;
        }

        if (length != sizeof(ccc)) {
                return ATT_ERROR_INVALID_VALUE_LENGTH;
        }

        ccc = get_u16(value);

        ble_storage_put_u32(conn_idx, user_svc->user_ccc_h, ccc, true);
        printf("2222\r\n");
        return ATT_ERROR_OK;
}


static void handle_read_req(ble_service_t *svc, const ble_evt_gatts_read_req_t *evt)
{
        user_service_t *user_svc = (user_service_t *) svc;

        if (evt->handle == user_svc->user_val_h) {
                do_user_read(user_svc, evt);
        }else if (evt->handle == user_svc->user_ccc_h) {
                uint16_t ccc = 0x0000;

                ble_storage_get_u16(evt->conn_idx, user_svc->user_ccc_h, &ccc);

                // we're little-endian, ok to write directly from uint16_t
                ble_gatts_read_cfm(evt->conn_idx, evt->handle, ATT_ERROR_OK, sizeof(ccc), &ccc);
        } else {
                ble_gatts_read_cfm(evt->conn_idx, evt->handle, ATT_ERROR_READ_NOT_PERMITTED, 0, NULL);
        }
}

static void handle_write_req(ble_service_t *svc, const ble_evt_gatts_write_req_t *evt)
{
        user_service_t *user_svc = (user_service_t *) svc;
        att_error_t status = ATT_ERROR_WRITE_NOT_PERMITTED;

        if (evt->handle == user_svc->user_val_h) {
                status = do_user_write(user_svc, evt->conn_idx, evt->offset, evt->length, evt->value);
                goto done;
        } else if (evt->handle == user_svc->user_ccc_h) {
                status = do_user_ccc_write(user_svc, evt->conn_idx, evt->offset, evt->length, evt->value);
                goto done;
        }

done:
        if (status == ((att_error_t) -1)) {
                // write handler executed properly, will be replied by cfm call
                return;
        }

        ble_gatts_write_cfm(evt->conn_idx, evt->handle, status);
}

static void cleanup(ble_service_t *svc)
{
        user_service_t *user_svc = (user_service_t *) svc;

        ble_storage_remove_all(user_svc->user_ccc_h);

        OS_FREE(user_svc);
}

ble_service_t *user_service_init(const user_service_callbacks_t *cb)
{
        user_service_t *user_svc;
        uint16_t num_attr;
        att_uuid_t uuid;

        /* Make sure recieve_date_cb is defined */
        OS_ASSERT(cb->recieve_date_cb);

        user_svc = OS_MALLOC(sizeof(*user_svc));
        memset(user_svc, 0, sizeof(*user_svc));

        user_svc->svc.read_req = handle_read_req;
        user_svc->svc.write_req = handle_write_req;
        user_svc->svc.cleanup = cleanup;
        user_svc->cb = cb;

        num_attr = ble_gatts_get_num_attr(0, 1, 1);
        ble_uuid_create16(UUID_TX_RX_SERVICE, &uuid);
        ble_gatts_add_service(&uuid, GATT_SERVICE_PRIMARY, num_attr);

        // Write is optional
        ble_uuid_create16(UUID_TX_RX_CHARACTER, &uuid);
        ble_gatts_add_characteristic(&uuid,      GATT_PROP_READ|GATT_PROP_NOTIFY |GATT_PROP_WRITE_NO_RESP,
                                                 ATT_PERM_RW, 10,
                                                 GATTS_FLAG_CHAR_READ_REQ, NULL, &user_svc->user_val_h);

        ble_uuid_create16(UUID_GATT_CLIENT_CHAR_CONFIGURATION, &uuid);
        ble_gatts_add_descriptor(&uuid, ATT_PERM_RW, 2, 0, &user_svc->user_ccc_h);

        ble_gatts_register_service(&user_svc->svc.start_h, &user_svc->user_val_h, &user_svc->user_ccc_h,0);
        user_svc->svc.end_h = user_svc->svc.start_h + num_attr;
        ble_service_add(&user_svc->svc);

        return &user_svc->svc;
}

ble_service_t *user_sev_init()
{
        ble_service_t *user_svc;
        user_svc=user_service_init(&user_callbacks);
        return user_svc;
}


void service_send_date(ble_service_t *svc, uint16_t conn_idx, const uint8_t *value,uint8_t length)
{
        user_service_t *user_svc = (user_service_t *) svc;
        uint16_t ccc = 0x0000;
        ble_storage_get_u16(conn_idx, user_svc->user_ccc_h, &ccc);

        if (!(ccc & GATT_CCC_NOTIFICATIONS)) {
                return;
        }

       // printf("111\r\n");
        ble_gatts_send_event(conn_idx, user_svc->user_val_h, GATT_EVENT_NOTIFICATION, length, value);
}


void read_date_cfm(ble_service_t *svc, uint16_t conn_idx, att_error_t status,
                                                                const uint8_t *value)
{
        user_service_t *user_svc = (user_service_t *) svc;

        ble_gatts_read_cfm(conn_idx, user_svc->user_val_h, ATT_ERROR_OK, 6, &value);
}

/*WRITE RESPONSE*/
void write_date_response(ble_service_t *svc, uint16_t conn_idx, att_error_t status)
{
        user_service_t *user_svc = (user_service_t *) svc;

        ble_gatts_write_cfm(conn_idx, user_svc->user_val_h, status);
}



/*
 * user_service.h
 *
 *  Created on: 2018年11月26日
 *      Author: Jim
 */


/**
 ****************************************************************************************
 * contact me by wechat: life5270
 * @file user_service.h
 *
 * @brief user_service Service implementation API
 *
 * Copyright (C) 2015 Dialog Semiconductor.
 * This computer program includes Confidential, Proprietary Information
 * of Dialog Semiconductor. All Rights Reserved.
 *
 ****************************************************************************************
 */

#ifndef SDK_BLE_SERVICES_INCLUDE_USER_SERVICE_H_
#define SDK_BLE_SERVICES_INCLUDE_USER_SERVICE_H_

#include <stdint.h>
#include <ble_service.h>
#include <svc_types.h>


typedef void (* user_read_cb_t) (ble_service_t *svc, uint16_t conn_idx);

typedef void (* user_recieve_cb_t) (ble_service_t *svc, uint16_t conn_idx,\
                                        const uint8_t *value,uint8_t length);


/** CTS application callbacks */
typedef struct {
        /** User callback to call on every read data request */
        user_read_cb_t read_date_cb;

        /** User callback to call on write request, can be NULL, that will make characteristic RO */
        user_recieve_cb_t recieve_date_cb;
} user_service_callbacks_t;

/**
 * Register user_service instance
 *
 * Function initializes and register User Service.
 * \param [in] cb       application callbacks
 *
 * \return service instance
 *
 */
ble_service_t *user_service_init(const user_service_callbacks_t *cb);
ble_service_t *user_sev_init();
/**
 * Notify connected client about send data
 *
 * \param [in] svc      service instance
 * \param [in] conn_idx connection index
 * \param [in] value     data to send
 * \param [in] length    data length
 */
void service_send_date(ble_service_t *svc, uint16_t conn_idx, const uint8_t *value,uint8_t length);



/**
 * Response for \p write callback
 *
 * \param [in] svc      service instance
 * \param [in] conn_idx connection index
 * \param [in] status   ATT error
 *
 */
void write_date_response(ble_service_t *svc, uint16_t conn_idx, att_error_t status);


/**
 * Response for \p write callback
 * */
void read_date_cfm(ble_service_t *svc, uint16_t conn_idx, att_error_t status,
                                                                const uint8_t *value);



#endif /* SDK_BLE_SERVICES_INCLUDE_USER_SERVICE_H_ */

猜你喜欢

转载自blog.csdn.net/JaLLs/article/details/84558112