Ejemplo n.º 1
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;
	}
}
Ejemplo n.º 2
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;
    }
}