Quellcode durchsuchen

Merge pull request #4 from WaterFishJ/main

[add]支持128bit 和 32bit uuid,添加uart sample
朱天龙 (Armink) vor 4 Jahren
Ursprung
Commit
9ea9d6cf7b

+ 8 - 2
port/NIMBLE/bsal_nimble.c

@@ -279,7 +279,10 @@ static BSAL_STATUS bsal_int_srv_profile_reg_service(
         }
         else if (tmp_srv->characteristics[x].uuid->u_type == BSAL_UUID_TYPE_128BIT)
         {
-
+            ble_uuid128_t *tmp_uuid = bsal_osif_malloc(sizeof(ble_uuid128_t));
+            tmp_uuid->u.type = BLE_UUID_TYPE_128;
+            memcpy(tmp_uuid->value, tmp_srv->uuid->u128.value,16);
+            nimble_srvs->uuid = &tmp_uuid->u;
         }
         write_index++;
         //add include=============================================================
@@ -318,7 +321,10 @@ static BSAL_STATUS bsal_int_srv_profile_reg_service(
                 }
                 else if (tmp_srv->characteristics[x].uuid->u_type == BSAL_UUID_TYPE_128BIT)
                 {
-
+                    ble_uuid128_t *tmp_uuid = bsal_osif_malloc(sizeof(ble_uuid128_t));
+                    tmp_uuid->u.type = BLE_UUID_TYPE_128;
+                    memcpy(tmp_uuid->value, tmp_srv->characteristics[x].uuid->u128.value,16);
+                    nimble_chrs[x].uuid = &tmp_uuid->u;
                 }
                 nimble_chrs[x].access_cb = bsal_ble_svc_bas_access;
                 nimble_chrs[x].arg = bsal_get_local_stack_obj();

+ 310 - 0
profiles/service/bsal_uart/bsal_srv_uart.c

@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-09-09     WaterFishJ   the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <rthw.h>
+
+#include <stdio.h>
+#include <stdint.h>
+#include "bsal.h"
+#include "bsal_osif.h"
+#include "bsal_srv_uart.h"
+
+#define MYNEWT_VAL_BLEUART_MAX_INPUT 128
+
+#define ESC_KEY                      0x1B
+#define BACKSPACE_KEY                0x08
+#define DELECT_KEY                   0x7F
+
+/* {6E400001-B5A3-F393-E0A9-E50E24DCCA9E} */
+static const struct bsal_uuid128 gatt_svr_svc_uart_uuid =
+    BSAL_UUID128_INIT(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
+                      0x93, 0xf3, 0xa3, 0xb5, 0x01, 0x00, 0x40, 0x6e);
+
+/* {6E400002-B5A3-F393-E0A9-E50E24DCCA9E} */
+static const struct bsal_uuid128 gatt_svr_chr_uart_write_uuid =
+    BSAL_UUID128_INIT(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
+                      0x93, 0xf3, 0xa3, 0xb5, 0x02, 0x00, 0x40, 0x6e);
+
+
+/* {6E400003-B5A3-F393-E0A9-E50E24DCCA9E} */
+static const struct bsal_uuid128 gatt_svr_chr_uart_read_uuid =
+    BSAL_UUID128_INIT(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
+                      0x93, 0xf3, 0xa3, 0xb5, 0x03, 0x00, 0x40, 0x6e);
+
+/* Pointer to a console buffer */
+static rt_uint8_t *console_buf;
+
+struct bleuart_console
+{
+    struct rt_semaphore *rx_end;
+    struct rt_ringbuffer *rx_fifo;
+    rt_err_t (*old_rx_ind)(rt_device_t dev, rt_size_t size);
+};
+
+static struct bleuart_console bleuart = {0};
+
+static P_SRV_GENERAL_CB pfn_bas_cb = NULL;
+static void profile_callback(void *p)
+{
+    bsal_callbak_data_t *p_param = (bsal_callbak_data_t *)p;
+    bool is_app_cb = false;
+
+    rt_kprintf("type = %d\n", p_param->msg_type);
+    rt_kprintf("profile callback u_type: %d\n", p_param->srv_uuid.u_type);
+
+    if (p_param->msg_type == BSAL_CALLBACK_TYPE_READ_CHAR_VALUE)
+    {
+        //NO DEAL had not finished
+        is_app_cb = true;
+    }
+    else if (p_param->msg_type == BSAL_CALLBACK_TYPE_WRITE_CHAR_VALUE)
+    {
+        if (GATT_SVC_NUS_WRITE_INDEX == p_param->off_handle)
+        {
+            is_app_cb = true;
+            rt_device_write(rt_console_get_device(), 0, (char *)p_param->data, p_param->length);
+            rt_device_write(rt_console_get_device(), 0, "\n", 1);
+        }
+    }
+    else if (p_param->msg_type == BSAL_CALLBACK_TYPE_INDIFICATION_NOTIFICATION)
+    {
+        if (GATT_SVC_NUS_CHAR_CCCD_INDEX == p_param->off_handle)
+        {
+            if (p_param->length == 2)
+            {
+                is_app_cb = true;
+            }
+        }
+    }
+    if (is_app_cb && (pfn_bas_cb != NULL))
+    {
+        pfn_bas_cb(p_param);
+    }
+}
+
+void bsal_le_uart_svr_init(void *stack_ptr, void *app_callback)
+{
+    struct bsal_gatt_app_srv_def ble_svc_uart_defs[] =
+    {
+        {
+            /*** Uart Service. */
+            .type = BSAL_GATT_UUID_PRIMARY_SERVICE,
+            .uuid = BSAL_UUID128_DECLARE(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
+                                         0x93, 0xf3, 0xa3, 0xb5, 0x01, 0x00, 0x40, 0x6e),//(bsal_uuid_any_t *)&battery_srv,//BSAL_UUID16_DECLARE(GATT_UUID_BATTERY),
+            .characteristics = (bsal_gatt_chr_def_t[])
+            {
+                {
+                    /*** Uart read characteristic */
+                    .uuid = BSAL_UUID128_DECLARE(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
+                                                 0x93, 0xf3, 0xa3, 0xb5, 0x03, 0x00, 0x40, 0x6e),//(bsal_uuid_any_t *)&bas_char_bas_level,//BSAL_UUID16_DECLARE(GATT_UUID_CHAR_BAS_LEVEL),
+                    .properties = BSAL_ATT_P_NOTIFY,
+                    .permission = BSAL_GATT_PERM_READ_NONE,
+                    .value_length = 1,
+                },
+                {
+                    /*** Uart write characteristic */
+                    .uuid = BSAL_UUID128_DECLARE(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
+                                                 0x93, 0xf3, 0xa3, 0xb5, 0x02, 0x00, 0x40, 0x6e),//(bsal_uuid_any_t *)&bas_char_bas_level,//BSAL_UUID16_DECLARE(GATT_UUID_CHAR_BAS_LEVEL),
+                    .properties = BSAL_ATT_P_WRITE
+                    | BSAL_ATT_P_WRITE_WITHOUT_RESPONSE
+                    ,
+                    .permission = BSAL_GATT_PERM_WRITE_NONE,
+                    .value_length = 1,
+                },
+                {
+                    0, /* No more characteristics in this service. */
+                }
+            },
+        },
+
+        {
+            0, /* No more services. */
+        },
+    };
+    bsal_stack_le_srv_reg_func(stack_ptr, &ble_svc_uart_defs, (P_SRV_GENERAL_CB *)profile_callback);
+    pfn_bas_cb = (P_SRV_GENERAL_CB)app_callback;
+}
+
+static rt_err_t bleuart_rx_ind(rt_device_t dev, rt_size_t size)
+{
+    uint8_t ch;
+    int i;
+
+    for(i = 0; i < size; i++)
+    {
+        /* read a char */
+        if (rt_device_read(dev, 0, &ch, 1))
+        {
+            rt_ringbuffer_put_force(bleuart.rx_fifo, &ch, 1);
+            rt_sem_release(bleuart.rx_end);
+        }
+    }
+
+    return RT_EOK;
+}
+
+static uint8_t bleuart_read(void)
+{
+    uint8_t ch;
+
+    rt_sem_take(bleuart.rx_end, RT_WAITING_FOREVER);
+    rt_ringbuffer_getchar(bleuart.rx_fifo, &ch);
+
+    return ch;
+}
+
+void bsal_bleuart_deinit(void)
+{
+    rt_base_t level;
+    rt_device_t uart_console;
+
+    level = rt_hw_interrupt_disable();
+    uart_console = rt_console_get_device();
+    if(uart_console)
+    {
+        rt_device_set_rx_indicate(uart_console, bleuart.old_rx_ind);
+    }
+    rt_hw_interrupt_enable(level);
+
+    if (console_buf != RT_NULL)
+    {
+        rt_free(console_buf);
+        console_buf = RT_NULL;
+    }
+
+    if (bleuart.rx_end != RT_NULL)
+    {
+        rt_sem_delete(bleuart.rx_end);
+        bleuart.rx_end = RT_NULL;
+    }
+
+    if (bleuart.rx_fifo != RT_NULL)
+    {
+        rt_ringbuffer_destroy(bleuart.rx_fifo);
+        bleuart.rx_fifo = RT_NULL;
+    }
+}
+
+void bsal_bleuart_uart_proc(void *stack_ptr, uint16_t conn_id)
+{
+    int off = 0;
+    char ch;
+    struct os_mbuf *om;
+
+    bsal_uuid_any_t uuid_srv;
+    uuid_srv.u_type = BSAL_UUID_TYPE_128BIT;
+    rt_memcpy(uuid_srv.u128.value, gatt_svr_chr_uart_read_uuid.value, 16);
+    uint16_t start_handle = bsal_srv_get_start_handle(stack_ptr, uuid_srv);
+
+    rt_kprintf("======== Welcome to enter bluetooth uart mode ========\n");
+    rt_kprintf("Press 'ESC' to exit.\n");
+
+    /* process user input */
+    while (ESC_KEY != (ch = bleuart_read()))
+    {
+        if(ch != '\r' && ch != '\n')
+        {
+            if(ch == BACKSPACE_KEY || ch == DELECT_KEY)
+            {
+                if(off)
+                {
+                    console_buf[off--] = 0;
+                    rt_kprintf("\b \b");
+                }
+                continue;
+            }
+            else
+            {
+                console_buf[off++] = ch;
+                rt_kprintf("%c", ch);
+                continue;
+            }
+        }
+
+        console_buf[off] = '\0';
+        rt_kprintf("\n");
+        bsal_srv_send_notify_data(stack_ptr, conn_id, start_handle, GATT_SVC_NUS_READ_INDEX, sizeof(console_buf), console_buf);
+
+        off = 0;
+    }
+
+    bsal_bleuart_deinit();
+}
+
+
+int bsal_bleuart_init(void *stack_ptr, uint16_t conn_id)
+{
+    int rc;
+    rt_base_t level;
+    rt_device_t uart_console;
+
+    /* create buffer for send */
+    console_buf = rt_malloc(MYNEWT_VAL_BLEUART_MAX_INPUT);
+    if (console_buf == RT_NULL)
+    {
+        rc = -RT_ENOMEM;
+        goto __exit;
+    }
+
+    /* create semaphore for the end of char recived */
+    bleuart.rx_end = rt_sem_create("bleuart", 0, RT_IPC_FLAG_FIFO);
+    if (bleuart.rx_end == RT_NULL)
+    {
+        rc = -RT_ENOMEM;
+        goto __exit;
+    }
+
+    /* create recived fifo */
+    bleuart.rx_fifo = rt_ringbuffer_create(MYNEWT_VAL_BLEUART_MAX_INPUT);
+    if (bleuart.rx_fifo == RT_NULL)
+    {
+        rc = -RT_ENOMEM;
+        goto __exit;
+    }
+
+    level = rt_hw_interrupt_disable();
+    uart_console = rt_console_get_device();
+    if(uart_console)
+    {
+        /* back uart console old indicate callback */
+        bleuart.old_rx_ind = uart_console->rx_indicate;
+        rt_device_set_rx_indicate(uart_console, bleuart_rx_ind);
+    }
+    rt_hw_interrupt_enable(level);
+
+    /* Reads console and sends data over BLE */
+    bsal_bleuart_uart_proc(stack_ptr, conn_id);
+
+    return RT_EOK;
+
+__exit:
+    if (console_buf != RT_NULL)
+    {
+        rt_free(console_buf);
+        console_buf = RT_NULL;
+    }
+
+    if (bleuart.rx_end != RT_NULL)
+    {
+        rt_sem_delete(bleuart.rx_end);
+        bleuart.rx_end = RT_NULL;
+    }
+
+    if (bleuart.rx_fifo != RT_NULL)
+    {
+        rt_ringbuffer_destroy(bleuart.rx_fifo);
+        bleuart.rx_fifo = RT_NULL;
+    }
+
+    return rc;
+}
+

+ 38 - 0
profiles/service/bsal_uart/bsal_srv_uart.h

@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-09-09     WaterFishJ   the first version
+ */
+
+#ifndef __BSAL_SRV_UART_H__
+#define __BSAL_SRV_UART_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "bsal.h"
+
+
+#define GATT_SVC_NUS_READ_INDEX             2
+#define GATT_SVC_NUS_WRITE_INDEX            5
+#define GATT_SVC_NUS_CHAR_CCCD_INDEX    3
+
+
+
+int bsal_bleuart_init(void *stack_ptr, uint16_t conn_id);
+
+void bsal_le_uart_svr_init(void *stack_ptr, void *app_callback);
+
+
+
+
+#endif
+
+
+
+
+
+

+ 1 - 1
samples/ble_bas_only_app.c

@@ -29,7 +29,7 @@ uint16_t battery_start_handle = 0;
 void bsa_app_set_adv_data(void *stack_ptr)
 {
     uint8_t tmp_data[32] = {0} ; //must be zero
-    bsal_le_adv_data_add_flag(tmp_data, BSAL_GAP_ADTYPE_FLAGS_LIMITED | BSAL_GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED);
+    bsal_le_adv_data_add_flag(tmp_data, BSAL_GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED);
 
     char *adv_name = (char *)bsal_get_device_name(stack_ptr);
     bsal_adv_data_add_name(tmp_data, strlen(adv_name), adv_name);

+ 200 - 0
samples/ble_nus_app.c

@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2021-09-09     WaterFishJ   the first version
+ */
+
+
+#include "bsal.h"
+#include <stdio.h>
+#include <string.h>
+#include "bsal_osif.h"
+#include "bsal_srv_uart.h"
+
+#define BSAL_STACK_NAME PKG_BSAL_STACK_NAME
+
+static void *bsal_stack_ptr = NULL;
+static uint16_t bsal_app_conn_handle;
+rt_uint8_t gap_conn_state = BSAL_GAP_CONN_STATE_CONNECTED;
+
+static void bsa_app_set_adv_data(void *stack_ptr)
+{
+    uint8_t tmp_data[32] = {0} ; //must be zero
+    bsal_le_adv_data_add_flag(tmp_data, BSAL_GAP_ADTYPE_FLAGS_LIMITED | BSAL_GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED);
+
+    char *adv_name = (char *)bsal_get_device_name(stack_ptr);
+    bsal_adv_data_add_name(tmp_data, strlen(adv_name), adv_name);
+    //bsal_adv_data_add_uuid16(tmp_data, BSAL_GATT_SERVICE_BATTERY_SERVICE);
+    bsal_set_le_adv_data_user(stack_ptr, tmp_data);
+}
+
+static void bsal_app_all_callback(void *stack_ptr, uint8_t cb_layer, uint16_t cb_sub_event, uint8_t value_length, void *value)
+{
+    T_BSAL_GAP_MSG_DATA  *bsal_gap_msg_data = (T_BSAL_GAP_MSG_DATA *)value;
+    uint8_t bd_addr[6];
+    switch (cb_layer)
+    {
+    case BSAL_CB_LAYER_GAP:
+        switch (cb_sub_event)
+        {
+        case BSAL_CB_STACK_READY:
+            //get mac address
+
+            bsal_osif_printf_info("============stack ready===========\r\n");
+            bsa_app_set_adv_data(stack_ptr);
+            bsal_stack_start_adv(stack_ptr);
+            break;
+        case BSAL_CB_CONNECT_STATUS:
+            bsal_osif_printf_info("============stack connect id %d===========\r\n", bsal_gap_msg_data->gap_conn_state_change.conn_id);
+            if (bsal_gap_msg_data->gap_conn_state_change.new_state == BSAL_GAP_CONN_STATE_CONNECTED)
+            {
+                bsal_app_conn_handle = bsal_gap_msg_data->gap_conn_state_change.conn_id;
+            }
+            else if (bsal_gap_msg_data->gap_conn_state_change.new_state == BSAL_GAP_CONN_STATE_DISCONNECTED)
+            {
+                bsal_stack_start_adv(stack_ptr);
+            }
+            bsal_osif_printf_info("BSAL: conn_id %d old_state %d new_state %d, disc_cause 0x%x",
+                                  bsal_gap_msg_data->gap_conn_state_change.conn_id, gap_conn_state, bsal_gap_msg_data->gap_conn_state_change.new_state, bsal_gap_msg_data->gap_conn_state_change.disc_cause);
+
+            break;
+        default:
+            break;
+        }
+
+        if (cb_sub_event == BSAL_CB_STACK_READY)
+        {
+            //stack ready
+        }
+
+        break;
+    case BSAL_CB_LAYER_GATT_PROFILE:
+        switch (cb_sub_event)
+        {
+            //save the service start_handle
+            //case uuid profile save start_handle
+            //case SRV_CALLBACK66
+            //save the identity
+        }
+        break;
+    case BSAL_CB_LAYER_SM:
+        break;
+    case BSAL_CB_LAYER_COMMON:
+        //connected save the connect id
+
+        break;
+    case BSAL_CB_LAYER_UNKNOWN:
+        break;
+    default:
+        break;
+    }
+
+}
+
+bool nus_is_uuid(bsal_uuid_any_t *s, bsal_uuid_any_t *u)
+{
+    rt_kprintf("s_uuid_type: %d\n", s->u_type);
+    rt_kprintf("u_uuid_type: %d\n", u->u_type);
+    rt_kprintf("s_uuid_value: %d\n", s->u16.value);
+    if (s->u_type == u->u_type)
+    {
+        switch (s->u_type)
+        {
+        case BSAL_UUID_TYPE_128BIT:
+            for (rt_uint8_t i = 0; i < 16; i++)
+            {
+                if (s->u128.value[i] != u->u128.value[i])   return false;
+            }
+            return true;
+        case BSAL_UUID_TYPE_16BIT:
+            break;
+        case BSAL_UUID_TYPE_32BIT:
+            break;
+        default:
+            return false;
+        }
+    }
+    else    return false;
+}
+
+static void bsal_app_profile_callback(void *p)
+{
+    bsal_callbak_data_t *bsal_param = (bsal_callbak_data_t *)p;
+
+    rt_kprintf("type = %d\n", bsal_param->msg_type);
+
+    if (bsal_param->msg_type == BSAL_CALLBACK_TYPE_READ_CHAR_VALUE)
+    {
+        bsal_osif_printf_info("========callback read from %x====%x=======\r\n", bsal_param->off_handle, bsal_param->srv_uuid.u16.value);
+    }
+    else if (bsal_param->msg_type == BSAL_CALLBACK_TYPE_INDIFICATION_NOTIFICATION)
+    {
+        uint16_t  cccbits = bsal_param->value;
+        bsal_osif_printf_info("======callback notify from %x===data cccd %x====%x=====\r\n", bsal_param->off_handle, cccbits, bsal_param->srv_uuid.u16.value);
+        if (nus_is_uuid(&(bsal_param->srv_uuid), BSAL_UUID128_DECLARE(0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0,
+                        0x93, 0xf3, 0xa3, 0xb5, 0x03, 0x00, 0x40, 0x6e)))//uart_read_uuid
+        {
+            if (cccbits & BSAL_GATT_CCC_NOTIFY)
+            {
+                bsal_osif_printf_info("=========NOTIFY ENABLE from %x===data cccd %x====%x=====\r\n", bsal_param->off_handle, cccbits, bsal_param->srv_uuid.u16.value);
+            }
+            else
+            {
+                bsal_osif_printf_info("========NOTIFY DISABLE from %x===data cccd %x====%x=====\r\n", bsal_param->off_handle, cccbits, bsal_param->srv_uuid.u16.value);
+            }
+        }
+    }
+    else if (bsal_param->msg_type == BSAL_CALLBACK_TYPE_WRITE_CHAR_VALUE)
+    {
+        bsal_osif_printf_info("\r\n BSAL: THE DATA IS :%s\r\n", bsal_param->data);
+    }
+}
+
+int bsal_nus_app(void)
+{
+    void *stack_ptr = bsal_find_stack_ptr(BSAL_STACK_NAME);
+    if (stack_ptr == NULL)
+    {
+        //print error;
+        return 1;
+    }
+    //set iocapability
+
+
+    bsal_stack_ptr  = stack_ptr;
+    //1. init stack
+    bsal_stack_init(stack_ptr, bsal_app_all_callback);  // init param not start stack
+    // set device name
+    char *device_name = "ble_rtt_uart";
+    bsal_set_device_name(stack_ptr, strlen(device_name), (uint8_t *)device_name);
+    //2. bond type
+    bsal_set_device_le_bond_type(stack_ptr, false, BSAL_NO_INPUT, BSAL_NO_OUTPUT, BSAL_GAP_AUTHEN_BIT_NO_BONDING, false);
+    //set the bond flag:
+
+    //3. service begin
+    bsal_stack_le_srv_begin(stack_ptr, 1, bsal_app_profile_callback);  //will add 1 service
+
+    //4. uart init
+    bsal_le_uart_svr_init(stack_ptr, bsal_app_profile_callback);
+
+    //5. srv_end
+    bsal_stack_le_srv_end(stack_ptr);    //end srv add
+
+    //6. start stack
+    bsal_stack_startup(stack_ptr);    //start she
+
+    bsal_bleuart_init(stack_ptr, bsal_app_conn_handle);
+
+    return 0;
+}
+MSH_CMD_EXPORT_ALIAS(bsal_nus_app, bsal_nus_app, "bluetoooth uart sample");
+
+
+
+
+
+