/******************************************************************************* * Function Name: attrHandleInit ******************************************************************************** * * Summary: * This function gathhers all the information like attribute handles and MTU size * from the server. * * Parameters: * None. * * Return: * None. * *******************************************************************************/ void attrHandleInit() { switch(infoExchangeState) { case INFO_EXCHANGE_START: CyBle_GattcDiscoverPrimaryServiceByUuid(cyBle_connHandle, bleUartServiceUuidInfo); break; case BLE_UART_SERVICE_HANDLE_FOUND: attrHandleRange.startHandle = bleUartServiceHandle; attrHandleRange.endHandle = bleUartServiceEndHandle; CyBle_GattcDiscoverAllCharacteristics(cyBle_connHandle, attrHandleRange); break; case (SERVICE_AND_CHAR_HANDLES_FOUND): charDescHandleRange.startHandle = txCharHandle + 1; charDescHandleRange.endHandle = bleUartServiceEndHandle; CyBle_GattcDiscoverAllCharacteristicDescriptors(cyBle_connHandle, &charDescHandleRange); break; case (ALL_HANDLES_FOUND): CyBle_GattcExchangeMtuReq(cyBle_connHandle, CYBLE_GATT_MTU); break; default: break; } CyBle_ProcessEvents(); }
/******************************************************************************* * Function Name: StackEventHandler() ******************************************************************************** * Summary: * Event handler for the BLE events processing. * * Parameters: * uint32 eventCode: The event to be processed * void * eventParam: Pointer to hold the additional information associated * with an event * * Return: * None * * Theory: * The function is responsible for handling the events generated by the stack. * It first starts advertisement once the stack is initialized. * Upon advertisement timeout or disconnect events, this function sets a flag * to indicate to the main() function that it should enter Hibernate mode. * * Once the device is connected, this function initiates an authentication * request. It displays a 6-digit passkey on the UART output on a PC and asks * the user to enter this key on the iOS device (NP) side. * Once the authentication is complete, the function starts the discovery * procedure to know whether ANCS service is supported by the peer device. * * When the automated service discovery is complete, the function starts a manual * discovery procedure for the ANCS service (since the BLE component does not * handle discovery of custom services yet - that will be added as part of * Creator 3.2). * * When the automated service discovery is complete and the ANCS service is not * found, the function subscribes to the Service Changed characteristic * indication to know if and when the iOS device adds ANCS support later. * * Once the ANCS service is found and a new GATT Notification comes for any of * the ANCS characteristic, it calls the corresponding function in ANCS.c. * *******************************************************************************/ void StackEventHandler(uint32 eventCode, void * eventParam) { CYBLE_GATTC_HANDLE_VALUE_NTF_PARAM_T * handleValueNotification; switch(eventCode) { case CYBLE_EVT_STACK_ON: /* Minor change in ADV packet for service solicitation */ cyBle_discoveryData.advData[10] = 0x15; /* Start advertisement after stack is initialized */ UART_UartPutString("\n\rAdvertising."); CyBle_GappStartAdvertisement(CYBLE_ADVERTISING_FAST); break; case CYBLE_EVT_GAPP_ADVERTISEMENT_START_STOP: if(authState != AUTHENTICATION_BONDING_REMOVE_WAITING_EVENT) { if(CyBle_GetState() == CYBLE_STATE_DISCONNECTED) { UART_UartPutString("\n\rAdvertisement timed out. "); UART_UartPutString("Going to Hibernate mode."); /* Enter hibernate mode upon advertisement timeout */ enterHibernateFlag = true; } } else { UART_UartPutString("\n\rAdvertisement stopped. "); authState = AUTHENTICATION_BONDING_REMOVE_GO_AHEAD; } break; case CYBLE_EVT_GAP_DEVICE_DISCONNECTED: /* Enter Hibernate mode upon disconnect * Previous state is erased. */ if(authState != AUTHENTICATION_BONDING_REMOVE_WAITING_EVENT) { UART_UartPutString("\n\rDisconnected. Going to Hibernate mode."); enterHibernateFlag = true; } else { UART_UartPutString("\n\rDisconnected. "); authState = AUTHENTICATION_BONDING_REMOVE_GO_AHEAD; } Ancs_Reset(); break; case CYBLE_EVT_GAP_DEVICE_CONNECTED: UART_UartPutString("\n\rConnected to a peer device."); /* Send authentication request upon connection */ CyBle_GapAuthReq(cyBle_connHandle.bdHandle, &cyBle_authInfo); break; case CYBLE_EVT_GAP_PASSKEY_DISPLAY_REQUEST: UART_UartPutString("\n\rEnter this passkey in your iPhone: "); UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 5)); UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 4)); UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 3)); UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 2)); UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 1)); UART_UartPutChar(HexToDecimal(*(uint32 *)eventParam, 0)); break; case CYBLE_EVT_GAP_AUTH_COMPLETE: /* Authentication complete; initiate service discovery procedure */ UART_UartPutString("\n\rAuthentication complete. "); authState = AUTHENTICATION_COMPLETE_BONDING_REQD; CyBle_GattcStartDiscovery(cyBle_connHandle); break; case CYBLE_EVT_GAP_AUTH_FAILED: /* Authentication failed; enter Hibernate mode */ UART_UartPutString("\n\rAuthentication failed. Going to Hibernate mode."); enterHibernateFlag = true; /* Update authentication state so that bond information could be * removed later. */ authState = AUTHENTICATION_BONDING_COMPLETE; break; case CYBLE_EVT_GATTC_INDICATION: /* Server's services changed; restart service discovery */ UART_UartPutString("\n\rService changed indication. Redo service discovery."); Ancs_Reset(); CyBle_GattcStartDiscovery(cyBle_connHandle); break; case CYBLE_EVT_GATTC_DISCOVERY_COMPLETE: /* Automatic discovery does not cover discovery of service snd * characteristics with custom 128-bit UUIDs. This has to be done * manually. The Read by Group response for Service discovery covers * the ANCS custom service. For the ANCS service characteristics, the * Read by Type Request has to be sent by the application. */ if(ANCS_DISC_SERVICE_DISCOVERED == ancsDiscoveryStatus) { CyBle_GattcDiscoverAllCharacteristics(cyBle_connHandle, ancsServiceRange); } else if(ANCS_DISC_NONE_DISCOVERED == ancsDiscoveryStatus) { UART_UartPutString("\n\rANCS service not found. "); /* Service discovery procedure complete; subscribe to the GATT * Service changed indication by writing 0x02 to its CCCD. */ if((serviceChangedCccdWriteStatus == SERVICE_CHANGED_CCCD_WRITE_REQ_NOT_SENT) && (cyBle_gattc.serviceChanged.valueHandle != CYBLE_GATT_INVALID_ATTR_HANDLE_VALUE)) { serviceChangedCccdPacket.value = cccdIndFlagSetStruct; serviceChangedCccdPacket.attrHandle = cyBle_gattc.cccdHandle; CyBle_GattcWriteCharacteristicDescriptors(cyBle_connHandle, &serviceChangedCccdPacket); } /* Internal state machine tracking the CCCD status */ serviceChangedCccdWriteStatus = SERVICE_CHANGED_CCCD_WRITE_REQ_SENT; } else { /* Other conditions need not be handled; they are handled * in the event handler in ANCS.c. */ } break; case CYBLE_EVT_GATTC_READ_BY_GROUP_TYPE_RSP: case CYBLE_EVT_GATTC_READ_BY_TYPE_RSP: case CYBLE_EVT_GATTC_FIND_INFO_RSP: case CYBLE_EVT_GATTC_WRITE_RSP: case CYBLE_EVT_GATTC_ERROR_RSP: /* See if the events are for ANCS */ Ancs_EventHandler(eventCode, eventParam); break; case CYBLE_EVT_GATTC_HANDLE_VALUE_NTF: /* See if the notification packet is for any ANCS characteristic */ handleValueNotification = (CYBLE_GATTC_HANDLE_VALUE_NTF_PARAM_T *)eventParam; if(handleValueNotification->handleValPair.attrHandle == ancsNotifSourceCharHandle) { /* Notification source characteristic has a new notification */ Ancs_HandleNotifications(handleValueNotification->handleValPair.value.val); } else if(handleValueNotification->handleValPair.attrHandle == ancsDataSourceCharHandle) { /* Data source characteristic has a new notification */ Ancs_HandleData(handleValueNotification->handleValPair.value.val); } else { /* Some other characteristic notification; ignore */ } break; default: break; } }