diff --git a/libs/core/linux.cpp b/libs/core/linux.cpp index 5e7bcfa4..e3f16705 100644 --- a/libs/core/linux.cpp +++ b/libs/core/linux.cpp @@ -221,10 +221,6 @@ int current_time_ms() { return currTime() - startTime; } -int getSerialNumber() { - return 42; // TODO -} - void disposeThread(Thread *t) { if (allThreads == t) { allThreads = t->next; diff --git a/libs/core/pxt.json b/libs/core/pxt.json index 39c6f5e7..716d8e58 100644 --- a/libs/core/pxt.json +++ b/libs/core/pxt.json @@ -10,6 +10,7 @@ "linux.cpp", "mmap.cpp", "control.cpp", + "serialnumber.cpp", "buttons.ts", "png.cpp", "screen.cpp", diff --git a/libs/core/serialnumber.cpp b/libs/core/serialnumber.cpp new file mode 100644 index 00000000..7efde89f --- /dev/null +++ b/libs/core/serialnumber.cpp @@ -0,0 +1,78 @@ +#include "pxt.h" + +#include +#include +#include + +#define BTPROTO_HCI 1 +#define HCIGETDEVLIST _IOR('H', 210, int) +#define HCIGETDEVINFO _IOR('H', 211, int) + +struct hci_dev_info { + uint16_t dev_id; + char name[8]; + uint8_t bdaddr[6]; + uint32_t padding[32]; +}; + +struct hci_dev_req { + uint16_t dev_id; + uint32_t dev_opt; +}; + +struct hci_dev_list_req { + uint16_t dev_num; + hci_dev_req dev_req[2]; +}; + + +static uint32_t bt_addr() { + uint32_t res = 0; + + int fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); + if (fd < 0) { + DMESG("Can't open HCI socket"); + return res; + } + + hci_dev_list_req dl; + dl.dev_num = 1; + + if (ioctl(fd, HCIGETDEVLIST, (void *)&dl) < 0) { + DMESG("Failed to get HCI device list"); + goto done; + } + + hci_dev_info di; + di.dev_id = dl.dev_req[0].dev_id; + + if (ioctl(fd, HCIGETDEVINFO, (void *)&di) < 0) { + DMESG("Failed to get HCI device list"); + goto done; + } + + memcpy(&res, di.bdaddr, 4); + res *= 0x1000193; + res += di.bdaddr[4]; + res *= 0x1000193; + res += di.bdaddr[5]; + +done: + close(fd); + return res; +} + +namespace pxt { + +int getSerialNumber() { + static int serial; + + if (serial != 0) + return serial; + + serial = bt_addr() & 0x7fffffff; + + return serial; +} + +} // namespace pxt