/********************************************************************* * @fn timeAppProcessGattMsg * * @brief Process GATT messages * * @return none */ static void thermometerProcessGattMsg( gattMsgEvent_t *pMsg ) { //Measurement Indication Confirmation if( pMsg->method ==ATT_HANDLE_VALUE_CFM) { thermometerSendStoredMeas(); } if ( pMsg->method == ATT_HANDLE_VALUE_NOTI || pMsg->method == ATT_HANDLE_VALUE_IND ) { timeAppIndGattMsg( pMsg ); } else if ( pMsg->method == ATT_READ_RSP || pMsg->method == ATT_WRITE_RSP ) { timeAppConfigState = timeAppConfigGattMsg ( timeAppConfigState, pMsg ); if ( timeAppConfigState == TIMEAPP_CONFIG_CMPL ) { timeAppDiscoveryCmpl = TRUE; } } else { timeAppDiscState = timeAppDiscGattMsg( timeAppDiscState, pMsg ); if ( timeAppDiscState == DISC_IDLE ) { // Start characteristic configuration timeAppConfigState = timeAppConfigNext( TIMEAPP_CONFIG_START ); } } }
/********************************************************************* * @fn timeAppProcessGattMsg * * @brief Process GATT messages * * @return none */ static void timeAppProcessGattMsg( gattMsgEvent_t *pMsg ) { if ( pMsg->method == ATT_HANDLE_VALUE_NOTI || pMsg->method == ATT_HANDLE_VALUE_IND ) { timeAppIndGattMsg( pMsg ); } else if ( ( pMsg->method == ATT_READ_RSP || pMsg->method == ATT_WRITE_RSP ) || ( pMsg->method == ATT_ERROR_RSP && ( pMsg->msg.errorRsp.reqOpcode == ATT_READ_REQ || pMsg->msg.errorRsp.reqOpcode == ATT_WRITE_REQ ) ) ) { timeAppConfigState = timeAppConfigGattMsg ( timeAppConfigState, pMsg ); if ( timeAppConfigState == TIMEAPP_CONFIG_CMPL ) { timeAppDiscoveryCmpl = TRUE; } } else { timeAppDiscState = timeAppDiscGattMsg( timeAppDiscState, pMsg ); if ( timeAppDiscState == DISC_IDLE ) { // Start characteristic configuration timeAppConfigState = timeAppConfigNext( TIMEAPP_CONFIG_START ); } } }
/********************************************************************* * @fn timeAppConfigGattMsg() * * @brief Handle GATT messages for characteristic configuration. * * @param state - Discovery state. * @param pMsg - GATT message. * * @return New configuration state. */ uint8 timeAppConfigGattMsg( uint8 state, gattMsgEvent_t *pMsg ) { if ( (pMsg->method == ATT_READ_RSP || pMsg->method == ATT_WRITE_RSP) && (pMsg->hdr.status == SUCCESS) ) { // Process response switch ( timeAppConfigList[state] ) { case HDL_CURR_TIME_CT_TIME_START: // Set clock to time read from time server timeAppClockSet( pMsg->msg.readRsp.value ); break; default: break; } } return timeAppConfigNext( state + 1 ); }
/********************************************************************* * @fn timeAppGapStateCB * * @brief Notification from the profile of a state change. * * @param newState - new state * * @return none */ static void timeAppGapStateCB( gaprole_States_t newState ) { // if connected if ( newState == GAPROLE_CONNECTED ) { linkDBItem_t *pItem; // Get connection handle GAPRole_GetParameter( GAPROLE_CONNHANDLE, &timeAppConnHandle ); // Get peer bd address if ( (pItem = linkDB_Find( timeAppConnHandle )) != NULL) { // If connected to device without bond do service discovery if ( !osal_memcmp( pItem->addr, timeAppBondedAddr, B_ADDR_LEN ) ) { timeAppDiscoveryCmpl = FALSE; } // Initiate service discovery if necessary if ( timeAppDiscoveryCmpl == FALSE ) { osal_start_timerEx( timeAppTaskId, START_DISCOVERY_EVT, DEFAULT_DISCOVERY_DELAY ); } // Perform configuration of characteristics on connection setup else { timeAppConfigState = timeAppConfigNext( TIMEAPP_CONFIG_CONN_START ); } } LCD_WRITE_STRING( "Connected", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( "", HAL_LCD_LINE_2 ); } // if disconnected else if ( timeAppGapState == GAPROLE_CONNECTED && newState != GAPROLE_CONNECTED ) { uint8 advState = TRUE; timeAppDisconnected(); if ( newState == GAPROLE_WAITING_AFTER_TIMEOUT ) { // link loss timeout-- use fast advertising GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_FAST_ADV_INTERVAL ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_FAST_ADV_INTERVAL ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_MIN, DEFAULT_FAST_ADV_DURATION ); } else { // Else use slow advertising GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_SLOW_ADV_INTERVAL ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_SLOW_ADV_INTERVAL ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_MIN, DEFAULT_SLOW_ADV_DURATION ); } // Enable advertising GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advState ); LCD_WRITE_STRING( "Disconnected", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( "", HAL_LCD_LINE_2 ); } // if advertising stopped else if ( timeAppGapState == GAPROLE_ADVERTISING && newState == GAPROLE_WAITING ) { // if advertising stopped by user if ( timeAppAdvCancelled ) { timeAppAdvCancelled = FALSE; } // if fast advertising switch to slow else if ( GAP_GetParamValue( TGAP_GEN_DISC_ADV_INT_MIN ) == DEFAULT_FAST_ADV_INTERVAL ) { uint8 advState = TRUE; GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MIN, DEFAULT_SLOW_ADV_INTERVAL ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_INT_MAX, DEFAULT_SLOW_ADV_INTERVAL ); GAP_SetParamValue( TGAP_GEN_DISC_ADV_MIN, DEFAULT_SLOW_ADV_DURATION ); GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advState ); } } // if started else if ( newState == GAPROLE_STARTED ) { #ifndef CC2540_MINIDK uint8 bdAddr[B_ADDR_LEN]; GAPRole_GetParameter( GAPROLE_BD_ADDR, &bdAddr ); LCD_WRITE_STRING( "Time App", HAL_LCD_LINE_1 ); LCD_WRITE_STRING( bdAddr2Str( bdAddr ), HAL_LCD_LINE_2 ); #endif // Initialize time clock after writing first two lines of LCD timeAppClockInit(); } timeAppGapState = newState; }
/********************************************************************* * @fn timeAppConfigGattMsg() * * @brief Handle GATT messages for characteristic configuration. * * @param state - Discovery state. * @param pMsg - GATT message. * * @return New configuration state. */ uint8 timeAppConfigGattMsg( uint8 state, gattMsgEvent_t *pMsg ) { if ( state > TIMEAPP_CONFIG_MAX ) { return TIMEAPP_CONFIG_CMPL; } if ( (pMsg->method == ATT_READ_RSP || pMsg->method == ATT_WRITE_RSP) && (pMsg->hdr.status == SUCCESS) ) { // Process response switch ( timeAppConfigList[state] ) { case HDL_CURR_TIME_CT_TIME_START: // Set clock to time read from time server timeAppClockSet( pMsg->msg.readRsp.value ); break; case HDL_CURR_TIME_LOC_INFO: break; case HDL_CURR_TIME_REF_INFO: break; case HDL_DST_CHG_TIME_DST: break; case HDL_NWA_NWA_START: // Display network availability state if ( pMsg->msg.readRsp.value[0] == 1 ) { LCD_WRITE_STRING( "Network: Yes", HAL_LCD_LINE_1 ); } else { LCD_WRITE_STRING( "Network: None", HAL_LCD_LINE_1 ); } break; case HDL_BATT_LEVEL_START: // Display battery level LCD_WRITE_STRING_VALUE( "Battery%", pMsg->msg.readRsp.value[0], 10, HAL_LCD_LINE_2 ); break; case HDL_CURR_TIME_CT_TIME_CCCD: break; case HDL_ALERT_NTF_NEW_CAT: break; case HDL_ALERT_NTF_UNREAD_CAT: break; case HDL_ALERT_NTF_UNREAD_CCCD: break; case HDL_ALERT_NTF_NEW_CCCD: break; case HDL_NWA_NWA_CCCD: break; case HDL_PAS_ALERT_START: // Display phone alert status LCD_WRITE_STRING_VALUE( "Phone Alert:", pMsg->msg.readRsp.value[0], 16, HAL_LCD_LINE_1 ); break; case HDL_PAS_RINGER_START: // Display ringer state if ( pMsg->msg.readRsp.value[0] == 0 ) { LCD_WRITE_STRING( "Ringer Off", HAL_LCD_LINE_2 ); } else { LCD_WRITE_STRING( "Ringer On", HAL_LCD_LINE_2 ); } break; default: break; } } return timeAppConfigNext( state + 1 ); }