# HG changeset patch # User Michiel Broek # Date 1562497086 -7200 # Node ID 363dc36d2450349f18670b164b9e55e775f09d0b # Parent 93667d842c9b09483ec2d6a69e1b368c1234ae16 Added wiringPi hardware detection code. diff -r 93667d842c9b -r 363dc36d2450 thermferm/mqtt.c --- a/thermferm/mqtt.c Thu May 09 19:50:26 2019 +0200 +++ b/thermferm/mqtt.c Sun Jul 07 12:58:06 2019 +0200 @@ -58,6 +58,224 @@ char my_hostname[256]; +#ifndef HAVE_WIRINGPI_H + +/* + * Code from wiringPi written by Gordon Henderson. + * Copied here to have some sort of hardware detection without wiringPi. + */ +const char *piModelNames [20] = +{ + "Model A", // 0 + "Model B", // 1 + "Model A+", // 2 + "Model B+", // 3 + "Pi 2", // 4 + "Alpha", // 5 + "CM", // 6 + "Unknown07", // 07 + "Pi 3", // 08 + "Pi Zero", // 09 + "CM3", // 10 + "Unknown11", // 11 + "Pi Zero-W", // 12 + "Pi 3B+", // 13 + "Pi 3A+", // 14 + "Unknown15", // 15 + "CM3+", // 16 + "Unknown17", // 17 + "Unknown18", // 18 + "Unknown19", // 19 +}; +const char *piRevisionNames [16] = +{ + "00", + "01", + "02", + "03", + "04", + "05", + "06", + "07", + "08", + "09", + "10", + "11", + "12", + "13", + "14", + "15", +} ; +const char *piMakerNames [16] = +{ + "Sony", // 0 + "Egoman", // 1 + "Embest", // 2 + "Unknown", // 3 + "Embest", // 4 + "Unknown05", // 5 + "Unknown06", // 6 + "Unknown07", // 7 + "Unknown08", // 8 + "Unknown09", // 9 + "Unknown10", // 10 + "Unknown11", // 11 + "Unknown12", // 12 + "Unknown13", // 13 + "Unknown14", // 14 + "Unknown15", // 15 +} ; +const int piMemorySize [8] = +{ + 256, // 0 + 512, // 1 + 1024, // 2 + 0, // 3 + 0, // 4 + 0, // 5 + 0, // 6 + 0, // 7 +} ; + +void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty) +{ + FILE *cpuFd ; + char line [120] ; + char *c ; + unsigned int revision ; + int bRev, bType, bProc, bMfg, bMem, bWarranty ; + + *model = -1; // Mark no info + if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL) { + syslog(LOG_NOTICE, "Unable to open /proc/cpuinfo") ; + return; + } + + while (fgets (line, 120, cpuFd) != NULL) + if (strncmp (line, "Revision", 8) == 0) + break ; + + fclose (cpuFd) ; + + if (strncmp (line, "Revision", 8) != 0) { + syslog(LOG_NOTICE, "No \"Revision\" line"); + return; + } + +// Chomp trailing CR/NL + + for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c) + *c = 0 ; + + if (debug) + fprintf(stdout, "piBoardId: Revision string: %s\n", line) ; + +// Need to work out if it's using the new or old encoding scheme: + +// Scan to the first character of the revision number + + for (c = line ; *c ; ++c) + if (*c == ':') + break ; + + if (*c != ':') { + syslog(LOG_NOTICE, "Bogus \"Revision\" line (no colon)") ; + return; + } + +// Chomp spaces + + ++c ; + while (isspace (*c)) + ++c ; + + if (!isxdigit (*c)) + syslog(LOG_NOTICE, "Bogus \"Revision\" line (no hex digit at start of revision)") ; + + revision = (unsigned int)strtol (c, NULL, 16) ; // Hex number with no leading 0x + +// Check for new way: + + if ((revision & (1 << 23)) != 0) { // New way + if (debug) + fprintf(stdout, "piBoardId: New Way: revision is: %08X\n", revision) ; + + bRev = (revision & (0x0F << 0)) >> 0 ; + bType = (revision & (0xFF << 4)) >> 4 ; + bProc = (revision & (0x0F << 12)) >> 12 ; // Not used for now. + bMfg = (revision & (0x0F << 16)) >> 16 ; + bMem = (revision & (0x07 << 20)) >> 20 ; + bWarranty = (revision & (0x03 << 24)) != 0 ; + + *model = bType ; + *rev = bRev ; + *mem = bMem ; + *maker = bMfg ; + *warranty = bWarranty ; + + if (debug) + fprintf(stdout, "piBoardId: rev: %d, type: %d, proc: %d, mfg: %d, mem: %d, warranty: %d\n", bRev, bType, bProc, bMfg, bMem, bWarranty) ; + } else { // Old way + if (debug) + fprintf(stdout, "piBoardId: Old Way: revision is: %s\n", c) ; + + if (!isdigit (*c)) { + syslog(LOG_NOTICE, "Bogus \"Revision\" line (no digit at start of revision)") ; + return; + } + +// Make sure its long enough + + if (strlen (c) < 4) { + syslog(LOG_NOTICE, "Bogus \"Revision\" line (not long enough)") ; + return; + } + +// If longer than 4, we'll assume it's been overvolted + + *warranty = strlen (c) > 4 ; + +// Extract last 4 characters: + + c = c + strlen (c) - 4 ; + +// Fill out the replys as appropriate + + /**/ if (strcmp (c, "0002") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0003") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "0004") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0005") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0006") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "0007") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0008") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_SONY ; ; } + else if (strcmp (c, "0009") == 0) { *model = PI_MODEL_A ; *rev = PI_VERSION_1_2 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "000d") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "000e") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "000f") == 0) { *model = PI_MODEL_B ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "0010") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0013") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } + else if (strcmp (c, "0016") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0019") == 0) { *model = PI_MODEL_BP ; *rev = PI_VERSION_1_2 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + else if (strcmp (c, "0011") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0014") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } + else if (strcmp (c, "0017") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "001a") == 0) { *model = PI_MODEL_CM ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EGOMAN ; } + + else if (strcmp (c, "0012") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "0015") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 1 ; *maker = PI_MAKER_EMBEST ; } + else if (strcmp (c, "0018") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_SONY ; } + else if (strcmp (c, "001b") == 0) { *model = PI_MODEL_AP ; *rev = PI_VERSION_1_1 ; *mem = 0 ; *maker = PI_MAKER_EGOMAN ; } + + else { *model = 0 ; *rev = 0 ; *mem = 0 ; *maker = 0 ; } + } +} +#endif + + char *payload_header(void) { @@ -1168,6 +1386,7 @@ char *topic = NULL, *payload = NULL, sidx[10], buf[64]; struct utsname ubuf; bool comma = false; + int model, rev, mem, maker, warranty; payload = payload_header(); payload = xstrcat(payload, (char *)"{"); @@ -1180,7 +1399,6 @@ /* * Get the info from the WiringPi libary */ - int model, rev, mem, maker, warranty; piBoardId (&model, &rev, &mem, &maker, &warranty); payload = xstrcat(payload, (char *)"\"properties\":{\"hardwaremake\":\"Raspberry Pi "); payload = xstrcat(payload, (char *)piMakerNames[maker]); @@ -1190,7 +1408,19 @@ payload = xstrcat(payload, (char *)piRevisionNames[rev]); payload = xstrcat(payload, (char *)"\""); #else - if (uname(&ubuf) == 0) { + /* + * Get the info from the internal function + */ + piBoardId (&model, &rev, &mem, &maker, &warranty); + if (model != -1) { + payload = xstrcat(payload, (char *)"\"properties\":{\"hardwaremake\":\"Raspberry Pi "); + payload = xstrcat(payload, (char *)piMakerNames[maker]); + payload = xstrcat(payload, (char *)"\",\"hardwaremodel\":\""); + payload = xstrcat(payload, (char *)piModelNames[model]); + payload = xstrcat(payload, (char *)" rev "); + payload = xstrcat(payload, (char *)piRevisionNames[rev]); + payload = xstrcat(payload, (char *)"\""); + } else if (uname(&ubuf) == 0) { payload = xstrcat(payload, (char *)"\"properties\":{\"hardwaremake\":\""); payload = xstrcat(payload, ubuf.machine); payload = xstrcat(payload, (char *)"\",\"hardwaremodel\":\"Unknown\""); diff -r 93667d842c9b -r 363dc36d2450 thermferm/mqtt.h --- a/thermferm/mqtt.h Thu May 09 19:50:26 2019 +0200 +++ b/thermferm/mqtt.h Sun Jul 07 12:58:06 2019 +0200 @@ -6,6 +6,40 @@ #define STATUS_CONNACK_RECVD 1 #define STATUS_WAITING 2 +#ifndef HAVE_WIRINGPI_H + +// Pi model types and version numbers +// Intended for the GPIO program Use at your own risk. + +#define PI_MODEL_A 0 +#define PI_MODEL_B 1 +#define PI_MODEL_AP 2 +#define PI_MODEL_BP 3 +#define PI_MODEL_2 4 +#define PI_ALPHA 5 +#define PI_MODEL_CM 6 +#define PI_MODEL_07 7 +#define PI_MODEL_3B 8 +#define PI_MODEL_ZERO 9 +#define PI_MODEL_CM3 10 +#define PI_MODEL_ZERO_W 12 +#define PI_MODEL_3BP 13 +#define PI_MODEL_3AP 14 +#define PI_MODEL_CM3P 16 + +#define PI_VERSION_1 0 +#define PI_VERSION_1_1 1 +#define PI_VERSION_1_2 2 +#define PI_VERSION_2 3 + +#define PI_MAKER_SONY 0 +#define PI_MAKER_EGOMAN 1 +#define PI_MAKER_EMBEST 2 +#define PI_MAKER_UNKNOWN 3 + + +#endif + /* * Public functions