Exemplo n.º 1
0
Arquivo: MIDI.c Projeto: bhwj/BLE
/*******************************************************************************
* Function Name: IasEventHandler
********************************************************************************
*
* Summary:
*  This is an event callback function to receive events from the BLE Component,
*  which are specific to Immediate Alert Service.
*
* Parameters:
*  uint8 event:       Write Command event from the CYBLE component.
*  void* eventParams: A structure instance of CYBLE_GATT_HANDLE_VALUE_PAIR_T
*                     type.
*
* Return:
*  None
*
*******************************************************************************/
void MIDIEventHandler(uint32 event, void *eventParam)
{
    CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam;
    CYBLE_GATT_HANDLE_VALUE_PAIR_T midiNotificationCccdHandle;
    uint8 midiCccdUpdate = 0x01;
    
    switch(event)
    {
        case CYBLE_EVT_GATTS_WRITE_REQ:
            /* This event is received when iOS device sends a Write command on an Attribute */
            wrReqParam = (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 command is for correct attribute and update the flag for sending Notifications */
            if(CYBLE_MIDI_SERVICE_MIDI_IO_CHARATERISTIC_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE == wrReqParam->handleValPair.attrHandle)
        	{
        		/* Extract the Write value sent by the Client for CapSense Slider CCCD */
                enableMidi = wrReqParam->handleValPair.value.val[CYBLE_MIDI_SERVICE_MIDI_IO_CHARATERISTIC_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX];
        		
        		/* Update CCCD handle with notification status data*/
        		midiNotificationCccdHandle.attrHandle = CYBLE_MIDI_SERVICE_MIDI_IO_CHARATERISTIC_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE;
        		midiNotificationCccdHandle.value.val = &midiCccdUpdate;
        		midiNotificationCccdHandle.value.len = sizeof(midiCccdUpdate);
        		
        		/* Report data to BLE component for sending data when read by Central device */
        		CyBle_GattsWriteAttributeValue(&midiNotificationCccdHandle, 0, &cyBle_connHandle, CYBLE_GATT_DB_LOCALLY_INITIATED);
            }
            
            CyBle_GattsWriteRsp(cyBle_connHandle);
        break;
            
        case CYBLE_EVT_GATTS_WRITE_CMD_REQ:
           ServiceMidiOutData();
        break;
    }
}
Exemplo n.º 2
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.º 3
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.º 4
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.º 5
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.º 6
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.º 7
0
/*****************************************************************************
* Function Name: EventHandler()
******************************************************************************
* Summary:
*   Handles the events generated by stack and take necessary actions when
*   event is received.
*
* Parameters:
*   eventCode - the event code
*   *event_params - the event parameters
*
* Return:
*   None.
*
* Note:
*   
*****************************************************************************/
void EventHandler(uint32 eventCode, void *eventParam)
{
    // Local variable to store the data received as part of the Write request
    // events.
	CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam;
    
    // Log all the events.
    eventCodesLog[pointer++] = eventCode;
    
    switch(eventCode)
    {
        //////////////////////////////////////////////////////////////////////
        // General events
        //////////////////////////////////////////////////////////////////////
        // This event is received when the module is started.
        case CYBLE_EVT_STACK_ON: // eventCode == 0x01
            
            #if LOWPOWERMODE_ENABLED
                // Get the configured clock parameters for BLE subsystem.
                CyBle_GetBleClockCfgParam(&clockConfig);

                // Set the device sleep-clock accuracy (SCA) based on the
                // tuned ppm of the WCO.
                clockConfig.bleLlSca = CYBLE_LL_SCA_000_TO_020_PPM;

                // Set the clock parameter of BLESS with updated values.
                CyBle_SetBleClockCfgParam(&clockConfig);
            #endif
        
            // Start fast advertisement
			_BLE_restartAdvertisement = TRUE;
        
            break;
            
        
        // This event is received when there is a timeout and application  
        // needs to handle the event. Timeout reason is defined by 
        // CYBLE_TO_REASON_CODE_T.
        case CYBLE_EVT_TIMEOUT: // eventCode == 0x02
            
            // If triggered by the advertisement timeout.
            if( *(CYBLE_TO_REASON_CODE_T *)eventParam == CYBLE_GAP_ADV_MODE_TO ) {
            }
            
            break;
            
        
        // 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.
        case CYBLE_EVT_STACK_BUSY_STATUS: // eventCode == 0x05
			
			// Extract the present stack status.
            _BLE_busyStatus = *(uint8*)eventParam;
            
            break;
            
            
        //////////////////////////////////////////////////////////////////////
        // GAP events
        //////////////////////////////////////////////////////////////////////
        // This event is received by Peripheral and Central devices. When it is
        // received by Peripheral, peripheral needs to Call CyBle_GappAuthReqReply()
        // to reply to authentication request from Central.
        case CYBLE_EVT_GAP_AUTH_REQ: // eventCode == 0x21
            
            // Reply to the authentification request.
            CyBle_GappAuthReqReply(connectionHandle.bdHandle, &cyBle_authInfo);
            
            break;
            
        
        // Authentication process failed between two devices. The return value 
        // of type CYBLE_GAP_AUTH_FAILED_REASON_T indicates the reason for failure.
        case CYBLE_EVT_GAP_AUTH_FAILED: // eventCode == 0x25
            
            break;
                
            
        // If the current BLE state is Disconnected, then the Advertisement
    	// Start_Stop event implies that advertisement has stopped.
        case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: // eventCode == 0x26
            
            // Restart fast advertisement
            if(CyBle_GetState() != CYBLE_STATE_ADVERTISING)
                _BLE_restartAdvertisement = TRUE;
            
            break;
            
            
        // This event is generated at the GAP Peripheral end after 
        // connection is completed with peer Centra  device.
        case CYBLE_EVT_GAP_DEVICE_CONNECTED: // eventCode == 0x27
            
            break;

        
        // Disconnected from remote device or failed to establish
        // connection. Parameter returned with the event contains pointer to 
        // the reason for disconnection.
        case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: // eventCode == 0x28
            
            break;
            
            
        // This event is generated at the GAP Central and the Peripheral end
        // after connection parameter update is requested from the host to 
        // the controller. Event parameter is a pointer to a structure of type
        // CYBLE_GAP_CONN_PARAM_UPDATED_IN_CONTROLLER_T.
        case CYBLE_EVT_GAP_CONNECTION_UPDATE_COMPLETE: // eventCode == 0x2A
            
            break;
            
                
        //////////////////////////////////////////////////////////////////////
        // GATT events
        //////////////////////////////////////////////////////////////////////
        // This event is received when device is connected at GATT level.
        case CYBLE_EVT_GATT_CONNECT_IND: // eventCode == 0x41
        
			// Update attribute handle on GATT Connection.
            connectionHandle = *(CYBLE_CONN_HANDLE_T *)eventParam;
            
            // Set the connection status flag.
            _BLE_deviceConnected = TRUE;
            
            // Set all the flags for the current connection.
            updateSensorsCCCDreq = TRUE;
            updateControlValuesReq = TRUE;
            _BLE_UpdateCCCD();
            _BLE_UpdateControl();
            _BLE_writeStatusFlags();
            
            break;
        
        
        // This event is received when device is disconnected at GATT level.
        case CYBLE_EVT_GATT_DISCONNECT_IND: // eventCode == 0x42
            
            // Reset the connection status flag.
            _BLE_deviceConnected = FALSE;
            
            // Reset the connection status flag.
            _BLE_resetNeeded = TRUE;
            
            break;
            
            
        // 'MTU  Exchange  Request'  received  from  GATT  client  device. 
        // Event parameter contains the MTU size of type CYBLE_GATT_XCHG_MTU_PARAM_T. 
        case CYBLE_EVT_GATTS_XCNHG_MTU_REQ: // eventCode == 0x43
            
            // Establish the MTU that is going to be used during communication.
            negotiatedMtu = (((CYBLE_GATT_XCHG_MTU_PARAM_T *)eventParam)->mtu < CYBLE_GATT_MTU) ?
                            ((CYBLE_GATT_XCHG_MTU_PARAM_T *)eventParam)->mtu : CYBLE_GATT_MTU;
            
            break;
            
        
        // This event is received when Central device sends a Write command
        // on an Attribute.
        case CYBLE_EVT_GATTS_WRITE_REQ: // eventCode == 0x4C
            
            wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *) eventParam;
            
			// The peripheral has received a write command on the Sensors
            // Characteristic CCCD.
            if(CYBLE_CAPSENSE_SENSORS_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE ==
                wrReqParam->handleValPair.attrHandle)
            {
                // Extract the Write value sent by the Client CCCD.
                if( wrReqParam->handleValPair.value.val[CYBLE_CAPSENSE_SENSORS_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX] & CCCD_NTF_BIT_MASK )
                    sendDataNotifications = TRUE;
                else
                    sendDataNotifications = FALSE;
                
                if( wrReqParam->handleValPair.value.val[CYBLE_CAPSENSE_SENSORS_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX] & CCCD_IND_BIT_MASK )
				    sendDataIndications = TRUE;
                else
                    sendDataIndications = FALSE;
                
                // Set flag to allow CCCD to be updated.
				updateSensorsCCCDreq = TRUE;
            }
            
            // The peripheral has received a write command on the Control
            // Characteristic.
            else if(CYBLE_CAPSENSE_CONTROL_CHAR_HANDLE ==
                wrReqParam->handleValPair.attrHandle)
            {
                // Update 'acquireData' flag:
                    // FALSE only if 'Status_Acquiring' is TRUE;
                    // TRUE only if 'Status_Ready' is also TRUE.
                if ( Status_Acquiring && !wrReqParam->handleValPair.value.val[CONTROL_ACQUIRE_DATA_BYTE_MASK] )
                    _BLE_acquireData = FALSE;
                else if ( Status_Ready && wrReqParam->handleValPair.value.val[CONTROL_ACQUIRE_DATA_BYTE_MASK] )
                    _BLE_acquireData = TRUE;
                
                // Update 'sendData' flag:
                    // FALSE only if 'Status_NoMoreData' is TRUE;
                    // TRUE only if 'Status_DataAcquired' is also TRUE.
                if ( !wrReqParam->handleValPair.value.val[CONTROL_SEND_DATA_BYTE_MASK] && Status_NoMoreData )
                    _BLE_sendData = FALSE;
                else if ( wrReqParam->handleValPair.value.val[CONTROL_SEND_DATA_BYTE_MASK] && Status_DataAcquired )
                    _BLE_sendData = TRUE;
                
                // Update 'sendDataSyncronously' flag:
                    // FALSE only if 'Status_Acquiring' OR 'Status_Ready' is TRUE;
                    // TRUE only if 'Status_Ready' is also TRUE.
                if ( (Status_Acquiring || Status_Ready) && !wrReqParam->handleValPair.value.val[CONTROL_SEND_DATA_SYNCHRONOUSLY_BYTE_MASK] )
                    _BLE_sendDataSynchronously = FALSE;
                else if ( Status_Ready && wrReqParam->handleValPair.value.val[CONTROL_SEND_DATA_SYNCHRONOUSLY_BYTE_MASK] )
                    _BLE_sendDataSynchronously = TRUE;

                
                // Set the flag to allow the control values to be updated.
                updateControlValuesReq = TRUE;
            }
            
            // The peripheral has received a write command on the Status
            // Characteristic CCCD.
            else if(CYBLE_CAPSENSE_STATUS_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE ==
                wrReqParam->handleValPair.attrHandle)
            {
                // Extract the Write value sent by the Client CCCD.
                if( wrReqParam->handleValPair.value.val[CYBLE_CAPSENSE_STATUS_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX] & CCCD_NTF_BIT_MASK )
                    sendStatusNotifications = TRUE;
                else
                    sendStatusNotifications = FALSE;
                
                if( wrReqParam->handleValPair.value.val[CYBLE_CAPSENSE_STATUS_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX] & CCCD_IND_BIT_MASK )
				    sendStatusIndications = TRUE;
                else
                    sendStatusIndications = FALSE;
                
                // Set flag to allow CCCD to be updated.
				updateStatusCCCDreq = TRUE;
            }
            
            // Update control flags
            _BLE_sendStatus = sendStatusNotifications | sendStatusIndications;
            
            // Send the response to the write request received.
			CyBle_GattsWriteRsp(connectionHandle);
            
            break;
            
            
        // Confirmation to indication response from client device. Event
        // parameter is a pointer to a structure of type CYBLE_CONN_HANDLE_T. 
        case CYBLE_EVT_GATTS_HANDLE_VALUE_CNF: // eventCode == 0x54
            
            break;
            
            
        // Event parameters for characteristic read value access event 
        // generated by BLE Stack upon an access of Characteristic value read  
        // for the characteristic definition which has
        // CYBLE_GATT_DB_ATTR_CHAR_VAL_RD_EVENT property set.
        case CYBLE_EVT_GATTS_READ_CHAR_VAL_ACCESS_REQ: // eventCode == 0x57
            
            // Make sure all the flags are updated.
            _BLE_writeStatusFlags();
            
            break;
            

        default:
            
            break;
    }
}
Exemplo n.º 8
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.º 9
0
/*******************************************************************************
* Function Name: ProcessWriteReq
********************************************************************************
*
* Summary:
*  Process all GATT level write requests and responds with appropriate status
*
* Parameters:
*  CYBLE_GATTS_WRITE_CMD_REQ_PARAM_T:  GATT write command request prameter
*
* Return:
*  None
*
*******************************************************************************/
void ProcessWriteReq(CYBLE_GATTS_WRITE_CMD_REQ_PARAM_T writeCmdReq)
{
    bool value_val;
    uint8 status = LOCKED, key_buf[LOCK_CODE_LENGTH];
    uint16 beaconPeriod = 0;
    CYBLE_GATT_HANDLE_VALUE_PAIR_T valuePairT;
    /* Reset error send flag */
    errorSent = false;
    /* Retrieve the LOCK status from the GATT DB */
    valuePairT.attrHandle =
                        CYBLE_EDDYSTONE_CONFIGURATION_LOCK_STATE_CHAR_HANDLE;
    valuePairT.value.val = (uint8 *)&value_val;
    valuePairT.value.len = sizeof(bool);

    CyBle_GattsReadAttributeValue( &valuePairT, &cyBle_connHandle,
                                    CYBLE_GATT_DB_LOCALLY_INITIATED );

    /* Check the LOCK status */
    if(valuePairT.value.val[0] == UNLOCKED)
    {
        /*URL Data*/
        if(writeCmdReq.handleValPair.attrHandle ==
                            CYBLE_EDDYSTONE_CONFIGURATION_URI_DATA_CHAR_HANDLE)
        {
            /* First byte should be scheme prefix and length should be less than
            *  or equal to MAX_URL_LENGTH */
            if( (writeCmdReq.handleValPair.value.len <= MAX_URL_LENGTH) &&
                (writeCmdReq.handleValPair.value.val[0] < URL_PREFIX_MAX)   )
            {
                uint8 TempURL[MAX_URL_LENGTH];
                memset(TempURL, 0, MAX_URL_LENGTH);
                memcpy(
                            TempURL,
                            writeCmdReq.handleValPair.value.val,
                            writeCmdReq.handleValPair.value.len
                       );
                if( CYBLE_GATT_ERR_NONE == WriteAttributeValue   (
                            CYBLE_EDDYSTONE_CONFIGURATION_URI_DATA_CHAR_HANDLE,
                            writeCmdReq.handleValPair.value.len,
                            writeCmdReq.handleValPair.value.val,
                            CYBLE_GATT_DB_PEER_INITIATED        ) )
                {
                    /* Update the length as per the new URL data */
                    URLLength = writeCmdReq.handleValPair.value.len;
                    cyBle_attValuesLen[16].actualLength = URLLength;
                    /* Update the URL data */
                    memcpy(CurrentURL, TempURL, MAX_URL_LENGTH);
                }
            }
            else if (writeCmdReq.handleValPair.value.len > MAX_URL_LENGTH)
            {
                 /* Invalid length. Send error response */
               SendErrorResponse        (
                            CYBLE_EDDYSTONE_CONFIGURATION_URI_DATA_CHAR_HANDLE,
                            CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN
                                        );
            }
        }
        /* Lock Characteristic */
        else if(writeCmdReq.handleValPair.attrHandle ==
                                CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE)
        {

            if(writeCmdReq.handleValPair.value.len == LOCK_CODE_LENGTH)
            {
                WriteAttributeValue (
                                CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE,
                                writeCmdReq.handleValPair.value.len,
                                writeCmdReq.handleValPair.value.val,
                                CYBLE_GATT_DB_PEER_INITIATED
                                    );

                /* Update the LOCK characteristic */
                status = LOCKED;
                WriteAttributeValue (
                        CYBLE_EDDYSTONE_CONFIGURATION_LOCK_STATE_CHAR_HANDLE,
                        sizeof(bool), &status,
                        CYBLE_GATT_DB_LOCALLY_INITIATED
                                    );
            }
            else
            {
                /* Invalid length. Send error response */
               SendErrorResponse(CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE,
                                    CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN);
            }
        }
        /* Advertised Tx power level */
        else if(writeCmdReq.handleValPair.attrHandle ==
           CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE)
        {

            if (writeCmdReq.handleValPair.value.len == MAX_NUM_PWR_LVL)
            {
                WriteAttributeValue (
                    CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE,
                    writeCmdReq.handleValPair.value.len,
                    writeCmdReq.handleValPair.value.val,
                    CYBLE_GATT_DB_PEER_INITIATED
                                    );

                if (writeCmdReq.handleValPair.value.len == MAX_NUM_PWR_LVL)
                {
                    /* Update Tx Power levels */
                    memcpy  (
                                currentTxPowerLevels,
                                writeCmdReq.handleValPair.value.val,
                                MAX_NUM_PWR_LVL
                            );
                }
                else
                {
                    SendErrorResponse   (
                        CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE,
                        CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN
                                        );
                }
            }
            else
            {
                /* Invalid length. Send error response */
               SendErrorResponse    (
                    CYBLE_EDDYSTONE_CONFIGURATION_ADVERTISED_TX_POWER_LEVELS_CHAR_HANDLE,
                    CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN
                                    );
            }
        }
        /* Tx Power Mode */
        else if(writeCmdReq.handleValPair.attrHandle ==
                        CYBLE_EDDYSTONE_CONFIGURATION_TX_POWER_MODE_CHAR_HANDLE)
        {

            if(writeCmdReq.handleValPair.value.val[0] <= 0x03)
            {
                WriteAttributeValue (
                        CYBLE_EDDYSTONE_CONFIGURATION_TX_POWER_MODE_CHAR_HANDLE,
                        writeCmdReq.handleValPair.value.len,
                        writeCmdReq.handleValPair.value.val,
                        CYBLE_GATT_DB_PEER_INITIATED
                                    );
                currentTxmode = writeCmdReq.handleValPair.value.val[0];

                UpdateTxPower(currentTxmode);
            }
            else /* Invalid value. Write not permitted. */
            {
                SendErrorResponse   (
                        CYBLE_EDDYSTONE_CONFIGURATION_TX_POWER_MODE_CHAR_HANDLE,
                        CYBLE_GATT_ERR_WRITE_NOT_PERMITTED
                                    );
            }
        }
        /* Beacon Period */
        else if(writeCmdReq.handleValPair.attrHandle ==
                        CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE)
        {

            beaconPeriod =
                        CyBle_Get16ByPtr(writeCmdReq.handleValPair.value.val);

            /* Disable URL FRAMES */
            if(beaconPeriod == 0)
            {
                eddystoneImplenmentation = EDDYSTONE_UID;
                WriteAttributeValue (
                        CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE,
                        writeCmdReq.handleValPair.value.len,
                        writeCmdReq.handleValPair.value.val,
                        CYBLE_GATT_DB_PEER_INITIATED
                                    );
            }
            /* Values in valid range */
            else if((beaconPeriod >= MIN_BEACON_PERIOD) &&
                    (beaconPeriod <= MAX_BEACON_PERIOD))
            {
                WriteAttributeValue (
                        CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE,
                        writeCmdReq.handleValPair.value.len,
                        writeCmdReq.handleValPair.value.val,
                        CYBLE_GATT_DB_PEER_INITIATED
                                    );
                CurrentAdvPeriod = beaconPeriod / 0.625;
                eddystoneImplenmentation = EDDYSTONE_URL;
            }
            else
            {
                uint16 temp = MIN_BEACON_PERIOD;
                /* Values not supportes. Write default values */
                WriteAttributeValue(
                        CYBLE_EDDYSTONE_CONFIGURATION_BEACON_PERIOD_CHAR_HANDLE,
                        sizeof(temp),
                        (uint8 *)&temp,
                        CYBLE_GATT_DB_PEER_INITIATED);
                CurrentAdvPeriod = CYBLE_GAP_ADV_ADVERT_INTERVAL_NONCON_MIN;
                eddystoneImplenmentation = EDDYSTONE_URL;
            }
        }
        /* Reset the Configurations to default */
        else if((writeCmdReq.handleValPair.attrHandle ==
                CYBLE_EDDYSTONE_CONFIGURATION_RESET_CHAR_HANDLE) &&
                (writeCmdReq.handleValPair.value.val[0] != 0))

        {
            ResetGattDb();
        }
    }
    else if(valuePairT.value.val[0] == LOCKED)
    {

        if(writeCmdReq.handleValPair.attrHandle ==
                                CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE)
        {
            /* Accesing the lock in LOCKED state */
            SendErrorResponse(writeCmdReq.handleValPair.attrHandle,
                                    CYBLE_GATT_ERR_INSUFFICIENT_AUTHORIZATION);
        }
    }

    if(writeCmdReq.handleValPair.attrHandle ==
                        CYBLE_EDDYSTONE_CONFIGURATION_UNLOCK_CHAR_HANDLE)
    {
        if(writeCmdReq.handleValPair.value.len == LOCK_CODE_LENGTH)
        {
            if(valuePairT.value.val[0] == LOCKED)
            {
                int compareResult;
                valuePairT.attrHandle =
                                CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE;
                valuePairT.value.val = key_buf;
                valuePairT.value.len = sizeof(LOCK);
                CyBle_GattsReadAttributeValue(&valuePairT, &cyBle_connHandle,
                                            CYBLE_GATT_DB_LOCALLY_INITIATED);

                compareResult = memcmp  (
                                            valuePairT.value.val,
                                            writeCmdReq.handleValPair.value.val,
                                            LOCK_CODE_LENGTH
                                        );

                if(compareResult == 0)
                {
                    status = UNLOCKED;
                    /* Update the LOCK STATE */
                    WriteAttributeValue (
                        CYBLE_EDDYSTONE_CONFIGURATION_LOCK_STATE_CHAR_HANDLE,
                        sizeof(bool), &status,
                        CYBLE_GATT_DB_LOCALLY_INITIATED
                                        );

                    /* Reset the LOCK */
                    WriteAttributeValue (
                                CYBLE_EDDYSTONE_CONFIGURATION_LOCK_CHAR_HANDLE,
                                sizeof(LOCK), (uint8 *)LOCK,
                                CYBLE_GATT_DB_LOCALLY_INITIATED
                                        );
                }
                else /* LOCK not matched */
                {
                    SendErrorResponse(writeCmdReq.handleValPair.attrHandle,
                                    CYBLE_GATT_ERR_INSUFFICIENT_AUTHORIZATION);
                }
            }
        }
        else /* Invalid length */
        {
            SendErrorResponse(writeCmdReq.handleValPair.attrHandle,
                                        CYBLE_GATT_ERR_INVALID_ATTRIBUTE_LEN);
        }
    }

    if (errorSent == false)
    {
        CyBle_GattsWriteRsp(cyBle_connHandle);
    }
}
Exemplo n.º 10
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.º 11
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.º 12
0
/*************************************************************************************************************************
* Function Name: CustomEventHandler
**************************************************************************************************************************
* Summary: This is a call back event function to handle various events from BLE stack.
*
* Parameters:
*  Event - Event returned
*  EventParameter - Link to value of the event returned
*
* Return:
*  void
*
*************************************************************************************************************************/
void CustomEventHandler(uint32 Event, void *EventParameter)
{
    switch(Event)
	{
        /**********************************************************
        *                       General Events
        ***********************************************************/
		case CYBLE_EVT_STACK_ON: //This event is received when the BLE component is started			
            StartAdvertisement = TRUE; //Set the advertisement flag
		break;
            
        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
            BLEStackStatus = *(uint8*)EventParameter; //Extract the BLE stack status
        break;
        
        /**********************************************************
        *                       GAP Events
        ***********************************************************/		
        case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: //This event is received when the device starts or stops advertising
            if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED)
            {
                StartAdvertisement = TRUE; //Set the advertisement flag
            }
        break;
			
		case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: //This event is received when the device is disconnected
			StartAdvertisement = TRUE; //Set the advertisement flag
        break;

        /**********************************************************
        *                       GATT Events
        ***********************************************************/
        case CYBLE_EVT_GATT_CONNECT_IND: //This event is received when the device is connected over GATT level
			ConnectionHandle = *(CYBLE_CONN_HANDLE_T *)EventParameter; //Update the attribute handle on GATT connection
			
			DeviceConnected = TRUE; //Set device connection status flag
            ChangePowerPinDriveMode = FALSE; //Clear change power pin drive mode flag
        break;
			
        case CYBLE_EVT_GATT_DISCONNECT_IND: //This event is received when device is disconnected
			DeviceConnected = FALSE; //Clear device connection status flag
            TemperatureNotificationEnabled = FALSE; //Clear the temperature notification flag
            PressureNotificationEnabled =  FALSE; //Clear the pressure notification flag
            AltitudeNotificationEnabled = FALSE; //Clear the altitude notification flag
            UpdateTemperatureNotificationAttribute = TRUE; //Clear the update temperature notification flag
            UpdatePressureNotificationAttribute = TRUE; //Clear the update pressure notification flag
            UpdateAltitudeNotificationAttribute = TRUE; //Clear the update altitude notification flag
            /* Clear temperature notification data */
            TemperatureNotificationData[0x03] = TemperatureNotificationData[0x02] = TemperatureNotificationData[0x01] = TemperatureNotificationData[0x00] = ZERO;
            /* Clear pressure notification data */
            PressureNotificationData[0x03] = PressureNotificationData[0x02] = PressureNotificationData[0x01] = PressureNotificationData[0x00] = ZERO;
            /* Clear altitude notification data */
            AltitudeNotificationData[0x03] = AltitudeNotificationData[0x02] = AltitudeNotificationData[0x01] = AltitudeNotificationData[0x00] = ZERO;
            LastTemperatureData = ZERO; //Clear last stored temperature notification data
            LastPressureData = ZERO; //Clear last stored pressure notification data
            LastAltitudeData = ZERO; //Clear last stored altitude notification data
            ChangePowerPinDriveMode = TRUE; //Set change power pin drive mode flag
            ConnectionParametersUpdateRequired = TRUE; //Set the Connection Parameters Update flag
            UpdateNotificationCCCDAttribute(); //Update the CCCD writing by the Central device
		break;
            
        case CYBLE_EVT_GATTS_WRITE_REQ: //When this event is triggered, the peripheral has received a write command on the custom characteristic
			/* Extract the write value from the event parameter */
            WriteRequestedParameter = (CYBLE_GATTS_WRITE_REQ_PARAM_T *)EventParameter;
			
			/* Check if command is for notification attribute and update the flag for sending notifications */
            if(WriteRequestedParameter->handleValPair.attrHandle == CYBLE_BMP180_TEMPERATURE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE)
            {
                /* Set temperature notification flag so that application can start sending notifications */
				TemperatureNotificationEnabled = WriteRequestedParameter->handleValPair.value.val[CYBLE_BMP180_TEMPERATURE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX];
                
                UpdateTemperatureNotificationAttribute = TRUE; //Set flag to allow CCCD to be updated for next read operation
            }
            
            /* Check if command is for notification attribute and update the flag for sending notifications */
            if(WriteRequestedParameter->handleValPair.attrHandle == CYBLE_BMP180_PRESSURE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE)
            {
                /* Set pressure notification flag so that application can start sending notifications */
				PressureNotificationEnabled = WriteRequestedParameter->handleValPair.value.val[CYBLE_BMP180_PRESSURE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX];
                
                UpdatePressureNotificationAttribute = TRUE; //Set flag to allow CCCD to be updated for next read operation
            }
            
            /* Check if command is for notification attribute and update the flag for sending notifications */
            if(WriteRequestedParameter->handleValPair.attrHandle == CYBLE_BMP180_ALTITUDE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_HANDLE)
            {
                /* Set altitude notification flag so that application can start sending notifications */
				AltitudeNotificationEnabled = WriteRequestedParameter->handleValPair.value.val[CYBLE_BMP180_ALTITUDE_CLIENT_CHARACTERISTIC_CONFIGURATION_DESC_INDEX];
                
                UpdateAltitudeNotificationAttribute = TRUE; //Set flag to allow CCCD to be updated for next read operation
            }
            
            /* Send response to the write command received */
			CyBle_GattsWriteRsp(ConnectionHandle);
        break;
            
        /**********************************************************
        *                       L2CAP Events
        ***********************************************************/
            
        case CYBLE_EVT_L2CAP_CONN_PARAM_UPDATE_RSP: //This event is generated when the L2CAP connection parameter update response received
            ConnectionParametersUpdateRequired = FALSE; //Clear the Connection Parameters Update flag
        break;
			
        default:
        break;
	}
}