1d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati/****************************************************************************** 2d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * 3d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * Copyright (C) 2014 Google, Inc. 4d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * 5d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * Licensed under the Apache License, Version 2.0 (the "License"); 6d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * you may not use this file except in compliance with the License. 7d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * You may obtain a copy of the License at: 8d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * 9d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * http://www.apache.org/licenses/LICENSE-2.0 10d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * 11d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * Unless required by applicable law or agreed to in writing, software 12d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * distributed under the License is distributed on an "AS IS" BASIS, 13d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * See the License for the specific language governing permissions and 15d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * limitations under the License. 16d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati * 17d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati ******************************************************************************/ 18d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati 193623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton#include <assert.h> 203623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton#include <stdio.h> 213623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton#include <stdlib.h> 22d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati#include <string.h> 23d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati 243623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton#include "btcore/include/uuid.h" 253623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton#include "osi/include/allocator.h" 263623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 273623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonstatic const size_t UUID_WELL_FORMED_STRING_LEN = 36; 283623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonstatic const size_t UUID_WELL_FORMED_STRING_LEN_WITH_NULL = 36 + 1; 293623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 303623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantontypedef struct uuid_string_t { 313623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton char string[0]; 323623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton} uuid_string_t; 33d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati 34d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavatistatic const bt_uuid_t empty_uuid = {{ 0 }}; 35d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati 363623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton// The base UUID is used for calculating 128-bit UUIDs from 16 and 373623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton// 32 bit UUIDs as described in the SDP specification. 383623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonstatic const bt_uuid_t base_uuid = { 393623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 403623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b, 0x34, 0xfb, }}; 413623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 423623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonstatic bool uuid_is_base(const bt_uuid_t *uuid); 433623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 443623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonuuid_string_t *uuid_string_new(void) { 453623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return osi_calloc(UUID_WELL_FORMED_STRING_LEN_WITH_NULL); 463623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton} 473623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 483623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonvoid uuid_string_free(uuid_string_t *uuid_string) { 493623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton osi_free(uuid_string); 503623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton} 513623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 523623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonconst char *uuid_string_data(const uuid_string_t *uuid_string) { 533623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton assert(uuid_string != NULL); 543623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return (const char *)uuid_string->string; 553623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton} 563623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 573623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonbt_uuid_t *uuid_new(const char *uuid_string) { 583623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton assert(uuid_string != NULL); 593623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 603623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton if (strlen(uuid_string) < UUID_WELL_FORMED_STRING_LEN) 613623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return NULL; 623623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton if (uuid_string[8] != '-' || uuid_string[13] != '-' || uuid_string[18] != '-' || uuid_string[23] != '-') 633623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return NULL; 643623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 653623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton bt_uuid_t *uuid = osi_calloc(sizeof(bt_uuid_t)); 663623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 673623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton const char *s = uuid_string; 683623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton for (size_t i = 0; i < sizeof(bt_uuid_t); ++i, s+=2) { 69addbe8f4895fdcac71c6ef2ea844612e3bb5938cAjay Panicker char buf[3] = {0}; 703623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton buf[0] = s[0]; 713623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton buf[1] = s[1]; 723623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton uuid->uu[i] = strtoul(buf, NULL, 16); 733623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton // Adjust by skipping the dashes 743623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton switch(i) { 753623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton case 3: 763623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton case 5: 773623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton case 7: 783623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton case 9: 793623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton s++; 803623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton break; 813623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton } 823623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton } 833623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return uuid; 843623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton} 853623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 863623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonvoid uuid_free(bt_uuid_t *uuid) { 873623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton osi_free(uuid); 883623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton} 893623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 90d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavatibool uuid_is_empty(const bt_uuid_t *uuid) { 91d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati return !uuid || !memcmp(uuid, &empty_uuid, sizeof(bt_uuid_t)); 92d1e05dea6cf4ff14b39a7aee6650ba59af57e3eaSharvil Nanavati} 933623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 943623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonbool uuid_is_equal(const bt_uuid_t *first, const bt_uuid_t *second) { 953623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton assert(first != NULL); 963623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton assert(second != NULL); 973623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return !memcmp(first, second, sizeof(bt_uuid_t)); 983623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton} 993623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 1003623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonbt_uuid_t *uuid_copy(bt_uuid_t *dest, const bt_uuid_t *src) { 1013623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton assert(dest != NULL); 1023623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton assert(src != NULL); 1033623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return (bt_uuid_t *)memcpy(dest, src, sizeof(bt_uuid_t)); 1043623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton} 1053623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 1063623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonbool uuid_128_to_16(const bt_uuid_t *uuid, uint16_t *uuid16) { 1073623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton assert(uuid != NULL); 1083623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton assert(uuid16 != NULL); 1093623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 1103623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton if (!uuid_is_base(uuid)) 1113623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return false; 1123623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 1133623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton *uuid16 = (uuid->uu[2] << 8) + uuid->uu[3]; 1143623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return true; 1153623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton} 1163623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 1173623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonbool uuid_128_to_32(const bt_uuid_t *uuid, uint32_t *uuid32) { 1183623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton assert(uuid != NULL); 1193623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton assert(uuid32 != NULL); 1203623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 1213623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton if (!uuid_is_base(uuid)) 1223623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return false; 1233623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 1243623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton *uuid32 = (uuid->uu[0] << 24) + (uuid->uu[1] << 16) + (uuid->uu[2] << 8) + uuid->uu[3]; 1253623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return true; 1263623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton} 1273623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 1283623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonvoid uuid_to_string(const bt_uuid_t *uuid, uuid_string_t *uuid_string) { 1293623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton assert(uuid != NULL); 1303623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton assert(uuid_string != NULL); 1313623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 1323623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton char *string = uuid_string->string; 1333623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 1343623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton for (int i = 0; i < 4; i++) { 1353623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton string += sprintf(string, "%02x", uuid->uu[i]); 1363623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton } 1373623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton string += sprintf(string, "-"); 1383623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton for (int i = 4; i < 6; i++) { 1393623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton string += sprintf(string, "%02x", uuid->uu[i]); 1403623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton } 1413623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton string += sprintf(string, "-"); 1423623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton for (int i = 6; i < 8; i++) { 1433623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton string += sprintf(string, "%02x", uuid->uu[i]); 1443623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton } 1453623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton string += sprintf(string, "-"); 1463623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton for (int i = 8; i < 10; i++) { 1473623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton string += sprintf(string, "%02x", uuid->uu[i]); 1483623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton } 1493623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton string += sprintf(string, "-"); 1503623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton for (int i = 10; i < 16; i++) { 1513623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton string += sprintf(string, "%02x", uuid->uu[i]); 1523623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton } 1533623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton} 1543623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 1553623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Mantonstatic bool uuid_is_base(const bt_uuid_t *uuid) { 1563623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton if (!uuid) 1573623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return false; 1583623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton 1593623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton for (int i = 4; i < 16; i++) { 1603623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton if (uuid->uu[i] != base_uuid.uu[i]) 1613623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return false; 1623623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton } 1633623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton return true; 1643623bc8d9533f30c96dc17e50cd5dc2baf0799a4Chris Manton} 165