Esempio n. 1
0
/*********************************************************************
 * @fn      gapCentralRole_ProcessGAPMsg
 *
 * @brief   Process an incoming task message from GAP.
 *
 * @param   pMsg - message to process
 *
 * @return  none
 */
static void gapCentralRole_ProcessGAPMsg( gapEventHdr_t *pMsg )
{
  switch ( pMsg->opcode )
  {
    case GAP_DEVICE_INIT_DONE_EVENT:
      {
        gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *) pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          // Save off the generated keys
          VOID osal_snv_write( BLE_NVID_IRK, KEYLEN, gapCentralRoleIRK );
          VOID osal_snv_write( BLE_NVID_CSRK, KEYLEN, gapCentralRoleSRK );

          // Save off the information
          VOID osal_memcpy( gapCentralRoleBdAddr, pPkt->devAddr, B_ADDR_LEN );
        }
      }
      break;

    case GAP_LINK_ESTABLISHED_EVENT:
      {
        gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *) pMsg;

        if (pPkt->hdr.status == SUCCESS)
        {
          // Notify the Bond Manager of the connection
          VOID GAPBondMgr_LinkEst( pPkt->devAddrType, pPkt->devAddr,
                                   pPkt->connectionHandle, GAP_PROFILE_CENTRAL );
        }
      }
      break;

    case GAP_LINK_TERMINATED_EVENT:
      {
        uint16 connHandle = ((gapTerminateLinkEvent_t *) pMsg)->connectionHandle;

        GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );

        // Cancel RSSI reads
        GAPCentralRole_CancelRssi( connHandle );
      }
      break;

    // temporary workaround
    case GAP_SLAVE_REQUESTED_SECURITY_EVENT:
      GAPBondMgr_ProcessGAPMsg( pMsg );
      break;

    default:
      break;
  }

  // Pass event to app
  if ( pGapCentralRoleCB && pGapCentralRoleCB->eventCB )
  {
    pGapCentralRoleCB->eventCB( (gapCentralRoleEvent_t *) pMsg );
  }
}
/*********************************************************************
 * @fn      gapRole_ProcessGAPMsg
 *
 * @brief   Process an incoming task message.
 *
 * @param   pMsg - message to process
 *
 * @return  none
 */
static void gapRole_ProcessGAPMsg( gapEventHdr_t *pMsg )
{
  uint8 notify = FALSE;   // State changed notify the app? (default no)

  switch ( pMsg->opcode )
  {
    case GAP_DEVICE_INIT_DONE_EVENT:
      {
        gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *)pMsg;
        bStatus_t stat = pPkt->hdr.status;

        if ( stat == SUCCESS )
        {
          // Save off the generated keys
          VOID osal_snv_write( BLE_NVID_IRK, KEYLEN, gapRole_IRK );
          VOID osal_snv_write( BLE_NVID_CSRK, KEYLEN, gapRole_SRK );
          
          // Save off the information
          VOID osal_memcpy( gapRole_bdAddr, pPkt->devAddr, B_ADDR_LEN );

          gapRole_state = GAPROLE_STARTED;

          // Update the advertising data
          stat = GAP_UpdateAdvertisingData( gapRole_TaskID,
                              TRUE, gapRole_AdvertDataLen, gapRole_AdvertData );
        }

        if ( stat != SUCCESS )
        {
          gapRole_state = GAPROLE_ERROR;
        }

        notify = TRUE;
      }
      break;

    case GAP_ADV_DATA_UPDATE_DONE_EVENT:
      {
        gapAdvDataUpdateEvent_t *pPkt = (gapAdvDataUpdateEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          if ( pPkt->adType )
          {
            // Setup the Response Data
            pPkt->hdr.status = GAP_UpdateAdvertisingData( gapRole_TaskID,
                              FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData );
          }
          else
          {
            // Start advertising
            VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
          }
        }

        if ( pPkt->hdr.status != SUCCESS )
        {
          // Set into Error state
          gapRole_state = GAPROLE_ERROR;
          notify = TRUE;
        }
      }
      break;

    case GAP_MAKE_DISCOVERABLE_DONE_EVENT:
    case GAP_END_DISCOVERABLE_DONE_EVENT:
      {
        gapMakeDiscoverableRspEvent_t *pPkt = (gapMakeDiscoverableRspEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          if ( pMsg->opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT )
          {
            if ( gapRole_state == GAPROLE_CONNECTED )
            {
              gapRole_state = GAPROLE_CONNECTED_ADV;
            }
            else
            {
              gapRole_state = GAPROLE_ADVERTISING;
            }
          }
          else // GAP_END_DISCOVERABLE_DONE_EVENT
          {
            
            if ( gapRole_AdvertOffTime != 0 )
            {
              if ( ( gapRole_AdvEnabled ) )
              {
                VOID osal_start_timerEx( gapRole_TaskID, START_ADVERTISING_EVT, gapRole_AdvertOffTime );
              }
            }
            else
            {            
              // Since gapRole_AdvertOffTime is set to 0, the device should not
              // automatically become discoverable again after a period of time.
              // Set enabler to FALSE; device will become discoverable again when
              // this value gets set to TRUE
              gapRole_AdvEnabled = FALSE;
            }

            // In the Advertising Off period
            gapRole_state = GAPROLE_WAITING;

          }
        }
        else
        {
          gapRole_state = GAPROLE_ERROR;
        }
        notify = TRUE;
      }
      break;

    case GAP_LINK_ESTABLISHED_EVENT:
      {
        gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          VOID osal_memcpy( gapRole_ConnectedDevAddr, pPkt->devAddr, B_ADDR_LEN );
          gapRole_ConnectionHandle = pPkt->connectionHandle;
          gapRole_state = GAPROLE_CONNECTED;

          if ( gapRole_RSSIReadRate )
          {
            // Start the RSSI Reads
            VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate );
          }

          // Check whether update parameter request is enabled, and check the connection parameters
          if ( ( gapRole_ParamUpdateEnable == TRUE ) &&
               ( (pPkt->connInterval < gapRole_MinConnInterval) ||
                 (pPkt->connInterval > gapRole_MaxConnInterval) ||
                 (pPkt->connLatency != gapRole_SlaveLatency)    ||
                 (pPkt->connTimeout != gapRole_TimeoutMultiplier) ))
          {
            gapRole_SendUpdateParam( pPkt->connInterval, pPkt->connLatency );
          }
          
          // Notify the Bond Manager to the connection
          VOID GAPBondMgr_LinkEst( pPkt->devAddrType, pPkt->devAddr, pPkt->connectionHandle, GAP_PROFILE_PERIPHERAL );  
        }
        else
        {
          gapRole_state = GAPROLE_ERROR;
        }
        notify = TRUE;
      }
      break;

    case GAP_LINK_TERMINATED_EVENT:
      {
        VOID GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
        osal_memset( gapRole_ConnectedDevAddr, 0, B_ADDR_LEN );
        
        if ( gapRole_state == GAPROLE_CONNECTED_ADV )
        {
          // End the non-connectable advertising
          GAP_EndDiscoverable( gapRole_TaskID );
          gapRole_state = GAPROLE_CONNECTED;
        }
        else
        {
          gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *)pMsg;
          if( pPkt->reason == LL_SUPERVISION_TIMEOUT_TERM )
          {
            gapRole_state = GAPROLE_WAITING_AFTER_TIMEOUT;
          }
          else
          {
            gapRole_state = GAPROLE_WAITING;
          }

          notify = TRUE;

          VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
        }

        gapRole_ConnectionHandle = INVALID_CONNHANDLE;
      }
      break;

    case GAP_LINK_PARAM_UPDATE_EVENT:
      {
        gapLinkUpdateEvent_t *pPkt = (gapLinkUpdateEvent_t *)pMsg;

        if ( (pPkt->hdr.status != SUCCESS)
            || (pPkt->connInterval < gapRole_MinConnInterval)
              || (pPkt->connInterval > gapRole_MaxConnInterval) )
        {
          // Ask to change the interval
          gapRole_SendUpdateParam( pPkt->connInterval, pPkt->connLatency );
        }
        else
        {
          // All is good stop Update Parameters timeout
          VOID osal_stop_timerEx( gapRole_TaskID, UPDATE_PARAMS_TIMEOUT_EVT );
        }
      }
      break;
      
    default:
      break;
  }

  if ( notify == TRUE )
  {
    // Notify the application
    if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )
    {
      pGapRoles_AppCGs->pfnStateChange( gapRole_state );
    }
  }
}
Esempio n. 3
0
/*********************************************************************
 * @fn      gapRole_ProcessGAPMsg
 *
 * @brief   Process an incoming task message.
 *
 * @param   pMsg - message to process
 *
 * @return  none
 */
static void gapRole_ProcessGAPMsg( gapEventHdr_t *pMsg )
{
  uint8 notify = FALSE;   // State changed notify the app? (default no)

  switch ( pMsg->opcode )
  {
    case GAP_DEVICE_INIT_DONE_EVENT:
      {
        gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *)pMsg;
        bStatus_t stat = pPkt->hdr.status;

        if ( stat == SUCCESS )
        {
          // Save off the generated keys
          VOID osal_snv_write( BLE_NVID_IRK, KEYLEN, gapRole_IRK );
          VOID osal_snv_write( BLE_NVID_CSRK, KEYLEN, gapRole_SRK );

          // Save off the information
          VOID osal_memcpy( gapRole_bdAddr, pPkt->devAddr, B_ADDR_LEN );

          gapRole_state = GAPROLE_STARTED;

          // Update the advertising data
          stat = GAP_UpdateAdvertisingData( gapRole_TaskID,
                              TRUE, gapRole_AdvertDataLen, gapRole_AdvertData );
        }

        if ( stat != SUCCESS )
        {
          gapRole_state = GAPROLE_ERROR;
        }

        notify = TRUE;
      }
      break;

    case GAP_ADV_DATA_UPDATE_DONE_EVENT:
      {
        gapAdvDataUpdateEvent_t *pPkt = (gapAdvDataUpdateEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          if ( pPkt->adType )
          {
            // Setup the Response Data
            pPkt->hdr.status = GAP_UpdateAdvertisingData( gapRole_TaskID,
                              FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData );
          }
          else
          {
            // Start advertising
            VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
          }
        }

        if ( pPkt->hdr.status != SUCCESS )
        {
          // Set into Error state
          gapRole_state = GAPROLE_ERROR;
          notify = TRUE;
        }
      }
      break;

    case GAP_MAKE_DISCOVERABLE_DONE_EVENT:
    case GAP_END_DISCOVERABLE_DONE_EVENT:
      {
        gapMakeDiscoverableRspEvent_t *pPkt = (gapMakeDiscoverableRspEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          if ( pMsg->opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT )
          {
            gapRole_state = GAPROLE_ADVERTISING;
          }
          else // GAP_END_DISCOVERABLE_DONE_EVENT
          {

            if ( gapRole_AdvertOffTime != 0 )
            {
              if ( ( gapRole_AdvEnabled ) )
              {
                VOID osal_start_timerEx( gapRole_TaskID, START_ADVERTISING_EVT, gapRole_AdvertOffTime );
              }
            }
            else
            {
              // Since gapRole_AdvertOffTime is set to 0, the device should not
              // automatically become discoverable again after a period of time.
              // Set enabler to FALSE; device will become discoverable again when
              // this value gets set to TRUE
              gapRole_AdvEnabled = FALSE;
            }

            // In the Advertising Off period
            gapRole_state = GAPROLE_WAITING;

          }
        }
        else
        {
          gapRole_state = GAPROLE_ERROR;
        }
        notify = TRUE;
      }
      break;

    case GAP_LINK_ESTABLISHED_EVENT:
      {
        gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          VOID osal_memcpy( gapRole_ConnectedDevAddr, pPkt->devAddr, B_ADDR_LEN );
          gapRole_ConnectionHandle = pPkt->connectionHandle;
          gapRole_state = GAPROLE_CONNECTED;

          if ( gapRole_RSSIReadRate )
          {
            // Start the RSSI Reads
            VOID osal_start_timerEx( gapRole_TaskID, RSSI_READ_EVT, gapRole_RSSIReadRate );
          }

          // Store connection information
          gapRole_ConnInterval = pPkt->connInterval;
          gapRole_ConnSlaveLatency = pPkt->connLatency;
          gapRole_ConnTimeout = pPkt->connTimeout;

          // Check whether update parameter request is enabled
          if ( gapRole_ParamUpdateEnable == TRUE )
          {
            // Get the minimum time upon connection establishment before the 
            // peripheral can start a connection update procedure.
            uint16 timeout = GAP_GetParamValue( TGAP_CONN_PAUSE_PERIPHERAL );
            
            osal_start_timerEx( gapRole_TaskID, START_CONN_UPDATE_EVT, timeout*1000 );
          }

          // Notify the Bond Manager to the connection
          VOID GAPBondMgr_LinkEst( pPkt->devAddrType, pPkt->devAddr, pPkt->connectionHandle, GAP_PROFILE_PERIPHERAL );
        }
        else if ( pPkt->hdr.status == bleGAPConnNotAcceptable )
        {
          // Set enabler to FALSE; device will become discoverable again when
          // this value gets set to TRUE
          gapRole_AdvEnabled = FALSE;

          // Go to WAITING state, and then start advertising
          gapRole_state = GAPROLE_WAITING;
        }
        else
        {
          gapRole_state = GAPROLE_ERROR;
        }
        notify = TRUE;
      }
      break;

    case GAP_LINK_TERMINATED_EVENT:
      {
        gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *)pMsg;

        GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );
        osal_memset( gapRole_ConnectedDevAddr, 0, B_ADDR_LEN );

        // Erase connection information
        gapRole_ConnInterval = 0;
        gapRole_ConnSlaveLatency = 0;
        gapRole_ConnTimeout = 0;

        // Cancel all connection parameter update timers (if any active)
        VOID osal_stop_timerEx( gapRole_TaskID, START_CONN_UPDATE_EVT );
        VOID osal_stop_timerEx( gapRole_TaskID, CONN_PARAM_TIMEOUT_EVT );
          
        // Go to WAITING state, and then start advertising
        if( pPkt->reason == LL_SUPERVISION_TIMEOUT_TERM )
        {
          gapRole_state = GAPROLE_WAITING_AFTER_TIMEOUT;
        }
        else
        {
          gapRole_state = GAPROLE_WAITING;
        }

        notify = TRUE;

        VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );

        gapRole_ConnectionHandle = INVALID_CONNHANDLE;
      }
      break;

    case GAP_LINK_PARAM_UPDATE_EVENT:
      {
        gapLinkUpdateEvent_t *pPkt = (gapLinkUpdateEvent_t *)pMsg;

        // Cancel connection param update timeout timer (if active)
        VOID osal_stop_timerEx( gapRole_TaskID, CONN_PARAM_TIMEOUT_EVT );
        
        if ( pPkt->hdr.status == SUCCESS )
        {
          // Store new connection parameters
          gapRole_ConnInterval = pPkt->connInterval;
          gapRole_ConnSlaveLatency = pPkt->connLatency;
          gapRole_ConnTimeout = pPkt->connTimeout;
          
          // Make sure there's no pending connection update procedure
          if ( osal_get_timeoutEx( gapRole_TaskID, START_CONN_UPDATE_EVT ) == 0 )
          {
            // Notify the application with the new connection parameters
            if ( pGapRoles_ParamUpdateCB != NULL )
            {
              (*pGapRoles_ParamUpdateCB)( gapRole_ConnInterval, 
                                          gapRole_ConnSlaveLatency, 
                                          gapRole_ConnTimeout );
            }
          }
        }
      }
      break;

    default:
      break;
  }

  if ( notify == TRUE )
  {
    // Notify the application with the new state change
    if ( pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange )
    {
      pGapRoles_AppCGs->pfnStateChange( gapRole_state );
    }
  }
}
Esempio n. 4
0
/*********************************************************************
 * @fn      gapRole_processGAPMsg
 *
 * @brief   Process an incoming task message.
 *
 * @param   pMsg - message to process
 *
 * @return  none
 */
static uint8_t gapRole_processGAPMsg(gapEventHdr_t *pMsg)
{
  uint8_t notify = FALSE;   // State changed notify the app? (default no)

  switch (pMsg->opcode)
  {
    case GAP_DEVICE_INIT_DONE_EVENT:
      {
        gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *)pMsg;
        bStatus_t stat = pPkt->hdr.status;

        if (stat == SUCCESS)
        {
          // Save off the generated keys
          VOID osal_snv_write(BLE_NVID_IRK, KEYLEN, gapRole_IRK);
          VOID osal_snv_write(BLE_NVID_CSRK, KEYLEN, gapRole_SRK);

          // Save off the information
          VOID memcpy(gapRole_bdAddr, pPkt->devAddr, B_ADDR_LEN);

          // Update the advertising data
          stat = GAP_UpdateAdvertisingData(selfEntity,
                              TRUE, gapRole_AdvertDataLen, gapRole_AdvertData);
        }

        if (stat != SUCCESS)
        {
          gapRole_abort();
        }

        notify = TRUE;
      }
      break;

    case GAP_ADV_DATA_UPDATE_DONE_EVENT:
      {
        gapAdvDataUpdateEvent_t *pPkt = (gapAdvDataUpdateEvent_t *)pMsg;

        if (pPkt->hdr.status == SUCCESS)
        {
          if (pPkt->adType)
          {
            // Setup the Response Data
            pPkt->hdr.status = GAP_UpdateAdvertisingData(selfEntity,
                              FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData);
          }
          else if (Util_isActive(&startAdvClock) == FALSE)
          {
            // Start advertising
            gapRole_setEvent(START_ADVERTISING_EVT);
          }
        }

        if (pPkt->hdr.status != SUCCESS)
        {
          // Set into Error state
          gapRole_abort();
          notify = TRUE;
        }
      }
      break;

    case GAP_MAKE_DISCOVERABLE_DONE_EVENT:
    case GAP_END_DISCOVERABLE_DONE_EVENT:
      {
        gapMakeDiscoverableRspEvent_t *pPkt = (gapMakeDiscoverableRspEvent_t *)pMsg;

        if (pPkt->hdr.status == SUCCESS)
        {
          if (pMsg->opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT)
          {
            gapRole_AdvEnabled = TRUE;
          }
          else // GAP_END_DISCOVERABLE_DONE_EVENT
          {
            if (gapRole_AdvertOffTime != 0) //restart advertising if param is set
            {
              if ((gapRole_AdvEnabled) || (gapRole_AdvNonConnEnabled))
              {
                Util_restartClock(&startAdvClock, gapRole_AdvertOffTime);
              }
            }
            else
            {
              // Since gapRole_AdvertOffTime is set to 0, the device should not
              // automatically become discoverable again after a period of time.
              // Set enabler to FALSE; device will become discoverable again when
              // this value gets set to TRUE
              if (gapRole_AdvEnabled == TRUE)
              {
                gapRole_AdvEnabled = FALSE;
              }
            }
          }
          notify = TRUE;
        }
        else if (pPkt->hdr.status == LL_STATUS_ERROR_COMMAND_DISALLOWED) //we're already advertising
        {
          notify = FALSE;
        }
        else
        {
          gapRole_abort();
        }
      }
      break;

    case GAP_LINK_ESTABLISHED_EVENT:
      {
        gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *)pMsg;
        uint8_t advertEnable = TRUE;

        if (pPkt->hdr.status == SUCCESS)
        {
          // Notify the Bond Manager to the connection
          VOID GAPBondMgr_LinkEst(pPkt->devAddrType, pPkt->devAddr,
                                  pPkt->connectionHandle, pPkt->connRole);    

          //advertising will stop after connection formed as slave
          if ((pPkt->connRole) == GAP_PROFILE_PERIPHERAL)
          {
            gapRole_AdvEnabled = FALSE;
            //reenable advertising
            GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
                                 &advertEnable, NULL);            
          }
        }
        else if (pPkt->hdr.status == bleGAPConnNotAcceptable)
        {
          // Set enabler to FALSE; device will become discoverable again when
          // this value gets set to TRUE
          gapRole_AdvEnabled = FALSE;
        }
        else
        {
          gapRole_abort();
        }
        
        notify = TRUE;
      }
      break;

    case GAP_LINK_TERMINATED_EVENT:
      {
        gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *)pMsg;

        linkDBInfo_t pInfo;
        linkDB_GetInfo(pPkt->connectionHandle, &pInfo);
        
        // notify bond manager
        GAPBondMgr_LinkTerm(pPkt->connectionHandle);

        notify = TRUE;
      }
      break;

    case GAP_SLAVE_REQUESTED_SECURITY_EVENT:
      {
        uint16_t connHandle = ((gapSlaveSecurityReqEvent_t *)pMsg)->connectionHandle;
        uint8_t authReq = ((gapSlaveSecurityReqEvent_t *)pMsg)->authReq;
        
        GAPBondMgr_SlaveReqSecurity(connHandle, authReq);
      }
      break;     
      
    case GAP_LINK_PARAM_UPDATE_EVENT:
      {
        gapLinkUpdateEvent_t *pPkt = (gapLinkUpdateEvent_t *)pMsg;
        
        // Cancel connection param update timeout timer (if active)
        Util_stopClock(&updateTimeoutClock);
        
        if (pPkt->hdr.status == SUCCESS)
        {
          notify = TRUE;
        }
      }
      break;
      
    default:
      notify = TRUE;
      break;
  }

  if (notify == TRUE) //app needs to take further action
  {
    if (pGapRoles_AppCGs && pGapRoles_AppCGs->pfnPassThrough)
    {
      return (pGapRoles_AppCGs->pfnPassThrough((gapMultiRoleEvent_t *)pMsg));
    }
  }
  
  return TRUE;
    
}
/*********************************************************************
 * @fn      gapRole_processGAPMsg
 *
 * @brief   Process an incoming task message.
 *
 * @param   pMsg - message to process
 *
 * @return  none
 */
static uint8_t gapRole_processGAPMsg(gapEventHdr_t *pMsg) {
	uint8_t notify = FALSE;   // State changed notify the app? (default no)

	switch (pMsg->opcode) {
	case GAP_DEVICE_INIT_DONE_EVENT: {
		gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *) pMsg;
		bStatus_t stat = pPkt->hdr.status;

		if (stat == SUCCESS) {
			// Save off the generated keys
			VOID osal_snv_write(BLE_NVID_IRK, KEYLEN, gapRole_IRK);
			VOID osal_snv_write(BLE_NVID_CSRK, KEYLEN, gapRole_SRK);

			// Save off the information
			VOID memcpy(gapRole_bdAddr, pPkt->devAddr, B_ADDR_LEN);

			gapRole_peripheralState = GAPROLE_STARTED;
			gapRole_peripheralStateChangeHandler(gapRole_peripheralState);

			// Update the advertising data
			stat = GAP_UpdateAdvertisingData(selfEntity,
			TRUE, gapRole_AdvertDataLen, gapRole_AdvertData);
		}

		if (stat != SUCCESS) {
			gapRole_peripheralState = GAPROLE_ERROR;
			gapRole_peripheralStateChangeHandler(gapRole_peripheralState);
			//gapRole_abort();
		}

		notify = TRUE;
	}
		break;

	case GAP_ADV_DATA_UPDATE_DONE_EVENT: {
		gapAdvDataUpdateEvent_t *pPkt = (gapAdvDataUpdateEvent_t *) pMsg;

        if (pPkt->hdr.status == SUCCESS)
        {
          if (pPkt->adType)
          {
            // Setup the Response Data
            pPkt->hdr.status = GAP_UpdateAdvertisingData(selfEntity,
                              FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData);
          }
          else if ((gapRole_peripheralState != GAPROLE_ADVERTISING)   &&
                   (gapRole_peripheralState != GAPROLE_CONNECTED_ADV) &&
                   (gapRole_peripheralState != GAPROLE_CONNECTED ||
                    gapRole_AdvNonConnEnabled == TRUE)      &&
                   (Util_isActive(&startAdvClock) == FALSE))
          {
            // Start advertising
            gapRole_setEvent(START_ADVERTISING_EVT);
          }
          notify = FALSE;
        }else {
			// Set into Error state
			gapRole_peripheralState = GAPROLE_ERROR;
			gapRole_peripheralStateChangeHandler(gapRole_peripheralState);
			//gapRole_abort();
			notify = TRUE;
		}
	}
		break;

	case GAP_MAKE_DISCOVERABLE_DONE_EVENT:
	case GAP_END_DISCOVERABLE_DONE_EVENT: {
		gapMakeDiscoverableRspEvent_t *pPkt = (gapMakeDiscoverableRspEvent_t *) pMsg;

		if (pPkt->hdr.status == SUCCESS) {
			if (pMsg->opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT) {
				if (gapRole_peripheralState == GAPROLE_CONNECTED) {
					gapRole_peripheralState = GAPROLE_CONNECTED_ADV;
					gapRole_peripheralStateChangeHandler(gapRole_peripheralState);
				} else if (gapRole_AdvEnabled) {
					gapRole_peripheralState = GAPROLE_ADVERTISING;
					gapRole_peripheralStateChangeHandler(gapRole_peripheralState);
				} else {
					gapRole_peripheralState = GAPROLE_ADVERTISING_NONCONN;
					gapRole_peripheralStateChangeHandler(gapRole_peripheralState);
				}
			} else // GAP_END_DISCOVERABLE_DONE_EVENT
			{
				if (gapRole_AdvertOffTime != 0) //restart advertising if param is set
						{
					if ((gapRole_AdvEnabled) || (gapRole_AdvNonConnEnabled)) {
						Util_restartClock(&startAdvClock, gapRole_AdvertOffTime);
					}
				} else {
					// Since gapRole_AdvertOffTime is set to 0, the device should not
					// automatically become discoverable again after a period of time.
					// Set enabler to FALSE; device will become discoverable again when
					// this value gets set to TRUE
					if (gapRole_AdvEnabled == TRUE) {
						gapRole_AdvEnabled = FALSE;
					} else {
						gapRole_AdvNonConnEnabled = FALSE;
					}
				}

				// Update state.
				if (gapRole_peripheralState == GAPROLE_CONNECTED_ADV) {
					// In the Advertising Off period
					gapRole_peripheralState = GAPROLE_CONNECTED;
					gapRole_peripheralStateChangeHandler(gapRole_peripheralState);
				} else {
					// In the Advertising Off period
					gapRole_peripheralState = GAPROLE_WAITING;
					gapRole_peripheralStateChangeHandler(gapRole_peripheralState);
				}
			}
			notify = TRUE;
		} else if (pPkt->hdr.status == LL_STATUS_ERROR_COMMAND_DISALLOWED) //we're already advertising
		{
			notify = FALSE;
		} else {
			gapRole_peripheralState = GAPROLE_ERROR;
			gapRole_peripheralStateChangeHandler(gapRole_peripheralState);
			//gapRole_abort();
		}
	}
		break;

	case GAP_LINK_ESTABLISHED_EVENT: {
		gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *) pMsg;

		if (pPkt->hdr.status == SUCCESS) {
			//add to database
			gapRoleInfo_Add(pPkt);

			// advertising will stop when a connection forms in the peripheral role
			if (pPkt->connRole == GAP_PROFILE_PERIPHERAL) {

				gapRole_peripheralState = GAPROLE_CONNECTED;
				gapRole_peripheralStateChangeHandler(gapRole_peripheralState);

				// Check whether update parameter request is enabled
				if (gapRole_ParamUpdateEnable == TRUE) {
						// Get the minimum time upon connection establishment before the
						// peripheral can start a connection update procedure.
						uint16_t timeout = GAP_GetParamValue(
						TGAP_CONN_PAUSE_PERIPHERAL);

						Util_restartClock(&startUpdateClock, timeout * 1000);

				}
			}
			// Notify the Bond Manager to the connection
			VOID GAPBondMgr_LinkEst(pPkt->devAddrType, pPkt->devAddr, pPkt->connectionHandle, pPkt->connRole);
		} else if (pPkt->hdr.status == bleGAPConnNotAcceptable) {
			// Set enabler to FALSE; device will become discoverable again when
			// this value gets set to TRUE
			gapRole_AdvEnabled = FALSE;

	        // Go to WAITING state, and then start advertising
			if (pPkt->connRole == GAP_PROFILE_PERIPHERAL) {
				gapRole_peripheralState = GAPROLE_WAITING;
				gapRole_peripheralStateChangeHandler(gapRole_peripheralState);
			}
		} else {
			if (pPkt->connRole == GAP_PROFILE_PERIPHERAL) {
				gapRole_peripheralState = GAPROLE_ERROR;
				gapRole_peripheralStateChangeHandler(gapRole_peripheralState);
			} else {
				gapRole_abort();
			}
		}
		notify = TRUE;
	}
		break;

	case GAP_LINK_TERMINATED_EVENT: {
		gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *) pMsg;

		// notify bond manager
		GAPBondMgr_LinkTerm(pPkt->connectionHandle);

		// Erase connection information (maybe make this a function)
		uint8 connHandleIndex = gapRoleInfo_Find(pPkt->connectionHandle);
		multiConnInfo[connHandleIndex].gapRole_ConnectionHandle = INVALID_CONNHANDLE;
		multiConnInfo[connHandleIndex].gapRole_ConnInterval = 0;
		multiConnInfo[connHandleIndex].gapRole_ConnSlaveLatency = 0;
		multiConnInfo[connHandleIndex].gapRole_ConnTimeout = 0;

		// Cancel all connection parameter update timers (if any active)
		Util_stopClock(&startUpdateClock);
		Util_stopClock(&updateTimeoutClock);

		notify = TRUE;

		if (multiConnInfo[connHandleIndex].gapRole_ConnRole == GAP_PROFILE_PERIPHERAL) {
			// If device was advertising when connection dropped
			if (gapRole_AdvNonConnEnabled) {
				// Continue advertising.
				gapRole_peripheralState = GAPROLE_ADVERTISING_NONCONN;
				gapRole_peripheralStateChangeHandler(gapRole_peripheralState);
			}
			// Else go to WAITING state.
			else {
				if (pPkt->reason == LL_SUPERVISION_TIMEOUT_TERM) {
					gapRole_peripheralState = GAPROLE_WAITING_AFTER_TIMEOUT;
					gapRole_peripheralStateChangeHandler(gapRole_peripheralState);
				} else {
					gapRole_peripheralState = GAPROLE_WAITING;
					gapRole_peripheralStateChangeHandler(gapRole_peripheralState);
				}

				// Start advertising, if enabled.
				gapRole_setEvent(START_ADVERTISING_EVT);
			}
		}
	}
		break;

	case GAP_LINK_PARAM_UPDATE_EVENT: {
		gapLinkUpdateEvent_t *pPkt = (gapLinkUpdateEvent_t *) pMsg;

		// Cancel connection param update timeout timer (if active)
		Util_stopClock(&updateTimeoutClock);

		if (pPkt->hdr.status == SUCCESS) {
			// Store new connection parameters
//              gapRole_ConnInterval = pPkt->connInterval;
//              gapRole_ConnSlaveLatency = pPkt->connLatency;
//              gapRole_ConnTimeout = pPkt->connTimeout;

			// Make sure there's no pending connection update procedure
			if (Util_isActive(&startUpdateClock) == FALSE) {
//                // Notify the application with the new connection parameters
//                if (pGapRoles_ParamUpdateCB != NULL)
//                {
//                  (*pGapRoles_ParamUpdateCB)(gapRole_ConnInterval,
//                                             gapRole_ConnSlaveLatency,
//                                             gapRole_ConnTimeout);
//                }
			}
		}
		notify = TRUE;
	}
		break;

	case GAP_PAIRING_REQ_EVENT: {
		gapPairingReqEvent_t *pPkt = (gapPairingReqEvent_t *) pMsg;

		// Send Pairing Failed Response
		VOID GAP_TerminateAuth(pPkt->connectionHandle,
		SMP_PAIRING_FAILED_NOT_SUPPORTED);
	}
		break;

	case GAP_SLAVE_REQUESTED_SECURITY_EVENT: {
        uint16_t connHandle = ((gapSlaveSecurityReqEvent_t *)pMsg)->connectionHandle;
        uint8_t authReq = ((gapSlaveSecurityReqEvent_t *)pMsg)->authReq;

        GAPBondMgr_SlaveReqSecurity(connHandle, authReq);
	}
		break;

	case GAP_DEVICE_INFO_EVENT:
	case GAP_DEVICE_DISCOVERY_EVENT:
		notify = TRUE;
		break;

	default:
		notify = FALSE;
		break;
	}

	if (notify == TRUE) //app needs to take further action
	{
		if (pGapRoles_AppCGs && pGapRoles_AppCGs->pfnPassThrough) {
			return (pGapRoles_AppCGs->pfnPassThrough((gapMultiRoleEvent_t *) pMsg));
		}
	}

	return TRUE;

}
/*********************************************************************
 * @fn      gapCentralRole_ProcessGAPMsg
 *
 * @brief   Process an incoming task message from GAP.
 *
 * @param   pMsg - message to process
 *
 * @return  none
 */
static void gapCentralRole_ProcessGAPMsg( gapEventHdr_t *pMsg )
{
  
  uint8 isBroadcastMsg = FALSE;
  
  switch ( pMsg->opcode )
  {
    case GAP_DEVICE_INIT_DONE_EVENT:
      {
        gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *) pMsg;
        bStatus_t stat = pPkt->hdr.status;
        
        if ( pPkt->hdr.status == SUCCESS )
        {
          // Save off the generated keys
          VOID osal_snv_write( BLE_NVID_IRK, KEYLEN, gapCentralRoleIRK );
          VOID osal_snv_write( BLE_NVID_CSRK, KEYLEN, gapCentralRoleSRK );

          // Save off the information
          VOID osal_memcpy( gapCentralRoleBdAddr, pPkt->devAddr, B_ADDR_LEN );
          
         ///////////////////////////////////////////////////////////////////////
         // Broadcast

          // Save off the information
          VOID osal_memcpy( gapRole_bdAddr, pPkt->devAddr, B_ADDR_LEN );

          gapRole_state = GAPROLE_STARTED;

          // Update the advertising data
          stat =GAP_UpdateAdvertisingData( gapRole_TaskID, TRUE,
                                            gapRole_AdvertDataLen,
                                            gapRole_AdvertData );
        }
        
        if ( stat != SUCCESS )
        {
          gapRole_state = GAPROLE_ERROR;
        }
        
        isBroadcastMsg = TRUE;        
      }
      break;

    case GAP_LINK_ESTABLISHED_EVENT:
      {
        gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *) pMsg;

        if (pPkt->hdr.status == SUCCESS)
        {
          // Notify the Bond Manager of the connection
          VOID GAPBondMgr_LinkEst( pPkt->devAddrType, pPkt->devAddr,
                                   pPkt->connectionHandle, GAP_PROFILE_CENTRAL );
        }
      }
      break;

    case GAP_LINK_TERMINATED_EVENT:
      {
        uint16 connHandle = ((gapTerminateLinkEvent_t *) pMsg)->connectionHandle;

        GAPBondMgr_ProcessGAPMsg( (gapEventHdr_t *)pMsg );

        // Cancel RSSI reads
        GAPCentralRole_CancelRssi( connHandle );
      }
      break;

    // temporary workaround
    case GAP_SLAVE_REQUESTED_SECURITY_EVENT:
      GAPBondMgr_ProcessGAPMsg( pMsg );
      break;

    case GAP_ADV_DATA_UPDATE_DONE_EVENT:
      {
        gapAdvDataUpdateEvent_t *pPkt = (gapAdvDataUpdateEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          if ( pPkt->adType )
          {
            // Setup the Response Data
            pPkt->hdr.status = GAP_UpdateAdvertisingData( gapRole_TaskID,
                              FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData );
          }
          else
          {
            // Start advertising
            VOID osal_set_event( gapRole_TaskID, START_ADVERTISING_EVT );
          }
        }

        if ( pPkt->hdr.status != SUCCESS )
        {
          // Set into Error state
          gapRole_state = GAPROLE_ERROR;
          isBroadcastMsg = TRUE;
        }
      }
      break;

    case GAP_MAKE_DISCOVERABLE_DONE_EVENT:
    case GAP_END_DISCOVERABLE_DONE_EVENT:
      {
        gapMakeDiscoverableRspEvent_t *pPkt = (gapMakeDiscoverableRspEvent_t *)pMsg;

        if ( pPkt->hdr.status == SUCCESS )
        {
          if ( pMsg->opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT )
          {
            gapRole_state = GAPROLE_ADVERTISING;
          }
          else // GAP_END_DISCOVERABLE_DONE_EVENT
          {

            if ( gapRole_AdvertOffTime != 0 )
            {
              if ( ( gapRole_AdvEnabled ) )
              {
                VOID osal_start_timerEx( gapRole_TaskID, START_ADVERTISING_EVT, gapRole_AdvertOffTime );
              }
            }
            else
            {
              // Since gapRole_AdvertOffTime is set to 0, the device should not
              // automatically become discoverable again after a period of time.
              // Set enabler to FALSE; device will become discoverable again when
              // this value gets set to TRUE
              gapRole_AdvEnabled = FALSE;
            }

            // In the Advertising Off period
            gapRole_state = GAPROLE_WAITING;

          }
        }
        else
        {
          gapRole_state = GAPROLE_ERROR;
        }
        isBroadcastMsg = TRUE;
      }
      break;
      
    default:
      break;
  }
  
  // If a broadcast event, pass to broadcast callback.
  if ( isBroadcastMsg == TRUE )
  {
    // Notify the application
    if ( pGapCentralRoleCB && pGapCentralRoleCB->broadcastCB )
    {
      pGapCentralRoleCB->broadcastCB( gapRole_state );
    }
  }
  // Otherwise pass to central callback
  else if ( pGapCentralRoleCB && pGapCentralRoleCB->centralCB )
  {
    pGapCentralRoleCB->centralCB( (gapCentralRoleEvent_t *) pMsg );
  }
  
}
/*********************************************************************
 * @fn      gapRole_processGAPMsg
 *
 * @brief   Process an incoming task message.
 *
 * @param   pMsg - message to process
 *
 * @return  none
 */
static uint8 gapRole_processGAPMsg(gapEventHdr_t *pMsg)
{
  uint8_t stateChangeNotify = FALSE;   // State changed stateChangeNotify the app? (default no)
  uint8_t gapEvtNotify = FALSE;
  switch (pMsg->opcode)
  {
    case GAP_DEVICE_INIT_DONE_EVENT:
      {
        gapDeviceInitDoneEvent_t *pPkt = (gapDeviceInitDoneEvent_t *)pMsg;
        bStatus_t stat = pPkt->hdr.status;

        if (stat == SUCCESS)
        {
          // Save off the generated keys
          VOID osal_snv_write(BLE_NVID_IRK, KEYLEN, gapRole_IRK);
          VOID osal_snv_write(BLE_NVID_CSRK, KEYLEN, gapRole_SRK);

          // Save off the information
          VOID memcpy(gapRole_bdAddr, pPkt->devAddr, B_ADDR_LEN);

          gapRole_state = GAPROLE_STARTED;

          // Update the advertising data
          stat = GAP_UpdateAdvertisingData(selfEntity,
                              TRUE, gapRole_AdvertDataLen, gapRole_AdvertData);
        }

        if (stat != SUCCESS)
        {
          gapRole_state = GAPROLE_ERROR;
        }

        stateChangeNotify = TRUE;
        gapEvtNotify = TRUE;
      }
      break;

    case GAP_ADV_DATA_UPDATE_DONE_EVENT:
      {
        gapAdvDataUpdateEvent_t *pPkt = (gapAdvDataUpdateEvent_t *)pMsg;

        if (pPkt->hdr.status == SUCCESS)
        {
          if (pPkt->adType)
          {
            // Setup the Response Data
            pPkt->hdr.status = GAP_UpdateAdvertisingData(selfEntity,
                              FALSE, gapRole_ScanRspDataLen, gapRole_ScanRspData);
          }
          else if ((gapRole_state != GAPROLE_ADVERTISING)   &&
                   (gapRole_state != GAPROLE_CONNECTED_ADV) &&
                   (gapRole_state != GAPROLE_CONNECTED || 
                    gapRole_AdvNonConnEnabled == TRUE)      &&
                   (Util_isActive(&startAdvClock) == FALSE))
          {
            // Start advertising
            gapRole_setEvent(START_ADVERTISING_EVT);
          }
        }

        if (pPkt->hdr.status != SUCCESS)
        {
          // Set into Error state
          gapRole_state = GAPROLE_ERROR;
          stateChangeNotify = TRUE;
        }
      }
      break;

    case GAP_MAKE_DISCOVERABLE_DONE_EVENT:
    case GAP_END_DISCOVERABLE_DONE_EVENT:
      {
        gapMakeDiscoverableRspEvent_t *pPkt = (gapMakeDiscoverableRspEvent_t *)pMsg;

        if (pPkt->hdr.status == SUCCESS)
        {
          if (pMsg->opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT)
          {
            if (gapRole_state == GAPROLE_CONNECTED)
            {
              gapRole_state = GAPROLE_CONNECTED_ADV;
            }
            else if (gapRole_AdvEnabled)
            {
              gapRole_state = GAPROLE_ADVERTISING;
            }
            else
            {
              gapRole_state = GAPROLE_ADVERTISING_NONCONN;
            }
          }
          else // GAP_END_DISCOVERABLE_DONE_EVENT
          {
            if (gapRole_AdvertOffTime != 0)
            {
              if ((gapRole_AdvEnabled) || (gapRole_AdvNonConnEnabled))
              {
                Util_restartClock(&startAdvClock, gapRole_AdvertOffTime);
              }
            }
            else
            {
              // Since gapRole_AdvertOffTime is set to 0, the device should not
              // automatically become discoverable again after a period of time.
              // Set enabler to FALSE; device will become discoverable again when
              // this value gets set to TRUE
              if (gapRole_AdvEnabled == TRUE)
              {
                gapRole_AdvEnabled = FALSE;
              }
              else
              {
                gapRole_AdvNonConnEnabled = FALSE;
              }
            }
            
            // Update state.
            if (gapRole_state == GAPROLE_CONNECTED_ADV)
            {
              // In the Advertising Off period
              gapRole_state = GAPROLE_CONNECTED;
            }
            else
            {
              // In the Advertising Off period
              gapRole_state = GAPROLE_WAITING;
            }
          }
        }
        else
        {
          gapRole_state = GAPROLE_ERROR;
        }
        
        stateChangeNotify = TRUE;
        gapEvtNotify = FALSE;
      }
      break;

    case GAP_LINK_ESTABLISHED_EVENT:
      {
        gapEstLinkReqEvent_t *pPkt = (gapEstLinkReqEvent_t *)pMsg;

        if (pPkt->hdr.status == SUCCESS)
        {
          VOID memcpy(gapRole_ConnectedDevAddr, pPkt->devAddr, B_ADDR_LEN);
          gapRole_ConnectionHandle = pPkt->connectionHandle;
          gapRole_state = GAPROLE_CONNECTED;

          // Store connection information
          gapRole_ConnInterval = pPkt->connInterval;
          gapRole_ConnSlaveLatency = pPkt->connLatency;
          gapRole_ConnTimeout = pPkt->connTimeout;
          gapRole_ConnectedDevAddrType = pPkt->devAddrType;

          // Check whether update parameter request is enabled
          if (gapRole_ParamUpdateEnable == TRUE)
          {
            // Get the minimum time upon connection establishment before the 
            // peripheral can start a connection update procedure.
            uint16_t timeout = GAP_GetParamValue(TGAP_CONN_PAUSE_PERIPHERAL);
            
            Util_restartClock(&startUpdateClock, timeout*1000);
          }

          // Notify the Bond Manager to the connection
          VOID GAPBondMgr_LinkEst(pPkt->devAddrType, pPkt->devAddr, 
                                  pPkt->connectionHandle, GAP_PROFILE_PERIPHERAL);
        }
        else if (pPkt->hdr.status == bleGAPConnNotAcceptable)
        {
          // Set enabler to FALSE; device will become discoverable again when
          // this value gets set to TRUE
          gapRole_AdvEnabled = FALSE;

          // Go to WAITING state, and then start advertising
          gapRole_state = GAPROLE_WAITING;
        }
        else
        {
          gapRole_state = GAPROLE_ERROR;
        }
        stateChangeNotify = TRUE;
      }
      break;

    case GAP_LINK_TERMINATED_EVENT:
      {
        gapTerminateLinkEvent_t *pPkt = (gapTerminateLinkEvent_t *)pMsg;

        GAPBondMgr_LinkTerm(pPkt->connectionHandle);
        
        memset(gapRole_ConnectedDevAddr, 0, B_ADDR_LEN);

        // Erase connection information
        gapRole_ConnInterval = 0;
        gapRole_ConnSlaveLatency = 0;
        gapRole_ConnTimeout = 0;
        gapRole_ConnTermReason = pPkt->reason;

        // Cancel all connection parameter update timers (if any active)
        Util_stopClock(&startUpdateClock);
        Util_stopClock(&updateTimeoutClock);

        stateChangeNotify = TRUE;
        
        gapRole_ConnectionHandle = INVALID_CONNHANDLE;
        
        // If device was advertising when connection dropped
        if (gapRole_AdvNonConnEnabled)
        {
          // Continue advertising.
          gapRole_state = GAPROLE_ADVERTISING_NONCONN;
        }
        // Else go to WAITING state.
        else
        {
          if(pPkt->reason == LL_SUPERVISION_TIMEOUT_TERM)
          {
            gapRole_state = GAPROLE_WAITING_AFTER_TIMEOUT;
          }
          else
          {
            gapRole_state = GAPROLE_WAITING;
          }
          
          // Start advertising, if enabled.
          gapRole_setEvent(START_ADVERTISING_EVT);
        }
      }
      break;

    case GAP_LINK_PARAM_UPDATE_EVENT:
      {
        gapLinkUpdateEvent_t *pPkt = (gapLinkUpdateEvent_t *)pMsg;

        // Cancel connection param update timeout timer (if active)
        Util_stopClock(&updateTimeoutClock);
        
        if (pPkt->hdr.status == SUCCESS)
        {
          // Store new connection parameters
          gapRole_ConnInterval = pPkt->connInterval;
          gapRole_ConnSlaveLatency = pPkt->connLatency;
          gapRole_ConnTimeout = pPkt->connTimeout;
          
          // Make sure there's no pending connection update procedure
          if(Util_isActive(&startUpdateClock) == FALSE)
          {
            // Notify the application with the new connection parameters
            if (pGapRoles_ParamUpdateCB != NULL)
            {
              (*pGapRoles_ParamUpdateCB)(gapRole_ConnInterval, 
                                         gapRole_ConnSlaveLatency, 
                                         gapRole_ConnTimeout);
            }
          }
        }
      }
      break;

	case GAP_PAIRING_REQ_EVENT: {
		gapPairingReqEvent_t *pPkt = (gapPairingReqEvent_t *) pMsg;

		// Send Pairing Failed Response
		VOID GAP_TerminateAuth(pPkt->connectionHandle,
		SMP_PAIRING_FAILED_NOT_SUPPORTED);
	}
		break;



	case GAP_DEVICE_INFO_EVENT: //se ricevi questi due eventi girali semplicemente all'applicazione
	case GAP_DEVICE_DISCOVERY_EVENT:
		gapEvtNotify = TRUE;
		break;
	default:
  		break;
  }

  if (stateChangeNotify == TRUE)
  {
    // Notify the application with the new state change
    if (pGapRoles_AppCGs && pGapRoles_AppCGs->pfnStateChange)
    {
      pGapRoles_AppCGs->pfnStateChange(gapRole_state);
    }
  }

  if(gapEvtNotify == TRUE){
  	 // Pass event to app
  	 if (pGapRoles_AppCGs && pGapRoles_AppCGs->eventCB) {
  	 	return (pGapRoles_AppCGs->eventCB( (gapObserverRoleEvent_t *)pMsg ));
  	 }

    }

  return TRUE;
}