Exemple #1
0
/*********************************************************************
 * @fn      performPeriodicTask
 *
 * @brief   Perform a periodic application task.
 *
 * @param   none
 *
 * @return  none
 */
static void performPeriodicTask( void )
{
    uint8 notify_interval;
    int32 n32;

    //Measurement Ready - send if Client Configuration is Configured
    if(temperatureMeasCharConfig == true)
    {
        //read stored interval value
        Thermometer_GetParameter( THERMOMETER_INTERVAL, &notify_interval );

        n32 = ((uint32)(notify_interval)) * (1000);

        //if interval is zero don't send indication
        if( n32 != 0)
        {
            // send thermometer measurement notification
            thermometerMeasIndicate();

            // Start interval timer
            osal_start_timerEx( thermometerTaskId, TH_PERIODIC_MEAS_EVT, n32 );
        }
    }
}
/*********************************************************************
 * @fn      thermometer_HandleKeys
 *
 * @brief   Handles all key events for this device.
 *
 * @param   shift - true if in shift/alt.
 * @param   keys - bit field for key events. Valid entries:
 *                 HAL_KEY_SW_2
 *                 HAL_KEY_SW_1
 *
 * @return  none
 */
static void thermometer_HandleKeys( uint8 shift, uint8 keys )
{

    bStatus_t status;
    uint8 notify_interval;

    if ( keys & HAL_KEY_SW_1 )
    {
        // set simulated measurement flag index
        thermometerFlagsIdx+=1;

        if (thermometerFlagsIdx == FLAGS_IDX_MAX)
        {
            thermometerFlagsIdx = 0;
        }
    }


    //read stored interval value
    Thermometer_GetParameter( THERMOMETER_INTERVAL, &notify_interval );

    if(notify_interval == 0)
    {
        thMeasTimerRunning = FALSE;
    }

    if ( keys & HAL_KEY_SW_2 )
    {
        // if device is not in a connection, pressing the right key should toggle
        // advertising on and off. If timer is running, then will adv when meas is ready
        if((gapProfileState != GAPROLE_CONNECTED) &&  (thMeasTimerRunning == FALSE))
        {
            uint8 current_adv_enabled_status;
            uint8 new_adv_enabled_status;

            //Find the current GAP advertisement status
            GAPRole_GetParameter( GAPROLE_ADVERT_ENABLED, &current_adv_enabled_status );

            if( current_adv_enabled_status == FALSE )
            {
                new_adv_enabled_status = TRUE;
            }
            else
            {
                new_adv_enabled_status = FALSE;
            }

            //change the GAP advertisement status to opposite of current status
            GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &new_adv_enabled_status );
        }
        else //timer is running, so allow simulated changes
        {
            //change temperature, remove single precision
            if((thermometerCelcius) < 0X000175)
            {
                thermometerCelcius +=1;
            }
            else
            {
                uint8 thInterval = 30;
                attHandleValueInd_t intervalIndication;

                thermometerCelcius = 0X000173;

                //Simulate interval change
                Thermometer_SetParameter( THERMOMETER_INTERVAL, THERMOMETER_INTERVAL_LEN, &thInterval );

                if(temperatureIntervalConfig == true)
                {
                    intervalIndication.value[0] = thInterval;
                    intervalIndication.handle = THERMOMETER_INTERVAL_VALUE_POS;

                    status = Thermometer_IntervalIndicate( gapConnHandle, &intervalIndication, thermometerTaskId );

                    // we can fail if there was pending meas or not connected
                    if (status != SUCCESS)
                    {
                        //queue indication
                        thermometerStoreIndications(&intervalIndication);
                    }
                }
            }
        }
    }
}
/*********************************************************************
 * @fn      Thermometer_ProcessEvent
 *
 * @brief   Thermometer Application Task event processor.  This function
 *          is called to process all events for the task.  Events
 *          include timers, messages and any other user defined events.
 *
 * @param   task_id  - The OSAL assigned task ID.
 * @param   events - events to process.  This is a bit map and can
 *                   contain more than one event.
 *
 * @return  events not processed
 */
uint16 Thermometer_ProcessEvent( uint8 task_id, uint16 events )
{

    VOID task_id; // OSAL required parameter that isn't used in this function
    uint8 notify_interval;
    int32 n32;

    if ( events & SYS_EVENT_MSG )
    {
        uint8 *pMsg;

        if ( (pMsg = osal_msg_receive( thermometerTaskId )) != NULL )
        {
            thermometer_ProcessOSALMsg( (osal_event_hdr_t *)pMsg );

            // Release the OSAL message
            VOID osal_msg_deallocate( pMsg );
        }

        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
    }

    if ( events & TH_START_DEVICE_EVT )
    {
        // Start the Device
        VOID GAPRole_StartDevice( &thermometer_PeripheralCBs );

        // Register with bond manager after starting device
        VOID GAPBondMgr_Register( &thermometer_BondMgrCBs );

        updateUI();

        return ( events ^ TH_START_DEVICE_EVT );
    }

    if ( events & TH_START_DISCOVERY_EVT )
    {
        if ( timeAppPairingStarted )
        {
            // Postpone discovery until pairing completes
            timeAppDiscPostponed = TRUE;
        }
        else
        {
            timeAppDiscState = timeAppDiscStart();
        }

        timeAppDiscState = timeAppDiscStart();

        return ( events ^ TH_START_DISCOVERY_EVT );
    }

    //periodic indications - if enabled
    if ( events & TH_PERIODIC_MEAS_EVT )
    {
        // Perform periodic application task
        performPeriodicTask();
        return (events ^ TH_PERIODIC_MEAS_EVT);
    }
    //periodic notifications for IMEAS
    if ( events & TH_PERIODIC_IMEAS_EVT )
    {
        // Perform periodic application task
        performPeriodicImeasTask();
        return (events ^ TH_PERIODIC_IMEAS_EVT);
    }

    // Disconnect after sending measurement
    if ( events & TH_DISCONNECT_EVT )
    {

        uint8 advEnable = FALSE;

        //disable advertising on disconnect
        GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &advEnable );

        // Terminate Connection
        GAPRole_TerminateConnection();

        return (events ^ TH_DISCONNECT_EVT);
    }

    if ( events & TH_CCC_UPDATE_EVT )

        //This event is triggered when CCC is enabled
        if (gapProfileState == GAPROLE_CONNECTED)
        {
            temperatureMeasCharConfig = true;

            //if previously connected and measurements are active send stored
            if( connectedToLastAddress == true)
            {
                //send stored measurements
                thermometerSendStoredMeas();
            }

            //Only start meas timer if it's not running
            if(thMeasTimerRunning == FALSE)
            {
                //read stored interval value
                Thermometer_GetParameter( THERMOMETER_INTERVAL, &notify_interval );
                n32 = ((uint32)(notify_interval)) * (1000);

                //zero interval means should not perform meas
                if (n32 !=0)
                {
                    // Start interval timer
                    osal_start_timerEx( thermometerTaskId, TH_PERIODIC_MEAS_EVT, n32 );
                    thMeasTimerRunning = TRUE;
                }
            }
            return (events ^ TH_CCC_UPDATE_EVT);
        }

    return 0;
}
Exemple #4
0
/*********************************************************************
 * @fn      thermometerMeasIndicate
 *
 * @brief   Prepare and send a thermometer measurement indication
 *
 * @return  none
 */
static void thermometerMeasIndicate(void)
{
    // Thermometer measurement value stored in this structure.
    attHandleValueInd_t thermometerMeas;

    thermometerMeas.pValue = GATT_bm_alloc(gapConnHandle,
                                           ATT_HANDLE_VALUE_IND,
                                           THERMOMETER_MEAS_LEN, NULL);
    if (thermometerMeas.pValue != NULL)
    {
        // att value notification structure
        uint8 *p = thermometerMeas.pValue;

        // temperature
        uint32 temperature;

        //flags
        uint8 flags = thermometerFlags[thermometerFlagsIdx];

        // flags 1 byte long
        *p++ = flags;

        if(flags & THERMOMETER_FLAGS_FARENHEIT)
        {
            temperature =  (thermometerCelcius *9/5) +320;
        }
        else
        {
            temperature = thermometerCelcius;
        }

        temperature = 0xFF000000 | temperature;

        //osal_buffer_uint32
        p = osal_buffer_uint32( p, temperature );

        //timestamp
        if (flags & THERMOMETER_FLAGS_TIMESTAMP)
        {
            UTCTimeStruct time;

            // Get time structure from OSAL
            osal_ConvertUTCTime( &time, osal_getClock() );

            *p++ = LO_UINT16(time.year);
            *p++ = HI_UINT16(time.year);
            *p++ = time.month;
            *p++ = time.day;
            *p++ = time.hour;
            *p++ = time.minutes;
            *p++ = time.seconds;
        }

        if(flags & THERMOMETER_FLAGS_TYPE)
        {
            uint8 site;
            Thermometer_GetParameter( THERMOMETER_TYPE, &site );
            *p++ =  site;
        }

        thermometerMeas.len = (uint8) (p - thermometerMeas.pValue);
        thermometerMeas.handle = THERMOMETER_TEMP_VALUE_POS;

        // Queue indication.
        thermometerStoreIndications( &thermometerMeas);

        //advertise measurement is ready
        thermometer_Advertise();
    }
}
Exemple #5
0
/*********************************************************************
 * @fn      thermometerMeasNotify
 *
 * @brief   Prepare and send a thermometer measurement notification
 *
 * @return  none
 */
static void thermometerImeasNotify(void)
{
    if (temperatureIMeasCharConfig == true)
    {
        attHandleValueNoti_t thermometerIMeas;

        thermometerIMeas.pValue = GATT_bm_alloc( gapConnHandle,
                                  ATT_HANDLE_VALUE_NOTI,
                                  THERMOMETER_IMEAS_LEN, NULL );
        if ( thermometerIMeas.pValue != NULL )
        {
            // att value notification structure
            uint8 *p = thermometerIMeas.pValue;

            // temperature
            uint32 temperature;

            //flags
            uint8 flags = thermometerFlags[thermometerFlagsIdx];

            // flags 1 byte long
            *p++ = flags;

            if(flags & THERMOMETER_FLAGS_FARENHEIT)
            {
                temperature =  (thermometerCelcius *9/5) +320;
            }
            else
            {
                temperature = thermometerCelcius;
            }

            temperature = 0xFF000000 | temperature;

            //osal_buffer_uint32
            p = osal_buffer_uint32( p, temperature );

            //timestamp
            if (flags & THERMOMETER_FLAGS_TIMESTAMP)
            {
                UTCTimeStruct time;

                // Get time structure from OSAL
                osal_ConvertUTCTime( &time, osal_getClock() );

                *p++ = LO_UINT16(time.year);
                *p++ = HI_UINT16(time.year);
                *p++ = time.month;
                *p++ = time.day;
                *p++ = time.hour;
                *p++ = time.minutes;
                *p++ = time.seconds;
            }

            if(flags & THERMOMETER_FLAGS_TYPE)
            {
                uint8 site;
                Thermometer_GetParameter( THERMOMETER_TYPE, &site );
                *p++ =  site;
            }

            thermometerIMeas.len = (uint8) (p - thermometerIMeas.pValue);

            if ( Thermometer_IMeasNotify( gapConnHandle, &thermometerIMeas) != SUCCESS )
            {
                GATT_bm_free( (gattMsg_t *)&thermometerIMeas, ATT_HANDLE_VALUE_NOTI );
            }
        }
    }
}
Exemple #6
0
/*********************************************************************
 * @fn      Thermometer_handleKeys
 *
 * @brief   Handles all key events for this device.
 *
 * @param   shift - true if in shift/alt.
 * @param   keys - bit field for key events.
 *
 * @return  none
 */
static void Thermometer_handleKeys(uint8_t shift, uint8_t keys)
{
  bStatus_t status; 
  uint8_t notify_interval;
  
  if (keys & KEY_UP)
  {
    // Set simulated measurement flag index.
    thermometerFlagsIdx+=1;
    
    if (thermometerFlagsIdx == FLAGS_IDX_MAX)
    {
      thermometerFlagsIdx = 0;
    }
  }
  
  // Read stored interval value.
  Thermometer_GetParameter(THERMOMETER_INTERVAL, &notify_interval); 

  if(notify_interval == 0)
  {
    thMeasTimerRunning = FALSE;
  }
  
  if (keys & KEY_RIGHT)
  {
    // If device is not in a connection, pressing the right key should toggle
    // advertising on and off. If timer is running, then will adv when meas is 
    // ready.
    if((gapProfileState != GAPROLE_CONNECTED) && (thMeasTimerRunning == FALSE))
    {
      uint8_t current_adv_enabled_status;
      uint8_t new_adv_enabled_status;
      
      // Find the current GAP advertisement status.
      GAPRole_GetParameter(GAPROLE_ADVERT_ENABLED, &current_adv_enabled_status);
      
      if(current_adv_enabled_status == FALSE)
      {
        new_adv_enabled_status = TRUE;
      }
      else
      {
        new_adv_enabled_status = FALSE;
      }
      
      // Change the GAP advertisement status to opposite of current status.
      GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                           &new_adv_enabled_status);   
    }
    // Timer is running, so allow simulated changes.
    else
    {
      // Change temperature, remove single precision.
      if((thermometerCelcius) < 0x000175)
      {
        thermometerCelcius += 1;
      }
      else
      {
        uint16_t thInterval = 30;
        
        thermometerCelcius = 0x000173;

        // Simulate interval change.
        Thermometer_SetParameter(THERMOMETER_INTERVAL, THERMOMETER_INTERVAL_LEN,
                                 &thInterval);
        
        if(temperatureIntervalConfig == true) 
        {
          attHandleValueInd_t intervalInd;
          
          intervalInd.pValue = GATT_bm_alloc(thermometer_connHandle, 
                                             ATT_HANDLE_VALUE_IND, 
                                             THERMOMETER_INTERVAL_LEN, NULL);
          if (intervalInd.pValue != NULL)
          {
            intervalInd.len = THERMOMETER_INTERVAL_LEN;
            intervalInd.pValue[0] = LO_UINT16(thInterval);
            intervalInd.pValue[1] = HI_UINT16(thInterval);
            intervalInd.handle = THERMOMETER_INTERVAL_VALUE_POS;
        
            status = Thermometer_IntervalIndicate(thermometer_connHandle, 
                                                  &intervalInd,
                                                  ICall_getEntityId());
            // We can fail if there was pending meas or not connected.
            if (status != SUCCESS)
            {
              // Queue indication.
              Thermometer_storeIndications(&intervalInd);
            }
          }
        }
      }
    }
  }
}