From 6348e507596eb10420e277c6e2a0bf28d770c6bc Mon Sep 17 00:00:00 2001 From: schneider <schneider@blinkenlichts.net> Date: Sun, 4 Aug 2019 01:31:37 +0200 Subject: [PATCH] chore(ble): Move UART service into a separate file --- epicardium/ble/ble.c | 146 +------------------------------- epicardium/ble/meson.build | 3 +- epicardium/ble/uart.c | 169 +++++++++++++++++++++++++++++++++++++ 3 files changed, 173 insertions(+), 145 deletions(-) create mode 100644 epicardium/ble/uart.c diff --git a/epicardium/ble/ble.c b/epicardium/ble/ble.c index 973b6326..f35dfce7 100644 --- a/epicardium/ble/ble.c +++ b/epicardium/ble/ble.c @@ -175,144 +175,6 @@ static void scheduleTimer(void) } } -#define UART_START_HDL 0x800 /*!< \brief Service start handle. */ -#define UART_END_HDL (BATT_MAX_HDL - 1) /*!< \brief Service end handle. */ - -/************************************************************************************************** - Handles -**************************************************************************************************/ - -/*! \brief UART Service Handles */ -enum -{ - UART_SVC_HDL = UART_START_HDL, /*!< \brief UART service declaration */ - UART_RX_CH_HDL, /*!< \brief UART rx characteristic */ - UART_RX_HDL, /*!< \brief UART rx value */ - UART_TX_CH_HDL, /*!< \brief UART tx characteristic */ - UART_TX_HDL, /*!< \brief UART tx value */ - UART_TX_CH_CCC_HDL, /*!< \brief UART tx CCCD */ - BATT_MAX_HDL /*!< \brief Maximum handle. */ -}; -/**@}*/ - -static const uint8_t UARTSvc[] = {0x9E,0xCA,0xDC,0x24,0x0E,0xE5,0xA9,0xE0,0x93,0xF3,0xA3,0xB5,0x01,0x00,0x40,0x6E}; - -static const uint8_t uartRxCh[] = {ATT_PROP_WRITE, UINT16_TO_BYTES(UART_RX_HDL), 0x9E,0xCA,0xDC,0x24,0x0E,0xE5,0xA9,0xE0,0x93,0xF3,0xA3,0xB5,0x02,0x00,0x40,0x6E}; -const uint8_t attUartRxChUuid[] = {0x9E,0xCA,0xDC,0x24,0x0E,0xE5, 0xA9,0xE0,0x93,0xF3,0xA3,0xB5,0x02,0x00,0x40,0x6E}; - -static const uint8_t uartTxCh[] = {ATT_PROP_READ | ATT_PROP_NOTIFY, UINT16_TO_BYTES(UART_TX_HDL), 0x9E,0xCA,0xDC,0x24,0x0E,0xE5,0xA9,0xE0,0x93,0xF3,0xA3,0xB5,0x03,0x00,0x40,0x6E}; -const uint8_t attUartTxChUuid[] = {0x9E,0xCA,0xDC,0x24,0x0E,0xE5, 0xA9,0xE0,0x93,0xF3,0xA3,0xB5,0x03,0x00,0x40,0x6E}; -/* Battery level client characteristic configuration */ - - - -void *SvcUARTAddGroupDyn(void) -{ - void *pSHdl; - uint8_t initCcc[] = {UINT16_TO_BYTES(0x0000)}; - uint8_t initUARTVal[] = {0x20}; - - /* Create the service */ - pSHdl = AttsDynCreateGroup(UART_START_HDL, UART_END_HDL); - - if (pSHdl != NULL) - { - /* Primary service */ - AttsDynAddAttrConst(pSHdl, attPrimSvcUuid, UARTSvc, sizeof(UARTSvc), 0, ATTS_PERMIT_READ); - - - /* UART rx characteristic */ - AttsDynAddAttrConst(pSHdl, attChUuid, uartRxCh, sizeof(uartRxCh), 0, ATTS_PERMIT_READ); - // XXX: attUartRxChUuid is 16 bytes but nothing says so.... - /* UART rx value */ - // XXX: not sure if max value of 128 is fine... - AttsDynAddAttr(pSHdl, attUartRxChUuid, NULL, 0, 128, - ATTS_SET_WRITE_CBACK | ATTS_SET_VARIABLE_LEN, ATTS_PERMIT_WRITE); - - - /* UART tx characteristic */ - AttsDynAddAttrConst(pSHdl, attChUuid, uartTxCh, sizeof(uartTxCh), 0, ATTS_PERMIT_READ); - /* UART tx value */ - /* TODO: do we need ATTS_SET_READ_CBACK ? */ - AttsDynAddAttr(pSHdl, attUartTxChUuid, initUARTVal, sizeof(uint8_t), sizeof(uint8_t), - ATTS_SET_READ_CBACK, ATTS_PERMIT_READ); - /* UART tx CCC descriptor */ - AttsDynAddAttr(pSHdl, attCliChCfgUuid, initCcc, sizeof(uint16_t), sizeof(uint16_t), - ATTS_SET_CCC, ATTS_PERMIT_READ | ATTS_PERMIT_WRITE); - } - - return pSHdl; -} - -dmConnId_t active_connection = 0; - -uint8_t UARTReadCback(dmConnId_t connId, uint16_t handle, uint8_t operation, - uint16_t offset, attsAttr_t *pAttr) -{ - //AppHwBattRead(pAttr->pValue); - printf("read callback\n"); - return ATT_SUCCESS; -} - -uint8_t UARTWriteCback(dmConnId_t connId, uint16_t handle, uint8_t operation, - uint16_t offset, uint16_t len, uint8_t *pValue, - attsAttr_t *pAttr) -{ - active_connection = connId; - - //printf("UARTWriteCback %d: ", len); - int i; - for(i=0; i<len; i++) { - //printf("%c", pValue[i]); - serial_enqueue_char(pValue[i]); - } - serial_enqueue_char('\r'); - //printf("\n"); - -#if 0 - AttsSetAttr(UART_TX_HDL, len, pValue); - AttsHandleValueNtf(connId, UART_TX_HDL, len, pValue); -#endif - - return ATT_SUCCESS; -} - -uint8_t ble_uart_tx_buf[129]; -uint8_t ble_uart_buf_tx_fill; -int ble_uart_lasttick = 0; - -void ble_uart_write(uint8_t *pValue, uint8_t len) -{ - int i; - for(i=0; i<len; i++) { - if(pValue[i] >= 0x20 && pValue[i] < 0x7f) { - ble_uart_tx_buf[ble_uart_buf_tx_fill] = pValue[i]; - ble_uart_buf_tx_fill++; - } else if(pValue[i] == '\r' || pValue[i] == '\n') { - if(ble_uart_buf_tx_fill > 0) { - AttsSetAttr(UART_TX_HDL, ble_uart_buf_tx_fill, ble_uart_tx_buf); - if(active_connection) { - int x = xTaskGetTickCount() - ble_uart_lasttick; - if(x < 100) { - // Ugly hack if we already send something recently. - // TODO: figure out how these notifications are acknowledged - vTaskDelay(100 - x); - } - //printf("notify: "); - //int j; - //for(j=0;j<ble_uart_buf_tx_fill;j++) { - // printf("%02x ", ble_uart_tx_buf[j]); - //} - //printf("\n"); - AttsHandleValueNtf(active_connection, UART_TX_HDL, ble_uart_buf_tx_fill, ble_uart_tx_buf); - ble_uart_lasttick = xTaskGetTickCount(); - } - ble_uart_buf_tx_fill = 0; - } - } - } -} - static void ble_init(void) { @@ -325,13 +187,9 @@ static void ble_init(void) NVIC_SetPriority(BTLE_RX_RCVD_IRQn, 2); AppInit(); BleStart(); - - /* Add the UART service dynamically */ AttsDynInit(); - void *pSHdl; - pSHdl = SvcUARTAddGroupDyn(); - AttsDynRegister(pSHdl, UARTReadCback, UARTWriteCback); - //AttsDynRegister(pSHdl, NULL, UARTWriteCback); + + bleuart_init(); lasttick = xTaskGetTickCount(); diff --git a/epicardium/ble/meson.build b/epicardium/ble/meson.build index 9e00b125..02f2eeb5 100644 --- a/epicardium/ble/meson.build +++ b/epicardium/ble/meson.build @@ -6,5 +6,6 @@ ble_sources = files( 'svc_core.c', 'app/app_main.c', 'app/common/app_db.c', - 'app/common/app_ui.c' + 'app/common/app_ui.c', + 'uart.c' ) diff --git a/epicardium/ble/uart.c b/epicardium/ble/uart.c new file mode 100644 index 00000000..add1e1f1 --- /dev/null +++ b/epicardium/ble/uart.c @@ -0,0 +1,169 @@ +#include "wsf_types.h" +#include "wsf_os.h" +#include "wsf_buf.h" +#include "wsf_timer.h" +#include "wsf_trace.h" +#include "app_ui.h" +#include "ble_api.h" +#include "hci_vs.h" + +#include "att_defs.h" +#include "util/bstream.h" +#include "att_api.h" + +#include "modules/modules.h" +#include "FreeRTOS.h" +#include "timers.h" + +#include <stdio.h> +#include <string.h> +#include <stdbool.h> + + +#define UART_START_HDL 0x800 /*!< \brief Service start handle. */ +#define UART_END_HDL (BATT_MAX_HDL - 1) /*!< \brief Service end handle. */ + +/************************************************************************************************** + Handles +**************************************************************************************************/ + +/*! \brief UART Service Handles */ +enum +{ + UART_SVC_HDL = UART_START_HDL, /*!< \brief UART service declaration */ + UART_RX_CH_HDL, /*!< \brief UART rx characteristic */ + UART_RX_HDL, /*!< \brief UART rx value */ + UART_TX_CH_HDL, /*!< \brief UART tx characteristic */ + UART_TX_HDL, /*!< \brief UART tx value */ + UART_TX_CH_CCC_HDL, /*!< \brief UART tx CCCD */ + BATT_MAX_HDL /*!< \brief Maximum handle. */ +}; +/**@}*/ + +static const uint8_t UARTSvc[] = {0x9E,0xCA,0xDC,0x24,0x0E,0xE5,0xA9,0xE0,0x93,0xF3,0xA3,0xB5,0x01,0x00,0x40,0x6E}; + +static const uint8_t uartRxCh[] = {ATT_PROP_WRITE, UINT16_TO_BYTES(UART_RX_HDL), 0x9E,0xCA,0xDC,0x24,0x0E,0xE5,0xA9,0xE0,0x93,0xF3,0xA3,0xB5,0x02,0x00,0x40,0x6E}; +const uint8_t attUartRxChUuid[] = {0x9E,0xCA,0xDC,0x24,0x0E,0xE5, 0xA9,0xE0,0x93,0xF3,0xA3,0xB5,0x02,0x00,0x40,0x6E}; + +static const uint8_t uartTxCh[] = {ATT_PROP_READ | ATT_PROP_NOTIFY, UINT16_TO_BYTES(UART_TX_HDL), 0x9E,0xCA,0xDC,0x24,0x0E,0xE5,0xA9,0xE0,0x93,0xF3,0xA3,0xB5,0x03,0x00,0x40,0x6E}; +const uint8_t attUartTxChUuid[] = {0x9E,0xCA,0xDC,0x24,0x0E,0xE5, 0xA9,0xE0,0x93,0xF3,0xA3,0xB5,0x03,0x00,0x40,0x6E}; +/* Battery level client characteristic configuration */ + + + +static void *SvcUARTAddGroupDyn(void) +{ + void *pSHdl; + uint8_t initCcc[] = {UINT16_TO_BYTES(0x0000)}; + uint8_t initUARTVal[] = {0x20}; + + /* Create the service */ + pSHdl = AttsDynCreateGroup(UART_START_HDL, UART_END_HDL); + + if (pSHdl != NULL) + { + /* Primary service */ + AttsDynAddAttrConst(pSHdl, attPrimSvcUuid, UARTSvc, sizeof(UARTSvc), 0, ATTS_PERMIT_READ); + + + /* UART rx characteristic */ + AttsDynAddAttrConst(pSHdl, attChUuid, uartRxCh, sizeof(uartRxCh), 0, ATTS_PERMIT_READ); + // XXX: attUartRxChUuid is 16 bytes but nothing says so.... + /* UART rx value */ + // XXX: not sure if max value of 128 is fine... + AttsDynAddAttr(pSHdl, attUartRxChUuid, NULL, 0, 128, + ATTS_SET_WRITE_CBACK | ATTS_SET_VARIABLE_LEN, ATTS_PERMIT_WRITE); + + + /* UART tx characteristic */ + AttsDynAddAttrConst(pSHdl, attChUuid, uartTxCh, sizeof(uartTxCh), 0, ATTS_PERMIT_READ); + /* UART tx value */ + /* TODO: do we need ATTS_SET_READ_CBACK ? */ + AttsDynAddAttr(pSHdl, attUartTxChUuid, initUARTVal, sizeof(uint8_t), sizeof(uint8_t), + ATTS_SET_READ_CBACK, ATTS_PERMIT_READ); + /* UART tx CCC descriptor */ + AttsDynAddAttr(pSHdl, attCliChCfgUuid, initCcc, sizeof(uint16_t), sizeof(uint16_t), + ATTS_SET_CCC, ATTS_PERMIT_READ | ATTS_PERMIT_WRITE); + } + + return pSHdl; +} + +dmConnId_t active_connection = 0; + +static uint8_t UARTReadCback(dmConnId_t connId, uint16_t handle, uint8_t operation, + uint16_t offset, attsAttr_t *pAttr) +{ + //AppHwBattRead(pAttr->pValue); + printf("read callback\n"); + return ATT_SUCCESS; +} + +static uint8_t UARTWriteCback(dmConnId_t connId, uint16_t handle, uint8_t operation, + uint16_t offset, uint16_t len, uint8_t *pValue, + attsAttr_t *pAttr) +{ + active_connection = connId; + + //printf("UARTWriteCback %d: ", len); + int i; + for(i=0; i<len; i++) { + //printf("%c", pValue[i]); + serial_enqueue_char(pValue[i]); + } + serial_enqueue_char('\r'); + //printf("\n"); + +#if 0 + AttsSetAttr(UART_TX_HDL, len, pValue); + AttsHandleValueNtf(connId, UART_TX_HDL, len, pValue); +#endif + + return ATT_SUCCESS; +} + +uint8_t ble_uart_tx_buf[129]; +uint8_t ble_uart_buf_tx_fill; +int ble_uart_lasttick = 0; + +void ble_uart_write(uint8_t *pValue, uint8_t len) +{ + int i; + for(i=0; i<len; i++) { + if(pValue[i] >= 0x20 && pValue[i] < 0x7f) { + ble_uart_tx_buf[ble_uart_buf_tx_fill] = pValue[i]; + ble_uart_buf_tx_fill++; + } else if(pValue[i] == '\r' || pValue[i] == '\n') { + if(ble_uart_buf_tx_fill > 0) { + AttsSetAttr(UART_TX_HDL, ble_uart_buf_tx_fill, ble_uart_tx_buf); + if(active_connection) { + int x = xTaskGetTickCount() - ble_uart_lasttick; + if(x < 100) { + // Ugly hack if we already send something recently. + // TODO: figure out how fast we can send or use indications + vTaskDelay(100 - x); + } + //printf("notify: "); + //int j; + //for(j=0;j<ble_uart_buf_tx_fill;j++) { + // printf("%02x ", ble_uart_tx_buf[j]); + //} + //printf("\n"); + AttsHandleValueNtf(active_connection, UART_TX_HDL, ble_uart_buf_tx_fill, ble_uart_tx_buf); + ble_uart_lasttick = xTaskGetTickCount(); + } + ble_uart_buf_tx_fill = 0; + } + } + } +} + +void bleuart_init(void) +{ + /* Add the UART service dynamically */ + void *pSHdl; + pSHdl = SvcUARTAddGroupDyn(); + AttsDynRegister(pSHdl, UARTReadCback, UARTWriteCback); + //AttsDynRegister(pSHdl, NULL, UARTWriteCback); +} + -- GitLab