/*********************************************************************
 * @fn      Time_indGattMsg
 *
 * @brief   Handle indications and notifications. 
 *
 * @param   pMsg - GATT message.
 *
 * @return  none
 */
void Time_indGattMsg(gattMsgEvent_t *pMsg)
{
  uint8_t i;
  
  // Look up the handle in the handle cache
  for (i = 0; i < HDL_CACHE_LEN; i++)
  {
    if (pMsg->msg.handleValueNoti.handle == Time_handleCache[i])
    {
      break;
    }
  }

  // Perform processing for this handle 
  switch (i)
  {
    case HDL_CURR_TIME_CT_TIME_START:
      // Set clock to time read from time server
      Time_clockSet(pMsg->msg.handleValueNoti.pValue);
      break;
      
 
     default:
      break;
  }
  
  // Send confirm for indication
  if (pMsg->method == ATT_HANDLE_VALUE_IND)
  {
    ATT_HandleValueCfm(pMsg->connHandle);
  }
}
Example #2
0
/*********************************************************************
 * @fn      timeAppIndGattMsg
 *
 * @brief   Handle indications and notifications. 
 *
 * @param   pMsg - GATT message.
 *
 * @return  none
 */
void timeAppIndGattMsg( gattMsgEvent_t *pMsg )
{
  uint8 i;
  
  // Look up the handle in the handle cache
  for ( i = 0; i < HDL_CACHE_LEN; i++ )
  {
    if ( pMsg->msg.handleValueNoti.handle == timeAppHdlCache[i] )
    {
      break;
    }
  }

  // Perform processing for this handle 
  switch ( i )
  {
    case HDL_CURR_TIME_CT_TIME_START:
      // Set clock to time read from time server
      timeAppClockSet( pMsg->msg.handleValueNoti.pValue );
      break;
      
    case HDL_NWA_NWA_START:             
      // Display network availability state
      if ( pMsg->msg.handleValueInd.pValue[0] == 1 )
      {
        LCD_WRITE_STRING( "Network: Yes", HAL_LCD_LINE_1 );
      }
      else
      {
        LCD_WRITE_STRING( "Network: None", HAL_LCD_LINE_1 );
      }
      break;
      
    case HDL_ALERT_NTF_UNREAD_START:
      // Display unread message alert
      {
        uint8 *p = pMsg->msg.handleValueNoti.pValue;
        uint8 len = pMsg->msg.handleValueNoti.len;
        
        if ( p[0] <= ALERT_CAT_ID_MAX && len == 2 )
        {
          LCD_WRITE_STRING_VALUE( (char *) timeAppAlertCatStr[p[0]], p[1], 10, HAL_LCD_LINE_1 );
          LCD_WRITE_STRING( "", HAL_LCD_LINE_2 );
        }
      }
      break;
      
    case HDL_ALERT_NTF_NEW_START:
      // Display incoming message
      timeAppDisplayAlert( pMsg->msg.handleValueNoti.pValue,
                           pMsg->msg.handleValueNoti.len );
      break;

    case HDL_BATT_LEVEL_START:
      // Display battery level
      LCD_WRITE_STRING_VALUE( "Battery%", pMsg->msg.handleValueNoti.pValue[0], 10, HAL_LCD_LINE_2 );
      break;

    case HDL_PAS_ALERT_START:
      // Display phone alert status
      LCD_WRITE_STRING_VALUE( "Phone Alert:",  pMsg->msg.handleValueNoti.pValue[0], 16, HAL_LCD_LINE_1 );
      break;

    case HDL_PAS_RINGER_START:
      // Display ringer state
      if ( pMsg->msg.handleValueNoti.pValue[0] == 0 )
      {
        LCD_WRITE_STRING( "Ringer Off", HAL_LCD_LINE_2 );
      }
      else
      {
        LCD_WRITE_STRING( "Ringer On", HAL_LCD_LINE_2 );
      }    
      break;

    default:
      break;
  }
  
  // Send confirm for indication
  if ( pMsg->method == ATT_HANDLE_VALUE_IND )
  {
    ATT_HandleValueCfm( pMsg->connHandle );
  }
}
Example #3
0
static void hidappProcessGATTMsg( gattMsgEvent_t *pPkt )
{
  // Build the message first
  switch ( pPkt->method )
  {
    case ATT_HANDLE_VALUE_NOTI:
      // First try to send out pending HID report
      if ( reportRetries > 0 )
      {
        hidappSendInReport( &lastInReport );

        reportRetries = 0;
        osal_stop_timerEx( hidappTaskId, HIDAPP_EVT_REPORT_RETRY );
      }

      // Send incoming HID report
      if ( hidappSendInReport( &(pPkt->msg.handleValueNoti) ) == FALSE )
      {
        // Save report for retries later
        osal_memcpy( &lastInReport, &(pPkt->msg.handleValueNoti), sizeof( attHandleValueNoti_t ) );

        reportRetries = 1;
        osal_start_timerEx( hidappTaskId, HIDAPP_EVT_REPORT_RETRY, HIDAPP_INPUT_RETRY_TIMEOUT );
      }
      break;

    case ATT_FIND_BY_TYPE_VALUE_RSP:
      // Response from GATT_DiscPrimaryServiceByUUID
      // Service found, store handles
      if ( pPkt->msg.findByTypeValueRsp.numInfo > 0 )
      {
        serviceStartHandle = pPkt->msg.findByTypeValueRsp.handlesInfo[0].handle;
        serviceEndHandle   = pPkt->msg.findByTypeValueRsp.handlesInfo[0].grpEndHandle;
      }
      // If procedure complete
      else if ( pPkt->hdr.status == bleProcedureComplete )
      {
        if ( serviceStartHandle != 0 )
        {
          if ( serviceToDiscover == GATT_SERVICE_UUID )
          {
            // Begin the search for characteristic handle of the service
            readReq.startHandle = serviceStartHandle;
            readReq.endHandle = serviceEndHandle;
            readReqType.len = 2;
            readReqType.uuid[0] = LO_UINT16(SERVICE_CHANGED_UUID);
            readReqType.uuid[1] = HI_UINT16(SERVICE_CHANGED_UUID);
            readReq.type = readReqType;

            GATT_DiscCharsByUUID(connHandle, &readReq, hidappTaskId );
          }
          else if ( serviceToDiscover == HID_SERVICE_UUID )
          {
            // Discover all characteristics
            GATT_DiscAllChars( connHandle, serviceStartHandle, serviceEndHandle, hidappTaskId );
          }
        }
      }
      break;

    case ATT_READ_BY_TYPE_RSP:
      // Response from Discover all Characteristics.
      // Success indicates packet with characteristic discoveries.
      if ( pPkt->hdr.status == SUCCESS )
      {
        attReadByTypeRsp_t rsp = pPkt->msg.readByTypeRsp;
        uint8 idx = 0;

        if ( serviceToDiscover ==  GATT_SERVICE_UUID )
        {
          // We have discovered the GATT Service Characteristic handle
          uint8 low = LO_UINT16(pPkt->msg.readByTypeRsp.dataList[3]);
          uint8 high = HI_UINT16(pPkt->msg.readByTypeRsp.dataList[4]);
          serviceChangeHandle = BUILD_UINT16(low, high);
          // Break to skip next part, it doesn't apply here
          break;
        }

        // Search characteristics for those with notification permissions.
        while( idx < ((rsp.numPairs * rsp.len ) - 1))
        {
          // Check permissions of characteristic for notification permission
          if ( (rsp.dataList[idx+2] & GATT_PROP_NOTIFY ) )
          {
            uint16* pHandle = (mouseCharHandle == GATT_INVALID_HANDLE) ? &mouseCharHandle : &keyCharHandle ;

            if ( pHandle == &keyCharHandle && consumerCtrlCharHandle == GATT_INVALID_HANDLE )
            {
              pHandle = ( keyCharHandle == GATT_INVALID_HANDLE ) ? &keyCharHandle : &consumerCtrlCharHandle;
            }

            if ( *pHandle == GATT_INVALID_HANDLE )
            {
              *pHandle = BUILD_UINT16( rsp.dataList[idx+3], rsp.dataList[idx+4] );
            }
          }

          idx += rsp.len;
        }
      }
      // This indicates that there is no more characteristic data
      // to be discovered within the given handle range.
      else if ( pPkt->hdr.status == bleProcedureComplete )
      {
        if ( serviceToDiscover == GATT_SERVICE_UUID )
        {
          // Begin Service Discovery of HID Service
          serviceToDiscover = HID_SERVICE_UUID;
          hidappDiscoverService( connHandle, HID_SERVICE_UUID );
          // Break to skip next part, it doesn't apply yet.
          break;
        }

        if ( enableCCCDs == TRUE )
        {
          mouseCCCHandle = mouseCharHandle + 1;

          // Begin configuring the characteristics for notifications
          hidappEnableNotification( connHandle, mouseCCCHandle );
        }
        else
        {
          serviceDiscComplete = TRUE;
        }
      }
      break;

    case ATT_WRITE_RSP:
      if ( pPkt->hdr.status == SUCCESS && !serviceDiscComplete )
      {
        uint16 handle = ( keyCCCHandle == GATT_INVALID_HANDLE ) ?
                        ( keyCCCHandle = keyCharHandle + 1 ) :
                        ( consumerCtrlCCCHandle = consumerCtrlCharHandle + 1 );

        hidappEnableNotification( connHandle, handle );

        if ( consumerCtrlCCCHandle != GATT_INVALID_HANDLE)
        {
          serviceDiscComplete = TRUE;
        }
      }
      break;

    // Service Change indication
    case ATT_HANDLE_VALUE_IND:
      // Note: this logic assumes that the only indications that will be sent
      //       will come from that GATT Service Changed Characteristic
      if ( pPkt->hdr.status == SUCCESS )
      {
        serviceChange = CHANGE_OCCURED;

        // Acknowledge receipt of indication
        ATT_HandleValueCfm( pPkt->connHandle );

        // Handles in server have changed while devices are connected
        if ( ( gapBondMgrState == PAIRED_BONDED_STATE ) &&
            ( serviceChangeHandle == pPkt->msg.handleValueInd.handle ) )
        {
          // Begin Service Discovery of HID Service
          serviceToDiscover = HID_SERVICE_UUID;
          hidappDiscoverService( connHandle, HID_SERVICE_UUID );

          serviceChange = NO_CHANGE;
        }
      }
      break;

    default:
      // Unknown event
      break;
  }
}
Example #4
0
/*********************************************************************
 * @fn      timeAppIndGattMsg
 *
 * @brief   Handle indications and notifications. 
 *
 * @param   pMsg - GATT message.
 *
 * @return  none
 */
void timeAppIndGattMsg( gattMsgEvent_t *pMsg )
{
  uint8 i;
  
  // Look up the handle in the handle cache
  for ( i = 0; i < HDL_CACHE_LEN; i++ )
  {
    if ( pMsg->msg.handleValueNoti.handle == timeAppHdlCache[i] )
    {
      break;
    }
  }

  // Perform processing for this handle 
  switch ( i )
  {
    case HDL_CURR_TIME_CT_TIME_START:
      // Set clock to time read from time server
      timeAppClockSet( pMsg->msg.handleValueNoti.value );
      break;
      
    case HDL_NWA_NWA_START:             
      // Display network availability state
      if ( pMsg->msg.handleValueInd.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_ALERT_NTF_UNREAD_START:
      // Display unread message alerts
      {
        uint8 *p = pMsg->msg.handleValueNoti.value;
        uint8 len = pMsg->msg.handleValueNoti.len;
        uint8 line;
        
        for ( line = 1; line <= 2 && len >= 2; line++, len -= 2 )
        {
          if ( ALERT_MAJOR_CAT(p[0]) <= ALERT_CAT_ID_MAX )
          {
            LCD_WRITE_STRING_VALUE( (char *) timeAppAlertCatStr[ALERT_MAJOR_CAT(p[0])],
                                    p[1], 10, line );
          }
          p += 2;
        }
      }
      break;
      
    case HDL_ALERT_NTF_INCOM_START:
      // Display incoming message
      timeAppDisplayAlert( pMsg->msg.handleValueNoti.value,
                           pMsg->msg.handleValueNoti.len );
      break;

    case HDL_BATT_LEVEL_STATE_START:
      // Display battery level
      LCD_WRITE_STRING_VALUE( "Battery%", pMsg->msg.handleValueNoti.value[0], 10, HAL_LCD_LINE_2 );
      break;
        
     default:
      break;
  }
  
  // Send confirm for indication
  if ( pMsg->method == ATT_HANDLE_VALUE_IND )
  {
    ATT_HandleValueCfm( pMsg->connHandle );
  }
}
Example #5
0
/*********************************************************************
 * @fn      glucoseIndGattMsg
 *
 * @brief   Handle indications and notifications. 
 *
 * @param   pMsg - GATT message.
 *
 * @return  none
 */
void glucoseIndGattMsg( gattMsgEvent_t *pMsg )
{
  uint8 i;
  
  // Look up the handle in the handle cache
  for ( i = 0; i < HDL_CACHE_LEN; i++ )
  {
    if ( pMsg->msg.handleValueInd.handle == glucoseHdlCache[i] )
    {
      break;
    }
  }

  // Perform processing for this handle 
  switch ( i )
  {
    case HDL_GLUCOSE_START:     
      {
        uint8* p = pMsg->msg.handleValueNoti.value;

        // restart procedure timer
        if (glucCollWritePending == true)
        {
          osal_start_timerEx( glucCollTaskId, PROCEDURE_TIMEOUT_EVT, GLUCOSE_PROCEDURE_TIMEOUT );          
        }
        
        memset(&glucoseMeas, 0, sizeof(glucoseMeas));
        
        // Flags
        glucoseMeas.flags = *p++;
        
        // Sequence number
        glucoseMeas.seqNum = BUILD_UINT16(p[0], p[1]);
        LCD_WRITE_STRING_VALUE( "SeqNum:", glucoseMeas.seqNum, 10, HAL_LCD_LINE_1 );
        p += 2;
        
        // Base time
        memcpy(glucoseMeas.baseTime, p, 7);
        p += 7;
       
        // Time offset;
        if (glucoseMeas.flags & GLUCOSE_MEAS_FLAG_TIME_OFFSET)
        {
          glucoseMeas.timeOffset = BUILD_UINT16(p[0], p[1]);
          p += 2;
        }
        
        // Glucose concentration
        if(glucoseMeas.flags & GLUCOSE_MEAS_FLAG_CONCENTRATION)
        {
          glucoseMeas.concentration = BUILD_UINT16(p[0], p[1]);
          if(glucoseMeas.flags & GLUCOSE_MEAS_FLAG_UNITS)
            LCD_WRITE_STRING_VALUE( STR_MMOL_PER_L, glucoseMeas.concentration, 10, HAL_LCD_LINE_2 );
          else
            LCD_WRITE_STRING_VALUE( STR_MG_PER_DL, glucoseMeas.concentration, 10, HAL_LCD_LINE_2 );
          p += 2;
          
          // Type sample location
          glucoseMeas.typeSampleLocation = *p++;
        }
        
        // Sensor status annunciation
        if (glucoseMeas.flags & GLUCOSE_MEAS_FLAG_STATUS_ANNUNCIATION)
        {
          glucoseMeas.sensorStatus = BUILD_UINT16(p[0], p[1]);
          p += 2;
        }
      }
      break;
      
    case HDL_GLUCOSE_CONTEXT_START:  
      {
        uint8* p = pMsg->msg.handleValueNoti.value;

        // restart procedure timer
        if (glucCollWritePending == true)
        {
          osal_start_timerEx( glucCollTaskId, PROCEDURE_TIMEOUT_EVT, GLUCOSE_PROCEDURE_TIMEOUT );          
        }
        
        memset(&glucoseContext, 0, sizeof(glucoseContext));
        
        // Flags
        glucoseContext.flags = *p++;

        // Sequence number
        glucoseContext.seqNum = BUILD_UINT16(p[0], p[1]);
        p += 2;

        // Extended flags
        if(glucoseContext.flags & GLUCOSE_CONTEXT_FLAG_EXTENDED)
        {
          glucoseContext.extendedFlags = *p++;
        }
        
        // Carbohydrate
        if(glucoseContext.flags & GLUCOSE_CONTEXT_FLAG_CARBO)
        {
          // carbohydrate ID
          glucoseContext.carboId = *p++;
          
          // Carbohydrate
          glucoseContext.carboVal = BUILD_UINT16(p[0], p[1]);          
          p += 2;
        }
        
        // Meal
        if(glucoseContext.flags & GLUCOSE_CONTEXT_FLAG_MEAL)
        {
          glucoseContext.mealVal = *p++;
        }
        
        // Tester health
        if(glucoseContext.flags & GLUCOSE_CONTEXT_FLAG_TESTER_HEALTH)
        {
          glucoseContext.TesterHealthVal = *p++;
        }
        
        // Exercise
        if(glucoseContext.flags & GLUCOSE_CONTEXT_FLAG_EXERCISE)
        {
          // Duration
          glucoseContext.exerciseDuration = BUILD_UINT16(p[0], p[1]);              
          p += 2;
          
          // Intensity
          glucoseContext.exerciseIntensity = *p++;
        }
        
        // Medication
        if(glucoseContext.flags & GLUCOSE_CONTEXT_FLAG_MEDICATION)
        {
          // Medication ID
          glucoseContext.medId = *p++;

          // Medication
          glucoseContext.medVal = BUILD_UINT16(p[0], p[1]);  
          p += 2;
        }
        
        // HbA1c
        if(glucoseContext.flags & GLUCOSE_CONTEXT_FLAG_HbA1c)
        {
          glucoseContext.HbA1cVal = BUILD_UINT16(p[0], p[1]);             
          LCD_WRITE_STRING_VALUE( "HbA1c:",  glucoseContext.HbA1cVal, 10, HAL_LCD_LINE_3 );
          p += 2;
        }
        
      }
      break;
      
    case HDL_GLUCOSE_CTL_PNT_START:
      {
        uint8* pValue = pMsg->msg.handleValueInd.value;

        // stop procedure timer
        osal_stop_timerEx( glucCollTaskId, PROCEDURE_TIMEOUT_EVT );  
        
        if(pValue[0] == CTL_PNT_OP_NUM_RSP)
        {
          if(pMsg->msg.handleValueInd.len >= 3)
          {
            LCD_WRITE_STRING("Matching ",  HAL_LCD_LINE_1);
            LCD_WRITE_STRING( "Records:", HAL_LCD_LINE_2 );
            LCD_WRITE_STRING_VALUE("", BUILD_UINT16(pValue[2], pValue[3]), 10, HAL_LCD_LINE_3 );
          }
        }
        else if(pValue[0] == CTL_PNT_OP_REQ_RSP && glucCollClearPending)
        {
          glucCollClearPending = false;
          
          if(pMsg->msg.handleValueInd.len >= 3)
          {
            switch(pValue[3])
            {
            case CTL_PNT_RSP_SUCCESS:
              LCD_WRITE_STRING("Records",  HAL_LCD_LINE_1);
              LCD_WRITE_STRING("Cleared", HAL_LCD_LINE_2 );
              LCD_WRITE_STRING("", HAL_LCD_LINE_3 );
              break;
            case CTL_PNT_RSP_NO_RECORDS:
              LCD_WRITE_STRING("No Matching",  HAL_LCD_LINE_1);
              LCD_WRITE_STRING("Records", HAL_LCD_LINE_2 );
              LCD_WRITE_STRING("to Delete", HAL_LCD_LINE_3 );
              break;
            default:
              LCD_WRITE_STRING("Error:",  HAL_LCD_LINE_1);
              LCD_WRITE_STRING_VALUE("", pValue[3], 10, HAL_LCD_LINE_2 );  
              LCD_WRITE_STRING( "", HAL_LCD_LINE_3 );
              break;
            }
          }
        }
        else if(pValue[0] == CTL_PNT_OP_REQ_RSP)
        {
          if(pMsg->msg.handleValueInd.len >= 3)
          {
            switch(pValue[3])
            {
            case CTL_PNT_RSP_SUCCESS:
              break;
            case CTL_PNT_RSP_NO_RECORDS:
              LCD_WRITE_STRING("No Matching",  HAL_LCD_LINE_1);
              LCD_WRITE_STRING("Records", HAL_LCD_LINE_2 );
              LCD_WRITE_STRING("Found", HAL_LCD_LINE_3 );
              break;
            default:
              LCD_WRITE_STRING("Error:",  HAL_LCD_LINE_1);
              LCD_WRITE_STRING_VALUE("", pValue[3], 10, HAL_LCD_LINE_2 );  
              LCD_WRITE_STRING( "", HAL_LCD_LINE_3 );
              break;
            }
          }
        }
      }
      break;      
        
    default:
      break;
  }
  
  // Send confirm for indication
  if ( pMsg->method == ATT_HANDLE_VALUE_IND )
  {
    ATT_HandleValueCfm( pMsg->connHandle );
  }
  
}