In the name of God
The following C++
code, shows how to get Raspberry Pi hardware ID(s) in various ways.
You can concatenate the strings and calculate it's hash to take Raspberry Pi Fingerprint
:
rpid.cpp:
#include <cstdint>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <streambuf>
#include <sstream>
#include <string>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
// Header: /opt/vc/include/bcm_host.h
// Library: /opt/vc/lib/libbcm_host.so
#include <bcm_host.h>
// ----------------------------------------------------------------------------------------------------
std::string ReadCPUInfo()
{
std::ifstream fileStream("/proc/cpuinfo");
if(!fileStream)
{
throw std::runtime_error("Could not open: `/proc/cpuinfo`.");
}
std::string cpuinfo((std::istreambuf_iterator<char>(fileStream)), std::istreambuf_iterator<char>());
fileStream.close();
return cpuinfo;
}
// ----------------------------------------------------------------------------------------------------
std::string ReadSysBoardModel()
{
std::ifstream fileStream("/sys/firmware/devicetree/base/model");
if(!fileStream)
{
throw std::runtime_error("Could not open: `/sys/firmware/devicetree/base/model`.");
}
std::string model((std::istreambuf_iterator<char>(fileStream)), std::istreambuf_iterator<char>());
fileStream.close();
return model;
}
// ----------------------------------------------------------------------------------------------------
std::string ReadSysBoardSerial()
{
std::ifstream fileStream("/sys/firmware/devicetree/base/serial-number");
if(!fileStream)
{
throw std::runtime_error("Could not open: `/sys/firmware/devicetree/base/serial-number`.");
}
std::string serial((std::istreambuf_iterator<char>(fileStream)), std::istreambuf_iterator<char>());
fileStream.close();
return serial;
}
// ----------------------------------------------------------------------------------------------------
std::string ReadSysMACAddress()
{
std::ifstream fileStream("/sys/class/net/eth0/address");
if(!fileStream)
{
throw std::runtime_error("Could not open: `/sys/class/net/eth0/address`.");
}
std::string address((std::istreambuf_iterator<char>(fileStream)), std::istreambuf_iterator<char>());
fileStream.close();
return address;
}
// ----------------------------------------------------------------------------------------------------
std::string ReadMailboxBoardModel()
{
int fd = open("/dev/vcio", 0);
if (fd == -1)
{
throw std::runtime_error("Could not open: `/dev/vcio`.");
}
uint32_t property[32] =
{
0x0000001C, // Buffer size in bytes (including the header values, the end tag and padding): 7 * 4 = 28 = 0x1C.
0x00000000, // Request code: 0x00000000 = process request.
0x00010001, // Tag identifier: Get board model.
0x00000004, // Value buffer size in bytes: 1 * 4 = 4 = 0x4.
0x00000000, // Request code: b31 clear: request, b30-b0: reserved.
0x00000000, // Value buffer.
0x00000000 // End tag: 0x0
};
const unsigned long MAJOR_NUM = 100;
if (ioctl(fd, _IOWR(MAJOR_NUM, 0, char*), property) < 0)
{
close(fd);
throw std::runtime_error("`ioctl` failed.");
}
if (property[1] != 0x80000000)
{
close(fd);
throw std::runtime_error("Request failed.");
}
close(fd);
std::stringstream stream;
stream << std::hex << property[5];
std::string result = stream.str();
return result;
}
// ----------------------------------------------------------------------------------------------------
std::string ReadMailboxBoardRevision()
{
int fd = open("/dev/vcio", 0);
if (fd == -1)
{
throw std::runtime_error("Could not open: `/dev/vcio`.");
}
uint32_t property[32] =
{
0x0000001C, // Buffer size in bytes (including the header values, the end tag and padding): 7 * 4 = 28 = 0x1C.
0x00000000, // Request code: 0x00000000 = process request.
0x00010002, // Tag identifier: Get board revision.
0x00000004, // Value buffer size in bytes: 1 * 4 = 4 = 0x4.
0x00000000, // Request code: b31 clear: request, b30-b0: reserved.
0x00000000, // Value buffer.
0x00000000 // End tag: 0x0
};
const unsigned long MAJOR_NUM = 100;
if (ioctl(fd, _IOWR(MAJOR_NUM, 0, char*), property) < 0)
{
close(fd);
throw std::runtime_error("`ioctl` failed.");
}
if (property[1] != 0x80000000)
{
close(fd);
throw std::runtime_error("Request failed.");
}
close(fd);
std::stringstream stream;
stream << std::hex << property[5];
std::string result = stream.str();
return result;
}
// ----------------------------------------------------------------------------------------------------
std::string ReadMailboxBoardSerial()
{
int fd = open("/dev/vcio", 0);
if (fd == -1)
{
throw std::runtime_error("Could not open: `/dev/vcio`.");
}
uint32_t property[32] =
{
0x00000020, // Buffer size in bytes (including the header values, the end tag and padding): 8 * 4 = 32 = 0x20.
0x00000000, // Request code: 0x00000000 = process request.
0x00010004, // Tag identifier: Get board serial.
0x00000008, // Value buffer size in bytes: 2 * 4 = 8 = 0x8.
0x00000000, // Request code: b31 clear: request, b30-b0: reserved.
0x00000000, // Value buffer.
0x00000000, // Value buffer.
0x00000000 // End tag: 0x0
};
const unsigned long MAJOR_NUM = 100;
if (ioctl(fd, _IOWR(MAJOR_NUM, 0, char*), property) < 0)
{
close(fd);
throw std::runtime_error("`ioctl` failed.");
}
if (property[1] != 0x80000000)
{
close(fd);
throw std::runtime_error("Request failed.");
}
close(fd);
std::stringstream stream;
stream << std::hex << property[5]; // property[6] ignored.
std::string result = stream.str();
return result;
}
// ----------------------------------------------------------------------------------------------------
std::string ReadMailboxMACAddress()
{
int fd = open("/dev/vcio", 0);
if (fd == -1)
{
throw std::runtime_error("Could not open: `/dev/vcio`.");
}
uint32_t property[32] =
{
0x00000020, // Buffer size in bytes (including the header values, the end tag and padding): 8 * 4 = 32 = 0x20.
0x00000000, // Request code: 0x00000000 = process request.
0x00010003, // Tag identifier: Get board MAC address.
0x00000008, // Value buffer size in bytes: 2 * 4 = 8 = 0x8.
0x00000000, // Request code: b31 clear: request, b30-b0: reserved.
0x00000000, // Value buffer.
0x00000000, // Value buffer.
0x00000000 // End tag: 0x0
};
const unsigned long MAJOR_NUM = 100;
if (ioctl(fd, _IOWR(MAJOR_NUM, 0, char*), property) < 0)
{
close(fd);
throw std::runtime_error("`ioctl` failed.");
}
if (property[1] != 0x80000000)
{
close(fd);
throw std::runtime_error("Request failed.");
}
close(fd);
unsigned char* ptr = reinterpret_cast<unsigned char*>(&property[5]);
std::stringstream stream;
stream
<< std::hex
<< static_cast<int>(ptr[0]) << ":"
<< static_cast<int>(ptr[1]) << ":"
<< static_cast<int>(ptr[2]) << ":"
<< static_cast<int>(ptr[3]) << ":"
<< static_cast<int>(ptr[4]) << ":"
<< static_cast<int>(ptr[5]);
std::string result = stream.str();
return result;
}
// ----------------------------------------------------------------------------------------------------
std::string ReadOTPDump()
{
bcm_host_init();
char buffer[1024] = { 0 };
if (vc_gencmd(buffer, sizeof(buffer), "otp_dump") != 0)
{
bcm_host_deinit();
throw std::runtime_error("Could not execute `otp_dump` command.");
}
bcm_host_deinit();
std::string otpDump = buffer;
return otpDump;
}
// ----------------------------------------------------------------------------------------------------
int main()
{
std::cout << "-------------------- CPU Info: $ cat /proc/cpuinfo --------------------" << std::endl;
std::cout << ReadCPUInfo() << std::endl;
std::cout << "-------------------- Board Model: $ cat /sys/firmware/devicetree/base/model --------------------" << std::endl;
std::cout << ReadSysBoardModel() << std::endl;
std::cout << "-------------------- Board Serial: $ cat /sys/firmware/devicetree/base/serial-number --------------------" << std::endl;
std::cout << ReadSysBoardSerial() << std::endl;
std::cout << "-------------------- MAC Address: $ cat /sys/class/net/eth0/address --------------------" << std::endl;
std::cout << ReadSysMACAddress() << std::endl;
std::cout << "-------------------- Board Model: $ /opt/vc/bin/vcmailbox 0x10001 0x4 0x0 0x0 --------------------" << std::endl;
std::cout << ReadMailboxBoardModel() << std::endl;
std::cout << "-------------------- Board Revision: $ /opt/vc/bin/vcmailbox 0x10002 0x4 0x0 0x0 --------------------" << std::endl;
std::cout << ReadMailboxBoardRevision() << std::endl;
std::cout << "-------------------- Board Serial: $ /opt/vc/bin/vcmailbox 0x10004 0x8 0x0 0x0 0x0 --------------------" << std::endl;
std::cout << ReadMailboxBoardSerial() << std::endl;
std::cout << "-------------------- MAC Address: $ /opt/vc/bin/vcmailbox 0x10003 0x8 0x0 0x0 0x0 --------------------" << std::endl;
std::cout << ReadMailboxMACAddress() << std::endl;
std::cout << "-------------------- OTP: vcgencmd otp_dump --------------------" << std::endl;
std::cout << ReadOTPDump() << std::endl;
return 0;
}
To build the code, run the following command on Raspberry Pi terminal:
$ g++ \
rpid.cpp \
-I/opt/vc/include/ \
-L/opt/vc/lib/ \
-lbcm_host \
-o rpid
$ ./rpid
The following text generated by rpid
on my device:
-------------------- CPU Info: $ cat /proc/cpuinfo --------------------
processor : 0
model name : ARMv7 Processor rev 4 (v7l)
BogoMIPS : 38.40
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
processor : 1
model name : ARMv7 Processor rev 4 (v7l)
BogoMIPS : 38.40
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
processor : 2
model name : ARMv7 Processor rev 4 (v7l)
BogoMIPS : 38.40
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
processor : 3
model name : ARMv7 Processor rev 4 (v7l)
BogoMIPS : 38.40
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
Hardware : BCM2835
Revision : a22082
Serial : 00000000cae4d6b2
Model : Raspberry Pi 3 Model B Rev 1.2
-------------------- Board Model: $ cat /sys/firmware/devicetree/base/model --------------------
Raspberry Pi 3 Model B Rev 1.2
-------------------- Board Serial: $ cat /sys/firmware/devicetree/base/serial-number --------------------
00000000cae4d6b2
-------------------- MAC Address: $ cat /sys/class/net/eth0/address --------------------
b8:27:eb:e4:d6:b2
-------------------- Board Model: $ /opt/vc/bin/vcmailbox 0x10001 0x4 0x0 0x0 --------------------
0
-------------------- Board Revision: $ /opt/vc/bin/vcmailbox 0x10002 0x4 0x0 0x0 --------------------
a22082
-------------------- Board Serial: $ /opt/vc/bin/vcmailbox 0x10004 0x8 0x0 0x0 0x0 --------------------
cae4d6b2
-------------------- MAC Address: $ /opt/vc/bin/vcmailbox 0x10003 0x8 0x0 0x0 0x0 --------------------
b8:27:eb:e4:d6:b2
-------------------- OTP: vcgencmd otp_dump --------------------
08:00000000
09:00000000
10:00000000
11:00000000
12:00000000
13:00000000
14:00000000
15:00000000
16:00280000
17:1020000a
18:1020000a
19:ffffffff
20:ffffffff
21:ffffffff
22:ffffffff
23:ffffffff
24:ffffffff
25:ffffffff
26:ffffffff
27:00002727
28:cae4d6b2
29:351b294d
30:00a22082
31:00000000
32:00000000
33:00000000
34:00000000
35:00000000
36:00000000
37:00000000
38:00000000
39:00000000
40:00000000
41:00000000
42:00000000
43:00000000
44:00000000
45:00000000
46:00000000
47:00000000
48:00000000
49:00000000
50:00000000
51:00000000
52:00000000
53:00000000
54:00000000
55:00000000
56:00000000
57:00000000
58:00000000
59:00000000
60:00000000
61:00000000
62:00000000
63:00000000
64:00000000
65:00000000
66:00000000
You can run the following command on terminal to extract Hardware ID:
$ cat /proc/cpuinfo
$ cat /sys/firmware/devicetree/base/model
$ cat /sys/firmware/devicetree/base/serial-number
$ cat /sys/class/net/eth0/address
$ /opt/vc/bin/vcmailbox 0x10001 0x4 0x0 0x0
$ /opt/vc/bin/vcmailbox 0x10002 0x4 0x0 0x0
$ /opt/vc/bin/vcmailbox 0x10004 0x8 0x0 0x0 0x0
$ /opt/vc/bin/vcmailbox 0x10003 0x8 0x0 0x0 0x0
$ vcgencmd otp_dump
- https://github.com/raspberrypi/documentation/tree/JamesH65-mailbox_docs/configuration/mailboxes
- https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
- https://github.com/raspberrypi/userland/tree/master/host_applications/linux/apps/vcmailbox
- https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
- https://www.raspberrypi.org/documentation/hardware/raspberrypi/otpbits.md
- https://github.com/raspberrypi/userland/tree/master/host_applications/linux/libs/bcm_host
- https://github.com/raspberrypi/userland/tree/master/interface/vmcs_host
- https://www.raspberrypi.org/documentation/raspbian/applications/vcgencmd.md
- https://raspberrypi.stackexchange.com/questions/2086/how-do-i-get-the-serial-number
- https://github.com/AndrewFromMelbourne/raspi_serialnumber