diff --git a/build.py b/build.py index 4235c8d7..28319853 100644 --- a/build.py +++ b/build.py @@ -29,7 +29,7 @@ haldir = os.path.join (srcdir, "hal") halconfig = config.get("board", "halfile") halconfigfile = os.path.join (haldir, halconfig) if os.path.isfile(halconfigfile) and os.access(halconfigfile, os.R_OK): - print "Parsing hardware configuration from " + halconfigfile + print("Parsing hardware configuration from " + halconfigfile) else: sys.exit("Missing file " + halconfigfile + ", please create it! Aborting.") @@ -37,21 +37,21 @@ else: lmicconfig = config.get("common", "lmicconfigfile") lmicconfigfile = os.path.join (srcdir, lmicconfig) if os.path.isfile(lmicconfigfile) and os.access(lmicconfigfile, os.R_OK): - print "Parsing LMIC configuration from " + lmicconfigfile + print("Parsing LMIC configuration from " + lmicconfigfile) else: sys.exit("Missing file " + lmicconfigfile + ", please create it! Aborting.") # check if lora key file is present in source directory lorakeyfile = os.path.join (srcdir, config.get("common", "lorakeyfile")) if os.path.isfile(lorakeyfile) and os.access(lorakeyfile, os.R_OK): - print "Parsing LORAWAN keys from " + lorakeyfile + print("Parsing LORAWAN keys from " + lorakeyfile) else: sys.exit("Missing file " + lorakeyfile + ", please create it! Aborting.") # check if ota key file is present in source directory otakeyfile = os.path.join (srcdir, config.get("common", "otakeyfile")) if os.path.isfile(otakeyfile) and os.access(otakeyfile, os.R_OK): - print "Parsing OTA keys from " + otakeyfile + print("Parsing OTA keys from " + otakeyfile) else: sys.exit("Missing file " + otakeyfile + ", please create it! Aborting.") @@ -66,7 +66,7 @@ myboard = mykeys["board"] myuploadspeed = mykeys["upload_speed"] env.Replace(BOARD=myboard) env.Replace(UPLOAD_SPEED=myuploadspeed) -print '\033[94m' + "TARGET BOARD: " + myboard + " @ " + myuploadspeed + "bps" + '\033[0m' +print('\033[94m' + "TARGET BOARD: " + myboard + " @ " + myuploadspeed + "bps" + '\033[0m') # parse ota key file with open(otakeyfile) as myfile: @@ -136,4 +136,4 @@ def publish_bintray(source, target, env): # put build file name and upload command to platformio environment env.Replace( PROGNAME="firmware_" + package + "_v%s" % version, - UPLOADCMD=publish_bintray) \ No newline at end of file + UPLOADCMD=publish_bintray) diff --git a/include/globals.h b/include/globals.h index d76d0e4c..55ee199e 100644 --- a/include/globals.h +++ b/include/globals.h @@ -42,8 +42,8 @@ #define SCREEN_MODE (0x80) // I2C bus access control -#define I2C_MUTEX_LOCK() xSemaphoreTake(I2Caccess, pdMS_TO_TICKS(10)) == pdTRUE -#define I2C_MUTEX_UNLOCK() xSemaphoreGive(I2Caccess) +#define I2C_MUTEX_LOCK() (xSemaphoreTake(I2Caccess, pdMS_TO_TICKS(2000)) == pdTRUE) +#define I2C_MUTEX_UNLOCK() (xSemaphoreGive(I2Caccess)) // Struct holding devices's runtime configuration typedef struct { diff --git a/include/irqhandler.h b/include/irqhandler.h index db5dd2f1..3a06d3da 100644 --- a/include/irqhandler.h +++ b/include/irqhandler.h @@ -17,8 +17,8 @@ #include "timekeeper.h" void irqHandler(void *pvParameters); -int mask_user_IRQ(); -int unmask_user_IRQ(); +void mask_user_IRQ(); +void unmask_user_IRQ(); #ifdef HAS_DISPLAY void IRAM_ATTR DisplayIRQ(); diff --git a/src/blecsan.cpp b/src/blecsan.cpp index 1931c788..90761f75 100644 --- a/src/blecsan.cpp +++ b/src/blecsan.cpp @@ -146,7 +146,7 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, break; } -#if(VENDORFILTER) +#if (VENDORFILTER) if ((p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RANDOM) || (p->scan_rst.ble_addr_type == BLE_ADDR_TYPE_RPA_RANDOM)) { @@ -162,6 +162,7 @@ IRAM_ATTR void gap_callback_handler(esp_gap_ble_cb_event_t event, /* to be improved in vendorfilter if: + // you can search for elements in the payload using the // function esp_ble_resolve_adv_data() // @@ -207,21 +208,21 @@ esp_err_t register_ble_callback(void) { ESP_ERROR_CHECK(esp_ble_gap_register_callback(&gap_callback_handler)); static esp_ble_scan_params_t ble_scan_params = { - .scan_type = BLE_SCAN_TYPE_PASSIVE, - .own_addr_type = BLE_ADDR_TYPE_RANDOM, + .scan_type = BLE_SCAN_TYPE_PASSIVE, + .own_addr_type = BLE_ADDR_TYPE_RANDOM, -#if(VENDORFILTER) - .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR, +#if (VENDORFILTER) + .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR, // ADV_IND, ADV_NONCONN_IND, ADV_SCAN_IND packets are used for broadcasting // data in broadcast applications (e.g., Beacons), so we don't want them in // vendorfilter mode #else - .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, + .scan_filter_policy = BLE_SCAN_FILTER_ALLOW_ALL, #endif - .scan_interval = - (uint16_t)(cfg.blescantime * 10 / 0.625), // Time = N * 0.625 msec - .scan_window = (uint16_t)(BLESCANWINDOW / 0.625) // Time = N * 0.625 msec + .scan_interval = + (uint16_t)(cfg.blescantime * 10 / 0.625), // Time = N * 0.625 msec + .scan_window = (uint16_t)(BLESCANWINDOW / 0.625) // Time = N * 0.625 msec }; ESP_LOGI(TAG, "Set GAP scan parameters"); @@ -234,12 +235,11 @@ esp_err_t register_ble_callback(void) { } // register_ble_callback void start_BLEscan(void) { -#if(BLECOUNTER) +#if (BLECOUNTER) ESP_LOGI(TAG, "Initializing bluetooth scanner ..."); ESP_ERROR_CHECK(esp_coex_preference_set( - (esp_coex_prefer_t) - ESP_COEX_PREFER_BALANCE)); // configure Wifi/BT coexist lib + ESP_COEX_PREFER_BALANCE)); // configure Wifi/BT coexist lib // Initialize BT controller to allocate task and other resource. btStart(); @@ -254,14 +254,14 @@ void start_BLEscan(void) { } // start_BLEscan void stop_BLEscan(void) { -#if(BLECOUNTER) +#if (BLECOUNTER) ESP_LOGI(TAG, "Shutting down bluetooth scanner ..."); ESP_ERROR_CHECK(esp_ble_gap_register_callback(NULL)); ESP_ERROR_CHECK(esp_bluedroid_disable()); ESP_ERROR_CHECK(esp_bluedroid_deinit()); btStop(); // disable bt_controller - ESP_ERROR_CHECK(esp_coex_preference_set(( - esp_coex_prefer_t)ESP_COEX_PREFER_WIFI)); // configure Wifi/BT coexist lib + ESP_ERROR_CHECK(esp_coex_preference_set( + ESP_COEX_PREFER_WIFI)); // configure Wifi/BT coexist lib ESP_LOGI(TAG, "Bluetooth scanner stopped"); #endif // BLECOUNTER } // stop_BLEscan diff --git a/src/display.cpp b/src/display.cpp index 0c1a9422..632e0ee8 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -62,8 +62,9 @@ void DisplayKey(const uint8_t *key, uint8_t len, bool lsb) { void init_display(const char *Productname, const char *Version) { // block i2c bus access - if (I2C_MUTEX_LOCK()) { - + if (!I2C_MUTEX_LOCK()) + ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0); + else { // show startup screen uint8_t buf[32]; u8x8.begin(); @@ -141,8 +142,9 @@ void refreshTheDisplay(bool nextPage) { myTZ.toLocal(now()); // note: call now() here *before* locking mutex! // block i2c bus access - if (I2C_MUTEX_LOCK()) { - + if (!I2C_MUTEX_LOCK()) + ESP_LOGW(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0); + else { // set display on/off according to current device configuration if (DisplayIsOn != cfg.screenon) { DisplayIsOn = cfg.screenon; @@ -165,7 +167,9 @@ void draw_page(time_t t, uint8_t page) { char timeState, buff[16]; uint8_t msgWaiting; +#if (HAS_GPS) static bool wasnofix = true; +#endif // update counter (lines 0-1) snprintf( diff --git a/src/gpsread.cpp b/src/gpsread.cpp index 1bc8f343..d99a7c46 100644 --- a/src/gpsread.cpp +++ b/src/gpsread.cpp @@ -80,11 +80,12 @@ void IRAM_ATTR gps_storetime(gpsStatus_t &gps_store) { if (gps.time.isUpdated() && gps.date.isValid() && (gps.time.age() < 1000)) { // nmea telegram serial delay compensation; not sure if we need this? - + /* if (gps.time.age() > nmea_txDelay_ms) gps_store.timedate.Second = gps.time.second() + 1; else gps_store.timedate.Second = gps.time.second(); + */ gps_store.timedate.Second = gps.time.second(); gps_store.timedate.Minute = gps.time.minute(); diff --git a/src/hal/generic.h b/src/hal/generic.h index 280a68ad..9d1d0b4e 100644 --- a/src/hal/generic.h +++ b/src/hal/generic.h @@ -53,8 +53,6 @@ #define HAS_BUTTON (39) // on board button #define HAS_RGB_LED (0) // WS2812B RGB LED on GPIO0 -#define BOARD_HAS_PSRAM // use extra 4MB extern RAM - // GPS settings #define HAS_GPS 1 // use on board GPS #define GPS_SERIAL 9600, SERIAL_8N1, GPIO_NUM_12, GPIO_NUM_15 // UBlox NEO 6M diff --git a/src/irqhandler.cpp b/src/irqhandler.cpp index f95f6fe9..fabda2f2 100644 --- a/src/irqhandler.cpp +++ b/src/irqhandler.cpp @@ -119,18 +119,6 @@ void IRAM_ATTR GpsIRQ() { } #endif -int mask_user_IRQ() { - // begin of time critical section: lock I2C bus to ensure accurate timing - if (I2C_MUTEX_LOCK()) { - xTaskNotify(irqHandlerTask, MASK_IRQ, eSetBits); - return 0; - } else - return 1; // failure -} +void mask_user_IRQ() { xTaskNotify(irqHandlerTask, MASK_IRQ, eSetBits); } -int unmask_user_IRQ() { - // end of time critical section: release I2C bus - I2C_MUTEX_UNLOCK(); - xTaskNotify(irqHandlerTask, UNMASK_IRQ, eSetBits); - return 0; -} \ No newline at end of file +void unmask_user_IRQ() { xTaskNotify(irqHandlerTask, UNMASK_IRQ, eSetBits); } \ No newline at end of file diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 5507e12b..af8d04bb 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -306,7 +306,7 @@ void onEvent(ev_t ev) { break; case EV_TXSTART: - if (!(LMIC.opmode & OP_JOINING)) + if (!(LMIC.opmode & OP_JOINING)) { #if (TIME_SYNC_LORASERVER) // if last packet sent was a timesync request, store TX time if (LMIC.pendTxPort == TIMEPORT) @@ -314,6 +314,7 @@ void onEvent(ev_t ev) { else #endif strcpy_P(buff, PSTR("TX START")); + } break; case EV_TXCANCELED: @@ -506,9 +507,15 @@ void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime, return; } - // begin of time critical section: lock I2C bus to ensure accurate timing - if (!mask_user_IRQ()) - return; // failure + // begin of time critical section + + // lock I2C bus and application irq to ensure accurate timing + mask_user_IRQ(); + if (!I2C_MUTEX_LOCK()) { + ESP_LOGW(TAG, "[%0.3f] Timesync handshake error: i2c bus locking failed", + millis() / 1000.0); + goto finish; // failure + } // Update userUTCTime, considering the difference between the GPS and UTC // time, and the leap seconds until year 2019 @@ -524,7 +531,9 @@ void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime, // Update system time with time read from the network setMyTime(*pUserUTCTime + requestDelaySec, 0); - // end of time critical section: release I2C bus +finish: + // end of time critical section: release I2C bus and app irq + I2C_MUTEX_UNLOCK(); unmask_user_IRQ(); } // user_request_network_time_callback diff --git a/src/macsniff.cpp b/src/macsniff.cpp index cd20e39a..0b00e7c1 100644 --- a/src/macsniff.cpp +++ b/src/macsniff.cpp @@ -2,7 +2,7 @@ // Basic Config #include "globals.h" -#if(VENDORFILTER) +#if (VENDORFILTER) #include "vendor_array.h" #endif @@ -37,33 +37,35 @@ void printKey(const char *name, const uint8_t *key, uint8_t len, bool lsb) { } uint64_t macConvert(uint8_t *paddr) { - return ((uint64_t)paddr[0]) | ((uint64_t)paddr[1] << 8) | - ((uint64_t)paddr[2] << 16) | ((uint64_t)paddr[3] << 24) | - ((uint64_t)paddr[4] << 32) | ((uint64_t)paddr[5] << 40); + uint64_t *mac; + mac = (uint64_t *)paddr; + return (__builtin_bswap64(*mac) >> 8); } bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) { - char buff[16]; // temporary buffer for printf + if (!salt) // ensure we have salt (appears after radio is turned on) + return false; + + char buff[10]; // temporary buffer for printf bool added = false; int8_t beaconID; // beacon number in test monitor mode uint16_t hashedmac; // temporary buffer for generated hash value - uint32_t addr2int; // temporary buffer for shortened MAC -#if(VENDORFILTER) - uint32_t vendor2int; // temporary buffer for Vendor OUI -#endif + uint32_t *mac; // temporary buffer for shortened MAC // only last 3 MAC Address bytes are used for MAC address anonymization - // but since it's uint32 we take 4 bytes to avoid 1st value to be 0 - addr2int = ((uint32_t)paddr[2]) | ((uint32_t)paddr[3] << 8) | - ((uint32_t)paddr[4] << 16) | ((uint32_t)paddr[5] << 24); + // but since it's uint32 we take 4 bytes to avoid 1st value to be 0. + // this gets MAC in msb (= reverse) order, but doesn't matter for hashing it. + mac = (uint32_t *)(paddr + 2); + +#if (VENDORFILTER) + uint32_t *oui; // temporary buffer for vendor OUI + oui = (uint32_t *)paddr; -#if(VENDORFILTER) - vendor2int = ((uint32_t)paddr[2]) | ((uint32_t)paddr[1] << 8) | - ((uint32_t)paddr[0] << 16); // use OUI vendor filter list only on Wifi, not on BLE if ((sniff_type == MAC_SNIFF_BLE) || - std::find(vendors.begin(), vendors.end(), vendor2int) != vendors.end()) { + std::find(vendors.begin(), vendors.end(), __builtin_bswap32(*oui) >> 8) != + vendors.end()) { #endif // salt and hash MAC, and if new unique one, store identifier in container @@ -71,10 +73,9 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) { // https://en.wikipedia.org/wiki/MAC_Address_Anonymization snprintf(buff, sizeof(buff), "%08X", - addr2int + (uint32_t)salt); // convert usigned 32-bit salted MAC - // to 8 digit hex string - hashedmac = rokkit(&buff[3], 5); // hash MAC last string value, use 5 chars - // to fit hash in uint16_t container + *mac + (uint32_t)salt); // convert unsigned 32-bit salted MAC + // to 8 digit hex string + hashedmac = rokkit(&buff[3], 5); // hash MAC 8 digit -> 5 digit auto newmac = macs.insert(hashedmac); // add hashed MAC, if new unique added = newmac.second ? true : false; // true if hashed MAC is unique in container @@ -88,7 +89,7 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) { blink_LED(COLOR_GREEN, 50); #endif } -#if(BLECOUNTER) +#if (BLECOUNTER) else if (sniff_type == MAC_SNIFF_BLE) { macs_ble++; // increment BLE Macs counter #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) @@ -115,13 +116,14 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) { // Log scan result ESP_LOGV(TAG, - "%s %s RSSI %ddBi -> MAC %s -> Hash %04X -> WiFi:%d BLTH:%d -> " + "%s %s RSSI %ddBi -> salted MAC %s -> Hash %04X -> WiFi:%d " + "BLTH:%d -> " "%d Bytes left", added ? "new " : "known", sniff_type == MAC_SNIFF_WIFI ? "WiFi" : "BLTH", rssi, buff, hashedmac, macs_wifi, macs_ble, getFreeRAM()); -#if(VENDORFILTER) +#if (VENDORFILTER) } else { // Very noisy // ESP_LOGD(TAG, "Filtered MAC %02X:%02X:%02X:%02X:%02X:%02X", diff --git a/src/main.cpp b/src/main.cpp index ae883673..f06eb6cd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,10 +116,9 @@ void setup() { // create some semaphores for syncing / mutexing tasks I2Caccess = xSemaphoreCreateMutex(); // for access management of i2c bus - if (I2Caccess) - xSemaphoreGive(I2Caccess); // Flag the i2c bus available for use + assert(I2Caccess != NULL); - // disable brownout detection + // disable brownout detection #ifdef DISABLE_BROWNOUT // register with brownout is at address DR_REG_RTCCNTL_BASE + 0xd4 (*((uint32_t volatile *)ETS_UNCACHED_ADDR((DR_REG_RTCCNTL_BASE + 0xd4)))) = 0; @@ -262,8 +261,8 @@ void setup() { // remove bluetooth stack to gain more free memory btStop(); ESP_ERROR_CHECK(esp_bt_mem_release(ESP_BT_MODE_BTDM)); - ESP_ERROR_CHECK(esp_coex_preference_set(( - esp_coex_prefer_t)ESP_COEX_PREFER_WIFI)); // configure Wifi/BT coexist lib + ESP_ERROR_CHECK(esp_coex_preference_set( + ESP_COEX_PREFER_WIFI)); // configure Wifi/BT coexist lib #endif // initialize gps diff --git a/src/timesync.cpp b/src/timesync.cpp index 88bc6aa8..35fb8c84 100644 --- a/src/timesync.cpp +++ b/src/timesync.cpp @@ -64,7 +64,7 @@ void process_timesync_req(void *taskparameter) { // wait until we are joined if we are not while (!LMIC.devaddr) { - vTaskDelay(5000); + vTaskDelay(3000); } // collect timestamp samples @@ -110,10 +110,10 @@ void process_timesync_req(void *taskparameter) { } } // end of for loop to collect timestamp samples - // begin of time critical section: lock app irq's and I2C bus - if (!mask_user_IRQ()) { - ESP_LOGW(TAG, - "[%0.3f] Timesync handshake error: irq / i2c masking failed", + // lock I2C bus and application irq to ensure accurate timing + mask_user_IRQ(); + if (!I2C_MUTEX_LOCK()) { + ESP_LOGW(TAG, "[%0.3f] Timesync handshake error: i2c bus locking failed", millis() / 1000.0); goto finish; // failure } @@ -135,10 +135,11 @@ void process_timesync_req(void *taskparameter) { setMyTime(time_to_set, time_to_set_fraction_msec); - // end of time critical section: release I2C bus and re-enable app irq's + finish: + // end of time critical section: release I2C bus and app irq + I2C_MUTEX_UNLOCK(); unmask_user_IRQ(); - finish: timeSyncPending = false; } // infinite while(1) diff --git a/src/wifiscan.cpp b/src/wifiscan.cpp index 750f9c5a..85fdf6a1 100644 --- a/src/wifiscan.cpp +++ b/src/wifiscan.cpp @@ -57,8 +57,8 @@ void wifi_sniffer_init(void) { wificfg.nvs_enable = 0; // we don't need any wifi settings from NVRAM wificfg.wifi_task_core_id = 0; // we want wifi task running on core 0 - // wifi_promiscuous_filter_t filter = { - // .filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT}; // only MGMT frames + //wifi_promiscuous_filter_t filter = { + // .filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT}; // only MGMT frames // .filter_mask = WIFI_PROMIS_FILTER_MASK_ALL}; // we use all frames wifi_promiscuous_filter_t filter = {.filter_mask = @@ -73,7 +73,7 @@ void wifi_sniffer_init(void) { ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_NULL)); ESP_ERROR_CHECK(esp_wifi_stop()); ESP_ERROR_CHECK( - esp_wifi_set_promiscuous_filter(&filter)); // set MAC frame filter + esp_wifi_set_promiscuous_filter(&filter)); // set frame filter ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(&wifi_sniffer_packet_handler)); ESP_ERROR_CHECK(esp_wifi_set_promiscuous(true)); // now switch on monitor mode