static unsigned getUCSChar(const std::string& unicode4HexChar)
{
    return (HexToDecimal(unicode4HexChar[0]) << 12) |
           (HexToDecimal(unicode4HexChar[1]) << 8) |
           (HexToDecimal(unicode4HexChar[2]) << 4) |
           (HexToDecimal(unicode4HexChar[3]));
}
예제 #2
0
파일: ANCS.c 프로젝트: Ahamedjee/PSoC-4-BLE
/*******************************************************************************
* Function Name: Ancs_UpdateOutputInformation()
********************************************************************************
* Summary:
* This function prints data onto the UART terminal.
*
* Parameters:
* None
*
* Return:
* None
*
* Theory:
* The function prints the number of Missed calls, Voicemails and Emails on the 
* screen. The same line on the terminal is updated with new data if no other
* notification came up.
*
*******************************************************************************/
static void Ancs_UpdateOutputInformation(void)
{
    /* Update the same line if no new notification since. */
    if(printStatus == PRINT_SAME_LINE)
    {
        /* Go back to the same line */
        UART_UartPutChar(13);
    }
    else
    {
        UART_UartPutString("\n\r");
    }
    
    printStatus = PRINT_SAME_LINE;
    
    UART_UartPutString("Missed calls: ");
    UART_UartPutChar(HexToDecimal(missedCallCount, 1));
    UART_UartPutChar(HexToDecimal(missedCallCount, 0));
    
    UART_UartPutString("   Voicemails: ");
    UART_UartPutChar(HexToDecimal(voiceMailCount, 1));
    UART_UartPutChar(HexToDecimal(voiceMailCount, 0));
    
    UART_UartPutString("   Emails: ");
    UART_UartPutChar(HexToDecimal(emailCount, 1));
    UART_UartPutChar(HexToDecimal(emailCount, 0));
}
예제 #3
0
/**
 * Parses an input Intel HEX formatted stream one character at a time, loading
 * the data contents into the device's internal FLASH memory.
 *
 * \param[in] ReadCharacter  Next input ASCII byte of data to parse
 */
static void ParseIntelHEXByte(const char ReadCharacter)
{
	/* Reset the line parser while waiting for a new line to start */
	if ((HEXParser.ParserState == HEX_PARSE_STATE_WAIT_LINE) || (ReadCharacter == ':'))
	{
		HEXParser.Checksum     = 0;
		HEXParser.CurrAddress  = HEXParser.CurrBaseAddress;
		HEXParser.ReadMSB      = false;

		/* ASCII ':' indicates the start of a new HEX record */
		if (ReadCharacter == ':')
		  HEXParser.ParserState = HEX_PARSE_STATE_BYTE_COUNT;

		return;
	}

	/* Only allow ASCII HEX encoded digits, ignore all other characters */
	int8_t ReadCharacterDec = HexToDecimal(ReadCharacter);
	if (ReadCharacterDec < 0)
	  return;

	/* Read and convert the next nibble of data from the current character */
	HEXParser.Data    = (HEXParser.Data << 4) | ReadCharacterDec;
	HEXParser.ReadMSB = !HEXParser.ReadMSB;

	/* Only process further when a full byte (two nibbles) have been read */
	if (HEXParser.ReadMSB)
	  return;

	/* Intel HEX checksum is for all fields except starting character and the
	 * checksum itself
	 */
	if (HEXParser.ParserState != HEX_PARSE_STATE_CHECKSUM)
	  HEXParser.Checksum += HEXParser.Data;

	switch (HEXParser.ParserState)
	{
		case HEX_PARSE_STATE_BYTE_COUNT:
			HEXParser.DataRem      = HEXParser.Data;
			HEXParser.ParserState  = HEX_PARSE_STATE_ADDRESS_HIGH;
			break;

		case HEX_PARSE_STATE_ADDRESS_HIGH:
			HEXParser.CurrAddress += ((uint16_t)HEXParser.Data << 8);
			HEXParser.ParserState  = HEX_PARSE_STATE_ADDRESS_LOW;
			break;

		case HEX_PARSE_STATE_ADDRESS_LOW:
			HEXParser.CurrAddress += HEXParser.Data;
			HEXParser.ParserState  = HEX_PARSE_STATE_RECORD_TYPE;
			break;

		case HEX_PARSE_STATE_RECORD_TYPE:
			HEXParser.RecordType   = HEXParser.Data;
			HEXParser.ParserState  = (HEXParser.DataRem ? HEX_PARSE_STATE_READ_DATA : HEX_PARSE_STATE_CHECKSUM);
			break;

		case HEX_PARSE_STATE_READ_DATA:
			/* Track the number of read data bytes in the record */
			HEXParser.DataRem--;

			/* Protect the bootloader against being written to */
			if (HEXParser.CurrAddress >= BOOT_START_ADDR)
			{
				HEXParser.ParserState = HEX_PARSE_STATE_WAIT_LINE;
				PageDirty = false;
				return;
			}

			/* Wait for a machine word (two bytes) of data to be read */
			if (HEXParser.DataRem & 0x01)
			{
				HEXParser.PrevData = HEXParser.Data;
				break;
			}

			/* Convert the last two received data bytes into a 16-bit word */
			uint16_t NewDataWord = ((uint16_t)HEXParser.Data << 8) | HEXParser.PrevData;

			switch (HEXParser.RecordType)
			{
				case HEX_RECORD_TYPE_Data:
					/* If we are writing to a new page, we need to erase it first */
					if (!(PageDirty))
					{
						boot_page_erase(HEXParser.PageStartAddress);
						boot_spm_busy_wait();

						PageDirty = true;
					}

					/* Fill the FLASH memory buffer with the new word of data */
					boot_page_fill(HEXParser.CurrAddress, NewDataWord);
					HEXParser.CurrAddress += 2;

					/* Flush the FLASH page to physical memory if we are crossing a page boundary */
					FlushPageIfRequired();
					break;

				case HEX_RECORD_TYPE_ExtendedSegmentAddress:
					/* Extended address data - store the upper 12-bits of the new address */
					HEXParser.CurrBaseAddress = ((uint32_t)NewDataWord << 4);
					break;

				case HEX_RECORD_TYPE_ExtendedLinearAddress:
					/* Extended address data - store the upper 16-bits of the new address */
					HEXParser.CurrBaseAddress = ((uint32_t)NewDataWord << 16);
					break;
			}

			if (!HEXParser.DataRem)
			  HEXParser.ParserState = HEX_PARSE_STATE_CHECKSUM;
			break;

		case HEX_PARSE_STATE_CHECKSUM:
			/* Verify checksum of the completed record */
			if (HEXParser.Data != ((~HEXParser.Checksum + 1) & 0xFF))
			  break;

			/* Flush the FLASH page to physical memory if we are crossing a page boundary */
			FlushPageIfRequired();

			/* If end of the HEX file reached, the bootloader should exit at next opportunity */
			if (HEXParser.RecordType == HEX_RECORD_TYPE_EndOfFile)
			  RunBootloader = false;

			break;

		default:
			HEXParser.ParserState = HEX_PARSE_STATE_WAIT_LINE;
			break;
	}
}
예제 #4
0
파일: main.c 프로젝트: Charhong/PSoC-4-BLE
/*******************************************************************************
* 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;
    }
}