/********************************************************************* * @fn simpleTopology_sendAttRsp * * @brief Send a pending ATT response message. * * @param none * * @return none */ static void simpleTopology_sendAttRsp(void) { // See if there's a pending ATT Response to be transmitted if (pAttRsp != NULL) { uint8_t status; // Increment retransmission count rspTxRetry++; // Try to retransmit ATT response till either we're successful or // the ATT Client times out (after 30s) and drops the connection. status = GATT_SendRsp(pAttRsp->connHandle, pAttRsp->method, &(pAttRsp->msg)); if ((status != blePending) && (status != MSG_BUFFER_NOT_AVAIL)) { // Disable connection event end notice HCI_EXT_ConnEventNoticeCmd(pAttRsp->connHandle, selfEntity, 0); // We're done with the response message simpleTopology_freeAttRsp(status); } else { // Continue retrying LCD_WRITE_STRING_VALUE("Rsp send retry:", rspTxRetry, 10, LCD_PAGE6); } } }
/********************************************************************* * @fn SimpleBLEPeripheral_sendAttRsp * * @brief Send a pending ATT response message. * * @param none * * @return none */ static void SimpleBLEPeripheral_sendAttRsp(void) { // See if there's a pending ATT Response to be transmitted if (pAttRsp != NULL) { uint8_t status; // Increment retransmission count rspTxRetry++; // Try to retransmit ATT response till either we're successful or // the ATT Client times out (after 30s) and drops the connection. status = GATT_SendRsp(pAttRsp->connHandle, pAttRsp->method, &(pAttRsp->msg)); if ((status != blePending) && (status != MSG_BUFFER_NOT_AVAIL)) { // Disable connection event end notice HCI_EXT_ConnEventNoticeCmd(pAttRsp->connHandle, selfEntity, 0); // We're done with the response message SimpleBLEPeripheral_freeAttRsp(status); } else { // Continue retrying Display_print1(dispHandle, 5, 0, "Rsp send retry: %d", rspTxRetry); } } }
/********************************************************************* * @fn SimplePropBeacon_processGATTMsg * * @brief Process GATT messages and events. * * @return TRUE if safe to deallocate incoming message, FALSE otherwise. */ static uint8_t SimplePropBeacon_processGATTMsg(gattMsgEvent_t *pMsg) { // See if GATT server was unable to transmit an ATT response if (pMsg->hdr.status == blePending) { // No HCI buffer was available. Let's try to retransmit the response // on the next connection event. if (HCI_EXT_ConnEventNoticeCmd(pMsg->connHandle, selfEntity, SPB_CONN_EVT_END_EVT) == SUCCESS) { // First free any pending response SimplePropBeacon_freeAttRsp(FAILURE); // Hold on to the response message for retransmission pAttRsp = pMsg; // Don't free the response message yet return (FALSE); } } else if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT) { // ATT request-response or indication-confirmation flow control is // violated. All subsequent ATT requests or indications will be dropped. // The app is informed in case it wants to drop the connection. // Display the opcode of the message that caused the violation. Display_print1(dispHandle, 5, 0, "FC Violated:", pMsg->msg.flowCtrlEvt.opcode); } else if (pMsg->method == ATT_MTU_UPDATED_EVENT) { // MTU size updated Display_print1(dispHandle, 5, 0, "FC Violated:", pMsg->msg.mtuEvt.MTU); } // Free message payload. Needed only for ATT Protocol messages GATT_bm_free(&pMsg->msg, pMsg->method); // It's safe to free the incoming message return (TRUE); }
/********************************************************************* * @fn simpleTopology_processGATTMsg * * @brief Process GATT messages and events. * * @return TRUE if safe to deallocate incoming message, FALSE otherwise. */ static uint8_t simpleTopology_processGATTMsg(gattMsgEvent_t *pMsg) { // See if GATT server was unable to transmit an ATT response if (pMsg->hdr.status == blePending) { // No HCI buffer was available. Let's try to retransmit the response // on the next connection event. if (HCI_EXT_ConnEventNoticeCmd(pMsg->connHandle, selfEntity, SBT_CONN_EVT_END_EVT) == SUCCESS) { // First free any pending response simpleTopology_freeAttRsp(FAILURE); // Hold on to the response message for retransmission pAttRsp = pMsg; // Don't free the response message yet return (FALSE); } } else if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT) { // ATT request-response or indication-confirmation flow control is // violated. All subsequent ATT requests or indications will be dropped. // The app is informed in case it wants to drop the connection. // Display the opcode of the message that caused the violation. LCD_WRITE_STRING_VALUE("FC Violated:", pMsg->msg.flowCtrlEvt.opcode, 10, LCD_PAGE6); } else if (pMsg->method == ATT_MTU_UPDATED_EVENT) { // MTU size updated LCD_WRITE_STRING_VALUE("MTU Size:", pMsg->msg.mtuEvt.MTU, 10, LCD_PAGE6); } //messages from GATT server if ((gapRoleNumLinks(GAPROLE_ACTIVE_LINKS) > 0)) { if ((pMsg->method == ATT_READ_RSP) || ((pMsg->method == ATT_ERROR_RSP) && (pMsg->msg.errorRsp.reqOpcode == ATT_READ_REQ))) { if (pMsg->method == ATT_ERROR_RSP) { LCD_WRITE_STRING_VALUE("Read Error", pMsg->msg.errorRsp.errCode, 10, LCD_PAGE6); } else { // After a successful read, display the read value LCD_WRITE_STRING_VALUE("Read rsp:", pMsg->msg.readRsp.pValue[0], 10, LCD_PAGE6); } } else if ((pMsg->method == ATT_WRITE_RSP) || ((pMsg->method == ATT_ERROR_RSP) && (pMsg->msg.errorRsp.reqOpcode == ATT_WRITE_REQ))) { if (pMsg->method == ATT_ERROR_RSP == ATT_ERROR_RSP) { LCD_WRITE_STRING_VALUE("Write Error", pMsg->msg.errorRsp.errCode, 10, LCD_PAGE6); } else { // After a succesful write, display the value that was written and // increment value LCD_WRITE_STRING_VALUE("Write sent:", charVal++, 10, LCD_PAGE6); } } else if (discState != BLE_DISC_STATE_IDLE) { simpleTopology_processGATTDiscEvent(pMsg); } } // else - in case a GATT message came after a connection has dropped, ignore it. // Free message payload. Needed only for ATT Protocol messages GATT_bm_free(&pMsg->msg, pMsg->method); // It's safe to free the incoming message return (TRUE); }