/* Find the rfcomm server channel in a service record */ static bool findRfcommServerChannel(const uint8 *ptr, const uint8 *end, Region *value) { ServiceDataType type; Region record, protocols, protocol; record.begin = ptr; record.end = end; while(ServiceFindAttribute(&record, saProtocolDescriptorList, &type, &protocols)) { if(type == sdtSequence) { while(ServiceGetValue(&protocols, &type, &protocol)) { if(type == sdtSequence && ServiceGetValue(&protocol, &type, value) && type == sdtUUID && RegionMatchesUUID32(value, (uint32) UUID_RFCOMM) && ServiceGetValue(&protocol, &type, value) && type == sdtUnsignedInteger) { /* Hah! found the server channel field */ return 1; } } } } return 0; /* Failed */ }
/* Find the supported features in a service record */ static bool findHfpSupportedFeatures(const uint8 *begin, const uint8 *end, Region *value) { ServiceDataType type; Region record; record.begin = begin; record.end = end; if (ServiceFindAttribute(&record, saSupportedFeatures, &type, value)) { if(type == sdtUnsignedInteger) return 1; } return 0; }
static bool findProtocolDescriptorList(const uint8 size_service_record, const uint8* service_record, Region* protocols) { ServiceDataType type; Region record; record.begin = service_record; record.end = service_record + size_service_record; /* Move protocols to Protocol Descriptor List */ while(ServiceFindAttribute(&record, saProtocolDescriptorList, &type, protocols)) if(type == sdtSequence) /* Success */ return TRUE; /* Failed */ return FALSE; }
static bool findPbapRepos(const uint8 size_service_record, const uint8* service_record, Region* value) { ServiceDataType type; Region record; record.begin = service_record; record.end = service_record + size_service_record; if (ServiceFindAttribute(&record, saPbapRepos, &type, value)) if(type == sdtUnsignedInteger) { /* Found the Attribute Field */ return TRUE; } /* Failed */ return FALSE; }
static bool findSupportedFeatures(const uint8 length, const uint8* begin, Region* value) { ServiceDataType type; Region record; record.begin = begin; record.end = begin + length; if (ServiceFindAttribute(&record, saSupportedFeatures, &type, value)) if(type == sdtUnsignedInteger) { /* Found the Supported Features */ return TRUE; } /* Failed */ return FALSE; }
static bool findServiceName(const uint8 size_service_record, const uint8* service_record, ServiceAttributeId id, Region* value) { ServiceDataType type; Region record; record.begin = service_record; record.end = service_record + size_service_record; if (ServiceFindAttribute(&record, id, &type, value)) if(type == sdtTextString) { /* Found the Attribute Field */ return TRUE; } /* Failed */ return FALSE; }
/* Note1 - HFP spec states that the service class UUID should be Handsfree (0x111e). Some AG's return a UUID of HandsfreeAudioGateway(0x111f). We need to allow for this. */ static bool findProfileVersion(const uint8 *ptr, const uint8 *end, Region *value) { ServiceDataType type; Region record, protocols, protocol; record.begin = ptr; record.end = end; while(ServiceFindAttribute(&record, saBluetoothProfileDescriptorList, &type, &protocols)) if(type == sdtSequence) while(ServiceGetValue(&protocols, &type, &protocol)) if(type == sdtSequence && ServiceGetValue(&protocol, &type, value) && type == sdtUUID && (RegionMatchesUUID32(value, (uint32) 0x111e) || RegionMatchesUUID32(value, (uint32) 0x111f)) /* See Note1 above */ && ServiceGetValue(&protocol, &type, value) && type == sdtUnsignedInteger) { /* Have found the profile version */ return 1; } /* Failed */ return 0; }