Exemplo n.º 1
0
/*******************************************************************************
* Function Name: BLE_StackEventHandler
********************************************************************************
*
* Summary:
*   BLE stack generic event handler routine for handling connection, discovery, 
*   security etc. events.
*
* Parameters:  
*  event - event that triggered this callback
*  eventParam - parameters for the event.
*
* Return: 
*  None
*******************************************************************************/
void BLE_StackEventHandler(uint32 event, void* eventParam)
{
    CYBLE_API_RESULT_T apiResult;
    
    (void) eventParam;
    
    switch(event)
    {
        case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
            
        break;
        
        case CYBLE_EVT_STACK_ON:
            /* Put the device into discoverable mode so that remote can search it. */
            apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            
            if(apiResult != CYBLE_ERROR_OK)
            {
                CYASSERT(0);    
            }
        break;
            
        /* ADD YOUR CODE TO HANDLE OTHER GENERIC BLE STACK EVENTS */
            
        /* All the BLE stack events can be found in BLE_Stack.h (see CYBLE_EVENT_T enum) and  BLE_eventHandler.h (see
         * CYBLE_EVT_T enum ) */
                
        default:
        
        break;
    }
}
Exemplo n.º 2
0
Arquivo: main.c Projeto: Shogun5/BLE
/*******************************************************************************
* Function Name: StartAdvertisement
********************************************************************************
*
* Summary:
*   Initiates the advertisement procedure.
*   Prints the Device Address.
*
* Parameters:
*   None.
*
* Return:
*   None.
*
*******************************************************************************/
void StartAdvertisement(uint8 advType)
{
    CYBLE_API_RESULT_T apiResult = CYBLE_ERROR_OK;
    CYBLE_GAP_BD_ADDR_T localAddr;
    uint16 i;
    
    if(advType == ADV_STATE_GENERAL)
    {
        cyBle_discoveryParam.advFilterPolicy = SCAN_ANY_CONNECT_ANY;
    }
    else
    {
        cyBle_discoveryParam.advFilterPolicy  = SCAN_WHITELIST_CONNECT_WHITELIST;
    }
    
    apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
    
    if(apiResult != CYBLE_ERROR_OK)
    {
        printf("StartAdvertisement API Error: %x \r\n", (int) apiResult);
    }
    else
    {
        printf("Start Advertisement with addr: ");
        CyBle_GetDeviceAddress(&localAddr);
        for(i = CYBLE_GAP_BD_ADDR_SIZE; i > 0u; i--)
        {
            printf("%2.2x", localAddr.bdAddr[i-1]);
        }
        printf("\r\n");
    }
}
Exemplo n.º 3
0
/*******************************************************************************
* Function Name: StackEventHandler
********************************************************************************
*
* Summary:
*  This is an event callback function to receive events from the BLE Component.
*
* Parameters:
*  uint8 event:       Event from the CYBLE component
*  void* eventParams: A structure instance for corresponding event type. The
*                     list of event structure is described in the component
*                     datasheet.
*
* Return:
*  None
*
*******************************************************************************/
void StackEventHandler(uint32 event, void *eventParam)
{
    switch(event)
    {
    /* Mandatory events to be handled by Find Me Target design */
    case CYBLE_EVT_STACK_ON:
    case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
        /* Start BLE advertisement for 30 seconds and update link
         * status on LEDs */
        CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
        Advertising_LED_Write(LED_ON);
        break;

    case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
        if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED)
        {
            /* Advertisement event timed out, go to low power
             * mode (Hibernate mode) and wait for an external
             * user event to wake up the device again */
            Advertising_LED_Write(LED_OFF);
            Hibernate_LED_Write(LED_ON);
            Wakeup_SW_ClearInterrupt();
            Wakeup_Interrupt_ClearPending();
            Wakeup_Interrupt_Start();
            CySysPmHibernate();
        }
        break;

    default:
        break;
    }
}
Exemplo n.º 4
0
/* Main loop */
int main()
{
    CYBLE_API_RESULT_T apiResult;
    
    CyGlobalIntEnable;
    Initialization();
    
    for(;;)
    {
        /* Delayed start of advertisement */
        if(initCounter == 6)
        {
            initCounter = 7;
            WDT_DisableWcoEcoCounters();
            
            apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_CUSTOM);
            if(apiResult != CYBLE_ERROR_OK)
            {
                CYASSERT(0);
            }
        }
        
        CyBle_ProcessEvents(); /* BLE stack processing state machine interface */
        
        LowPower();
    }
}
Exemplo n.º 5
0
void StartAdvertisment() {
    apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
    if (apiResult != CYBLE_ERROR_OK) {
        printf("CyBle_Start API error: %x \r\n", apiResult);
        Error_Led_Write(LED_ON);
    } else {
        Advertising_Led_Write(LED_ON);
    }
}
Exemplo n.º 6
0
/*******************************************************************************
* Function Name: main
********************************************************************************
* Summary:
*        System entrance point. This calls the initializing function and
* continuously process BLE and CapSense events.
*
* Parameters:
*  void
*
* Return:
*  int
*

*******************************************************************************/
int main()
{
    uint8 lpmSel = DEEPSLEEP; 
	/* This function will initialize the system resources such as BLE and CapSense */
    InitializeSystem();
	
    for(;;)
    {
        /*Process event callback to handle BLE events. The events generated and 
		* used for this application are inside the 'CustomEventHandler' routine*/
        CyBle_ProcessEvents();
		
		/* Updated LED for status during BLE active states */
		HandleStatusLED();
		
		if(TRUE == deviceConnected)
		{
			/* After the connection, send new connection parameter to the Client device 
			* to run the BLE communication on desired interval. This affects the data rate 
			* and power consumption. High connection interval will have lower data rate but 
			* lower power consumption. Low connection interval will have higher data rate at
			* expense of higher power. This function is called only once per connection. */
			UpdateConnectionParam();
			
			/* When the Client Characteristic Configuration descriptor (CCCD) is written
			* by Central device for enabling/disabling notifications, then the same
			* descriptor value has to be explicitly updated in application so that
			* it reflects the correct value when the descriptor is read */
			UpdateNotificationCCCD();
			lpmSel = LPMselData;
		}
		
		#ifdef ENABLE_LOW_POWER_MODE
			/* Put system to Deep sleep, including BLESS, and wakeup on interrupt. 
			* The source of the interrupt can be either BLESS Link Layer in case of 
			* BLE advertisement and connection or by User Button press during BLE 
			* disconnection */
			HandleLowPowerMode(lpmSel);
		#endif
		
		if(restartAdvertisement)
		{
			/* Reset 'restartAdvertisement' flag*/
			restartAdvertisement = FALSE;

			/* Start Advertisement and enter Discoverable mode*/
			CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);	
		}
    }	/* End of for(;;) */
}
Exemplo n.º 7
0
Arquivo: main.c Projeto: bhwj/BLE
/*******************************************************************************
* Function Name: BLE_AppEventHandler
********************************************************************************
*
* Summary:
*   BLE stack generic event handler routine for handling connection, discovery, 
*   security etc. events.
*
* Parameters:  
*  event - event that triggered this callback
*  eventParam - parameters for the event.
*
* Return: 
*  None
*******************************************************************************/
void BLE_AppEventHandler(uint32 event, void* eventParam)
{
    CYBLE_API_RESULT_T apiResult;
    
    (void)eventParam;

    switch (event)
	{
        /**********************************************************
        *                       General Events
        ***********************************************************/
		case CYBLE_EVT_STACK_ON: /* This event is received when component is Started */
            /* Enter in to discoverable mode so that remote can search it. */
            apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            
            if(apiResult != CYBLE_ERROR_OK)
            {
                CYASSERT(0);
            }
        break;
            
        case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
            if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED)
            {
                /* On advertisement timeout, restart advertisement */
                apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
                if(apiResult != CYBLE_ERROR_OK)
                {
                    CYASSERT(0);
                }
            }
        break;
            
		default:
        break;
	}
}
Exemplo n.º 8
0
/* BLE stack event handler */
void BLE_AppEventHandler(uint32 event, void* eventParam)
{
    CYBLE_API_RESULT_T apiResult;

    switch (event)
	{
        /**********************************************************
        *                       General Events
        ***********************************************************/

        /* This event is received when component is Started */
        case CYBLE_EVT_STACK_ON: 
            
            /* Start with a regular UID/URL packet */
            isRegularAdvScheduled = true;
            ConfigureAdvPacket(isRegularAdvScheduled);

            initCounter = 0;
            WDT_EnableWcoCounter();     /* Enable WDT's WCO counter (counter 0) */
        break;
            
        case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
            if(CyBle_GetState() != CYBLE_STATE_ADVERTISING)
            {
                /* On advertisement timeout, restart advertisement */

            #if (IS_EDDYSTONE_TLM_PRESENT)
                if(true == isRegularAdvScheduled)
                {
                    /* Configure for TLM packet */
                    isRegularAdvScheduled = false;
                }
                else
                {
                    /* Configure for regular UID/URL packet */
                    isRegularAdvScheduled = true;
                }
                
                ConfigureAdvPacket(isRegularAdvScheduled);
            #endif
            
                CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_CUSTOM);
            }
        break;
            
		default:
        break;
	}
}
Exemplo n.º 9
0
/*******************************************************************************
* Function Name: main
********************************************************************************
* Summary:
*        System entrance point. This calls the initializing function and
* continuously process BLE events.
*
* Parameters:
*  void
*
* Return:
*  int
*

*******************************************************************************/
int main()
{

    /* This function will initialize the system resources such as BLE and 
     * NEC pulse timer 
     */
    InitializeSystem();
	
    for(;;)
    {
        /* Process event callback to handle BLE events. The events generated and 
		 * used for this application are inside the 'CustomEventHandler' routine
         */
        CyBle_ProcessEvents();
		
		/* Update LED for status during BLE active states */
		HandleStatusLED();
		
		if(TRUE == deviceConnected)
		{
			/* After the connection, send new connection parameter to the Client device 
			* to run the BLE communication on desired interval. This affects the data rate 
			* and power consumption. High connection interval will have lower data rate but 
			* lower power consumption. Low connection interval will have higher data rate at
			* expense of higher power. This function is called only once per connection. 
            */
			UpdateConnectionParam();
		}
		
		if(restartAdvertisement)
		{
			/* Reset 'restartAdvertisement' flag*/
			restartAdvertisement = FALSE;
			
			/* Start Advertisement and enter Discoverable mode*/
			CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);	
		}
    }	/* End of for(;;) */
}
Exemplo n.º 10
0
void StackEventHandler(uint32 event,void * eventParam)
{
    /*Local avriables*/
    uint8 i;
    CYBLE_GAP_BD_ADDR_T localAddr;
        
    switch(event)
    {
        case CYBLE_EVT_STACK_ON:
        
                printf("BLE Stack ON: \r\n");
                /*Get local device address*/
                CyBle_GetDeviceAddress(&localAddr);

                for(i = CYBLE_GAP_BD_ADDR_SIZE; i > 0u; i--)
                {
                    printf("%2.2x", localAddr.bdAddr[i-1]);
                }
                
                printf("\r\n");
                 
                /*Start to advertise*/
                CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            
            break;                
       
        case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
                
            if(CyBle_GetState()==CYBLE_STATE_DISCONNECTED)
            {
                printf("Advertising stopped\r\n");
            }
            else if(CyBle_GetState()==CYBLE_STATE_ADVERTISING)
            {
                printf("Started to Advertise\r\n");
            }
            break;
            
        case CYBLE_EVT_GAP_DEVICE_CONNECTED:             
                printf("Device Connected\r\n)");                                               
            break;
            
        case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
                disSupport=0;
                CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            break;
                
         case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE:
                printf("\r\n");
                printf("Discovery complete.\r\n");
                printf("Discovered services: \r\n");
                
                for(i = 0u; i < CYBLE_SRVI_COUNT; i++)
                {          /*Check for DIS service*/
                    if(cyBle_serverInfo[i].uuid == CYBLE_UUID_DEVICE_INFO_SERVICE)
                    {
                        if(cyBle_serverInfo[i].range.startHandle < cyBle_serverInfo[i].range.endHandle)
                        {
                            printf("Peer device supports Device Information Service \r\n");
                            disSupport=1;
                        }
                        else
                        {
                            printf("Peer device doesn't supports Device Information Service \r\n");
                        }
                    }

                }                
                printf("\r\n");
            break; 
          
        default:
            break;
        
    }
}
Exemplo n.º 11
0
/*******************************************************************************
* Function Name: StackEventHandler
********************************************************************************
*
* Summary:
*  This is an event callback function to receive events from the BLE Component.
*
* Parameters:
*  uint8 event:       Event from the CYBLE component
*  void* eventParams: A structure instance for corresponding event type. The
*                     list of event structure is described in the component
*                     datasheet.
*
* Return:
*  None
*
*******************************************************************************/
void StackEventHandler(uint32 event, void *eventParam)
{
	char authFailReasonCode[3];
	CYBLE_GAP_AUTH_FAILED_REASON_T *authFailReason;
	
    switch(event)
    {
    /* Mandatory events to be handled by Find Me Target design */
    case CYBLE_EVT_STACK_ON:	
    case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
        /* Start BLE advertisement for 30 seconds and update link
         * status on LEDs */
    	CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
        Advertising_LED_Write(LED_ON);
        PWM_WriteCompare(LED_NO_ALERT);
        break;

    case CYBLE_EVT_GAP_DEVICE_CONNECTED:
    	UART_UartPutString("GAP Device Connected\r\n");
    	
        /* BLE link is established */
        Advertising_LED_Write(LED_OFF);			
        break;

    case CYBLE_EVT_TIMEOUT:
        if(*(uint8 *) eventParam == CYBLE_GAP_ADV_MODE_TO)
        {
            /* Advertisement event timed out, go to low power
             * mode (Hibernate mode) and wait for an external
             * user event to wake up the device again */
            Advertising_LED_Write(LED_OFF);
            Hibernate_LED_Write(LED_ON);
            PWM_Stop();
            Wakeup_SW_ClearInterrupt();
            Wakeup_Interrupt_ClearPending();
            Wakeup_Interrupt_Start();
            CySysPmHibernate();
        }
        break;

    /**********************************************************
    *                       GAP Events
    ***********************************************************/
    case CYBLE_EVT_GAP_AUTH_REQ:						
		UART_UartPutString("Authorization Requested\r\n");
        break;
		
    case CYBLE_EVT_GAP_AUTH_COMPLETE:
		UART_UartPutString("Pairing is Successful!\r\n");
        break;
		
    case CYBLE_EVT_GAP_AUTH_FAILED:
		authFailReason = ((CYBLE_GAP_AUTH_FAILED_REASON_T *)eventParam);
		UART_UartPutString("Authentication Failed with Reason Code: ");
		snprintf(authFailReasonCode, sizeof(authFailReasonCode), "%lu", (uint32)(*authFailReason));
		UART_UartPutString(authFailReasonCode);
		UART_UartPutChar("\r\n");			
        break;

    /**********************************************************
    *                       GATT Events
    ***********************************************************/
    case CYBLE_EVT_GATT_CONNECT_IND:
		UART_UartPutString("GATT Connection Indication\r\n");
		
		/* Set OOB data after the connection indication but before the authorization
		 * request is received. 
		 */
		
		if(CyBle_GapSetOobData(cyBle_connHandle.bdHandle, CYBLE_GAP_OOB_ENABLE, securityKey, NULL, NULL)  != CYBLE_ERROR_OK)
		{
			UART_UartPutString("Error in Setting OOB Data\r\n");
		}
		else
		{
			UART_UartPutString("OOB Data is Set\r\n");
		}
        break;

    default:
        break;
    }
}
Exemplo n.º 12
0
void CustomEventHandler(uint32 event, void * eventParam)
{
	CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam;
   
    switch(event)
    {
        case CYBLE_EVT_STACK_ON:
        case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
			/* Start Advertisement and enter Discoverable mode*/
			CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
			break;
			
		case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
			/* Set the BLE state variable to control LED status */
            if(CYBLE_STATE_DISCONNECTED == CyBle_GetState())
            {
                /* Start Advertisement and enter Discoverable mode*/
                CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            }
			break;
			
        case CYBLE_EVT_GATT_CONNECT_IND:
			/* This flag is used in application to check connection status */
			deviceConnected = TRUE;
			break;
        
        case CYBLE_EVT_GATT_DISCONNECT_IND:
			/* Update deviceConnected flag*/
			deviceConnected = FALSE;
			
			/* Reset CapSense notification flag to prevent further notifications
			 * being sent to Central device after next connection. */
			//sendCapSenseSliderNotifications = FALSE;
			
			/* Reset the CCCD value to disable notifications */
			//updateNotificationCCCAttribute = TRUE;
			
			/* Reset the color coordinates */
			RGBledData[RED_INDEX] = 0;
            RGBledData[GREEN_INDEX] = 0;
            RGBledData[BLUE_INDEX] = 0;
            RGBledData[INTENSITY_INDEX] = 0;
			UpdateRGBled();

			break;
        
            
        case CYBLE_EVT_GATTS_WRITE_REQ: 							
            /* This event is received when Central device sends a Write command 
             * on an Attribute. 
             * We first get the attribute handle from the event parameter and 
             * then try to match that handle with an attribute in the database.
             */
            wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam;
            
            /* This condition checks whether the RGB LED characteristic was
             * written to by matching the attribute handle.
             * If the attribute handle matches, then the value written to the 
             * attribute is extracted and used to drive RGB LED.
             */
            
            /* ADD_CODE to extract the attribute handle for the RGB LED 
             * characteristic from the custom service data structure.
             */
            //if(wrReqParam->handleValPair.attrHandle == cyBle_customs[RGB_LED_SERVICE_INDEX].\
			//					customServiceInfo[RGB_LED_CHAR_INDEX].customServiceCharHandle)
            if(wrReqParam->handleValPair.attrHandle == cyBle_customs[CYBLE_RGB_LED_SERVICE_SERVICE_INDEX].\
								customServiceInfo[CYBLE_RGB_LED_SERVICE_RGB_LED_CHARACTERISTIC_CHAR_INDEX].customServiceCharHandle)
            {
                /* ADD_CODE to extract the value of the attribute from 
                 * the handle-value pair database. */
                RGBledData[RED_INDEX] = wrReqParam->handleValPair.value.val[RED_INDEX];
                RGBledData[GREEN_INDEX] = wrReqParam->handleValPair.value.val[GREEN_INDEX];
                RGBledData[BLUE_INDEX] = wrReqParam->handleValPair.value.val[BLUE_INDEX];
                RGBledData[INTENSITY_INDEX] = wrReqParam->handleValPair.value.val[INTENSITY_INDEX];
                
                /* Update the PrISM components and the attribute for RGB LED read 
                 * characteristics */
                UpdateRGBled();
                //SendVoltageMeasurementNotification(voltageReading);
            }
            if(wrReqParam->handleValPair.attrHandle == 0x2A00) {
                RGBledData[RED_INDEX] = 0;
                RGBledData[GREEN_INDEX] = 0;
                RGBledData[BLUE_INDEX] = 0;
                RGBledData[INTENSITY_INDEX] = 0;
                
                /* Update the PrISM components and the attribute for RGB LED read 
                 * characteristics */
                UpdateRGBled();
            }
            //printf("%d",wrReqParam->handleValPair.attrHandle);
			
			/* ADD_CODE to send the response to the write request received. */
			CyBle_GattsWriteRsp(cyBle_connHandle);
			break;
        case CYBLE_EVT_GATTS_READ_CHAR_VAL_ACCESS_REQ:
            // Is this in response to a read request?
            
            break;
            
        default:
       	 	break;
    }
}
Exemplo n.º 13
0
/*******************************************************************************
* Function Name: AppCallBack
********************************************************************************
*
* Summary:
*  This is an event callback function to receive events from the CYBLE Component.
*
* Parameters:
*  uint8 event:       Event from the CYBLE component.
*  void* eventParams: A structure instance for corresponding event type. The
*                     list of event structure is described in the component
*                     datasheet.
*
* Return:
*  None
*
*******************************************************************************/
void AppCallBack(uint32 event, void* eventParam)
{
    CYBLE_API_RESULT_T apiResult;
    CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam;

    switch (event)
	{
        /**********************************************************
        *                       General Events
        ***********************************************************/
		case CYBLE_EVT_STACK_ON: /* This event is received when component is Started */
            /* Enter into discoverable mode so that remote can search it. */
            apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            if(apiResult != CYBLE_ERROR_OK)
            {
                //ShowError();
            }
            printf("CYBLE_EVT_STACK_ON\n");
            break;
		case CYBLE_EVT_TIMEOUT:
            printf("CYBLE_EVT_TIMEOUT\n");
			break;
		case CYBLE_EVT_HARDWARE_ERROR:  /* This event indicates that some internal HW error has occurred. */
            //ShowError();
            break;

        /**********************************************************
        *                       GAP Events
        ***********************************************************/
        case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
            printf("CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP\n");
            if(CYBLE_STATE_DISCONNECTED == CyBle_GetState())
            {
                /* Fast and slow advertising period complete, go to low power
                 * mode (Hibernate mode) and wait for an external
                 * user event to wake up the device again */
//                Advertising_LED_Write(LED_OFF);
//                Disconnect_LED_Write(LED_ON);
//                SW2_ClearInterrupt();
//                Wakeup_Interrupt_ClearPending();
//                Wakeup_Interrupt_Start();
                CySysPmHibernate();
            }
            break;
        case CYBLE_EVT_GAP_DEVICE_CONNECTED:
            printf("CYBLE_EVT_GAP_DEVICE_CONNECTED\n");
//            Disconnect_LED_Write(LED_OFF);
//            Advertising_LED_Write(LED_OFF);
            break;
        case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
            /* Put the device to discoverable mode so that remote can search it. */
            printf("CYBLE_EVT_GAP_DEVICE_DISCONNECTED\n");
            apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            if(apiResult != CYBLE_ERROR_OK)
            {
                //ShowError();
            }
            break;
        case CYBLE_EVT_GAPC_CONNECTION_UPDATE_COMPLETE:
            break;

        /**********************************************************
        *                       GATT Events
        ***********************************************************/
        case CYBLE_EVT_GATT_CONNECT_IND:
            printf("CYBLE_EVT_GATT_CONNECT_IND\n");
            break;
        case CYBLE_EVT_GATT_DISCONNECT_IND:
            printf("CYBLE_EVT_GATT_DISCONNECT_IND\n");

            // Reset the rotation notification
            _rotationCCCDValue[0]   = 0;
            _voltageCCCDValue[0]    = 0;
            _drawCCCDValue[0]       = 0;
            break;

        case CYBLE_EVT_GATTS_WRITE_REQ:
            printf("CYBLE_EVT_GATTS_WRITE_REQ\n");
            wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam;

            /* Write request for time/date */
            if(wrReqParam->handleValPair.attrHandle == CYBLE_POVDISPLAY_TIME_CHAR_HANDLE)
            {
                /* only update the value and write the response if the requested write is allowed */
                if(CYBLE_GATT_ERR_NONE == CyBle_GattsWriteAttributeValue(&wrReqParam->handleValPair, 0, &cyBle_connHandle, CYBLE_GATT_DB_PEER_INITIATED))
                {
                    uint64_t datetime = wrReqParam->handleValPair.value.val[0];
                    datetime <<= 8;
                    datetime |= wrReqParam->handleValPair.value.val[1];
                    datetime <<= 8;
                    datetime |= wrReqParam->handleValPair.value.val[2];
                    datetime <<= 8;
                    datetime |= wrReqParam->handleValPair.value.val[3];
                    printf("Date time EPOCH: %08x\n", (unsigned int)(datetime >> 32));
                    printf("Date time EPOCH: %08x\n", (unsigned int)datetime);
                    RTC_SetUnixTime(datetime);
                }
            }
            /* Write request for time/date */
            if(wrReqParam->handleValPair.attrHandle == CYBLE_POVDISPLAY_FILTERGAIN_CHAR_HANDLE)
            {
                /* only update the value and write the response if the requested write is allowed */
                if(CYBLE_GATT_ERR_NONE == CyBle_GattsWriteAttributeValue(&wrReqParam->handleValPair, 0, &cyBle_connHandle, CYBLE_GATT_DB_PEER_INITIATED))
                {
                    _rotationFilterGain = wrReqParam->handleValPair.value.val[0];
                    _rotationFilterGain <<= 8;
                    _rotationFilterGain |= wrReqParam->handleValPair.value.val[1];
                    _rotationFilterGain <<= 8;
                    _rotationFilterGain |= wrReqParam->handleValPair.value.val[2];
                    _rotationFilterGain <<= 8;
                    _rotationFilterGain |= wrReqParam->handleValPair.value.val[3];
                }
            }

            if(wrReqParam->handleValPair.attrHandle == CYBLE_POVDISPLAY_DRAWOFFSET_CHAR_HANDLE)
            {
                /* only update the value and write the response if the requested write is allowed */
                if(CYBLE_GATT_ERR_NONE == CyBle_GattsWriteAttributeValue(&wrReqParam->handleValPair, 0, &cyBle_connHandle, CYBLE_GATT_DB_PEER_INITIATED))
                {
                    _drawOffset = wrReqParam->handleValPair.value.val[0];
                    _drawOffset <<= 8;
                    _drawOffset |= wrReqParam->handleValPair.value.val[1];
                }
            }

            if(wrReqParam->handleValPair.attrHandle == CYBLE_POVDISPLAY_ROTATIONSPEED_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE)
            {
                /* only update the value and write the response if the requested write is allowed */
                if(wrReqParam->handleValPair.value.val[CYBLE_POVDISPLAY_ROTATIONSPEED_CHARACTERISTIC_USER_DESCRIPTION_DESC_INDEX] == 1)
                {
                    _rotationCCCDValue[0]  = 1;
                }
                else
                {
                    _rotationCCCDValue[0]  = 0;
                }

        		/* Update CCCD handle with notification status data*/
        		_rotationNotificationCCCDHandle.attrHandle = CYBLE_POVDISPLAY_ROTATIONSPEED_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE;
        		_rotationNotificationCCCDHandle.value.val  = _rotationCCCDValue;
        		_rotationNotificationCCCDHandle.value.len  = 2;

        		/* Report data to BLE component for sending data when read by Central device */
        		CyBle_GattsWriteAttributeValue(&_rotationNotificationCCCDHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_PEER_INITIATED);
            }

            if(wrReqParam->handleValPair.attrHandle == CYBLE_POVDISPLAY_VOLTAGE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE)
            {
                /* only update the value and write the response if the requested write is allowed */
                if(wrReqParam->handleValPair.value.val[CYBLE_POVDISPLAY_VOLTAGE_CHARACTERISTIC_USER_DESCRIPTION_DESC_INDEX] == 1)
                {
                    _voltageCCCDValue[0]  = 1;
                }
                else
                {
                    _voltageCCCDValue[0]  = 0;
                }

        		/* Update CCCD handle with notification status data*/
        		_voltageNotificationCCCDHandle.attrHandle = CYBLE_POVDISPLAY_VOLTAGE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE;
        		_voltageNotificationCCCDHandle.value.val  = _voltageCCCDValue;
        		_voltageNotificationCCCDHandle.value.len  = 2;

        		/* Report data to BLE component for sending data when read by Central device */
        		CyBle_GattsWriteAttributeValue(&_voltageNotificationCCCDHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_PEER_INITIATED);
            }

            if(wrReqParam->handleValPair.attrHandle == CYBLE_POVDISPLAY_DRAWTIME_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE)
            {
                /* only update the value and write the response if the requested write is allowed */
                if(wrReqParam->handleValPair.value.val[CYBLE_POVDISPLAY_DRAWTIME_CHARACTERISTIC_USER_DESCRIPTION_DESC_INDEX] == 1)
                {
                    _drawCCCDValue[0]  = 1;
                }
                else
                {
                    _drawCCCDValue[0]  = 0;
                }

        		/* Update CCCD handle with notification status data*/
        		_drawNotificationCCCDHandle.attrHandle = CYBLE_POVDISPLAY_DRAWTIME_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE;
        		_drawNotificationCCCDHandle.value.val  = _drawCCCDValue;
        		_drawNotificationCCCDHandle.value.len  = 2;

        		/* Report data to BLE component for sending data when read by Central device */
        		CyBle_GattsWriteAttributeValue(&_drawNotificationCCCDHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_PEER_INITIATED);
            }
            CyBle_GattsWriteRsp(cyBle_connHandle);
            break;

        /**********************************************************
        *                       Other Events
        ***********************************************************/
		case CYBLE_EVT_STACK_BUSY_STATUS:
			/* This event is generated when the internal stack buffer is full and no more
			* data can be accepted or the stack has buffer available and can accept data.
			* This event is used by application to prevent pushing lot of data to stack. */

			/* Extract the present stack status */
            _busyStatus = * (uint8*)eventParam;
            break;


        default:
            break;
	}
Exemplo n.º 14
0
/*******************************************************************************
* Function Name: BondingImplementation()
********************************************************************************
* Summary:
* Implements bonding of peer BLE device information.
*
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* The function stores the peer BLE device information to flash (called bonding)
* when the device is ready. When the user wants to clear the bond information, 
* it is cleared in this function.
*
*******************************************************************************/
static void BondingImplementation(void)
{
    uint8 command;
    CYBLE_GAP_BD_ADDR_T clearAllDevices = {{0,0,0,0,0,0},0};
    
    switch(authState)
    {
        case AUTHENTICATION_COMPLETE_BONDING_REQD:
            /* Store bonding data of the current connection */
            while(CYBLE_ERROR_OK != CyBle_StoreBondingData(1));
            
            authState = AUTHENTICATION_BONDING_COMPLETE;
            UART_UartPutString("Bonding complete. ");
            break;
            
            
        case AUTHENTICATION_BONDING_COMPLETE:
            /* See if the user pressed 'R' button to clear the bond list. */
            command = UART_UartGetChar();
            
            if(command != 0u)
            {
                if((command == 'r') || (command == 'R'))
                {
                    /* User wants the bond to be removed */
                    UART_UartPutString("\n\rClear the bond list. ");
                    if(CyBle_GetState() == CYBLE_STATE_CONNECTED)
                    {
                        /* Disconnect */
                        authState = AUTHENTICATION_BONDING_REMOVE_WAITING_EVENT;
                        CyBle_GapDisconnect(cyBle_connHandle.bdHandle);
                    }
                    else if(CyBle_GetState() == CYBLE_STATE_ADVERTISING)
                    {
                        /* Stop advertisement */
                        authState = AUTHENTICATION_BONDING_REMOVE_WAITING_EVENT;
                        CyBle_GappStopAdvertisement();
                    }
                    else
                    {
                        authState = AUTHENTICATION_BONDING_REMOVE_GO_AHEAD;
                    }
                }
            }
            break;
            
            
        case AUTHENTICATION_BONDING_REMOVE_GO_AHEAD:
            /* Remove all bonded devices in the list */
            CyBle_GapRemoveDeviceFromWhiteList(&clearAllDevices);
            
            while(CYBLE_ERROR_OK != CyBle_StoreBondingData(1));
            UART_UartPutString("Cleared the list of bonded devices. \n\n\r");
                
            authState = AUTHENTICATION_NOT_CONNECTED;
            
            /* Start advertisement again */
            UART_UartPutString("Advertising. ");
            CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            break;
            
            
        default:
            break;
    }
}
Exemplo n.º 15
0
/*******************************************************************************
* Function Name: StackEventHandler()
********************************************************************************
* Summary:
* Event handler function for the BLE events processing.
*
* Parameters:
* uint32 eventCode: The event to be processed
* void * eventParam: Pointer to hold the additional information associated 
*                    with an event
*
* Return:
* None
*
* Theory:
* The function is responsible for handling the events generated by the stack.
* In addition to handling general events for BLE advertisement, connection, 
* and disconnection, this function handles the events related to L2CAP CBFC 
* connection-oriented channel connection and disconnection.
*
* For details on L2CAP connection-oriented channels, refer to Bluetooth 4.1 
* specification, Volume 3, Part A, section 3.4.
*
* Side Effects:
* None
*
*******************************************************************************/
void StackEventHandler(uint32 eventCode, void * eventParam)
{
    CYBLE_L2CAP_CBFC_CONN_CNF_PARAM_T cbfcResponse;
    uint8 counter; 
    
    switch(eventCode)
    {
        /* Stack initialized; ready for advertisement */
        case CYBLE_EVT_STACK_ON:
            UART_UartPutString("\n\rAdvertising with Address: ");
            for(counter = 6; counter > 0; counter--)
            {
                UART_UartPutChar(HexToAscii(cyBle_deviceAddress.bdAddr[counter - 1], 1));
                UART_UartPutChar(HexToAscii(cyBle_deviceAddress.bdAddr[counter - 1], 0));
                UART_UartPutChar(' ');
            }
            CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            break;
        
        /* Advertisement timed out; Restart advertisement */
        case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
            if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED)
            {
                CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            }
            break;
        
        case CYBLE_EVT_GAP_DEVICE_CONNECTED:
            UART_UartPutString("\n\rConnected. ");
            break;
            
        /* Device disconnected */
        case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
            /* The L2CAP channel is disconnected but the PSM is already 
             * registered. Update the state machine.
             */
            channelState = CHANNEL_PSM_REGISTERED;
            previousDataTransmitted = true;
            
            /* Restart advertisement */
            UART_UartPutString("\n\n\rDisconnected. ");
            UART_UartPutString("\n\rAdvertising again. ");
            UART_UartPutString("Address: ");
            for(counter = 6; counter > 0; counter--)
            {
                UART_UartPutChar(HexToAscii(cyBle_deviceAddress.bdAddr[counter - 1], 1));
                UART_UartPutChar(HexToAscii(cyBle_deviceAddress.bdAddr[counter - 1], 0));
                UART_UartPutChar(' ');
            }
            CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            break;
        
        /* CBFC connection response is received */
        case CYBLE_EVT_L2CAP_CBFC_CONN_CNF:
            cbfcResponse = *(CYBLE_L2CAP_CBFC_CONN_CNF_PARAM_T *)eventParam;
            
            /* If the connection request was accepted */
            if(cbfcResponse.response == CYBLE_L2CAP_CONNECTION_SUCCESSFUL)
            {
                UART_UartPutString("\n\rL2CAP channel connection request accepted. Sending data. ");
                
                /* Cache the connection parameters and channel ID */
                cbfcPeerParameters = cbfcResponse.connParam;
                l2capCid = cbfcResponse.lCid;

                /* Update the state machine to indicate that the channel 
                 * is created.
                 */
                channelState = CHANNEL_CREATED;
            }
            break;
        
        /* Peer device requested for CBFC channel disconnection */
        case CYBLE_EVT_L2CAP_CBFC_DISCONN_IND:
            if(*(uint16 *)eventParam == l2capCid)
            {
                /* L2CAP channel disconnected but the PSM is still registered */
                channelState = CHANNEL_PSM_REGISTERED;
                previousDataTransmitted = true;
            }
            break;
            
        /* Invalid credits received from peer device; initiate disconnect */
        case CYBLE_EVT_L2CAP_CBFC_TX_CREDIT_IND:
            if(((CYBLE_L2CAP_CBFC_LOW_TX_CREDIT_PARAM_T *)eventParam)->result != CYBLE_L2CAP_RESULT_SUCCESS)
            {
                CyBle_L2capDisconnectReq(l2capCid);
                channelState = CHANNEL_PSM_REGISTERED;
            }
            break;

        /* Previous data transmission completed */
        case CYBLE_EVT_L2CAP_CBFC_DATA_WRITE_IND:
            previousDataTransmitted = true;
            break;
            
        default:
            break;
    }
}
Exemplo n.º 16
0
/*******************************************************************************
* Function Name: main
********************************************************************************
*
* Summary:
*   This is the main entry point for this application. This function initializes all the 
*	components used in the project. It computes the frequency whenever a capture event is 
*
* Parameters:  
*   None
*
* Return:
*   None
*
*******************************************************************************/
int main()
{
	#if(UART_DEBUG_ENABLE)
		/* Variable to store the loop number */
		uint8 loopNo = 0;
	#endif
	/* Enable global interrupt mask */
	CyGlobalIntEnable;	
	
	/* Disable ILO as it is not used */
	CySysClkIloStop();
	
	/* Initialize components related to BLE communication */
	InitializeBLESystem();
	
	/* Initialize components related to frequency counting */
	Initialize_Freq_Meas_System();
	
	/* Start UART component if UART debug is enabled */
	#if(UART_DEBUG_ENABLE)
		/* Start UART component and send welcome string to hyper terminal on PC */
		UART_Start();
		UART_UartPutString("Welcome to Frequency Measurement Using PSoC 4 BLE\n");
		UART_PutCRLF();
	#endif
	
    while(1)
    {
		/* Compute frequency once in every PWM interval(2s) */
		if(Calculate_Frequency == TRUE)
		{
			/* Check if valid capture event is detected */
			if((Input_Sig_Ctr_Capture == 1) && (Ref_Clk_Ctr_Capture == 1))
			{
				/* Compute frequency using the latched count value, computed frequency 
				will be stored in ASCII format in a global array */
				Compute_Frequency();
				
				#if(UART_DEBUG_ENABLE)
					/* Print input signal counter value in hexadecimal */
					UART_UartPutString("Input Signal Counter Value: ");
					UART_SendDebugData(Input_Signal_Count);
					UART_UartPutString("      ");
					
					/* Print input signal counter value in ASCII format */	
					/* Reset the array before storing the ASCII character */
					Reset_Array(InputCounter_ASCII, DATA_END);
					
					Convert_HextoDec(Input_Signal_Count, InputCounter_ASCII);
					for(loopNo = 0; loopNo < DATA_END; loopNo++)
					{
						UART_UartPutChar(InputCounter_ASCII[DATA_END - loopNo -1]);
					}
					UART_PutCRLF();	

					/* Print reference clock counter value */
					UART_UartPutString("Reference Clock Counter Value: ");
					UART_SendDebugData(Ref_Clock_Count);
					UART_UartPutString("      ");
					
					/* Print input signal counter value in ASCII format */	
					/* Reset the array before storing the ASCII character */				
					Reset_Array(RefCounter_ASCII, DATA_END);
					Convert_HextoDec(Ref_Clock_Count, RefCounter_ASCII);
					for(loopNo = 0; loopNo < DATA_END; loopNo++)
					{
						UART_UartPutChar(RefCounter_ASCII[DATA_END - loopNo -1]);
					}
					UART_PutCRLF();
					
					/* Print Input Signal Frequency in decimal format */
					UART_UartPutString("Input Frequency: ");
					for(loopNo = 0; loopNo < DATA_END; loopNo++)
					{
						UART_UartPutChar(Input_Frequency[DATA_END - loopNo -1]);
					}
					UART_PutCRLF();			
				#endif
				/* Reset the capture flag after computing the frequency */
				Input_Sig_Ctr_Capture = 0;
				Ref_Clk_Ctr_Capture = 0;
			} 
			/* If valid capture event is not registered, set the value of frequency to 
			   zero */
			else
			{
				/* Reset the input_frequency array before storing the frequency value */
				Reset_Array(Input_Frequency, DATA_END);

				/* If no capture event is detected in the 1s interval, set the frequency to zero */
				FormatFrequencyData(ZERO_HZ);
				
				#if(UART_DEBUG_ENABLE)
					/* Print Input Signal Frequency in decimal format */
					UART_UartPutString("Input Frequency: ");
					for(loopNo = 0; loopNo < DATA_END; loopNo++)
					{
						UART_UartPutChar(Input_Frequency[DATA_END - loopNo -1]);
					}
					UART_PutCRLF();	
				#endif
			}
			/* Reset the 2s interval flag for computing the frequency in the next interval */
			Calculate_Frequency = 0;
			/* Send frequency value only if BLE device is connected */
			if(TRUE == deviceConnected) 
			{
				/* Send frequency value when notifications are enabled */
				if((startNotification & CCCD_NTF_BIT_MASK))
				{

					/* Send the frequency value to BLE central device by notifications */
					SendDataOverFreqCounterNotification(Input_Frequency);
				}
			}
		}

		
		/* Function to handle LED status depending on BLE state */
		HandleStatusLED();
		
		/* Handle CCCD value update only if BLE device is connected */
		if(TRUE == deviceConnected) 
		{
	
			/* When the Client Characteristic Configuration descriptor (CCCD) is written
			* by Central device for enabling/disabling notifications, then the same
			* descriptor value has to be explicitly updated in application so that
			* it reflects the correct value when the descriptor is read */
			UpdateNotificationCCCD();	
		}		
		if(restartAdvertisement)
		{
			/* Reset 'restartAdvertisement' flag*/
			restartAdvertisement = FALSE;
			
			/* Start Advertisement and enter Discoverable mode*/
			CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);	
		}
		/*Process Event callback to handle BLE events. The events generated and 
		* used for this application are inside the 'CustomEventHandler' routine*/
		CyBle_ProcessEvents();
		
		/* Put CPU to sleep */
		CySysPmSleep();
    }
}
Exemplo n.º 17
0
/*******************************************************************************
* Function Name: SwitchRole
********************************************************************************
* Summary:
*        This function switches the role between Central and Peripheral. If device 
* is connected while switching role, then it is first disconnected.
*
* Parameters:
*  void
*
* Return:
*  void
*
*******************************************************************************/
void SwitchRole(void)
{
	CYBLE_API_RESULT_T  apiResult;
	
	/* if the switch role flag is set... */
	if(switch_Role == TRUE)
	{	
		/* Process pending BLE events */
		CyBle_ProcessEvents();
		
		/* If there is an existing connection, then disconnect before switching
		* role. */
		if((cyBle_connHandle.bdHandle != 0))
		{
			/* Disconnect the device and process the event */
			CyBle_GapDisconnect(cyBle_connHandle.bdHandle);
			CyBle_ProcessEvents();
			#ifdef DEBUG_ENABLED
			UART_UartPutString("Peripheral closed connection ");
			SendBLEStatetoUART(CyBle_GetState());
			UART_UartPutCRLF(' ');
			#endif
		}		
		
		switch(ble_gap_state)
		{
			case BLE_PERIPHERAL:
				/* If the current role is Peripheral and system is advertising,
				* then stop advertisement before switching role */
				if(CyBle_GetState() == CYBLE_STATE_ADVERTISING)
				{
					CyBle_GappStopAdvertisement();
					CyBle_ProcessEvents();

					#ifdef DEBUG_ENABLED
						UART_UartPutString("Peripheral Advertisment Stopped ");
						SendBLEStatetoUART(CyBle_GetState());
						UART_UartPutCRLF(' ');
					#endif
				}
				
				if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED)
				{
					/* Switch BLE role by starting scan. This way, the system is set
					* to Central role */
					apiResult = CyBle_GapcStartScan(CYBLE_SCANNING_FAST);
					
					if(CYBLE_ERROR_OK == apiResult)
					{
						#ifdef DEBUG_ENABLED
						UART_UartPutString("Start Scan API called ");
						SendBLEStatetoUART(CyBle_GetState());
						UART_UartPutCRLF(' ');
						#endif
						
						/* Record the time at which Central role was started. This will be 
						* used for timeout and switching to Peripheral operation*/
						centralStartedTime = WatchDog_CurrentCount();
						
						/* Update the current BLE role to Central */
						ble_gap_state = BLE_CENTRAL;
						
						/* Reset the switch role flag*/
						switch_Role = FALSE;
					}
					else
					{
						/* If scanning did not start, maintain the current role and retry later */
						ble_gap_state = BLE_PERIPHERAL;
						
						#ifdef DEBUG_ENABLED
						UART_UartPutString("Start Scan API failed ");
						SendBLEStatetoUART(CyBle_GetState());
						UART_UartPutCRLF(' ');
						#endif
					}
				}
				
				/* Process Pending BLE Events */
				CyBle_ProcessEvents();
				
			break;
			
			case BLE_CENTRAL:
				/* If the current role is Central and system is scanning,
				* then stop scanning before switching role */
				if(CyBle_GetState() == CYBLE_STATE_SCANNING)
				{
					CyBle_GapcStopScan();
					CyBle_ProcessEvents();
					
					#ifdef DEBUG_ENABLED
						UART_UartPutString("Central Scan stopped ");
						UART_UartPutCRLF(' ');
					#endif
				}
				
				if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED)
				{
					#ifdef ENABLE_ADV_DATA_COUNTER
					/* Increment data counter */
					new_advData.advData[new_advData.advDataLen - 1] = dataADVCounter;
					
					cyBle_discoveryModeInfo.advData = &new_advData;
					
					#ifdef DEBUG_ENABLED
						UART_UartPutString("Updated ADV data = ");
						PrintNum(dataADVCounter);
						UART_UartPutCRLF(' ');
					#endif
					#endif
					
					/* Switch BLE role by starting advertisement. This way, the system is 
					* set to Peripheral role */
					apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
					
					if(apiResult == CYBLE_ERROR_OK)
					{
						/* If advertisement started successfully, set the BLE state and
						* reset the switch role flag*/
						ble_gap_state = BLE_PERIPHERAL;
						clientConnectToDevice = FALSE;	
						switch_Role = FALSE;
						
						#ifdef DEBUG_ENABLED
						UART_UartPutString("Peripheral Advertisment called ");
						SendBLEStatetoUART(CyBle_GetState());
						UART_UartPutCRLF(' ');
						#endif
					}
					else
					{
						/* If advertisement did not start, maintain the current role and retry later */
						ble_gap_state = BLE_CENTRAL;
						
						#ifdef DEBUG_ENABLED
						UART_UartPutString("Start Peripheral Advertisment Failed ");
						SendBLEStatetoUART(CyBle_GetState());
						UART_UartPutCRLF(' ');
						#endif					
					}
				}
				
				/* Process Pending BLE Events */
				CyBle_ProcessEvents();
			break;
			
			default:
			
			break;
			
		}
	}
}
Exemplo n.º 18
0
void StackEventHandler(uint32 event,void *eventParam)
{
    
    switch(event)
	{
        
		case CYBLE_EVT_STACK_ON:
            //Starting Advertisement as soon as Stack is ON
             apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            if (apiResult == CYBLE_ERROR_OK)
            {
                printf ("Starting Advertisement\r\n");
            }
            else
            {
                printf ("Error Start Adv %d\r\n",apiResult);
            }
            break;
            
        case CYBLE_EVT_TIMEOUT:
         if( CYBLE_GAP_ADV_MODE_TO ==*(uint16*) eventParam)
            {
                printf ("Advertisement TimedOut\r\n");
                apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
                if (apiResult != CYBLE_ERROR_OK)
                {
                    printf ("\nRestarting  Advertisement\r\n");
                }
            }
		
		case CYBLE_EVT_GATT_DISCONNECT_IND:
			/* Red LED Glows when device is disconnected */
            RED_LED_ON ();
            break;
            
        case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
            printf ("Disconnected \r\n");
            // Starting Advertisent again when there is disconnection
            apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            if (apiResult != CYBLE_ERROR_OK)
            {
                printf ("\nRestarting  Advertisement\r\n");
            }
            break;
            
			
		case CYBLE_EVT_GAP_DEVICE_CONNECTED:
            printf ("\n\r Connection Established \r\n");
            //Blue LED glows when device is connected
            BLUE_LED_ON ();
            break;

		
		case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
         // This Event is received when advertisement is started or stopped.
            if (CyBle_GetState() == CYBLE_STATE_ADVERTISING)
            {
                printf("Advertising...\r\n");
                //Green LED Indicates that Advertisement is going on.
                GREEN_LED_ON();
            }
            else
            {
                RED_LED_ON();
                printf ("Advertisement Stopped \r\n");
                if (AddRequest == 1)
                {
                    AddRequest = 0;
                    // Adding the Device to whitelist
                    apiResult = CyBle_GapAddDeviceToWhiteList(&whitelistdeviceaddress); 
                                
                    if(apiResult == CYBLE_ERROR_INVALID_PARAMETER)
					{
						printf ("Adding to Whitelist Failed. Invalid parameter \r\n");
                    }
                    else if   (apiResult ==CYBLE_ERROR_INVALID_OPERATION)
                    {
                        printf ("Invalid Operation \r\n");
                    }
                    else if (apiResult ==CYBLE_ERROR_INSUFFICIENT_RESOURCES)
                    {
                      printf ("Adding to Whitelist Failed. List already full \r\n");
                    }
                    else if (apiResult ==CYBLE_ERROR_DEVICE_ALREADY_EXISTS)
                    {
                        printf ("Device Already exists \r\n");
                    }
                    else if (apiResult == CYBLE_ERROR_OK)
                    {
                        //Copying the address to the BackUp Array
                        whitelistdeviceaddressBackup[Index] = whitelistdeviceaddress; 
                        Index++;
                        printf ("Device Added to WhiteList\r\n");
                        printf ("Press A to Add or R to remove a from Whitelist \r\n");
                    }
                    
                    // Restarting the advertisement
                    apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
                    if (apiResult == CYBLE_ERROR_OK)
                    {
                        printf ("Restarting Advertisement \r\n");
                        GREEN_LED_ON ();
                    }
                    else
                    {
                        printf ("Error Start Adv %d \r\n",apiResult);
                    }
                }
                if (DelRequest == 1)
                {
                    DelRequest = 0;
                    //Removing the Device from Whitelist
                    apiResult = CyBle_GapRemoveDeviceFromWhiteList 
                    (&whitelistdeviceaddressBackup[RemoveIndex]);
                    if (apiResult == CYBLE_ERROR_OK)
                    {
                        
                        uint8 j;
                        for (j = RemoveIndex; j<Index - 1; j++)
                        {
                            whitelistdeviceaddressBackup[j] = 
                            whitelistdeviceaddressBackup[j+1];
                        }
                        Index--;
                                                                                                                      
                        printf ("Device %d Removed from Whitelist\r\n",RemoveIndex + 1);
                        printf ("Press A to Add a Device or R to remove a device\r\n");
                    }
                    else if (apiResult == CYBLE_ERROR_NO_DEVICE_ENTITY)
                    {
                        printf ("No Such Device Exists. Press A to Add a Device or R to remove\r\n");
                    }
                    else 
                    {
                        printf ("Error: Operation cannot be performed");
                        printf ("Press A to Add a Device or R to remove\r\n");
                    }
                    //re-starting Advertisement
                    apiResult = CyBle_GappStartAdvertisement (CYBLE_ADVERTISING_FAST);
                    if (apiResult == CYBLE_ERROR_OK)
                    {
                        printf ("Restarting Advertisement\r\n");
                    }
                    else
                    {
                        printf ("Restarting Advertisement Failed\r\n");
                    }
                }
            }
            
		default:
			break;
	}
}
Exemplo n.º 19
0
/*******************************************************************************
* Function Name: BLE_StackEventHandler
********************************************************************************
*
* Summary:
*   BLE stack generic event handler routine for handling connection, discovery, 
*   security etc. events.
*
* Parameters:  
*  event - event that triggered this callback
*  eventParam - parameters for the event.
*
* Return: 
*  None
*******************************************************************************/
void BLE_StackEventHandler(uint32 event, void* eventParam)
{
#if (RESTART_ADV_ON_DISCONNECTION)    
    CYBLE_API_RESULT_T apiResult;
#endif /* End of #if (RESTART_ADV_ON_DISCONNECTION) */
    CYBLE_GATTC_ERR_RSP_PARAM_T *errorResponse;
    
    switch (event)
	{
        /**********************************************************
        *                       General Events
        ***********************************************************/
		case CYBLE_EVT_STACK_ON: /* This event is received when component is Started */
            /* Enter in to discoverable mode so that remote can search it. */
            (void) CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);  
            
#if(CONSOLE_LOG_ENABLED)
            printf("Advertising... \r\n\n");
#endif /* End of #if(CONSOLE_LOG_ENABLED) */             
            break;
            
		case CYBLE_EVT_TIMEOUT:            
#if (BLE_GATT_CLIENT_ENABLE)
            if(*(uint8 *)eventParam == CYBLE_GATT_RSP_TO && bleStatus == BLE_DISCOVEER_GATT_SERVICES)
            {
                /* The peer device didn't respond to service discovery, enable RTC in free run mode if configured */
                bleStatus = BLE_TIME_SERVER_ABSENT;
#if (RTC_ENABLE)
                RTC_Start();
#endif /* End of #if (RTC_ENABLE) */

#if DISCONNECT_BLE_AFTER_TIME_SYNC               
                BLE_RequestDisconnection();
#endif /* End of #if DISCONNECT_BLE_AFTER_TIME_SYNC */
            }
#endif /* End of #if (BLE_GATT_CLIENT_ENABLE) */    

			break;     
        /**********************************************************
        *                       GAP Events
        ***********************************************************/

        case CYBLE_EVT_GAP_AUTH_COMPLETE:
            /* we initiated the authentication with the iOS device and the authentication is now complete. Proceed
             * to characteristic value read after this */
            bleStatus = BLE_READ_TIME;
            break;    
            
        case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
#if RESTART_ADV_ON_DISCONNECTION            
            BLE_Engine_Reinit(); /* Re-initialize application data structures */
            /* Put the device to discoverable mode so that remote can search it. */
            apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            
            if(apiResult != CYBLE_ERROR_OK)
            {
                CYASSERT(0);    
            }
#endif  /* End of #if RESTART_ADV_ON_DISCONNECTION */
            break;    
        /**********************************************************
        *                       GATT Events
        ***********************************************************/
        case CYBLE_EVT_GATT_CONNECT_IND:
            bleStatus = BLE_CONNECTED;
            break;
            
        case CYBLE_EVT_GATT_DISCONNECT_IND:
            bleStatus = BLE_DISCONNECTED;
#if(CONSOLE_LOG_ENABLED)
            printf("Disconnected!\r\n\n");
#endif    
            break;
            
        case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE:
            if(cyBle_ctsc.currTimeCharacteristics[CYBLE_CTS_CURRENT_TIME].valueHandle == 0x0000)
            {
                bleStatus = BLE_TIME_SERVER_ABSENT;
                
#if (RTC_ENABLE)/* If the time server is absent, let the RTC run in free run mode */
                RTC_Start();
#endif /* End of #if (RTC_ENABLE) */

#if DISCONNECT_BLE_AFTER_TIME_SYNC               
                BLE_RequestDisconnection();
#endif /* End of #if DISCONNECT_BLE_AFTER_TIME_SYNC */
            }
            else
            {
                bleStatus = BLE_READ_TIME;
            }
            break;
            
        case CYBLE_EVT_GATTC_ERROR_RSP:
            errorResponse = (CYBLE_GATTC_ERR_RSP_PARAM_T*) eventParam;
            
            /* characteristic read requires an authenticated link */
            if(errorResponse -> errorCode == CYBLE_GATT_ERR_INSUFFICIENT_AUTHENTICATION)
            {
                bleStatus = BLE_INITIATE_AUTHENTICATION;
            }
            break;   
            
        default:            
			break;
	}
}
Exemplo n.º 20
0
/*******************************************************************************
* Function Name: GenericEventHandler
********************************************************************************
* Summary:
*        Event handler function for the BLE stack. All the events by BLE stack
* are received by application through this function. For this, CyBle_ProcessEvents()
* should be called continuously in main loop.
*
* Parameters:
*  event: 		event value
*  eventParame: pointer to the location where relevant event data is stored
*
* Return:
*  void
*
*******************************************************************************/
void GenericEventHandler(uint32 event, void * eventParam)
{
	/* Local variables and data structures*/
	CYBLE_GATTS_WRITE_REQ_PARAM_T 		writeReqData;
	CYBLE_GATTC_WRITE_REQ_T				writeADVcounterdata;
	CYBLE_GAPC_ADV_REPORT_T				scan_report;
	CYBLE_GATTS_WRITE_CMD_REQ_PARAM_T	writeCmdData;
	CYBLE_API_RESULT_T					apiResult;
	CYBLE_GATTC_WRITE_REQ_T 			writeRGBdata;
	
	switch(event)
	{
		case CYBLE_EVT_STACK_ON:
			#ifdef DEBUG_ENABLED
			UART_UartPutString("CYBLE_EVT_STACK_ON ");
			UART_UartPutCRLF(' ');
			#endif
			/* At the start of the BLE stack, start advertisement */
			CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
		break;
			
		case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
			/* This event is received at every start or stop of peripheral advertisement*/
			#ifdef DEBUG_ENABLED
			UART_UartPutString("CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP ");
			SendBLEStatetoUART(CyBle_GetState());
			UART_UartPutCRLF(' ');
			#endif
			
			if((CYBLE_STATE_DISCONNECTED == CyBle_GetState()) && (switch_Role == FALSE))
			{
				/* If the current state of the BLE is Disconnected, then restart advertisement.
				* Note that the advertisement should only be restarted if the switch flag is not
				* TRUE. If switch role flag is TRUE, then there is no need to start advertisement
				* as the GAP role has to be switched*/
				CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);	
				
				if(apiResult == CYBLE_ERROR_OK)
				{
					#ifdef DEBUG_ENABLED
					UART_UartPutString("Restart Advertisement ");
					SendBLEStatetoUART(CyBle_GetState());
					UART_UartPutCRLF(' ');
					#endif
				}
			}
		break;
			
		case CYBLE_EVT_GAPC_SCAN_START_STOP:
			/* This event is received at every start or stop of central scanning*/
			#ifdef DEBUG_ENABLED
			UART_UartPutString("CYBLE_EVT_GAPC_SCAN_START_STOP ");
			SendBLEStatetoUART(CyBle_GetState());
			UART_UartPutCRLF(' ');
			#endif
		break;
			
		case CYBLE_EVT_GATT_CONNECT_IND:
			/* This event is received at GATT connection with a device. This event
			* is received for both Client or Server role */
			#ifdef DEBUG_ENABLED
			UART_UartPutString("CYBLE_EVT_GATT_CONNECT_IND ");
			UART_UartPutCRLF(' ');
			#endif
		break;
		
		case CYBLE_EVT_GATT_DISCONNECT_IND:
			/* This event is received at GATT disconnection with a device. This event
			* is received for both Client or Server role */
			#ifdef DEBUG_ENABLED
			UART_UartPutString("CYBLE_EVT_GATT_DISCONNECT_IND ");
			UART_UartPutCRLF(' ');
			#endif
		break;
			
		case CYBLE_EVT_GATTS_WRITE_REQ:
			/* This event is received at when Server receives a Write request from
			* connected Client device */
			/* Save the associated event parameter in local variable */
			writeReqData = *(CYBLE_GATTS_WRITE_REQ_PARAM_T*)eventParam;

			if(writeReqData.handleValPair.attrHandle == CYBLE_RGB_LED_CONTROL_CHAR_HANDLE)
			{
				/* If the Write request is on RGB LED Control Characteristic, then Client is 
				* trying to set a new color to the device. */
				if(writeReqData.handleValPair.value.len == RGB_LED_DATA_LEN)
				{
					#ifdef DEBUG_ENABLED
						UART_UartPutString("RGB CYBLE_EVT_GATTS_WRITE_REQ ");
						UART_UartPutCRLF(' ');
					#endif
					
					/* Extract the four bytes containing the color value and store it */
					RGBData[RGB_RED_INDEX] = writeReqData.handleValPair.value.val[0];
					RGBData[RGB_GREEN_INDEX] = writeReqData.handleValPair.value.val[1];
					RGBData[RGB_BLUE_INDEX] = writeReqData.handleValPair.value.val[2];
					RGBData[RGB_INTENSITY_INDEX] = writeReqData.handleValPair.value.val[3];
					
					/* Modify RGB Color my configuring the PrISM components with new density 
					* value*/
					UpdateRGBled(RGBData, RGB_LED_DATA_LEN);
					
					/* Update the RGB LED Control characteristic in GATT DB  to allow
					* Client to read the latest RGB LED color value set */
					CyBle_GattsWriteAttributeValue(&writeReqData.handleValPair,0,&cyBle_connHandle,CYBLE_GATT_DB_LOCALLY_INITIATED);
							
					#ifdef ENABLE_ADV_DATA_COUNTER
					/* Increment the ADV data counter so that scanning Central device knows
					* if this device has updated RGB LED data or not */
					dataADVCounter++;
					#endif
					
					#ifdef DEBUG_ENABLED
					UART_UartPutString("incremented dataADVCounter value in CYBLE_EVT_GATTS_WRITE_REQ= ");
					PrintNum(dataADVCounter);
					UART_UartPutCRLF(' ');
					#endif
					
					/* After receiveing the color value, set the switch role flag to allow the system
					* to switch role to Central role */
					switch_Role = TRUE;
					
					#ifdef DEBUG_ENABLED
					UART_UartPutString("switchRole to Central");
					UART_UartPutCRLF(' ');
					#endif
				}
				else
				{
					/* Send the error code for invalid attribute length packet */
					SendErrorCode(CYBLE_GATT_WRITE_REQ, 
									writeReqData.handleValPair.attrHandle, 
									ERR_INVALID_ATT_LEN);
					
					return;
				}
			}

			/* As part of every write request, the server needs to send a write response. Note
			* that this will be sent only if all the application layer conditions are met on a 
			* write request. Else, an appropriate error code is sent. */
	        CyBle_GattsWriteRsp(cyBle_connHandle);
		break;
			
		case CYBLE_EVT_GATTS_WRITE_CMD_REQ:
			/* This event is generated whenever a Client device sends a Write Command (Write 
			* without response) to a connected Server. Save the associated event parameter in
			* local variable. */
			writeCmdData = *(CYBLE_GATTS_WRITE_CMD_REQ_PARAM_T*)eventParam;
			
			/* Check if the Write command is for ADV Data counter characteristic */
			if(writeCmdData.handleValPair.attrHandle == CYBLE_RGB_DATA_COUNT_CHAR_HANDLE)
			{
				/* If the data sent is of one byte, then proceed. */
				if(writeCmdData.handleValPair.value.len == 1)
				{
					/* Extract and save the set ADV data counter value */
					dataADVCounter = *(writeCmdData.handleValPair.value.val);	
					
					/* This increment is done to balance the ++ done as part of CYBLE_EVT_GATTS_WRITE_REQ */
					dataADVCounter--;
					
					/* Update the ADV data counter characteristic in GATT DB  to allow
					* Client to read the latest ADV data counter value */
					CyBle_GattsWriteAttributeValue(&writeCmdData.handleValPair,
													0,
													&cyBle_connHandle,
													CYBLE_GATT_DB_LOCALLY_INITIATED);

					#ifdef DEBUG_ENABLED
					UART_UartPutString("dataADVCounter from CYBLE_EVT_GATTS_WRITE_CMD_REQ = ");
					PrintNum(dataADVCounter);
					UART_UartPutCRLF(' ');
					#endif
				}	/* if(writeCmdData.handleValPair.value.len == 1) */
			}
			break;
		
		case CYBLE_EVT_GAPC_SCAN_PROGRESS_RESULT:
			/* This event is generated whenever there is a peripheral device found by 
			* while scanning */
			if(CYBLE_STATE_CONNECTED != CyBle_GetState())	
			{
				/* If we are not connected to any peripheral device, then save the new device  
				* information so to add it to our list */
				scan_report = *(CYBLE_GAPC_ADV_REPORT_T*)eventParam;
				
				#ifdef DEBUG_ENABLED
					UART_UartPutString("CYBLE_EVT_GAPC_SCAN_PROGRESS_RESULT ");
					UART_UartPutCRLF(' ');
				#endif
				
				#ifdef ENABLE_ADV_DATA_COUNTER
				/* If ADV DATA COUNTER is enabled, then the central device would check
				* if the counter in ADV packet of peripheral is less than its own counter
				* or not. If yes, then it will consider the peripheral as a potential 
				* device to connect to.*/
				if(scan_report.eventType == CYBLE_GAPC_CONN_UNDIRECTED_ADV)
				{
					/* If the scan report received is of advertising nature and the data 
					* length is as expected... */
					if(scan_report.dataLen == new_advData.advDataLen)
					{
						/* If the second last value of the advertising data matches the custom 
						* marker, then the peripheral is a node of the network */
						if(scan_report.data[scan_report.dataLen-2] == CUSTOM_ADV_DATA_MARKER)
						{
							/* If the ADV counter data in Advertising data is less than that of
							* the value in this scanning device, then the node is a potential node 
							* whose color has to be updated. */
							if((scan_report.data[scan_report.dataLen-1] < dataADVCounter) ||
							((scan_report.data[scan_report.dataLen-1] == 255) && (dataADVCounter == 0)))
							{
								/* Potential node found*/
								potential_node_found = TRUE;
								/* Save the advertising peripheral address and type*/
								memcpy(potential_node_bdAddr, scan_report.peerBdAddr, 6);
								potential_node_bdAddrType = scan_report.peerAddrType;
								
								#ifdef DEBUG_ENABLED
								UART_UartPutString("potential_node_found ");
								UART_UartPutCRLF(' ');
								#endif
							}
							else
							{
								/* If the ADV data counter is equal or more than the data counter
								* in this scanning device, then the node has latest RGB LED data
								* and does not need to be connected to. Reset the potential node 
								* address */
								potential_node_found = FALSE;
								
								potential_node_bdAddrType = 0;
								
								potential_node_bdAddr[0] = 0x00;
								potential_node_bdAddr[1] = 0x00;
								potential_node_bdAddr[2] = 0x00;
								potential_node_bdAddr[3] = 0x00;
								potential_node_bdAddr[4] = 0x00;
								potential_node_bdAddr[5] = 0x00;
							}
						}
					}
				}
				#endif
				
				/* If the received scan data is part of scan response from a peripheral... */
				if(scan_report.eventType == CYBLE_GAPC_SCAN_RSP)
				{
					/* If the data lenght of the scan reponse packet is equal to expected
					* scan response data lenght...*/
					if(scan_report.dataLen == SCAN_TAG_DATA_LEN)
					{
						#ifdef ENABLE_ADV_DATA_COUNTER
						/* If a potential node had been found earlier as part of received 
						* advertising data, then compare the address of stored potential 
						* node and received address of the scan response */
						if(potential_node_found)
						{
							/* Compare the two addresses and type */
							if((!memcmp(scan_report.peerBdAddr, potential_node_bdAddr, 6))  
								&& (potential_node_bdAddrType == scan_report.peerAddrType))
							{
						#endif
								/* If the scan report data matches the expected data (scan_tag),
								* then it is our desired node */
								if(!memcmp(scan_report.data, scan_tag, scan_report.dataLen))
								{
									#ifdef DEBUG_ENABLED
									UART_UartPutString("Titan Found ");
									UART_UartPutCRLF(' ');
									#endif
									/* Stop existing scan */
									CyBle_GapcStopScan();
									#ifdef DEBUG_ENABLED
									UART_UartPutString("Stop Scan called ");
									UART_UartPutCRLF(' ');
									#endif
									
									/* Save the peripheral BD address and type*/
									peripAddr.type = scan_report.peerAddrType;
									peripAddr.bdAddr[0] = scan_report.peerBdAddr[0];
									peripAddr.bdAddr[1] = scan_report.peerBdAddr[1];
									peripAddr.bdAddr[2] = scan_report.peerBdAddr[2];
									peripAddr.bdAddr[3] = scan_report.peerBdAddr[3];
									peripAddr.bdAddr[4] = scan_report.peerBdAddr[4];
									peripAddr.bdAddr[5] = scan_report.peerBdAddr[5];

									/* Set the flag to allow application to connect to the
									* peripheral found */
									clientConnectToDevice = TRUE;
									
									#ifdef ENABLE_ADV_DATA_COUNTER
									/* Reset the potential node flag*/
									potential_node_found = FALSE;
									#endif
								}
						#ifdef ENABLE_ADV_DATA_COUNTER
							}
						}
						#endif
					}
				}
			}

		break;
			
		case CYBLE_EVT_GAP_DEVICE_CONNECTED:
			/* This event is received whenever the device connect on GAP layer */
			if(ble_gap_state == BLE_CENTRAL)
			{
				#ifdef ENABLE_CENTRAL_DISCOVERY
					/* The Device is connected now. Start Attributes discovery process.*/
					CyBle_GattcStartDiscovery(cyBle_connHandle);
					#ifdef DEBUG_ENABLED
						UART_UartPutString("CYBLE_EVT_GAP_DEVICE_CONNECTED ");
						SendBLEStatetoUART(CyBle_GetState());
						UART_UartPutCRLF(' ');
					#endif
				#else
					/* If this system is currently acting in Central role and has connected
					* to a peripheral device, then write directly the ADV counter data and
					* RGB LED control data using attribute handles */
					
					/* Set the device connected flag */
					deviceConnected = TRUE;
					
					#ifdef DEBUG_ENABLED
						UART_UartPutString("Directly write RGB using Attr handle ");
						SendBLEStatetoUART(CyBle_GetState());
						UART_UartPutCRLF(' ');
					#endif
					
					/* Write the Data Counter value */
					writeADVcounterdata.attrHandle = CYBLE_RGB_DATA_COUNT_CHAR_HANDLE;
					writeADVcounterdata.value.val = &dataADVCounter;
					writeADVcounterdata.value.len = 1;
					CyBle_GattcWriteWithoutResponse(cyBle_connHandle, &writeADVcounterdata);
				
					/* Write the RGB LED Value */
					writeRGBdata.attrHandle = CYBLE_RGB_LED_CONTROL_CHAR_HANDLE;
					writeRGBdata.value.val = RGBData;
					writeRGBdata.value.len = RGB_LED_DATA_LEN;
					CyBle_GattcWriteCharacteristicValue(cyBle_connHandle, &writeRGBdata);
				#endif
			}	
        break;
			
		case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE:
			/* This event is generated whenever the discovery procedure is complete*/
			
			#ifdef ENABLE_CENTRAL_DISCOVERY
			deviceConnected = TRUE;
			#ifdef DEBUG_ENABLED
				UART_UartPutString("CYBLE_EVT_GATTC_DISCOVERY_COMPLETE ");
				SendBLEStatetoUART(CyBle_GetState());
				UART_UartPutCRLF(' ');
			#endif
			
			/* Write the Data Counter value */
			writeADVcounterdata.attrHandle = CYBLE_RGB_DATA_COUNT_CHAR_HANDLE;
			writeADVcounterdata.value.val = &dataADVCounter;
			writeADVcounterdata.value.len = 1;
			CyBle_GattcWriteWithoutResponse(cyBle_connHandle, &writeADVcounterdata);
		
			/* Write the RGB LED Value */
			writeRGBdata.attrHandle = CYBLE_RGB_LED_CONTROL_CHAR_HANDLE;
			writeRGBdata.value.val = RGBData;
			writeRGBdata.value.len = RGB_LED_DATA_LEN;
			CyBle_GattcWriteCharacteristicValue(cyBle_connHandle, &writeRGBdata);
			#endif
		break;
			
		case CYBLE_EVT_GATTC_WRITE_RSP:
			/* This event is generated when the Client device receives a response
			* as part of the Write request sent earlier. This indicates that
			* the RGB LED data was written successfully */
			#ifdef DEBUG_ENABLED
				UART_UartPutString("CYBLE_EVT_GATTC_WRITE_RSP ");
				SendBLEStatetoUART(CyBle_GetState());
				UART_UartPutCRLF(' ');
			#endif
			
			/* Disconnect the existing connection and restart scanning */
			if((cyBle_connHandle.bdHandle != 0))
			{
				CyBle_GapDisconnect(cyBle_connHandle.bdHandle);
				
				restartScanning = TRUE;
				#ifdef DEBUG_ENABLED
				UART_UartPutString("Disconnect from CYBLE_EVT_GATTC_WRITE_RSP ");
				SendBLEStatetoUART(CyBle_GetState());
				UART_UartPutCRLF(' ');
				#endif
			}
		break;

		case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
			/* This event is generated when the device disconnects from an 
			* existing connection */
			deviceConnected = FALSE;
			
			#ifdef DEBUG_ENABLED
				UART_UartPutString("CYBLE_EVT_GAP_DEVICE_DISCONNECTED ");
				SendBLEStatetoUART(CyBle_GetState());
				UART_UartPutCRLF(' ');
			#endif
			
			if((ble_gap_state == BLE_PERIPHERAL) && (switch_Role != TRUE))
			{
				/* If the current role of this system was Peripheral and the role
				* is not to be switched, then restart advertisement */
				if(CYBLE_STATE_DISCONNECTED == CyBle_GetState())
				{
					CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);	
					#ifdef DEBUG_ENABLED
					UART_UartPutString("Restart Advertisement ");
					SendBLEStatetoUART(CyBle_GetState());
					UART_UartPutCRLF(' ');
					#endif
				}
			}
			else if((ble_gap_state == BLE_CENTRAL) && (switch_Role != TRUE))
			{
				/* If the current role of this system was Central and the role
				* is not to be switched, then restart scanning */
				if(CYBLE_STATE_DISCONNECTED == CyBle_GetState())
				{
					CyBle_GapcStartScan(CYBLE_SCANNING_FAST);	
					#ifdef DEBUG_ENABLED
					UART_UartPutString("Restart Scanning ");
					SendBLEStatetoUART(CyBle_GetState());
					UART_UartPutCRLF(' ');
					#endif
				}	
			}
		break;
			
		default:
			eventParam = eventParam;
		break;
	}
}
Exemplo n.º 21
0
void StackEventHandler(uint32 event, void *eventParam) {
    switch (event) {
        //======================================================
        // Mandatory events to be handled
        //======================================================
        case CYBLE_EVT_STACK_ON:
            // Disable CCCD notification
            initializeCounterCccDescriptor();

            // Start BLE advertisement for 30 seconds 
            CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);

            // Initialize descriptor
            initializeRgbDescriptor();

            break;

        //======================================================
        //  GAP Events
        //======================================================
        case CYBLE_EVT_GAP_DEVICE_CONNECTED:
            // BLE link is established
            break;

        case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
            // Disable CCCD notification
            initializeCounterCccDescriptor();
        
            // Start BLE advertisement for 30 seconds 
            CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            break;
        
        //======================================================
        //  GATT Events
        //======================================================
        case CYBLE_EVT_GATT_CONNECT_IND:
            // This event is received when device is connected
            // over GATT level
			
            // Update attribute handle on GATT Connection
            connectionHandle = *(CYBLE_CONN_HANDLE_T  *)eventParam;
			
            // This flag is used in application
            // to check connection status
			deviceConnected = 1;
			
            break;
        
        case CYBLE_EVT_GATT_DISCONNECT_IND:
            // This event is received when device is disconnected
			
            // Update deviceConnected flag
            deviceConnected = 0;
			
            break;
            
        case CYBLE_EVT_GATTS_WRITE_REQ:
            // This event is received when Central device sends
            {
                CYBLE_GATTS_WRITE_REQ_PARAM_T *writeReqParam;

                // a Write command on an Attribute
                writeReqParam =
                    (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam;

                // When this event is triggered, the peripheral has
                // received a write command on the custom characteristic
                // Check if the returned handle is matching to
                // Counter CCCD Write Attribute
                if (writeReqParam->handleValPair.attrHandle
                    == COUNTER_CCC_HANDLE
                ) {
                    queueCounterCccDescriptor(
                        &(writeReqParam->handleValPair.value)
                    );
                }

                // Check if the returned handle is matching to
                // RGB Control Write Attribute
                if (writeReqParam->handleValPair.attrHandle
                    == RGB_CHAR_HANDLE
                ) {
                    queueRgbDescriptor(
                        &(writeReqParam->handleValPair.value)
                    );
                }

                // Send the response to the write request received.
                CyBle_GattsWriteRsp(connectionHandle);
            }
            break;
            
        default:
            break;
    }
}
Exemplo n.º 22
0
/*******************************************************************************
* Function Name: AppCallBack()
********************************************************************************
*
* Summary:
*   This is an event callback function to receive events from the BLE Component.
*
*******************************************************************************/
void AppCallBack(uint32 event, void* eventParam)
{
    CYBLE_API_RESULT_T apiResult;
    CYBLE_GAP_BD_ADDR_T localAddr;
    CYBLE_GAP_AUTH_INFO_T *authInfo;
    uint8 i;
    
    switch (event)
	{
        /**********************************************************
        *                       General Events
        ***********************************************************/
		case CYBLE_EVT_STACK_ON: /* This event is received when the component is Started */
            /* Enter into discoverable mode so that remote can search it. */
            apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            if(apiResult != CYBLE_ERROR_OK)
            {
                DBG_PRINTF("StartAdvertisement API Error: %d \r\n", apiResult);
            }
            DBG_PRINTF("Bluetooth On, StartAdvertisement with addr: ");
            localAddr.type = 0u;
            CyBle_GetDeviceAddress(&localAddr);
            for(i = CYBLE_GAP_BD_ADDR_SIZE; i > 0u; i--)
            {
                DBG_PRINTF("%2.2x", localAddr.bdAddr[i-1]);
            }
            DBG_PRINTF("\r\n");
            break;
		case CYBLE_EVT_TIMEOUT: 
            break;
		case CYBLE_EVT_HARDWARE_ERROR:    /* This event indicates that some internal HW error has occurred. */
            DBG_PRINTF("CYBLE_EVT_HARDWARE_ERROR \r\n");
			break;
            
    	/* This event will be triggered by host stack if BLE stack is busy or not busy.
    	 *  Parameter corresponding to this event will be the state of BLE stack.
    	 *  BLE stack busy = CYBLE_STACK_STATE_BUSY,
    	 *  BLE stack not busy = CYBLE_STACK_STATE_FREE 
         */
    	case CYBLE_EVT_STACK_BUSY_STATUS:
            DBG_PRINTF("CYBLE_EVT_STACK_BUSY_STATUS: %x\r\n", *(uint8 *)eventParam);
            break;
        case CYBLE_EVT_HCI_STATUS:
            DBG_PRINTF("CYBLE_EVT_HCI_STATUS: %x \r\n", *(uint8 *)eventParam);
			break;
            
        /**********************************************************
        *                       GAP Events
        ***********************************************************/
        case CYBLE_EVT_GAP_AUTH_REQ:
            DBG_PRINTF("CYBLE_EVT_AUTH_REQ: security=%x, bonding=%x, ekeySize=%x, err=%x \r\n", 
                (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).security, 
                (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).bonding, 
                (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).ekeySize, 
                (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).authErr);
            break;
        case CYBLE_EVT_GAP_PASSKEY_ENTRY_REQUEST:
            DBG_PRINTF("CYBLE_EVT_PASSKEY_ENTRY_REQUEST press 'p' to enter passkey \r\n");
            break;
        case CYBLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST:
            DBG_PRINTF("CYBLE_EVT_PASSKEY_DISPLAY_REQUEST %6.6ld \r\n", *(uint32 *)eventParam);
            break;
        case CYBLE_EVT_GAP_KEYINFO_EXCHNGE_CMPLT:
            DBG_PRINTF("CYBLE_EVT_GAP_KEYINFO_EXCHNGE_CMPLT \r\n");
            break;
        case CYBLE_EVT_GAP_AUTH_COMPLETE:
            authInfo = (CYBLE_GAP_AUTH_INFO_T *)eventParam;
            (void)authInfo;
            DBG_PRINTF("AUTH_COMPLETE: security:%x, bonding:%x, ekeySize:%x, authErr %x \r\n", 
                                    authInfo->security, authInfo->bonding, authInfo->ekeySize, authInfo->authErr);
            break;
        case CYBLE_EVT_GAP_AUTH_FAILED:
            DBG_PRINTF("CYBLE_EVT_AUTH_FAILED: %x \r\n", *(uint8 *)eventParam);
            break;
        case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
            DBG_PRINTF("CYBLE_EVT_ADVERTISING, state: %x \r\n", CyBle_GetState());
            if(CYBLE_STATE_DISCONNECTED == CyBle_GetState())
            {   
                /* Fast and slow advertising period complete, go to low power  
                 * mode (Hibernate mode) and wait for an external
                 * user event to wake up the device again */
                DBG_PRINTF("Hibernate \r\n");
                LED_BLU_Write(LED_OFF);
                LED_RED_Write(LED_ON);
                LED_GRN_Write(LED_OFF);
                SW2_ClearInterrupt();
                Wakeup_Interrupt_ClearPending();
                Wakeup_Interrupt_Start();
            #if (DEBUG_UART_ENABLED == ENABLED)
                /* Wait until debug info is sent */
                while((UART_DEB_SpiUartGetTxBufferSize() + UART_DEB_GET_TX_FIFO_SR_VALID) != 0);
            #endif /* (DEBUG_UART_ENABLED == ENABLED) */
                CySysPmHibernate();
            }
            break;
        case CYBLE_EVT_GAP_DEVICE_CONNECTED:
            DBG_PRINTF("CYBLE_EVT_GAP_DEVICE_CONNECTED \r\n");
            LED_BLU_Write(LED_OFF);
            break;
        case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
            DBG_PRINTF("CYBLE_EVT_GAP_DEVICE_DISCONNECTED\r\n");
            apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            if(apiResult != CYBLE_ERROR_OK)
            {
                DBG_PRINTF("StartAdvertisement API Error: %d \r\n", apiResult);
            }
            break;
        case CYBLE_EVT_GATTS_XCNHG_MTU_REQ:
            { 
                uint16 mtu;
                CyBle_GattGetMtuSize(&mtu);
                DBG_PRINTF("CYBLE_EVT_GATTS_XCNHG_MTU_REQ, final mtu= %d \r\n", mtu);
            }
            break;
        case CYBLE_EVT_GATTS_WRITE_REQ:
            DBG_PRINTF("CYBLE_EVT_GATT_WRITE_REQ: %x = ",((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.attrHandle);
            ShowValue(&((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.value);
            (void)CyBle_GattsWriteRsp(((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->connHandle);
            break;
        case CYBLE_EVT_GAP_ENCRYPT_CHANGE:
            DBG_PRINTF("CYBLE_EVT_GAP_ENCRYPT_CHANGE: %x \r\n", *(uint8 *)eventParam);
            break;
        case CYBLE_EVT_GAPC_CONNECTION_UPDATE_COMPLETE:
            DBG_PRINTF("CYBLE_EVT_CONNECTION_UPDATE_COMPLETE: %x \r\n", *(uint8 *)eventParam);
            break;
            
        /**********************************************************
        *                       GATT Events
        ***********************************************************/
        case CYBLE_EVT_GATT_CONNECT_IND:
            DBG_PRINTF("CYBLE_EVT_GATT_CONNECT_IND: %x, %x \r\n", cyBle_connHandle.attId, cyBle_connHandle.bdHandle);
            /* Register service specific callback functions */
            HidsInit();
            BasInit();
            ScpsInit();
            break;
        case CYBLE_EVT_GATT_DISCONNECT_IND:
            DBG_PRINTF("CYBLE_EVT_GATT_DISCONNECT_IND \r\n");
            break;
        case CYBLE_EVT_GATTS_READ_CHAR_VAL_ACCESS_REQ:
            /* Triggered on server side when client sends read request and when
            * characteristic has CYBLE_GATT_DB_ATTR_CHAR_VAL_RD_EVENT property set.
            * This event could be ignored by application unless it need to response
            * by error response which needs to be set in gattErrorCode field of
            * event parameter. */
            DBG_PRINTF("CYBLE_EVT_GATTS_READ_CHAR_VAL_ACCESS_REQ: handle: %x \r\n", 
                ((CYBLE_GATTS_CHAR_VAL_READ_REQ_T *)eventParam)->attrHandle);
            break;
            
        /**********************************************************
        *                       Other Events
        ***********************************************************/
		case CYBLE_EVT_PENDING_FLASH_WRITE:
            /* Inform application that flash write is pending. Stack internal data 
            * structures are modified and require to be stored in Flash using 
            * CyBle_StoreBondingData() */
            DBG_PRINTF("CYBLE_EVT_PENDING_FLASH_WRITE\r\n");
            break;

        default:
            DBG_PRINTF("OTHER event: %lx \r\n", event);
			break;
	}

}
Exemplo n.º 23
0
/*******************************************************************************
* Function Name: AppCallBack()
********************************************************************************
*
* Summary:
*   This finction handles events that are generated by BLE stack.
*
* Parameters:
*   None
*
* Return:
*   None
*
*******************************************************************************/
void AppCallBack(uint32 event, void* eventParam)
{
    CYBLE_API_RESULT_T apiResult;
    uint32  i = 0u;

    switch (event)
    {
    /**********************************************************
    *                       General Events
    ***********************************************************/
    case CYBLE_EVT_STACK_ON: /* This event received when component is Started */
        /* Enter in to discoverable mode so that remote can search it. */
        apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
        if(apiResult != CYBLE_ERROR_OK)
        {
        }
        break;
    case CYBLE_EVT_HARDWARE_ERROR:    /* This event indicates that some internal HW error has occurred. */
        DBG_PRINTF("CYBLE_EVT_HARDWARE_ERROR\r\n");
        break;


    /**********************************************************
    *                       GAP Events
    ***********************************************************/
    case CYBLE_EVT_GAP_AUTH_REQ:
        DBG_PRINTF("EVT_AUTH_REQ: security=%x, bonding=%x, ekeySize=%x, err=%x \r\n",
                   (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).security,
                   (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).bonding,
                   (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).ekeySize,
                   (*(CYBLE_GAP_AUTH_INFO_T *)eventParam).authErr);
        break;
    case CYBLE_EVT_GAP_PASSKEY_ENTRY_REQUEST:
        DBG_PRINTF("EVT_PASSKEY_ENTRY_REQUEST press 'p' to enter passkey \r\n");
        break;
    case CYBLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST:
        DBG_PRINTF("EVT_PASSKEY_DISPLAY_REQUEST %6.6ld \r\n", *(uint32 *)eventParam);
        break;
    case CYBLE_EVT_GAP_KEYINFO_EXCHNGE_CMPLT:
        DBG_PRINTF("EVT_GAP_KEYINFO_EXCHNGE_CMPLT \r\n");
        break;
    case CYBLE_EVT_GAP_AUTH_COMPLETE:
        DBG_PRINTF("AUTH_COMPLETE");
        break;
    case CYBLE_EVT_GAP_AUTH_FAILED:
        DBG_PRINTF("EVT_AUTH_FAILED: %x \r\n", *(uint8 *)eventParam);
        break;
    case CYBLE_EVT_GAP_DEVICE_CONNECTED:
        DBG_PRINTF("EVT_GAP_DEVICE_CONNECTED: %d \r\n", connHandle.bdHandle);
        LED_WRITE_MACRO(LED_OFF);
        break;
    case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
        DBG_PRINTF("EVT_GAP_DEVICE_DISCONNECTED\r\n");
        apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
        if(apiResult != CYBLE_ERROR_OK)
        {
            DBG_PRINTF("StartAdvertisement API Error: %d \r\n", apiResult);
        }
        break;
    case CYBLE_EVT_GAP_ENCRYPT_CHANGE:
        DBG_PRINTF("EVT_GAP_ENCRYPT_CHANGE: %x \r\n", *(uint8 *)eventParam);
        break;
    case CYBLE_EVT_GAPC_CONNECTION_UPDATE_COMPLETE:
        DBG_PRINTF("EVT_CONNECTION_UPDATE_COMPLETE: %x \r\n", *(uint8 *)eventParam);
        break;
    case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
        if(CYBLE_STATE_DISCONNECTED == CyBle_GetState())
        {
            /* Fast and slow advertising period complete, go to low power
             * mode (Hibernate mode) and wait for an external
             * user event to wake up the device again */
            DBG_PRINTF("Entering low power mode...\r\n");
            Bootloading_LED_Write(LED_ON);
            Advertising_LED_1_Write(LED_ON);
            Advertising_LED_2_Write(LED_ON);
            Bootloader_Service_Activation_ClearInterrupt();
            Wakeup_Interrupt_ClearPending();
            Wakeup_Interrupt_Start();
            CySysPmHibernate();
        }
        break;


    /**********************************************************
    *                       GATT Events
    ***********************************************************/
    case CYBLE_EVT_GATTS_WRITE_REQ:
        DBG_PRINTF("EVT_GATT_WRITE_REQ: %x = ",((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.attrHandle);
        for(i = 0; i < ((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.value.len; i++)
        {
            DBG_PRINTF("%2.2x ", ((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.value.val[i]);
        }
        DBG_PRINTF("\r\n");
        CyBle_GattsWriteAttributeValue(&((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair, 0u, \
                                       &((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->connHandle, CYBLE_GATT_DB_PEER_INITIATED);

        (void)CyBle_GattsWriteRsp(((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->connHandle);

        break;
    case CYBLE_EVT_GATT_CONNECT_IND:
        connHandle = *(CYBLE_CONN_HANDLE_T *)eventParam;
        break;
    case CYBLE_EVT_GATT_DISCONNECT_IND:
        connHandle.bdHandle = 0;
        break;
    case CYBLE_EVT_GATTS_WRITE_CMD_REQ:
        /* Pass packet to bootloader emulator */
        packetRXSize = ((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.value.len;
        memcpy(&packetRX[0], ((CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam)->handleValPair.value.val, packetRXSize);
        packetRXFlag = 1u;

        break;
    case CYBLE_EVT_GATTS_PREP_WRITE_REQ:
        (void)CyBle_GattsPrepWriteReqSupport(CYBLE_GATTS_PREP_WRITE_NOT_SUPPORT);
        break;
    case CYBLE_EVT_HCI_STATUS:
        DBG_PRINTF("CYBLE_EVT_HCI_STATUS\r\n");
    default:
        break;
    }
}
Exemplo n.º 24
0
void AppCallBack(uint32 event, void *eventParam)
{
	CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam;
    
   	switch (event)
   	{
	    case CYBLE_EVT_STACK_ON:
			/* start advertising */
	        apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
			
			if(apiResult == CYBLE_ERROR_OK)
			{
				
#ifdef 	LED_INDICATION	
				ADV_LED_ON();
#endif	/* LED_INDICATION */ 

			}
	        break;

	    case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
			
			sendNotifications = 0;
			
#ifdef	 ENABLE_SPI_ONLY_WHEN_CONNECTED	
			/* Stop SPI Slave operation */
			SPI_Stop();
			
#endif			
			
#ifdef 	LED_INDICATION
		    /* Indicate disconnect event to user */
			DISCON_LED_ON();
			
			CyDelay(3000); 
#endif	/* LED_INDICATION */ 

			/* start advertising */
	        apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
			
			if(apiResult == CYBLE_ERROR_OK)
			{
#ifdef 	LED_INDICATION	
				ADV_LED_ON();
#endif	/* LED_INDICATION */ 
			}	
	        break;    
     
	    case CYBLE_EVT_GATT_CONNECT_IND:
			
#ifdef 	LED_INDICATION	
			CONNECT_LED_ON();
#endif	/* LED_INDICATION */ 	
	        
#ifdef	 ENABLE_SPI_ONLY_WHEN_CONNECTED	
			/* Start SPI Slave operation */
			SPI_Start();
			
#endif	
			break;
        
	    /* Client may do Write Value or Write Value without Response. Handle both */   
	    case CYBLE_EVT_GATTS_WRITE_REQ:
	    case CYBLE_EVT_GATTS_WRITE_CMD_REQ:
	        wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam;
			
	        /* Handling Notification Enable */
			if(wrReqParam->handleValPair.attrHandle == CYBLE_SPI_READ_SPI_READ_DATA_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE)
	        {
				CYBLE_GATT_HANDLE_VALUE_PAIR_T    SPINotificationCCDHandle;
				uint8 SPICCDValue[2];
				
	            /* Extract CCCD Notification enable flag */
	            sendNotifications = wrReqParam->handleValPair.value.val[0];
				
				/* Write the present SPI notification status to the local variable */
				SPICCDValue[0] = sendNotifications;
				
				SPICCDValue[1] = 0x00;
				
				/* Update CCCD handle with notification status data*/
				SPINotificationCCDHandle.attrHandle = CYBLE_SPI_READ_SPI_READ_DATA_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE;
				
				SPINotificationCCDHandle.value.val = SPICCDValue;
				
				SPINotificationCCDHandle.value.len = 2;
				
				/* Report data to BLE component for sending data when read by Central device */
				CyBle_GattsWriteAttributeValue(&SPINotificationCCDHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_LOCALLY_INITIATED);			
	        }
				
	        /* Handling Write data from Client */
	        else if(wrReqParam->handleValPair.attrHandle == CYBLE_SPI_WRITE_SPI_WRITE_DATA_CHAR_HANDLE)
	        {
				while(SPI_SpiIsBusBusy())
				{
					
				}
				SPI_SpiUartClearTxBuffer();
				SPI_SpiUartPutArray(wrReqParam->handleValPair.value.val,wrReqParam->handleValPair.value.len);
					
	        }
	            
	        if (event == CYBLE_EVT_GATTS_WRITE_REQ)
			{
	            CyBle_GattsWriteRsp(cyBle_connHandle);
			}
	        break;
     
		default:
			break;
    }
}
Exemplo n.º 25
0
/*****************************************************************************
* Function Name: main()
******************************************************************************
* Summary:
*   Central function which controls the application flow.
*
* Parameters:
*   None.
*
* Return:
*   None.
*
* Note:
*
*****************************************************************************/
int main()
{
    // Init.
    InitializeSystem();

    // Wait for BLE component to finish initialization.
    while (CyBle_GetState() == CYBLE_STATE_INITIALIZING) {
        CyBle_ProcessEvents();
    } 

    //////////////////////////////////////////////////////////////////////////
    // Main Loop
    //////////////////////////////////////////////////////////////////////////
    for(;;)
    {

        // Process all the events in the stack.
        CyBle_ProcessEvents();


        #if LOWPOWERMODE_ENABLED
            // Put the BLESS in deepest sleep possible.
            CyBle_EnterLPM(CYBLE_BLESS_DEEPSLEEP);
        #endif

        //////////////////////////////////////////////////////////////////////
        // Device connected
        //////////////////////////////////////////////////////////////////////
        if (_BLE_deviceConnected) {
            
            // Update the CapSense CCCD.
            _BLE_UpdateCCCD();
            
            // Update the Control values.
            _BLE_UpdateControl();
            
            // If asked by client, send the status flags by notification or
            // indication.
            if (_BLE_sendStatus)
                _BLE_sendStatusFlags();
                

            #if LOWPOWERMODE_ENABLED
                // Handle the Capsense low power mode.
                LowPowerMode_Capsense();
            #endif
            
            // If asked by client, send the content of the vector containing
            // the CapSense data.
            if (_BLE_sendData) {
                SendData();
                // Allow DeepSleep between connection intervals.
                LowPowerMode_System_DeepSleepAllowed = TRUE;
            }
            
            // If asked by client, acquire CapSense data and store it in
            // the vector.
            else if (_BLE_acquireData || TEST_USB) {
                AcquireData();
                // Keep system in Active mode during scanning.
                LowPowerMode_System_DeepSleepAllowed = FALSE;
            }

            // If the 'acquireData' request is not present, but the vector
            // isn't empty, then no more data can be acquired.
            else if (!_BLE_acquireData && !vectorIsEmpty()) {
                ReadyToSendData();
                // Allow DeepSleep between connection intervals.
                LowPowerMode_System_DeepSleepAllowed = TRUE;
            }
            
            // If the 'sendData' and 'acquireData' requests are not present,
            // but the vector is empty, then data has been all sent and
            // it's ready to acquire new data.
            else if (!_BLE_sendData && !_BLE_acquireData && vectorIsEmpty()) {
                ReadyToAcquireData();
                // Allow DeepSleep between connection intervals.
                LowPowerMode_System_DeepSleepAllowed = TRUE;
            }
        }
        
        else
            // Allow DeepSleep between advertisement intervals.
            LowPowerMode_System_DeepSleepAllowed = TRUE;
        
        //////////////////////////////////////////////////////////////////////
        // Advertisement
        //////////////////////////////////////////////////////////////////////
        // Start advertisement if the flag is set in the BLE event handler.
        if (_BLE_restartAdvertisement) {
            // Reset the flag.
            _BLE_restartAdvertisement = FALSE;
            // Start advertisement.
            CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
        }
        
        //////////////////////////////////////////////////////////////////////
        // Reset
        //////////////////////////////////////////////////////////////////////
        // If the client is disconnected, reset everything as the program
        // would be is first started.
        if (_BLE_resetNeeded) {
            // Reset the flag.
            _BLE_resetNeeded = FALSE;
            // Reset everything that needs to.
            ResetSystem();
        }

        //////////////////////////////////////////////////////////////////////
        // Low Power Mode (Sleep)
        //////////////////////////////////////////////////////////////////////
        #if LOWPOWERMODE_ENABLED
            // Put the system in the deepest sleep possible.
            LowPowerMode_Sleep();
            // Reset flag.
            LowPowerMode_System_DeepSleepAllowed = FALSE;
        #endif
    }
}
Exemplo n.º 26
0
void AppCallBack(uint32 event, void *eventParam)
{
	uint8 i;
	CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam;
    
   	switch (event)
   	{
	    case CYBLE_EVT_STACK_ON:
			/* start advertising */
	        apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
			
			if(apiResult == CYBLE_ERROR_OK)
			{
				
#ifdef 	LED_INDICATION	
				ADV_LED_ON();
#endif	/* LED_INDICATION */ 

			}
	        break;

	    case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
			
			sendNotifications = 0;
			
#ifdef	 ENABLE_I2C_ONLY_WHEN_CONNECTED	
			/* Stop I2C Slave operation */
			I2C_Stop();
			
#endif			
			
#ifdef 	LED_INDICATION
		    /* Indicate disconnect event to user */
			DISCON_LED_ON();
			
			CyDelay(3000); 
#endif	/* LED_INDICATION */ 

			/* start advertising */
	        apiResult = CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
			
			if(apiResult == CYBLE_ERROR_OK)
			{
#ifdef 	LED_INDICATION	
				ADV_LED_ON();
#endif	/* LED_INDICATION */ 
			}	
	        break;    
     
	    case CYBLE_EVT_GATT_CONNECT_IND:
			
#ifdef 	LED_INDICATION	
			CONNECT_LED_ON();
#endif	/* LED_INDICATION */ 	
	        
#ifdef	 ENABLE_I2C_ONLY_WHEN_CONNECTED	
			/* Start I2C Slave operation */
			I2C_Start();
			
			/* Initialize I2C write buffer */
			I2C_I2CSlaveInitWriteBuf((uint8 *) wrBuf, I2C_WRITE_BUFFER_SIZE);
			
			/* Initialize I2C read buffer */
			I2C_I2CSlaveInitReadBuf((uint8 *) rdBuf, I2C_READ_BUFFER_SIZE);
#endif	
			break;
        
	    /* Client may do Write Value or Write Value without Response. Handle both */   
	    case CYBLE_EVT_GATTS_WRITE_REQ:
	    case CYBLE_EVT_GATTS_WRITE_CMD_REQ:
	        wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam;
			
	        /* Handling Notification Enable */
			if(wrReqParam->handleValPair.attrHandle == CYBLE_I2C_READ_I2C_READ_DATA_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE)
	        {
				CYBLE_GATT_HANDLE_VALUE_PAIR_T    I2CNotificationCCDHandle;
				uint8 I2CCCDValue[2];
				
	            /* Extract CCCD Notification enable flag */
	            sendNotifications = wrReqParam->handleValPair.value.val[0];
				
				/* Write the present I2C notification status to the local variable */
				I2CCCDValue[0] = sendNotifications;
				
				I2CCCDValue[1] = 0x00;
				
				/* Update CCCD handle with notification status data*/
				I2CNotificationCCDHandle.attrHandle = CYBLE_I2C_READ_I2C_READ_DATA_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE;
				
				I2CNotificationCCDHandle.value.val = I2CCCDValue;
				
				I2CNotificationCCDHandle.value.len = 2;
				
				/* Report data to BLE component for sending data when read by Central device */
				CyBle_GattsWriteAttributeValue(&I2CNotificationCCDHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_LOCALLY_INITIATED);			
	        }
				
	        /* Handling Write data from Client */
	        else if(wrReqParam->handleValPair.attrHandle == CYBLE_I2C_WRITE_I2C_WRITE_DATA_CHAR_HANDLE)
	        {
				/* Turn off I2C interrupt before updating read registers */
				I2C_DisableInt();
				
		        /*The data received from I2C client is extracted */
				for(i=0;i<(wrReqParam->handleValPair.value.len);i++)	
		        	rdBuf[i] = wrReqParam->handleValPair.value.val[i];
					
				/* Turn on I2C interrupt after updating read registers */
				I2C_EnableInt();	
	        }
	            
	        if (event == CYBLE_EVT_GATTS_WRITE_REQ)
			{
	            CyBle_GattsWriteRsp(cyBle_connHandle);
			}
	        break;
     
		default:
			break;
    }
}
Exemplo n.º 27
0
/*******************************************************************************
* Function Name: StackEventHandler()
********************************************************************************
* Summary:
* Event handler for the BLE events processing.
*
* Parameters:
* uint32 eventCode: The event to be processed
* void * eventParam: Pointer to hold the additional information associated 
*                    with an event
*
* Return:
* None
*
* Theory:
* The function is responsible for handling the events generated by the stack.
* It first starts advertisement once the stack is initialized. 
* Upon advertisement timeout or disconnect events, this function sets a flag
* to indicate to the main() function that it should enter Hibernate mode.
* 
* Once the device is connected, this function initiates an authentication 
* request. It displays a 6-digit passkey on the UART output on a PC and asks
* the user to enter this key on the iOS device (NP) side.
* Once the authentication is complete, the function starts the discovery 
* procedure to know whether ANCS service is supported by the peer device.
*
* When the automated service discovery is complete, the function starts a manual
* discovery procedure for the ANCS service (since the BLE component does not 
* handle discovery of custom services yet - that will be added as part of 
* Creator 3.2).
*
* When the automated service discovery is complete and the ANCS service is not 
* found, the function subscribes to the Service Changed characteristic 
* indication to know if and when the iOS device adds ANCS support later.
*
* Once the ANCS service is found and a new GATT Notification comes for any of 
* the ANCS characteristic, it calls the corresponding function in ANCS.c.
*
*******************************************************************************/
void StackEventHandler(uint32 eventCode, void * eventParam)
{
    CYBLE_GATTC_HANDLE_VALUE_NTF_PARAM_T * handleValueNotification;
    
    switch(eventCode)
    {
        case CYBLE_EVT_STACK_ON:
            /* Minor change in ADV packet for service solicitation */
            cyBle_discoveryData.advData[10] = 0x15;
            
            /* Start advertisement after stack is initialized */
            UART_UartPutString("\n\rAdvertising.");
            CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST);
            break;

            
        case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP:
            if(authState != AUTHENTICATION_BONDING_REMOVE_WAITING_EVENT)
            {
                if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED)
                {
                    UART_UartPutString("\n\rAdvertisement timed out. ");
                    UART_UartPutString("Going to Hibernate mode.");
                    
                    /* Enter hibernate mode upon advertisement timeout */
                    enterHibernateFlag = true;
                }
            }
            else
            {
                UART_UartPutString("\n\rAdvertisement stopped. ");
                authState = AUTHENTICATION_BONDING_REMOVE_GO_AHEAD;
            }
            break;
            
            
        case CYBLE_EVT_GAP_DEVICE_DISCONNECTED:
            /* Enter Hibernate mode upon disconnect 
             * Previous state is erased.
             */
            if(authState != AUTHENTICATION_BONDING_REMOVE_WAITING_EVENT)
            {
                UART_UartPutString("\n\rDisconnected. Going to Hibernate mode.");
                enterHibernateFlag = true;
            }
            else
            {
                UART_UartPutString("\n\rDisconnected. ");
                authState = AUTHENTICATION_BONDING_REMOVE_GO_AHEAD;
            }
            Ancs_Reset();
            break;
            
            
        case CYBLE_EVT_GAP_DEVICE_CONNECTED:
            UART_UartPutString("\n\rConnected to a peer device.");
            
            /* Send authentication request upon connection */
            CyBle_GapAuthReq(cyBle_connHandle.bdHandle, &cyBle_authInfo);
            break;
            
            
        case CYBLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST:
            UART_UartPutString("\n\rEnter this passkey in your iPhone: ");
            UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 5));
            UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 4));
            UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 3));
            UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 2));
            UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 1));
            UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 0));
            break;
            
            
        case CYBLE_EVT_GAP_AUTH_COMPLETE:
            /* Authentication complete; initiate service discovery procedure */
            UART_UartPutString("\n\rAuthentication complete. ");
            authState = AUTHENTICATION_COMPLETE_BONDING_REQD;
            CyBle_GattcStartDiscovery(cyBle_connHandle);
            break;
            
            
        case CYBLE_EVT_GAP_AUTH_FAILED:
            /* Authentication failed; enter Hibernate mode */
            UART_UartPutString("\n\rAuthentication failed. Going to Hibernate mode.");
            enterHibernateFlag = true;

            /* Update authentication state so that bond information could be 
             * removed later.
             */
            authState = AUTHENTICATION_BONDING_COMPLETE;
            break;
            
            
        case CYBLE_EVT_GATTC_INDICATION:
            /* Server's services changed; restart service discovery */
            UART_UartPutString("\n\rService changed indication. Redo service discovery.");
            Ancs_Reset();
            CyBle_GattcStartDiscovery(cyBle_connHandle);
            break;
            
            
        case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE:
            /* Automatic discovery does not cover discovery of service snd
             * characteristics with custom 128-bit UUIDs. This has to be done
             * manually. The Read by Group response for Service discovery covers
             * the ANCS custom service. For the ANCS service characteristics, the
             * Read by Type Request has to be sent by the application.
             */
            if(ANCS_DISC_SERVICE_DISCOVERED == ancsDiscoveryStatus)
            {
                CyBle_GattcDiscoverAllCharacteristics(cyBle_connHandle, ancsServiceRange);
            }
            else if(ANCS_DISC_NONE_DISCOVERED == ancsDiscoveryStatus)
            {
                UART_UartPutString("\n\rANCS service not found. ");
                
                /* Service discovery procedure complete; subscribe to the GATT
                 * Service changed indication by writing 0x02 to its CCCD.
                 */
                if((serviceChangedCccdWriteStatus == SERVICE_CHANGED_CCCD_WRITE_REQ_NOT_SENT) && 
                  (cyBle_gattc.serviceChanged.valueHandle != CYBLE_GATT_INVALID_ATTR_HANDLE_VALUE))
                {
                    serviceChangedCccdPacket.value = cccdIndFlagSetStruct;
                    serviceChangedCccdPacket.attrHandle = cyBle_gattc.cccdHandle;
                    CyBle_GattcWriteCharacteristicDescriptors(cyBle_connHandle, &serviceChangedCccdPacket);
                }
                
                /* Internal state machine tracking the CCCD status */
                serviceChangedCccdWriteStatus = SERVICE_CHANGED_CCCD_WRITE_REQ_SENT;
            }
            else
            {
                /* Other conditions need not be handled; they are handled
                 * in the event handler in ANCS.c.
                 */
            }
            break;
            
            
        case CYBLE_EVT_GATTC_READ_BY_GROUP_TYPE_RSP:
        case CYBLE_EVT_GATTC_READ_BY_TYPE_RSP:
        case CYBLE_EVT_GATTC_FIND_INFO_RSP:
        case CYBLE_EVT_GATTC_WRITE_RSP:
        case CYBLE_EVT_GATTC_ERROR_RSP:
            /* See if the events are for ANCS */
            Ancs_EventHandler(eventCode, eventParam);
            break;
            
            
        case CYBLE_EVT_GATTC_HANDLE_VALUE_NTF:
            /* See if the notification packet is for any ANCS characteristic */
            handleValueNotification = (CYBLE_GATTC_HANDLE_VALUE_NTF_PARAM_T *)eventParam;
            if(handleValueNotification->handleValPair.attrHandle == ancsNotifSourceCharHandle)
            {
                /* Notification source characteristic has a new notification */
                Ancs_HandleNotifications(handleValueNotification->handleValPair.value.val);
            }
            else if(handleValueNotification->handleValPair.attrHandle == ancsDataSourceCharHandle)
            {
                /* Data source characteristic has a new notification */
                Ancs_HandleData(handleValueNotification->handleValPair.value.val);
            }
            else
            {
                /* Some other characteristic notification; ignore */
            }
            break;
            
            
        default: 
            break;
    }
}