diff --git a/epicardium/ble/ble_api.h b/epicardium/ble/ble_api.h index 3c50745e91285c782ef6650dfa9c4645c360de64..059b0f6e85c964b6a4906743aed4698ee85427a3 100644 --- a/epicardium/ble/ble_api.h +++ b/epicardium/ble/ble_api.h @@ -27,9 +27,13 @@ void BleStart(void); /* ATT client module interface. Used by main BLE module */ void bleValueUpdate(attEvt_t *pMsg); void bleDiscCback(dmConnId_t connId, uint8_t status); -void ble_trigger_event(enum ble_event_type event); + void ble_epic_att_api_init(void); void ble_epic_att_api_event(attEvt_t *att_event); +void ble_epic_att_api_free_att_write_data(struct epic_att_write *w); + +void ble_epic_ble_api_trigger_event(enum epic_ble_event_type type, void *data); +void ble_epic_ble_api_init(void); /************************************************************************************************** Data Types diff --git a/epicardium/ble/ble_main.c b/epicardium/ble/ble_main.c index 373f5f37e37bc4633a090c19b63e4335e500f262..61e43788d7a13569c906ed0024bfb3596b6d800b 100644 --- a/epicardium/ble/ble_main.c +++ b/epicardium/ble/ble_main.c @@ -38,7 +38,6 @@ #include "ble_api.h" #include "epicardium.h" -#include "api/interrupt-sender.h" #include "modules/log.h" #include "modules/config.h" @@ -47,7 +46,6 @@ static bool active; static uint8_t advertising_mode = APP_MODE_NONE; static uint8_t advertising_mode_target = APP_MODE_NONE; -static enum ble_event_type ble_event; static struct epic_scan_report scan_reports[SCAN_REPORTS_NUM]; static int scan_reports_head; static int scan_reports_tail; @@ -620,27 +618,6 @@ void epic_ble_compare_response(bool confirmed) /* error condition */ } } -void ble_trigger_event(enum ble_event_type event) -{ - bool enabled; - epic_interrupt_is_enabled(EPIC_INT_BLE, &enabled); - - /* Print a warning if the app is missing events. Missing scan results - * is considered OK though, as they are queued and periodic. */ - if(ble_event && enabled && ble_event != BLE_EVENT_SCAN_REPORT) { - LOG_WARN("ble", "Application missed event %u", ble_event); - } - - ble_event = event; - api_interrupt_trigger(EPIC_INT_BLE); -} - -enum ble_event_type epic_ble_get_event(void) -{ - enum ble_event_type event = ble_event; - ble_event = 0; - return event; -} static void bleHandleNumericComparison(dmSecCnfIndEvt_t *pCnfInd) { @@ -651,7 +628,7 @@ static void bleHandleNumericComparison(dmSecCnfIndEvt_t *pCnfInd) pair_connId = (dmConnId_t)pCnfInd->hdr.param; pair_confirm_value = DmSecGetCompareValue(pCnfInd->confirm); LOG_INFO("ble", "Confirm Value: %ld", pair_confirm_value); - ble_trigger_event(BLE_EVENT_HANDLE_NUMERIC_COMPARISON); + ble_epic_ble_api_trigger_event(BLE_EVENT_HANDLE_NUMERIC_COMPARISON, NULL); } int epic_ble_get_scan_report(struct epic_scan_report *rpt) @@ -672,7 +649,7 @@ static void scannerScanReport(dmEvt_t *pMsg) int next_head = (scan_reports_head + 1) % SCAN_REPORTS_NUM; if(next_head == scan_reports_tail) { - ble_trigger_event(BLE_EVENT_SCAN_REPORT); + ble_epic_ble_api_trigger_event(BLE_EVENT_SCAN_REPORT, NULL); return; } scan_reports_head = next_head; @@ -688,7 +665,7 @@ static void scannerScanReport(dmEvt_t *pMsg) scan_report->directAddrType = pMsg->scanReport.directAddrType; memcpy(scan_report->directAddr, pMsg->scanReport.directAddr, BDA_ADDR_LEN); - ble_trigger_event(BLE_EVENT_SCAN_REPORT); + ble_epic_ble_api_trigger_event(BLE_EVENT_SCAN_REPORT, NULL); if((scan_reports_head + 1) % SCAN_REPORTS_NUM == scan_reports_tail) { LOG_WARN("ble", "Application missing scan results"); @@ -807,7 +784,7 @@ static void bleProcMsg(bleMsg_t *pMsg) AppDbNvmStoreBond(last_pairing); pair_connId = DM_CONN_ID_NONE; - ble_trigger_event(BLE_EVENT_PAIRING_COMPLETE); + ble_epic_ble_api_trigger_event(BLE_EVENT_PAIRING_COMPLETE, NULL); /* After a successful pairing, bonding is disabled again. * We don't want that for now. */ AppSetBondable(TRUE); @@ -832,7 +809,7 @@ static void bleProcMsg(bleMsg_t *pMsg) DmSecGenerateEccKeyReq(); pair_connId = DM_CONN_ID_NONE; - ble_trigger_event(BLE_EVENT_PAIRING_FAILED); + ble_epic_ble_api_trigger_event(BLE_EVENT_PAIRING_FAILED, NULL); break; case DM_SEC_ENCRYPT_IND: @@ -980,7 +957,7 @@ void BleStart(void) hid_init(); } - ble_epic_att_api_init(); + ble_epic_ble_api_init(); /* Reset the device */ DmDevReset(); diff --git a/epicardium/ble/epic_att_api.c b/epicardium/ble/epic_att_api.c index c155e80ee9a02585690438a65007ac549d8527bb..d35574200e3a54ce6700c57c220c25d8a47cb00a 100644 --- a/epicardium/ble/epic_att_api.c +++ b/epicardium/ble/epic_att_api.c @@ -14,52 +14,27 @@ #include <stdio.h> #include <string.h> -#define ATT_EVENT_QUEUE_SIZE 10 -#define ATT_WRITE_QUEUE_SIZE 10 - -static QueueHandle_t att_event_queue; -static uint8_t att_event_queue_buffer - [sizeof(struct epic_att_event) * ATT_EVENT_QUEUE_SIZE]; -static StaticQueue_t att_event_queue_data; - -static QueueHandle_t att_write_queue; -static uint8_t att_write_queue_buffer - [sizeof(struct epic_att_write) * ATT_WRITE_QUEUE_SIZE]; -static StaticQueue_t att_write_queue_data; - -int epic_ble_get_att_event(struct epic_att_event *e) -{ - if (xQueueReceive(att_event_queue, e, 0) != pdTRUE) { - return -ENOENT; - } - return uxQueueMessagesWaiting(att_event_queue); -} - void ble_epic_att_api_event(attEvt_t *att_event) { bool enabled; epic_interrupt_is_enabled(EPIC_INT_BLE, &enabled); if (enabled) { - if (xQueueSend(att_event_queue, att_event, 0) != pdTRUE) { - LOG_WARN("ble", "could not queue att event"); - } - ble_trigger_event(BLE_EVENT_ATT_EVENT); - } -} + attEvt_t *e = WsfBufAlloc(sizeof(*e)); -int epic_ble_get_att_write(struct epic_att_write *w) -{ - if (xQueueReceive(att_write_queue, w, 0) != pdTRUE) { - return -ENOENT; + if (e) { + memcpy(e, att_event, sizeof(*e)); + ble_epic_ble_api_trigger_event(BLE_EVENT_ATT_EVENT, e); + } else { + LOG_WARN("ble", "could not allocate att event"); + } } - return uxQueueMessagesWaiting(att_event_queue); } -int epic_ble_free_att_write(struct epic_att_write *w) +void ble_epic_att_api_free_att_write_data(struct epic_att_write *w) { WsfBufFree(w->buffer); - return 0; + WsfBufFree(w); } static uint8_t DynAttsWriteCback( @@ -72,24 +47,28 @@ static uint8_t DynAttsWriteCback( attsAttr_t *pAttr ) { printf("DynAttsWriteCback %d, %d, %d\n", handle, len, offset); - struct epic_att_write att_write; - att_write.hdr.param = connId; - att_write.handle = handle; - att_write.valueLen = len; - att_write.operation = operation; - att_write.offset = offset; - - att_write.buffer = WsfBufAlloc(len); - if (att_write.buffer) { - memcpy(att_write.buffer, pValue, len); - - if (xQueueSend(att_write_queue, &att_write, 0) != pdTRUE) { - LOG_WARN("ble", "could not queue att write"); - epic_ble_free_att_write(&att_write); + struct epic_att_write *att_write = WsfBufAlloc(sizeof(*att_write)); + ; + + if (att_write) { + att_write->hdr.param = connId; + att_write->handle = handle; + att_write->valueLen = len; + att_write->operation = operation; + att_write->offset = offset; + + att_write->buffer = WsfBufAlloc(len); + + if (att_write->buffer) { + memcpy(att_write->buffer, pValue, len); + ble_epic_ble_api_trigger_event( + BLE_EVENT_ATT_WRITE, att_write + ); + } else { + LOG_WARN("ble", "could allocate att write data"); + WsfBufFree(att_write); } - - ble_trigger_event(BLE_EVENT_ATT_WRITE); } else { LOG_WARN("ble", "could allocate att write"); } @@ -144,18 +123,6 @@ int epic_ble_atts_dyn_delete_groups(void) void ble_epic_att_api_init(void) { - att_event_queue = xQueueCreateStatic( - ATT_EVENT_QUEUE_SIZE, - sizeof(struct epic_att_event), - att_event_queue_buffer, - &att_event_queue_data - ); - att_write_queue = xQueueCreateStatic( - ATT_WRITE_QUEUE_SIZE, - sizeof(struct epic_att_write), - att_write_queue_buffer, - &att_write_queue_data - ); } int epic_ble_atts_handle_value_ntf( diff --git a/epicardium/ble/epic_ble_api.c b/epicardium/ble/epic_ble_api.c new file mode 100644 index 0000000000000000000000000000000000000000..4e68170be752fea04025edbdd222720a0d3a41df --- /dev/null +++ b/epicardium/ble/epic_ble_api.c @@ -0,0 +1,71 @@ +#include "ble_api.h" + +#include "epicardium.h" +#include "modules/log.h" +#include "api/interrupt-sender.h" + +#include "wsf_buf.h" + +#include "FreeRTOS.h" +#include "queue.h" + +#include <stdint.h> + +#define BLE_EVENT_QUEUE_SIZE 10 + +static QueueHandle_t ble_event_queue; +static uint8_t ble_event_queue_buffer + [sizeof(struct epic_ble_event) * BLE_EVENT_QUEUE_SIZE]; +static StaticQueue_t ble_event_queue_data; + +int epic_ble_free_event(struct epic_ble_event *e) +{ + if (e->data) { + if (e->type == BLE_EVENT_ATT_WRITE) { + ble_epic_att_api_free_att_write_data(e->att_write); + } else { + // Generic free + WsfBufFree(e->data); + } + } + return 0; +} + +void ble_epic_ble_api_trigger_event(enum epic_ble_event_type type, void *data) +{ + bool enabled; + epic_interrupt_is_enabled(EPIC_INT_BLE, &enabled); + + struct epic_ble_event e = { .type = type, .data = data }; + + if (xQueueSend(ble_event_queue, &e, 0) != pdTRUE) { + /* Print a warning if the app is missing events. Missing scan results + * is considered OK though, as they are queued and periodic. */ + if (type != BLE_EVENT_SCAN_REPORT) { + LOG_WARN("ble", "Application missed event %u", type); + } + epic_ble_free_event(&e); + } + + api_interrupt_trigger(EPIC_INT_BLE); +} + +int epic_ble_get_event(struct epic_ble_event *e) +{ + if (xQueueReceive(ble_event_queue, e, 0) != pdTRUE) { + return -ENOENT; + } + return uxQueueMessagesWaiting(ble_event_queue); +} + +void ble_epic_ble_api_init(void) +{ + ble_event_queue = xQueueCreateStatic( + BLE_EVENT_QUEUE_SIZE, + sizeof(struct epic_ble_event), + ble_event_queue_buffer, + &ble_event_queue_data + ); + + ble_epic_att_api_init(); +} diff --git a/epicardium/ble/meson.build b/epicardium/ble/meson.build index 66a4566ad2c78e1fb99b317a9d6d27830f26ff06..2372440b4e5416aeb6fa57c52154afce12608b7d 100644 --- a/epicardium/ble/meson.build +++ b/epicardium/ble/meson.build @@ -1,5 +1,6 @@ ble_sources = files( 'ble.c', + 'epic_ble_api.c', 'epic_att_api.c', 'stack.c', 'ble_main.c', diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h index ec74d98132d7aae9394d6ec9ecadcc55f3c222c9..6ac9a8d6121ca5e89f750f3e1a7f2e475e0ba9ee 100644 --- a/epicardium/epicardium.h +++ b/epicardium/epicardium.h @@ -171,7 +171,7 @@ typedef _Bool bool; #define API_BLE_ATTS_HANDLE_VALUE_NTF 0x166 #define API_BLE_ATTS_HANDLE_VALUE_IND 0x167 #define API_BLE_ATTS_GET_ATTR 0x168 -#define API_BLE_ATT_GET_EVENT 0x169 +#define API_BLE_FREE_EVENT 0x169 #define API_BLE_ATTS_SEND_SERVICE_CHANGED_IND 0x16A #define API_BLE_ATTS_DYN_DELETE_GROUPS 0x16B #define API_BLE_ATTS_SET_BUFFER 0x1BC @@ -2335,7 +2335,7 @@ API(API_CONFIG_SET_STRING, int epic_config_set_string(const char *key, const cha /** * BLE event type */ -enum ble_event_type { +enum epic_ble_event_type { /** No event pending */ BLE_EVENT_NONE = 0, /** Numeric comparison requested */ @@ -2348,8 +2348,45 @@ enum ble_event_type { BLE_EVENT_SCAN_REPORT = 4, BLE_EVENT_ATT_EVENT = 5, BLE_EVENT_ATT_WRITE = 6, + BLE_EVENT_DM_EVENT = 6, }; +struct epic_wsf_header +{ + uint16_t param; /*!< \brief General purpose parameter passed to event handler */ + uint8_t event; /*!< \brief General purpose event value passed to event handler */ + uint8_t status; /*!< \brief General purpose status value passed to event handler */ +}; + +struct epic_att_event +{ + struct epic_wsf_header hdr; /*!< \brief Header structure */ + uint8_t *pValue; /*!< \brief Value */ + uint16_t valueLen; /*!< \brief Value length */ + uint16_t handle; /*!< \brief Attribute handle */ + uint8_t continuing; /*!< \brief TRUE if more response packets expected */ + uint16_t mtu; /*!< \brief Negotiated MTU value */ +}; + +struct epic_att_write +{ + struct epic_wsf_header hdr; /*!< \brief Header structure */ + uint16_t valueLen; /*!< \brief Value length */ + uint16_t handle; /*!< \brief Attribute handle */ + uint8_t operation; + uint16_t offset; + void *buffer; +}; + + +struct epic_ble_event { + enum epic_ble_event_type type; + union { + void *data; + struct epic_att_event *att_event; + struct epic_att_write *att_write; + }; +}; /** * Scan report data. Bases on ``hciLeAdvReportEvt_t`` from BLE stack. @@ -2397,15 +2434,10 @@ API_ISR(EPIC_INT_BLE, epic_isr_ble); /** * Retreive the event which triggered :c:func:`epic_isr_ble` * - * The handling code needs to ensure to handle interrupts in a timely - * manner as new events will overwrite each other. Reading the event - * automatically resets it to :c:data:`BLE_EVENT_NONE`. - * - * :return: Event which triggered the interrupt. - * * .. versionadded:: 1.16 + * .. versionchanged:: 1.17 */ -API(API_BLE_GET_EVENT, enum ble_event_type epic_ble_get_event(void)); +API(API_BLE_GET_EVENT, int epic_ble_get_event(struct epic_ble_event *e)); /** * Retrieve the compare value of an ongoing pairing procedure. @@ -2532,37 +2564,7 @@ API(API_BLE_ATTS_HANDLE_VALUE_NTF, int epic_ble_atts_handle_value_ntf(uint8_t co API(API_BLE_ATTS_HANDLE_VALUE_IND, int epic_ble_atts_handle_value_ind(uint8_t connId, uint16_t handle, uint16_t valueLen, uint8_t *pValue)); API(API_BLE_ATTS_SET_BUFFER, int epic_ble_atts_set_buffer(uint16_t value_handle, size_t len, bool append)); -struct epic_wsf_header -{ - uint16_t param; /*!< \brief General purpose parameter passed to event handler */ - uint8_t event; /*!< \brief General purpose event value passed to event handler */ - uint8_t status; /*!< \brief General purpose status value passed to event handler */ -}; - -struct epic_att_event -{ - struct epic_wsf_header hdr; /*!< \brief Header structure */ - uint8_t *pValue; /*!< \brief Value */ - uint16_t valueLen; /*!< \brief Value length */ - uint16_t handle; /*!< \brief Attribute handle */ - uint8_t continuing; /*!< \brief TRUE if more response packets expected */ - uint16_t mtu; /*!< \brief Negotiated MTU value */ -}; - -API(API_BLE_ATT_GET_EVENT, int epic_ble_get_att_event(struct epic_att_event *e)); - -struct epic_att_write -{ - struct epic_wsf_header hdr; /*!< \brief Header structure */ - uint16_t valueLen; /*!< \brief Value length */ - uint16_t handle; /*!< \brief Attribute handle */ - uint8_t operation; - uint16_t offset; - void *buffer; -}; - -API(API_BLE_GET_ATT_WRITE, int epic_ble_get_att_write(struct epic_att_write *w)); -API(API_BLE_FREE_ATT_WRITE, int epic_ble_free_att_write(struct epic_att_write *w)); +API(API_BLE_FREE_EVENT, int epic_ble_free_event(struct epic_ble_event *e)); #endif /* _EPICARDIUM_H */ diff --git a/pycardium/modules/modbluetooth_card10.c b/pycardium/modules/modbluetooth_card10.c index 5395a68150d9bdf397727e493ea2afc9e5765055..36dd81dcb230ad0307e188e2b866dd3bffa2b46d 100644 --- a/pycardium/modules/modbluetooth_card10.c +++ b/pycardium/modules/modbluetooth_card10.c @@ -145,13 +145,15 @@ static void raise(void) static void clear_events(void) { - struct epic_att_event att_event; - struct epic_att_write att_write; - epic_ble_get_event(); - while (epic_ble_get_att_event(&att_event) >= 0) - ; - while (epic_ble_get_att_write(&att_write) >= 0) - epic_ble_free_att_write(&att_write); + struct epic_ble_event ble_event; + int ret; + + do { + ret = epic_ble_get_event(&ble_event); + if (ret >= 0) { + epic_ble_free_event(&ble_event); + } + } while (ret >= 0); } static void handle_att_event(struct epic_att_event *att_event) @@ -217,30 +219,21 @@ static void handle_att_write(struct epic_att_write *att_write) static mp_obj_t mp_ble_poll_events(mp_obj_t interrupt_id) { - enum ble_event_type event = epic_ble_get_event(); - - if (event == BLE_EVENT_ATT_EVENT) { - struct epic_att_event att_event; - int ret; - do { - ret = epic_ble_get_att_event(&att_event); - if (ret >= 0) { - handle_att_event(&att_event); + struct epic_ble_event ble_event; + int ret; + + do { + ret = epic_ble_get_event(&ble_event); + if (ret >= 0) { + if (ble_event.type == BLE_EVENT_ATT_EVENT) { + handle_att_event(ble_event.att_event); } - } while (ret >= 0); - } - - if (event == BLE_EVENT_ATT_WRITE) { - struct epic_att_write att_write; - int ret; - do { - ret = epic_ble_get_att_write(&att_write); - if (ret >= 0) { - handle_att_write(&att_write); - epic_ble_free_att_write(&att_write); + if (ble_event.type == BLE_EVENT_ATT_WRITE) { + handle_att_write(ble_event.att_write); } - } while (ret >= 0); - } + epic_ble_free_event(&ble_event); + } + } while (ret >= 0); return mp_const_none; } diff --git a/pycardium/modules/sys_ble.c b/pycardium/modules/sys_ble.c index 7b95d8d4d9081a72ed687eeb0c40fd750589e09e..647b3baa9cf09f3996032df7fb5e99c9ec5589ac 100644 --- a/pycardium/modules/sys_ble.c +++ b/pycardium/modules/sys_ble.c @@ -84,7 +84,11 @@ static MP_DEFINE_CONST_FUN_OBJ_0( static mp_obj_t mp_ble_get_event(void) { - return mp_obj_new_int(epic_ble_get_event()); + struct epic_ble_event e; + if (epic_ble_get_event(&e) >= 0) { + return mp_obj_new_int(e.type); + } + return BLE_EVENT_NONE; } static MP_DEFINE_CONST_FUN_OBJ_0(ble_get_event_obj, mp_ble_get_event);