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

/*
 * 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_ */

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用C#实现低功耗蓝牙BLE数据读写功能的示例代码: ```C# using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Windows.Devices.Bluetooth; using Windows.Devices.Bluetooth.GenericAttributeProfile; using Windows.Devices.Enumeration; namespace BleCommunication { class Program { static void Main(string[] args) { var task = MainAsync(args); task.Wait(); } static async Task MainAsync(string[] args) { // 查询所有蓝牙设备 string selector = BluetoothLEDevice.GetDeviceSelector(); var devices = await DeviceInformation.FindAllAsync(selector); // 过滤出指定名称的设备 var device = devices.FirstOrDefault(d => d.Name == "My BLE Device"); if (device != null) { // 连接设备 var bleDevice = await BluetoothLEDevice.FromIdAsync(device.Id); // 查询服务 var serviceUuid = Guid.Parse("0000fff0-0000-1000-8000-00805f9b34fb"); var serviceResult = await bleDevice.GetGattServicesForUuidAsync(serviceUuid); var service = serviceResult.Services.FirstOrDefault(); if (service != null) { // 查询特征值 var characteristicUuid = Guid.Parse("0000fff1-0000-1000-8000-00805f9b34fb"); var characteristicResult = await service.GetCharacteristicsForUuidAsync(characteristicUuid); var characteristic = characteristicResult.Characteristics.FirstOrDefault(); if (characteristic != null) { // 订阅特征值通知 var status = await characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify); if (status == GattCommunicationStatus.Success) { characteristic.ValueChanged += (sender, args) => { // 处理接收到的数据 var data = args.CharacteristicValue.ToArray(); Console.WriteLine("Received data: {0}", BitConverter.ToString(data)); }; // 发送数据 var dataToSend = new byte[] { 0x01, 0x02, 0x03 }; var writeStatus = await characteristic.WriteValueAsync(dataToSend.AsBuffer()); if (writeStatus == GattCommunicationStatus.Success) { Console.WriteLine("Data sent successfully."); } else { Console.WriteLine("Failed to send data."); } } else { Console.WriteLine("Failed to subscribe to notifications."); } } else { Console.WriteLine("Characteristic not found."); } } else { Console.WriteLine("Service not found."); } } else { Console.WriteLine("Device not found."); } Console.ReadLine(); } } } ``` 请注意,此示例仅用于演示BLE通信的基本过程。在实际应用中,您需要根据设备的具体规格和特性来编写更复杂的代码

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JaLLs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值