Esempio n. 1
0
/*****************************************************************************
 * FUNCTION
 *  BTAppVerifyApplicationDataElement
 * DESCRIPTION
 *  
 * PARAMETERS
 *  raw_data            [IN]        
 *  raw_data_length     [IN]        
 *  deepth              [IN]        
 * RETURNS
 *  
 *****************************************************************************/
BOOL BTAppVerifyApplicationDataElement(U8 *raw_data, U16 raw_data_length, U8 deepth)
{
    U16 current_len = 0;
    U16 attribute_len = 0;
    U16 element_size = 0;
    U16 element_header_size = 1;
    BOOL result = TRUE;
    U8 *data = 0;
    U8 i = 0;
    U8 size_descriptor;
    U8 attribute_type;

    if (deepth > BT_APP_MAX_DEEPTH_SIZE)
    {
        kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_DATA_ELEMENT_DATA_ELEMENT_TOO_LARGE_NOT_CHECK);
        return TRUE;
    }

    for (current_len = 0; current_len < raw_data_length; current_len += attribute_len)
    {
        if (current_len > raw_data_length)
        {
            kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_DATA_ELEMENT_INVALID_PARAMETERS);
            result = FALSE;
            break;
        }
        data = (U8*) & (raw_data[current_len]);
        size_descriptor = SDP_GetElemSize(data[0]);
        attribute_type = SDP_GetElemType(data[0]);

        switch (attribute_type)
        {
            case DETD_NIL:
            case DETD_BOOL:
                if (size_descriptor != DESD_1BYTE)
                {
                    result = FALSE;
                }
                else
                {
                    element_size = BTAppSdpGetValidSize(size_descriptor);
                }
                kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_DATA_ELEMENT_X1_THE_ELEMENT_SIZE_x02X, element_size);
                element_header_size = 1;
                break;
            case DETD_UINT:
            case DETD_SINT:
                if (size_descriptor > DESD_16BYTES)
                {
                    result = FALSE;
                }
                else
                {
                    element_size = BTAppSdpGetValidSize(size_descriptor);
                }
                kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_DATA_ELEMENT_X2_THE_ELEMENT_SIZE_x02X, element_size);
                element_header_size = 1;
                break;
            case DETD_UUID:
                if ((size_descriptor != DESD_2BYTES) && (size_descriptor != DESD_4BYTES) &&
                    (size_descriptor != DESD_16BYTES))
                {
                    result = FALSE;
                }
                else
                {
                    element_size = BTAppSdpGetValidSize(size_descriptor);
                }
                kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_DATA_ELEMENT_X3_THE_ELEMENT_SIZE_x02X, element_size);
                element_header_size = 1;
                break;
            case DETD_SEQ:
            case DETD_ALT:
            case DETD_TEXT: /* Text string. Valid Size 5,6,7 */
            case DETD_URL:  /* Uniform Resource Locator. Valid size 5,6,7 */
                element_header_size = SDP_GetElemSize(data[0]);
                kal_trace(
                    BT_TRACE_JSR82_GROUP,
                    BT_JSR82_VERIFY_DATA_ELEMENT_TYPEx02X_SIZE_INDEXx02X,
                    attribute_type,
                    element_header_size);
                if (element_header_size < DESD_ADD_8BITS)
                {
                    result = FALSE;
                }
                else
                {

                    /* If size descriptor=5,6,7 then its additional size_bytes=1(5-4),2(6-4),4 (7-4+1) followed (Type descriptor:5-bits size descriptor:3-bits) */
                    /* element_header_size -= 4; */
                    if (element_header_size == DESD_ADD_8BITS)
                    {
                        element_header_size = 1;
                    }
                    else if (element_header_size == DESD_ADD_16BITS)
                    {
                        element_header_size = 2;
                    }
                    else if (element_header_size == DESD_ADD_32BITS)
                    {
                        element_header_size = 4;
                    }
                    else
                    {
                        kal_trace(
                            BT_TRACE_JSR82_GROUP,
                            BT_JSR82_VERIFY_DATA_ELEMENT_INVALID_SIZE_DESCRIPTOR_VALUEx02X,
                            element_header_size);
                        result = FALSE;
                        return result;
                    }
                    element_size = 0;
                    for (i = 0; i < element_header_size; i++)
                    {
                        element_size = (element_size << 8) | (data[1 + i]);
                    }

                    /* Currently, element_header_size is number of bytes to store actual data length, +1: 5-bits Type descriptor + 3-bits Size descriptor */
                    element_header_size += 1;

                    if ((element_header_size + element_size) > (raw_data_length - current_len))
                    {
                        result = FALSE;
                        break;
                    }
                    kal_trace(
                        BT_TRACE_JSR82_GROUP,
                        BT_JSR82_VERIFY_DATA_ELEMENT_X5_THE_ELEMENT_SIZE_x02X,
                        element_size);
                    if (((attribute_type == DETD_SEQ) || (attribute_type == DETD_ALT)) && (element_size > 0))
                    {
                        if (!BTAppVerifyApplicationDataElement((U8*) & data[element_header_size], element_size, (U8) (deepth + 1)))
                        {
                            result = FALSE;
                        }
                    }
                }
                break;
            default:
                result = FALSE;
                break;
        }
        if (!result)
        {
            break;
        }
        if (result)
        {
            kal_trace(
                BT_TRACE_JSR82_GROUP,
                BT_JSR82_VERIFY_DATA_ELEMENT_ATTRIBUTE_VALUE_ELEMENT_SIZE_x02X,
                element_size);
            attribute_len = (element_header_size + element_size);
        }
        if (!result)
        {
            kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_DATA_ELEMENT_VERIFY_FAILED);
            return FALSE;
        }
    }
    if (current_len != raw_data_length)
    {
        kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_DATA_ELEMENT_PEASE_DATA_ELEMENT_FAILED);
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}
Esempio n. 2
0
// data is the attribute_value passed from the SDP callback.
// The formate of a profile descriptor is: 
BtStatus parseAvrcpVersion(U8 *data, U16 *version)
{
	BtStatus status = BT_STATUS_FAILED;
	
    U8 type = 0;
    U16 local_pos = 0, offset = 0, len = 0;
    U16 value_len = 0;
    U16 uuid16 = 0;
    U32 uuid32 = 0;
    U8 uuid128[16] = {0};

    
    type = SDP_GetElemType(data[local_pos]);
	len = SDP_ParseDataElement(&data[local_pos], &offset);
	
	OS_Report("[AVRCP] %s() type: %d, len: %d", __FUNCTION__, type, len);
	
	local_pos += offset;
	type = SDP_GetElemType(data[local_pos]);
	if (type == DETD_UUID) {
		value_len = SDP_ParseDataElement(&data[local_pos], &offset);
		local_pos += offset;
		
		// Print out the UUID field. Checking function can be added here.
        switch (value_len) {
            case 2:
                uuid16 = SDP_GetU16(&data[local_pos]);
                OS_Report("[AVRCP] %s() UUID16: 0x%04x", __FUNCTION__, uuid16);
                break;
            case 4:
                uuid32 = SDP_GetU32(&data[local_pos]);
                OS_Report("[AVRCP] %s() UUID32: 0x%08x", __FUNCTION__, uuid32);
                break;
            case 16:
                OS_MemCopy(uuid128, &data[local_pos], 16);
                OS_Report("[AVRCP] %s() UUID128: %02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x",
                    __FUNCTION__,
                    data[local_pos], data[local_pos + 1], data[local_pos + 2], data[local_pos + 3],
                    data[local_pos + 4], data[local_pos + 5], data[local_pos + 6], data[local_pos + 7],
                    data[local_pos + 8], data[local_pos + 9], data[local_pos + 10], data[local_pos + 11],
                    data[local_pos + 12], data[local_pos + 13], data[local_pos + 14], data[local_pos + 15]);
                break;
            default:
                OS_Report("[AVRCP] %s() Invalide uuid_len: %d", __FUNCTION__, value_len);
                return status;
        }    
        local_pos += value_len;
        
	} else {
		OS_Report("[AVRCP] %s() Invalid type: %d when parsing uuid.", __FUNCTION__, type);
	}

    	
	type = SDP_GetElemType(data[local_pos]);
	len = SDP_ParseDataElement(&data[local_pos], &offset);
	if (type == DETD_UINT) {
		local_pos += offset;
		*version = SDP_GetU16(&data[local_pos]);
		OS_Report("[AVRCP] %s() version:0x%x", __FUNCTION__, *version);
		status = BT_STATUS_SUCCESS;
		
	} else {
		OS_Report("[AVRCP] %s() Invalid type: %d when parsing version.", __FUNCTION__ , type);
	}
	
	return status;
}
Esempio n. 3
0
/*****************************************************************************
 * FUNCTION
 *  BTAppVerifyApplicationRecord
 * DESCRIPTION
 *  
 * PARAMETERS
 *  raw_data            [IN]        
 *  raw_data_length     [IN]        
 *  attribute_no        [IN]        
 *  ptr                 [IN]        
 * RETURNS
 *  
 *****************************************************************************/
BOOL BTAppVerifyApplicationRecord(U8 *raw_data, U16 raw_data_length, U8 *attribute_no, U8 *ptr)
{
    U16 attr_id = 0;
    U16 offset = 0;
    U16 element_size = 0;
    U16 element_header_size = 0;
    U8 *data = 0;
    BOOL result = TRUE;
    U16 i = 0;
    BOOL attribute_data_element = FALSE;
    U16 attribute_len = 0;
    U8 attribute_type = 0;
    U8 size_descriptor = 0;
    U8 attribute_index = 0;
    BT_APP_ATTRIBUTE_struct_t *attribute_buffer = NULL;

    attribute_index = 0;
    *attribute_no = 0;
    kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_RECORD_LENGTHx04X, raw_data_length);
    for (i = 0; i < raw_data_length; i += 8)
    {
        kal_trace(
            BT_TRACE_JSR82_GROUP,
            BT_JSR82_VERIFY_RECORD_ITS_DATAx02Xx02Xx02Xx02Xx02Xx02Xx02Xx02X,
            raw_data[i],
            raw_data[i + 1],
            raw_data[i + 2],
            raw_data[i + 3],
            raw_data[i + 4],
            raw_data[i + 5],
            raw_data[i + 6],
            raw_data[i + 7]);
    }

    /* attribute_len: attribute value's length; +2: attribute ID's length is two bytes */
    for (offset = 0; offset < raw_data_length; offset += (attribute_len + 2))
    {
        if (attribute_index > BT_APP_MAX_ATTRIBUTE_SIZE)
        {
            kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_ATTRIBUTE_INDEX_xD_TOO_LARGE, attribute_index);
        }
        data = (U8*) (raw_data + offset);
        kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_DATA0x02X_DATA1x02X, data[0], data[1]);
        attr_id = ((((U16) data[0]) << 8) | ((U16) data[1]));
        kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_THE_ATTRIBUTE_ID_xD, attr_id);
        data += 2;
        /* Retrieve attribute id */
        (*attribute_no)++;
        kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_THE_ELEMENT_TYPE_x02X, data[0]);
        attribute_data_element = FALSE;
        /* Retrieve attribute value size index and type descriptor */
        size_descriptor = SDP_GetElemSize(data[0]);
        attribute_type = SDP_GetElemType(data[0]);

        switch (attribute_type)
        {
            case DETD_NIL:
                element_header_size = 1;
                if (size_descriptor != DESD_1BYTE)
                {
                    result = FALSE;
                }
                else
                {
                    element_size = 0;
                }
                kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_A_THE_ELEMENT_SIZE_x02X, element_size);
                break;
            case DETD_BOOL:
                element_header_size = 1;
                if (size_descriptor != DESD_1BYTE)
                {
                    result = FALSE;
                }
                else
                {
                    element_size = BTAppSdpGetValidSize(size_descriptor);
                }
                kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_A_THE_ELEMENT_SIZE_x02X, element_size);
                break;
            case DETD_UINT:
            case DETD_SINT:
                element_header_size = 1;
                kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_B_THE_ELEMENT_SIZE_x02X, element_size);
                if (size_descriptor > DESD_16BYTES)
                {
                    result = FALSE;
                }
                else
                {
                    element_size = BTAppSdpGetValidSize(size_descriptor);
                }
                kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_B_THE_ELEMENT_SIZE_x02X, element_size);
                break;
            case DETD_UUID:
                element_header_size = 1;
                if ((size_descriptor != DESD_2BYTES) && (size_descriptor != DESD_4BYTES) &&
                    (size_descriptor != DESD_16BYTES))
                {
                    result = FALSE;
                }
                else
                {
                    element_size = BTAppSdpGetValidSize(size_descriptor);
                }
                kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_C_THE_ELEMENT_SIZE_x02X, element_size);
                break;
            case DETD_SEQ:  /* Data Element Sequence. Valid Size descriptor: 5,6,7 */
            case DETD_ALT:  /* Data Alternative. Valid Size descriptor: 5,6,7 */
            case DETD_TEXT: /* Text string. Valid Size 5,6,7 */
            case DETD_URL:  /* Uniform Resource Locator. Valid size 5,6,7 */
                element_header_size = SDP_GetElemSize(data[0]);
                kal_trace(
                    BT_TRACE_JSR82_GROUP,
                    BT_JSR82_VERIFY_RECORD_TYPEx02X_SIZE_INDEXx02X,
                    attribute_type,
                    element_header_size);
                if (element_header_size < DESD_ADD_8BITS)
                {
                    result = FALSE;
                }
                else
                {
                    if ((attribute_type == DETD_SEQ) || (attribute_type == DETD_ALT))
                    {
                        attribute_data_element = TRUE;
                    }

                    /* If size descriptor=5,6,7 then its additional size_bytes=1(5-4),2(6-4),4(7-4+1) followed (Type descriptor:5-bits size descriptor:3-bits) */
                    /* element_header_size -= 4; */
                    if (element_header_size == DESD_ADD_8BITS)
                    {
                        element_header_size = 1;
                    }
                    else if (element_header_size == DESD_ADD_16BITS)
                    {
                        element_header_size = 2;
                    }
                    else if (element_header_size == DESD_ADD_32BITS)
                    {
                        element_header_size = 4;
                    }
                    else
                    {
                        kal_trace(
                            BT_TRACE_JSR82_GROUP,
                            BT_JSR82_VERIFY_RECORD_INVALID_SIZE_DESCRIPTOR_VALUEx02X,
                            element_header_size);
                        result = FALSE;
                        return result;
                    }
                    element_size = 0;

                    /*
                     * The for loop is used to obtain the actual data size and stores this actual data size to element_size 
                     * data[0]: Type descriptor(5-bits) + size descriptor(3-bits)
                     * data[1] or data[1]-data[2] or data[1]-data[4] are actual data size
                     */
                    for (i = 0; i < element_header_size; i++)
                    {
                        element_size = (element_size << 8) | (data[1 + i]);
                    }

                    /*
                     * 5-bits (Type descriptor) + 3-bits (size descriptor) + 1 or 2 or 4 bytes (actual data size)
                     * +1: it means that this one byte: 5-bits (Type descriptor) + 3-bits (size descriptor)
                     */
                    element_header_size += 1;

                    if ((element_header_size + element_size) > (raw_data_length - offset))
                    {
                        result = FALSE;
                        break;
                    }

                    kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_E_THE_ELEMENT_SIZE_x02X, element_size);
                }
                break;
            default:
                result = FALSE;
                break;
        }
        if (result)
        {
            kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_ATTRIBUTE_VALUE_ELEMENT_SIZE_x04X, element_size);
            kal_trace(
                BT_TRACE_JSR82_GROUP,
                BT_JSR82_VERIFY_RECORD_ATTRIBUTE_VALUE_ELEMENT_HEADER_SIZE_x04X,
                element_header_size);
            if ((attribute_data_element) && (element_size > 0) && (element_size < BT_APP_MAX_DATA_ELEMENT_SIZE))
            {
                /* Process the attribute_value part and its data type belongs to Data Element Sequence (Because attribute_data_element is TRUE) */
                if (!BTAppVerifyApplicationDataElement(data + element_header_size, element_size, 0))
                {
                    result = FALSE;
                    return FALSE;
                }

            }
            attribute_data_element = FALSE;
        }
        /* The BTstack will automatically assign the record handle of the record in SDP_AddRecord()'s SDPS(nextHandle) */
        /* From SdpMarkAttribute(): It can be known that: aid= 0x0000 and aid= 0x0002 are assigned by BTStack */
        if (attr_id != AID_SERVICE_RECORD_HANDLE && attr_id != AID_SERVICE_RECORD_STATE)
        {
            attribute_buffer =
                (BT_APP_ATTRIBUTE_struct_t*) (ptr + sizeof(BT_APP_ATTRIBUTE_struct_t) * attribute_index);
            attribute_buffer->attribute_id = attr_id;
            attribute_buffer->attribute_value = data;
            attribute_buffer->attribute_size = element_size + element_header_size;
            attribute_index++;
        }
        attribute_len = (element_size + element_header_size);
    }
    if (offset != raw_data_length)
    {
        kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_VERIFY_FAILED);
        return FALSE;
    }
    else
    {
        kal_trace(BT_TRACE_JSR82_GROUP, BT_JSR82_VERIFY_RECORD_FINALLY_ATTRIBUTE_INDEXx02X, attribute_index);
        BTAppSdpCreateSortingAttributes(ptr, attribute_index);
        /* Note 2008-0410: actual stored attribute no is equal to attribute_index (aid=0x0000 is not stored) */
        (*attribute_no) = attribute_index;
        return TRUE;

    }

}
Esempio n. 4
0
/*---------------------------------------------------------------------------
 *            HidSdpParseDescriptorList()
 *---------------------------------------------------------------------------
 *
 * Synopsis:  Parses the SDP query response for an 16 bit value.
 *
 * Return:    (see SDP_ParseAttributes)
 */
static void HidSdpParseDescriptorList(HidChannel *Channel, U8 *in_value, U16 in_len, U8 result)
{
   // HidParseData	*hpd;
    //hpd = Hid_Init_Parser();

    if (in_value == NULL)
    {
        return;
    }
	
    if (!(Channel->queryRsp.queryFlags & SDPQ_FLAG_DESCRIPTOR_LIST)) {

        if (in_len == 0) {
            return;
        }
        
        //if ((result == BT_STATUS_SDP_CONT_STATE) &&
	     if(Channel->queryRsp.descriptorLenOffset == 0)
        {
            U8 elemType = 0;
            U8 elemSizeDescpt = 0;			
            U8 elemSize = 0;			
            U8 elemAddSize = 0;			
            U8 offset = 0;
            U8 i = 0;
			
            /* Only the first packet is preceded with data element header. The packet
              * in continuation sequence is raw data.
              */

            while (offset + Channel->queryRsp.descriptorLen < in_len) 
            {
                elemType = SDP_GetElemType(in_value[offset]);
                elemSizeDescpt = SDP_GetElemSize(in_value[offset]);
                switch (elemType)
                {
                    case DETD_SEQ:
                        if (elemSizeDescpt == DESD_ADD_8BITS) 
                        {
                            offset = offset + 1;
                        }
                        else if (elemSizeDescpt == DESD_ADD_16BITS) 
                        {
                            offset = offset + 2;
                        }
                        else if (elemSizeDescpt == DESD_ADD_32BITS) 
                        {
                            offset = offset + 4;
                        }
                        break;
						
                    case DETD_UINT:
                        if (elemSizeDescpt > DESD_16BYTES) 
                        {
                            return;
                        }
                        else
                        {
                            elemSize = HidSdpGetValidSize(elemSizeDescpt);
                            offset += elemSize;
                        }
                        break;
						
                    case DETD_TEXT:
                        if (elemSizeDescpt == DESD_ADD_8BITS) 
                        {
                            elemAddSize = 1;
                        }
                        else if (elemSizeDescpt == DESD_ADD_16BITS) 
                        {
                            elemAddSize = 2;
                        }
                        else if (elemSizeDescpt == DESD_ADD_32BITS) 
                        {
                            elemAddSize = 4;
                        }

                        for (i = 0; i < elemAddSize; i++)
                        {
                            Channel->queryRsp.descriptorLen = (Channel->queryRsp.descriptorLen << 8) | (in_value[offset + i + 1]);
                        }
                        offset = offset + elemAddSize;
                        break;
						
                    default:
                        // other data element shall not be come out in HID attribute list						
                        break;
                }

                offset++;
            }

            if((in_len - offset) <= 0)
            {
                return;
            }

            /* Allocate a new buffer */
            Channel->queryRsp.descriptorList = (U8 *)hid_malloc((U32)Channel->queryRsp.descriptorLen);
            if (Channel->queryRsp.descriptorList == NULL)
            {
                return;
            }
            btmtk_os_memset(Channel->queryRsp.descriptorList, 0, Channel->queryRsp.descriptorLen);

            /* Copy whatever data is available */
            btmtk_os_memcpy(Channel->queryRsp.descriptorList, in_value + offset, in_len - offset);
			
            Channel->queryRsp.descriptorLenOffset = in_len - offset;
        }
        else
        {
            btmtk_os_memcpy(Channel->queryRsp.descriptorList + Channel->queryRsp.descriptorLenOffset, 
				        in_value, in_len);

            /* in case that there is more continuation packet */
            Channel->queryRsp.descriptorLenOffset += in_len;		
	/*
	   if(Hid_SdpParse(Channel, hpd) == BT_STATUS_SUCCESS)
		bt_prompt_trace(MOD_BT,"[HID]Successed  SDP parser ");
	   else if(Hid_SdpParse(Channel, hpd) == BT_STATUS_FAILED)
	   	bt_prompt_trace(MOD_BT,"[HID]Failed  SDP parser ");
	   Hid_Free_Parser(hpd);*/
        }

        kal_trace(BT_TRACE_G2_PROFILES,HID_SDP_PARSEATTRIBUTES_SUCCEEDED_BYTES_READ__xD_UPDATED_BUFF_LEN__xD , in_len, Channel->queryRsp.descriptorLenOffset);

        if (result == BT_STATUS_SUCCESS)
        {
            Channel->queryRsp.queryFlags |= SDPQ_FLAG_DESCRIPTOR_LIST;
        }
    }

}