diff --git a/epicardium/ble/ble_api.h b/epicardium/ble/ble_api.h index 059b0f6e85c964b6a4906743aed4698ee85427a3..38c60f731a27ada94022ad2dcbd11f467824f0d6 100644 --- a/epicardium/ble/ble_api.h +++ b/epicardium/ble/ble_api.h @@ -34,6 +34,7 @@ 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); +void ble_epic_dm_api_event(dmEvt_t *dm_event); /************************************************************************************************** Data Types diff --git a/epicardium/ble/ble_main.c b/epicardium/ble/ble_main.c index 61e43788d7a13569c906ed0024bfb3596b6d800b..c40d3df62c1ce290b7378475a61537e4d7df9e51 100644 --- a/epicardium/ble/ble_main.c +++ b/epicardium/ble/ble_main.c @@ -686,7 +686,6 @@ static void scannerScanReport(dmEvt_t *pMsg) static void bleProcMsg(bleMsg_t *pMsg) { hciLeConnCmplEvt_t *connOpen; - attEvt_t e; switch(pMsg->hdr.event) { @@ -733,8 +732,6 @@ static void bleProcMsg(bleMsg_t *pMsg) bleESS_ccc_update(); HidProcMsg(&pMsg->hdr); UartProcMsg(pMsg); - e.hdr.event = ATT_CONNECTION_OPENED; e.hdr.param = connOpen->hdr.param; - ble_epic_att_api_event(&e); break; case DM_CONN_CLOSE_IND: @@ -770,8 +767,6 @@ static void bleProcMsg(bleMsg_t *pMsg) */ advertising_mode = APP_MODE_NONE; AppAdvStop(); - e.hdr.param = pMsg->dm.connClose.hdr.param; e.hdr.event = ATT_CONNECTION_CLOSED; - ble_epic_att_api_event(&e); bleClose(pMsg); break; @@ -905,6 +900,8 @@ static void BleHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) /* process discovery-related messages */ AppDiscProcDmMsg((dmEvt_t *) pMsg); + + ble_epic_dm_api_event((dmEvt_t *)pMsg); } else if (pMsg->event >= ATT_CBACK_START && pMsg->event <= ATT_CBACK_END) { diff --git a/epicardium/ble/epic_att_api.c b/epicardium/ble/epic_att_api.c index d35574200e3a54ce6700c57c220c25d8a47cb00a..284c623519e6715d65a2dc48ed7047a0a89c5b89 100644 --- a/epicardium/ble/epic_att_api.c +++ b/epicardium/ble/epic_att_api.c @@ -16,18 +16,13 @@ void ble_epic_att_api_event(attEvt_t *att_event) { - bool enabled; - epic_interrupt_is_enabled(EPIC_INT_BLE, &enabled); + attEvt_t *e = WsfBufAlloc(sizeof(*e)); - if (enabled) { - attEvt_t *e = WsfBufAlloc(sizeof(*e)); - - 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"); - } + 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"); } } diff --git a/epicardium/ble/epic_ble_api.c b/epicardium/ble/epic_ble_api.c index 4e68170be752fea04025edbdd222720a0d3a41df..910bc8ad7011c8db336816e4a577af111942139a 100644 --- a/epicardium/ble/epic_ble_api.c +++ b/epicardium/ble/epic_ble_api.c @@ -10,6 +10,7 @@ #include "queue.h" #include <stdint.h> +#include <string.h> #define BLE_EVENT_QUEUE_SIZE 10 @@ -38,16 +39,24 @@ void ble_epic_ble_api_trigger_event(enum epic_ble_event_type type, void *data) 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); + if (enabled) { + 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); + } else { epic_ble_free_event(&e); } - - api_interrupt_trigger(EPIC_INT_BLE); } int epic_ble_get_event(struct epic_ble_event *e) @@ -69,3 +78,15 @@ void ble_epic_ble_api_init(void) ble_epic_att_api_init(); } + +void ble_epic_dm_api_event(dmEvt_t *dm_event) +{ + dmEvt_t *e = WsfBufAlloc(sizeof(*e)); + + if (e) { + memcpy(e, dm_event, sizeof(*e)); + ble_epic_ble_api_trigger_event(BLE_EVENT_DM_EVENT, e); + } else { + LOG_WARN("ble", "could not allocate dm event"); + } +} diff --git a/epicardium/epicardium.h b/epicardium/epicardium.h index 6ac9a8d6121ca5e89f750f3e1a7f2e475e0ba9ee..d3d7df16995a0009df837d106ce3950f89925ae1 100644 --- a/epicardium/epicardium.h +++ b/epicardium/epicardium.h @@ -2348,7 +2348,7 @@ enum epic_ble_event_type { BLE_EVENT_SCAN_REPORT = 4, BLE_EVENT_ATT_EVENT = 5, BLE_EVENT_ATT_WRITE = 6, - BLE_EVENT_DM_EVENT = 6, + BLE_EVENT_DM_EVENT = 7, }; struct epic_wsf_header @@ -2368,6 +2368,45 @@ struct epic_att_event uint16_t mtu; /*!< \brief Negotiated MTU value */ }; +#define BDA_ADDR_LEN 6 +typedef uint8_t bdAddr_t[BDA_ADDR_LEN]; + +struct epic_hciLeConnCmpl_event +{ + struct epic_wsf_header hdr; /*!< \brief Event header */ + uint8_t status; /*!< \brief Status. */ + uint16_t handle; /*!< \brief Connection handle. */ + uint8_t role; /*!< \brief Local connection role. */ + uint8_t addrType; /*!< \brief Peer address type. */ + bdAddr_t peerAddr; /*!< \brief Peer address. */ + uint16_t connInterval; /*!< \brief Connection interval */ + uint16_t connLatency; /*!< \brief Connection latency. */ + uint16_t supTimeout; /*!< \brief Supervision timeout. */ + uint8_t clockAccuracy; /*!< \brief Clock accuracy. */ + + /* \brief enhanced fields */ + bdAddr_t localRpa; /*!< \brief Local RPA. */ + bdAddr_t peerRpa; /*!< \brief Peer RPA. */ +}; + +/*! \brief Disconnect complete event */ +struct epic_hciDisconnectCmpl_event +{ + struct epic_wsf_header hdr; /*!< \brief Event header */ + uint8_t status; /*!< \brief Disconnect complete status. */ + uint16_t handle; /*!< \brief Connect handle. */ + uint8_t reason; /*!< \brief Reason. */ +}; + + +struct epic_dm_event +{ + union { + struct epic_hciLeConnCmpl_event leConnCmpl; /*!< \brief LE connection complete. */ + struct epic_hciDisconnectCmpl_event disconnectCmpl; /*!< \brief Disconnect complete. */ + }; +}; + struct epic_att_write { struct epic_wsf_header hdr; /*!< \brief Header structure */ @@ -2378,12 +2417,12 @@ struct epic_att_write void *buffer; }; - struct epic_ble_event { enum epic_ble_event_type type; union { void *data; struct epic_att_event *att_event; + struct epic_dm_event *dm_event; struct epic_att_write *att_write; }; }; diff --git a/pycardium/modules/modbluetooth_card10.c b/pycardium/modules/modbluetooth_card10.c index 36dd81dcb230ad0307e188e2b866dd3bffa2b46d..55df544db7bb61c2d824c95d3fea7bcb01b8e1ae 100644 --- a/pycardium/modules/modbluetooth_card10.c +++ b/pycardium/modules/modbluetooth_card10.c @@ -85,9 +85,81 @@ const uint8_t attCliChCfgUuid[] = { UINT16_TO_BYTES( #define ATT_RSP_PENDING \ 0x79 /*!< \brief Responsed delayed pending higher layer */ -// card10 att interface specific events -#define ATT_CONNECTION_OPENED 0x81 -#define ATT_CONNECTION_CLOSED 0x82 +#define DM_CBACK_START 0x20 /*!< \brief DM callback event starting value */ + +/*! \brief DM callback events */ +enum { DM_RESET_CMPL_IND = DM_CBACK_START, /*!< \brief Reset complete */ + DM_ADV_START_IND, /*!< \brief Advertising started */ + DM_ADV_STOP_IND, /*!< \brief Advertising stopped */ + DM_ADV_NEW_ADDR_IND, /*!< \brief New resolvable address has been generated */ + DM_SCAN_START_IND, /*!< \brief Scanning started */ + DM_SCAN_STOP_IND, /*!< \brief Scanning stopped */ + DM_SCAN_REPORT_IND, /*!< \brief Scan data received from peer device */ + DM_CONN_OPEN_IND, /*!< \brief Connection opened */ + DM_CONN_CLOSE_IND, /*!< \brief Connection closed */ + DM_CONN_UPDATE_IND, /*!< \brief Connection update complete */ + DM_SEC_PAIR_CMPL_IND, /*!< \brief Pairing completed successfully */ + DM_SEC_PAIR_FAIL_IND, /*!< \brief Pairing failed or other security failure */ + DM_SEC_ENCRYPT_IND, /*!< \brief Connection encrypted */ + DM_SEC_ENCRYPT_FAIL_IND, /*!< \brief Encryption failed */ + DM_SEC_AUTH_REQ_IND, /*!< \brief PIN or OOB data requested for pairing */ + DM_SEC_KEY_IND, /*!< \brief Security key indication */ + DM_SEC_LTK_REQ_IND, /*!< \brief LTK requested for encyption */ + DM_SEC_PAIR_IND, /*!< \brief Incoming pairing request from master */ + DM_SEC_SLAVE_REQ_IND, /*!< \brief Incoming security request from slave */ + DM_SEC_CALC_OOB_IND, /*!< \brief Result of OOB Confirm Calculation Generation */ + DM_SEC_ECC_KEY_IND, /*!< \brief Result of ECC Key Generation */ + DM_SEC_COMPARE_IND, /*!< \brief Result of Just Works/Numeric Comparison Compare Value Calculation */ + DM_SEC_KEYPRESS_IND, /*!< \brief Keypress indication from peer in passkey security */ + DM_PRIV_RESOLVED_ADDR_IND, /*!< \brief Private address resolved */ + DM_PRIV_GENERATE_ADDR_IND, /*!< \brief Private resolvable address generated */ + DM_CONN_READ_RSSI_IND, /*!< \brief Connection RSSI read */ + DM_PRIV_ADD_DEV_TO_RES_LIST_IND, /*!< \brief Device added to resolving list */ + DM_PRIV_REM_DEV_FROM_RES_LIST_IND, /*!< \brief Device removed from resolving list */ + DM_PRIV_CLEAR_RES_LIST_IND, /*!< \brief Resolving list cleared */ + DM_PRIV_READ_PEER_RES_ADDR_IND, /*!< \brief Peer resolving address read */ + DM_PRIV_READ_LOCAL_RES_ADDR_IND, /*!< \brief Local resolving address read */ + DM_PRIV_SET_ADDR_RES_ENABLE_IND, /*!< \brief Address resolving enable set */ + DM_REM_CONN_PARAM_REQ_IND, /*!< \brief Remote connection parameter requested */ + DM_CONN_DATA_LEN_CHANGE_IND, /*!< \brief Data length changed */ + DM_CONN_WRITE_AUTH_TO_IND, /*!< \brief Write authenticated payload complete */ + DM_CONN_AUTH_TO_EXPIRED_IND, /*!< \brief Authenticated payload timeout expired */ + DM_PHY_READ_IND, /*!< \brief Read PHY */ + DM_PHY_SET_DEF_IND, /*!< \brief Set default PHY */ + DM_PHY_UPDATE_IND, /*!< \brief PHY update */ + DM_ADV_SET_START_IND, /*!< \brief Advertising set(s) started */ + DM_ADV_SET_STOP_IND, /*!< \brief Advertising set(s) stopped */ + DM_SCAN_REQ_RCVD_IND, /*!< \brief Scan request received */ + DM_EXT_SCAN_START_IND, /*!< \brief Extended scanning started */ + DM_EXT_SCAN_STOP_IND, /*!< \brief Extended scanning stopped */ + DM_EXT_SCAN_REPORT_IND, /*!< \brief Extended scan data received from peer device */ + DM_PER_ADV_SET_START_IND, /*!< \brief Periodic advertising set started */ + DM_PER_ADV_SET_STOP_IND, /*!< \brief Periodic advertising set stopped */ + DM_PER_ADV_SYNC_EST_IND, /*!< \brief Periodic advertising sync established */ + DM_PER_ADV_SYNC_EST_FAIL_IND, /*!< \brief Periodic advertising sync establishment failed */ + DM_PER_ADV_SYNC_LOST_IND, /*!< \brief Periodic advertising sync lost */ + DM_PER_ADV_SYNC_TRSF_EST_IND, /*!< \brief Periodic advertising sync transfer established */ + DM_PER_ADV_SYNC_TRSF_EST_FAIL_IND, /*!< \brief Periodic advertising sync transfer establishment failed */ + DM_PER_ADV_SYNC_TRSF_IND, /*!< \brief Periodic advertising sync info transferred */ + DM_PER_ADV_SET_INFO_TRSF_IND, /*!< \brief Periodic advertising set sync info transferred */ + DM_PER_ADV_REPORT_IND, /*!< \brief Periodic advertising data received from peer device */ + DM_REMOTE_FEATURES_IND, /*!< \brief Remote features from peer device */ + DM_READ_REMOTE_VER_INFO_IND, /*!< \brief Remote LL version information read */ + DM_CONN_IQ_REPORT_IND, /*!< \brief IQ samples from CTE of received packet from peer device */ + DM_CTE_REQ_FAIL_IND, /*!< \brief CTE request failed */ + DM_CONN_CTE_RX_SAMPLE_START_IND, /*!< \brief Sampling received CTE started */ + DM_CONN_CTE_RX_SAMPLE_STOP_IND, /*!< \brief Sampling received CTE stopped */ + DM_CONN_CTE_TX_CFG_IND, /*!< \brief Connection CTE transmit parameters configured */ + DM_CONN_CTE_REQ_START_IND, /*!< \brief Initiating connection CTE request started */ + DM_CONN_CTE_REQ_STOP_IND, /*!< \brief Initiating connection CTE request stopped */ + DM_CONN_CTE_RSP_START_IND, /*!< \brief Responding to connection CTE request started */ + DM_CONN_CTE_RSP_STOP_IND, /*!< \brief Responding to connection CTE request stopped */ + DM_READ_ANTENNA_INFO_IND, /*!< \brief Antenna information read */ + DM_L2C_CMD_REJ_IND, /*!< \brief L2CAP Command Reject */ + DM_ERROR_IND, /*!< \brief General error */ + DM_HW_ERROR_IND, /*!< \brief Hardware error */ + DM_VENDOR_SPEC_IND /*!< \brief Vendor specific event */ +}; #define ATTS_HANDLE_VALUE_CNF 15 @@ -171,21 +243,32 @@ static void handle_att_event(struct epic_att_event *att_event) } else if (att_event->hdr.status == ATT_ERR_OVERFLOW) { e->notification_status = NOTIFICATION_STATUS_OVERFLOW; } - } else if (att_event->hdr.event == ATT_CONNECTION_OPENED) { - uint8_t event = MP_BLUETOOTH_IRQ_CENTRAL_CONNECT; - uint16_t conn_handle = att_event->hdr.param; - uint8_t addr_type = 0; // TODO - uint8_t addr[8] = {}; // TODO + } +} + +static void handle_dm_event(struct epic_dm_event *dm_event) +{ + struct epic_wsf_header *hdr = (struct epic_wsf_header *)dm_event; + printf("MP got dm event %d,%d\n", hdr->event, hdr->status); + + if (hdr->event == DM_CONN_OPEN_IND) { + struct epic_hciLeConnCmpl_event *e = + (struct epic_hciLeConnCmpl_event *)dm_event; mp_bluetooth_gap_on_connected_disconnected( - event, conn_handle, addr_type, addr + MP_BLUETOOTH_IRQ_CENTRAL_CONNECT, + e->hdr.param, + e->addrType, + e->peerAddr ); - } else if (att_event->hdr.event == ATT_CONNECTION_CLOSED) { - uint8_t event = MP_BLUETOOTH_IRQ_CENTRAL_DISCONNECT; - uint16_t conn_handle = att_event->hdr.param; - uint8_t addr_type = 0; // TODO - uint8_t addr[8] = {}; // TODO + } else if (hdr->event == DM_CONN_CLOSE_IND) { + struct epic_hciDisconnectCmpl_event *e = + (struct epic_hciDisconnectCmpl_event *)dm_event; + uint8_t addr[6] = {}; mp_bluetooth_gap_on_connected_disconnected( - event, conn_handle, addr_type, addr + MP_BLUETOOTH_IRQ_CENTRAL_DISCONNECT, + e->hdr.param, + 0xFF, + addr ); } } @@ -228,6 +311,9 @@ static mp_obj_t mp_ble_poll_events(mp_obj_t interrupt_id) if (ble_event.type == BLE_EVENT_ATT_EVENT) { handle_att_event(ble_event.att_event); } + if (ble_event.type == BLE_EVENT_DM_EVENT) { + handle_dm_event(ble_event.dm_event); + } if (ble_event.type == BLE_EVENT_ATT_WRITE) { handle_att_write(ble_event.att_write); }