ESPHome  2024.12.2
ble_uuid.cpp
Go to the documentation of this file.
1 #include "ble_uuid.h"
2 
3 #ifdef USE_ESP32
4 
5 #include <cstring>
6 #include <cstdio>
7 #include <cinttypes>
8 #include "esphome/core/log.h"
9 
10 namespace esphome {
11 namespace esp32_ble {
12 
13 static const char *const TAG = "esp32_ble";
14 
15 ESPBTUUID::ESPBTUUID() : uuid_() {}
17  ESPBTUUID ret;
18  ret.uuid_.len = ESP_UUID_LEN_16;
19  ret.uuid_.uuid.uuid16 = uuid;
20  return ret;
21 }
23  ESPBTUUID ret;
24  ret.uuid_.len = ESP_UUID_LEN_32;
25  ret.uuid_.uuid.uuid32 = uuid;
26  return ret;
27 }
28 ESPBTUUID ESPBTUUID::from_raw(const uint8_t *data) {
29  ESPBTUUID ret;
30  ret.uuid_.len = ESP_UUID_LEN_128;
31  memcpy(ret.uuid_.uuid.uuid128, data, ESP_UUID_LEN_128);
32  return ret;
33 }
35  ESPBTUUID ret;
36  ret.uuid_.len = ESP_UUID_LEN_128;
37  for (uint8_t i = 0; i < ESP_UUID_LEN_128; i++)
38  ret.uuid_.uuid.uuid128[ESP_UUID_LEN_128 - 1 - i] = data[i];
39  return ret;
40 }
41 ESPBTUUID ESPBTUUID::from_raw(const std::string &data) {
42  ESPBTUUID ret;
43  if (data.length() == 4) {
44  ret.uuid_.len = ESP_UUID_LEN_16;
45  ret.uuid_.uuid.uuid16 = 0;
46  for (uint i = 0; i < data.length(); i += 2) {
47  uint8_t msb = data.c_str()[i];
48  uint8_t lsb = data.c_str()[i + 1];
49  uint8_t lsb_shift = i <= 2 ? (2 - i) * 4 : 0;
50 
51  if (msb > '9')
52  msb -= 7;
53  if (lsb > '9')
54  lsb -= 7;
55  ret.uuid_.uuid.uuid16 += (((msb & 0x0F) << 4) | (lsb & 0x0F)) << lsb_shift;
56  }
57  } else if (data.length() == 8) {
58  ret.uuid_.len = ESP_UUID_LEN_32;
59  ret.uuid_.uuid.uuid32 = 0;
60  for (uint i = 0; i < data.length(); i += 2) {
61  uint8_t msb = data.c_str()[i];
62  uint8_t lsb = data.c_str()[i + 1];
63  uint8_t lsb_shift = i <= 6 ? (6 - i) * 4 : 0;
64 
65  if (msb > '9')
66  msb -= 7;
67  if (lsb > '9')
68  lsb -= 7;
69  ret.uuid_.uuid.uuid32 += (((msb & 0x0F) << 4) | (lsb & 0x0F)) << lsb_shift;
70  }
71  } else if (data.length() == 16) { // how we can have 16 byte length string reprezenting 128 bit uuid??? needs to be
72  // investigated (lack of time)
73  ret.uuid_.len = ESP_UUID_LEN_128;
74  memcpy(ret.uuid_.uuid.uuid128, (uint8_t *) data.data(), 16);
75  } else if (data.length() == 36) {
76  // If the length of the string is 36 bytes then we will assume it is a long hex string in
77  // UUID format.
78  ret.uuid_.len = ESP_UUID_LEN_128;
79  int n = 0;
80  for (uint i = 0; i < data.length(); i += 2) {
81  if (data.c_str()[i] == '-')
82  i++;
83  uint8_t msb = data.c_str()[i];
84  uint8_t lsb = data.c_str()[i + 1];
85 
86  if (msb > '9')
87  msb -= 7;
88  if (lsb > '9')
89  lsb -= 7;
90  ret.uuid_.uuid.uuid128[15 - n++] = ((msb & 0x0F) << 4) | (lsb & 0x0F);
91  }
92  } else {
93  ESP_LOGE(TAG, "ERROR: UUID value not 2, 4, 16 or 36 bytes - %s", data.c_str());
94  }
95  return ret;
96 }
97 ESPBTUUID ESPBTUUID::from_uuid(esp_bt_uuid_t uuid) {
98  ESPBTUUID ret;
99  ret.uuid_.len = uuid.len;
100  if (uuid.len == ESP_UUID_LEN_16) {
101  ret.uuid_.uuid.uuid16 = uuid.uuid.uuid16;
102  } else if (uuid.len == ESP_UUID_LEN_32) {
103  ret.uuid_.uuid.uuid32 = uuid.uuid.uuid32;
104  } else if (uuid.len == ESP_UUID_LEN_128) {
105  memcpy(ret.uuid_.uuid.uuid128, uuid.uuid.uuid128, ESP_UUID_LEN_128);
106  }
107  return ret;
108 }
110  if (this->uuid_.len == ESP_UUID_LEN_128) {
111  return *this;
112  }
113  uint8_t data[] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
114  uint32_t uuid32;
115  if (this->uuid_.len == ESP_UUID_LEN_32) {
116  uuid32 = this->uuid_.uuid.uuid32;
117  } else {
118  uuid32 = this->uuid_.uuid.uuid16;
119  }
120  for (uint8_t i = 0; i < this->uuid_.len; i++) {
121  data[12 + i] = ((uuid32 >> i * 8) & 0xFF);
122  }
123  return ESPBTUUID::from_raw(data);
124 }
125 bool ESPBTUUID::contains(uint8_t data1, uint8_t data2) const {
126  if (this->uuid_.len == ESP_UUID_LEN_16) {
127  return (this->uuid_.uuid.uuid16 >> 8) == data2 && (this->uuid_.uuid.uuid16 & 0xFF) == data1;
128  } else if (this->uuid_.len == ESP_UUID_LEN_32) {
129  for (uint8_t i = 0; i < 3; i++) {
130  bool a = ((this->uuid_.uuid.uuid32 >> i * 8) & 0xFF) == data1;
131  bool b = ((this->uuid_.uuid.uuid32 >> (i + 1) * 8) & 0xFF) == data2;
132  if (a && b)
133  return true;
134  }
135  } else {
136  for (uint8_t i = 0; i < 15; i++) {
137  if (this->uuid_.uuid.uuid128[i] == data1 && this->uuid_.uuid.uuid128[i + 1] == data2)
138  return true;
139  }
140  }
141  return false;
142 }
143 bool ESPBTUUID::operator==(const ESPBTUUID &uuid) const {
144  if (this->uuid_.len == uuid.uuid_.len) {
145  switch (this->uuid_.len) {
146  case ESP_UUID_LEN_16:
147  if (uuid.uuid_.uuid.uuid16 == this->uuid_.uuid.uuid16) {
148  return true;
149  }
150  break;
151  case ESP_UUID_LEN_32:
152  if (uuid.uuid_.uuid.uuid32 == this->uuid_.uuid.uuid32) {
153  return true;
154  }
155  break;
156  case ESP_UUID_LEN_128:
157  for (uint8_t i = 0; i < ESP_UUID_LEN_128; i++) {
158  if (uuid.uuid_.uuid.uuid128[i] != this->uuid_.uuid.uuid128[i]) {
159  return false;
160  }
161  }
162  return true;
163  break;
164  }
165  } else {
166  return this->as_128bit() == uuid.as_128bit();
167  }
168  return false;
169 }
170 esp_bt_uuid_t ESPBTUUID::get_uuid() const { return this->uuid_; }
171 std::string ESPBTUUID::to_string() const {
172  switch (this->uuid_.len) {
173  case ESP_UUID_LEN_16:
174  return str_snprintf("0x%02X%02X", 6, this->uuid_.uuid.uuid16 >> 8, this->uuid_.uuid.uuid16 & 0xff);
175  case ESP_UUID_LEN_32:
176  return str_snprintf("0x%02" PRIX32 "%02" PRIX32 "%02" PRIX32 "%02" PRIX32, 10, (this->uuid_.uuid.uuid32 >> 24),
177  (this->uuid_.uuid.uuid32 >> 16 & 0xff), (this->uuid_.uuid.uuid32 >> 8 & 0xff),
178  this->uuid_.uuid.uuid32 & 0xff);
179  default:
180  case ESP_UUID_LEN_128:
181  std::string buf;
182  for (int8_t i = 15; i >= 0; i--) {
183  buf += str_snprintf("%02X", 2, this->uuid_.uuid.uuid128[i]);
184  if (i == 6 || i == 8 || i == 10 || i == 12)
185  buf += "-";
186  }
187  return buf;
188  }
189  return "";
190 }
191 
192 } // namespace esp32_ble
193 } // namespace esphome
194 
195 #endif
bool operator==(const ESPBTUUID &uuid) const
Definition: ble_uuid.cpp:143
static ESPBTUUID from_uuid(esp_bt_uuid_t uuid)
Definition: ble_uuid.cpp:97
static ESPBTUUID from_uint32(uint32_t uuid)
Definition: ble_uuid.cpp:22
static ESPBTUUID from_uint16(uint16_t uuid)
Definition: ble_uuid.cpp:16
std::string to_string() const
Definition: ble_uuid.cpp:171
bool contains(uint8_t data1, uint8_t data2) const
Definition: ble_uuid.cpp:125
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
static ESPBTUUID from_raw(const uint8_t *data)
Definition: ble_uuid.cpp:28
ESPBTUUID as_128bit() const
Definition: ble_uuid.cpp:109
std::string str_snprintf(const char *fmt, size_t len,...)
Definition: helpers.cpp:306
static ESPBTUUID from_raw_reversed(const uint8_t *data)
Definition: ble_uuid.cpp:34
esp_bt_uuid_t get_uuid() const
Definition: ble_uuid.cpp:170