/*--------------------------------------------------------------------------- * HidStartServiceQuery() *--------------------------------------------------------------------------- * * Synopsis: Initiate the SDP service query for a HID device. * * Return: See SDP_Query(). */ BtStatus HidStartServiceQuery(HidChannel *Channel) { BtStatus status = BT_STATUS_FAILED; sdap_service_search_multi_attribute_struct search_pattern; ReportDescriptorList* reportDescriptorList = NULL; HidParseData* hpd ; reportDescriptorList = HidFindReportDescriptorByAddr(Channel->cmgrHandler.remDev->bdAddr); if(reportDescriptorList != NULL && Channel->state == HID_STATE_OPEN) { Channel->queryRsp.descriptorLen = reportDescriptorList->reportDescriptorLength; Channel->queryRsp.descriptorList = (U8*)hid_malloc(reportDescriptorList->reportDescriptorLength); btmtk_os_memset((U8*) Channel->queryRsp.descriptorList, 0, reportDescriptorList->reportDescriptorLength); btmtk_os_memcpy((U8*) Channel->queryRsp.descriptorList, reportDescriptorList->reportDescriptor, reportDescriptorList->reportDescriptorLength); hpd = (HidParseData*)hid_malloc(sizeof(HidParseData)); Hid_Init_Parser(hpd); Channel->reportCons[0] = (HidReportConstructor*)hid_malloc(HID_REPORT_ID_MAX * sizeof(HidReportConstructor)); btmtk_os_memset((U8*) Channel->reportCons[0], 0, HID_REPORT_ID_MAX * sizeof(HidReportConstructor)); if(HidAddDescriptor(Channel) == BT_STATUS_SUCCESS) bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor Successed!"); else bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor failed!"); Hid_Free_Parser(hpd); Channel->flags &= ~CHNL_FLAG_SERVICE_QUERY; HidSdpCallback(Channel, BT_STATUS_SUCCESS); return BT_STATUS_SUCCESS; } else { search_pattern.rm = Channel->cmgrHandler.remDev; search_pattern.sqt = &Channel->sdpQueryToken; search_pattern.uuid = SC_HUMAN_INTERFACE_DEVICE; search_pattern.callback = HidSdpEventHandler; search_pattern.attribute_num = sizeof(bt_hid_attr_id_list)/sizeof(bt_hid_attr_id_list[0]); search_pattern.attribute_id = bt_hid_attr_id_list; status = SDAP_ServiceSearchMultipleAttribute2(search_pattern); return status; } }
U8 Hid_Init_Parser(HidParseData* tmpHidParser) { //HidParseData* tmpHidParser = (HidParseData*)hid_malloc(sizeof(HidParseData)); if(!tmpHidParser) { bt_prompt_trace(MOD_BT,"[HID]HidParseData hid_malloc error"); return 0; } tmpHidParser->reportDesc = NULL; tmpHidParser->usageQueue = (HidUsage*)hid_malloc(HID_USAGE_MAX * sizeof(HidUsage)); if(!tmpHidParser->usageQueue) { bt_prompt_trace(MOD_BT,"[HID]usageQueue hid_malloc error"); return 0; } btmtk_os_memset((U8*) tmpHidParser->usageQueue, 0, sizeof(HID_USAGE_MAX * sizeof(HidUsage))); tmpHidParser->usageSize = 0; tmpHidParser->usageNum = 0; tmpHidParser->reportDescLength = 0; tmpHidParser->logicalMAX = 0; tmpHidParser->logicalMIN = 0; tmpHidParser->physicalMAX = 0; tmpHidParser->physicalMIN = 0; tmpHidParser->reportCount = 0; tmpHidParser->reportSize = 0; tmpHidParser->reportID = 0; tmpHidParser->usagePage = 0; tmpHidParser->unitExponent = 0; tmpHidParser->unit = 0; tmpHidParser->pos = 0; tmpHidParser->collectionArray = (HidUsageCollection*)hid_malloc(HID_COLLECTION_MAX * sizeof(HidUsageCollection)); btmtk_os_memset((HidUsageCollection*) tmpHidParser->collectionArray, 0, sizeof(HID_COLLECTION_MAX * sizeof(HidUsageCollection))); tmpHidParser->collectionIndex = 0; //return tmpHidParser; Hid_Init_KeyArray(); return 1; }
BtStatus HidCacheReportDescriptor(BD_ADDR addr, U8* HidDescriptorList, U32 length) { U8 i = 0; for (i = 0; i < HID_MAX_REPORT_DESCRIPTOR_NUM; i++) { if (!CachedReportDescriptor[i].inUse) { btmtk_os_memcpy(CachedReportDescriptor[i].BtAddr.addr, addr.addr, 6); CachedReportDescriptor[i].inUse = TRUE; CachedReportDescriptor[i].reportDescriptor = (U8*)hid_malloc(length); if(!CachedReportDescriptor[i].reportDescriptor) { bt_prompt_trace(MOD_BT,"[HID]CachedReportDescriptor[i].reportDescriptor hid_malloc error"); return BT_STATUS_FAILED; } btmtk_os_memset(CachedReportDescriptor[i].reportDescriptor, 0 ,length); btmtk_os_memcpy(CachedReportDescriptor[i].reportDescriptor, HidDescriptorList, length); CachedReportDescriptor[i].reportDescriptorLength = length; break; } } return BT_STATUS_SUCCESS; }
/*--------------------------------------------------------------------------- * 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; } } }
void HidSdpEventHandler(SdpQueryToken *sqt, U8 result, U8 attr_idx, U8 *attr_val) { HidChannel *channel = ContainingRecord(sqt, HidChannel, sdpQueryToken); ReportDescriptorList* reportDescriptorList = NULL; HidParseData* hpd ; kal_trace(BT_TRACE_G2_PROFILES,BT_HID_SDP_QUERY_CALLBACK_x02X ,result); switch (result) { case BT_STATUS_SDP_CONT_STATE: kal_trace(BT_TRACE_G2_PROFILES,HID_SDP_SUCCESSFULLY); HidVerifySdpQueryRsp(channel, bt_hid_attr_id_list[attr_idx], attr_val, sqt->availValueLen, result); break; case BT_STATUS_SUCCESS: HidVerifySdpQueryRsp(channel, bt_hid_attr_id_list[attr_idx], attr_val, sqt->availValueLen, result); if (channel->bSDPDiscPending) { HidClearConnection(channel, result, 0); } else { hpd = (HidParseData*)hid_malloc(sizeof(HidParseData)); Hid_Init_Parser(hpd); channel->reportCons[0] = (HidReportConstructor*)hid_malloc(HID_REPORT_ID_MAX * sizeof(HidReportConstructor)); btmtk_os_memset((U8*) channel->reportCons[0], 0, HID_REPORT_ID_MAX * sizeof(HidReportConstructor)); reportDescriptorList = HidFindReportDescriptorByAddr(channel->cmgrHandler.remDev->bdAddr); if(reportDescriptorList != NULL ) { btmtk_os_memset(reportDescriptorList->BtAddr.addr, 0, 6); reportDescriptorList->inUse = FALSE; hid_free(reportDescriptorList->reportDescriptor); reportDescriptorList->reportDescriptorLength = 0; } HidCacheReportDescriptor(channel->cmgrHandler.remDev->bdAddr, channel->queryRsp.descriptorList, channel->queryRsp.descriptorLen); if(HidAddDescriptor(channel) == BT_STATUS_SUCCESS) bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor Successed!"); else bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor failed!"); Hid_Free_Parser(hpd); channel->flags &= ~CHNL_FLAG_SERVICE_QUERY; HidSdpCallback(channel, result); } break; case BT_STATUS_NOSERVICES: { static const U8 HidDescriptorList[] = { HID_DESCRIPTOR }; channel->queryRsp.descriptorLen = HID_DESCRIPTOR_LEN; channel->queryRsp.descriptorList = (U8*)hid_malloc(HID_DESCRIPTOR_LEN); btmtk_os_memset((U8*) channel->queryRsp.descriptorList, 0, HID_DESCRIPTOR_LEN); btmtk_os_memcpy((U8*) channel->queryRsp.descriptorList, HidDescriptorList, HID_DESCRIPTOR_LEN); hpd = (HidParseData*)hid_malloc(sizeof(HidParseData)); Hid_Init_Parser(hpd); channel->reportCons[0] = (HidReportConstructor*)hid_malloc(HID_REPORT_ID_MAX * sizeof(HidReportConstructor)); btmtk_os_memset((U8*) channel->reportCons[0], 0, HID_REPORT_ID_MAX * sizeof(HidReportConstructor)); if(HidAddDescriptor(channel) == BT_STATUS_SUCCESS) bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor Successed!"); else bt_prompt_trace(MOD_BT,"[HID]HidAddDescriptor failed!"); Hid_Free_Parser(hpd); channel->flags &= ~CHNL_FLAG_SERVICE_QUERY; HidSdpCallback(channel, BT_STATUS_SUCCESS); break; } case BT_STATUS_CONNECTION_FAILED: case BT_STATUS_FAILED: default: channel->flags &= ~CHNL_FLAG_SERVICE_QUERY; HidClearConnection(channel, result, 0); break; } }