#include #include #include #include #include // for the round function #include "esp_log.h" // For ESP_LOGI and other logging functions #include "nvs_flash.h" // For NVS functions like nvs_flash_init #include "esp_err.h" // For error handling #include "driver/usb_serial_jtag.h" // dis is da heacder fopr usb_serial_jtag_is_connected() #if CONFIG_DEEP_SLEEP_BURST_MODE #include "soc/soc_caps.h" // malloc and shit if lmao #include "esp_sleep.h" // For deep sleep functions #include "freertos/FreeRTOS.h" // freertosbullshit #include "freertos/task.h" // calculate da burst delay and burst delay microseconds #define DEEP_SLEEP_BURST_DELAY (CONFIG_DEEP_SLEEP_BURST_COUNT * CONFIG_ADVERTISEMENT_INTERVAL) #define DEEP_SLEEP_BURST_DELAY_MICROS (CONFIG_DEEP_SLEEP_DURATION_S * 1000000) #endif // macro to round float to int #define ROUND(x) ((int)((x) >= 0.0 ? floor((x) + 0.5) : ceil((x) - 0.5))) // handle da minutes config and round to da nearest integer #define ADVERTISE_INTERVAL_MIN ROUND((CONFIG_ADVERTISEMENT_INTERVAL / 0.625)) #define ADVERTISE_INTERVAL_MAX (ADVERTISE_INTERVAL_MIN + ROUND((CONFIG_ADVERTISEMENT_INTERVAL_JITTER_MS / 0.625))) // repoting tag #define TAG CONFIG_TAG // module configs //// esp32 classic #if defined(CONFIG_IDF_TARGET_ESP32) #include "esp_bt.h" // For esp_bt_controller_* functions #include "esp_bt_main.h" // For esp_bluedroid_* functions #include "esp_gap_ble_api.h" //// esp32c3 #elif defined(CONFIG_IDF_TARGET_ESP32C3) #include "esp_nimble_hci.h" #include "nimble/nimble_port.h" #include "nimble/nimble_port_freertos.h" #include "host/ble_hs.h" #include "host/util/util.h" #include "services/gap/ble_svc_gap.h" //// esp32c6 and esp32s3 #elif defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32S3) #include "nimble/nimble_port.h" #include "nimble/nimble_port_freertos.h" #include "host/ble_hs.h" #include "host/util/util.h" #include "services/gap/ble_svc_gap.h" //// unsupported #else #error "Unsupported target" #endif // RTC_SLOW_ATTR static struct timeval sleep_enter_time; // This is the advertisement key / EID. Change it to your own EID. const char *eid_string = CONFIG_ADVERTISEMENT_KEY; // // This is the advertisement key / EID. Change it to your own EID. // const char *eid_string = CONFIG_ADVERTISEMENT_KEY; // #define EID_STRING_LENGTH STRLENT((CONFIG_ADVERTISEMENT_KEY)) // #if EID_STRING_LENGTH != 40 // #error "EID string must be 40 hexadecimal characters (20 bytes)" // #endif // Find My Device Network (FMDN) advertisement // Octet Value Description // 0 0x02 Length // 1 0x01 Flags data type value // 2 0x06 Flags data // 3 0x18 or 0x19 Length // 4 0x16 Service data data type value // 5 0xAA 16-bit service UUID // 6 0xFE 16-bit service UUID // 7 0x40 or 0x41 FMDN frame type with unwanted tracking protection mode indication // 8..27 Random 20-byte ephemeral identifier // 28 Hashed flags uint8_t adv_raw_data[31] = { 0x02, // Length 0x01, // Flags data type value 0x06, // Flags data 0x19, // Length 0x16, // Service data data type value 0xAA, // 16-bit service UUID 0xFE, // 16-bit service UUID 0x41, // FMDN frame type with unwanted tracking protection mode indication // 20-byte ephemeral identifier (inserted below) // Hashed flags (implicitly initialized to 0) }; // Function to convert a hex string into a byte array void hex_string_to_bytes(const char *hex, uint8_t *bytes, size_t len) { for (size_t i = 0; i < len; i++) { sscanf(hex + 2 * i, "%2hhx", &bytes[i]); } } // esp32c3, esp32c6, and esp32s3 #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32S3) // BLE advertising callback static int ble_advertise_cb(struct ble_gap_event *event, void *arg) { switch (event->type) { case BLE_GAP_EVENT_ADV_COMPLETE: ESP_LOGI(TAG, "Advertising completed"); break; default: break; } return 0; } // Set up and start advertising static void ble_start_advertising(uint8_t *adv_raw_data, size_t adv_raw_data_len) { struct ble_gap_adv_params adv_params = { .conn_mode = BLE_GAP_CONN_MODE_NON, .disc_mode = BLE_GAP_DISC_MODE_GEN, // use calculated interval depending on config .itvl_min = ADVERTISE_INTERVAL_MIN, .itvl_max = ADVERTISE_INTERVAL_MAX, // for testing purposes, use fixed 32 cycles as interval (20ms) //// .itvl_min = 0x20, //// .itvl_max = 0x20 }; // set name ble_svc_gap_device_name_set(CONFIG_DEVICE_NAME); // set da data ble_gap_adv_set_data(adv_raw_data, adv_raw_data_len); // Start advertising #if CONFIG_RANDOM_MAC_ADDRESS ESP_LOGI(TAG, "Using Random MAC Address for advertising"); ble_gap_adv_start(BLE_OWN_ADDR_RANDOM, NULL, BLE_HS_FOREVER, &adv_params, ble_advertise_cb, NULL); #else ESP_LOGI(TAG, "Using Public MAC Address for advertising"); ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER, &adv_params, ble_advertise_cb, NULL); #endif ESP_LOGI(TAG, "Started advertising with interval %d ms", CONFIG_ADVERTISEMENT_INTERVAL); } static void ble_host_task(void *param) { ESP_LOGI(TAG, "BLE Host Task Started"); // run advertisement nimble_port_run(); nimble_port_freertos_deinit(); } // Sync callback static void on_sync(void) { // Set device name ble_svc_gap_device_name_set(CONFIG_DEVICE_NAME); // Start advertising ble_start_advertising(adv_raw_data, sizeof(adv_raw_data)); //print adv raw data ESP_LOGI(TAG, "adv_raw_data: %s", adv_raw_data); } static void ble_init(void) { ESP_LOGI(TAG, "Initializing BLE"); // 20-byte ephemeral identifier uint8_t eid_bytes[20]; hex_string_to_bytes(eid_string, eid_bytes, 20); memcpy(&adv_raw_data[8], eid_bytes, 20); // Initialize NimBLE - ESP-IDF v5.3 style ESP_ERROR_CHECK(nimble_port_init()); // Initialize the NimBLE host configuration ble_hs_cfg.sync_cb = on_sync; // Initialize GAP service ble_svc_gap_init(); // Create host task nimble_port_freertos_init(ble_host_task); } #if CONFIG_DEEP_SLEEP_BURST_MODE static void ble_deinit(void) { ESP_LOGI(TAG, "Deinitializing BLE"); nimble_port_stop(); nimble_port_deinit(); nimble_port_freertos_deinit(); } static void deep_sleep_register_rtc_timer_wakeup(void) { ESP_LOGI(TAG, "Woke up deep sleep, re-initializing BLE"); ble_init(); // const int wakeup_time_sec = CONFIG_DEEP_SLEEP_DURATION_S; // ESP_LOGI(TAG, "Enabling timer wakeup, %ds\n", CONFIG_DEEP_SLEEP_DURATION_S); // ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(DEEP_SLEEP_BURST_DELAY_MICROS)); } static void deep_sleep_wait_to_sleep() { vTaskDelay(pdMS_TO_TICKS(DEEP_SLEEP_BURST_DELAY)); ESP_LOGI(TAG, "Waited %d ms, preparing to enter deep sleep\n", DEEP_SLEEP_BURST_DELAY); ESP_LOGI(TAG, "Deiniting BTLE before deep sleep"); ble_deinit(); ESP_LOGI(TAG, "Entering deep sleep\n\tDuration %d ms\n\tburst count %d\n\tburst delay %d ms\n", CONFIG_DEEP_SLEEP_DURATION_S * 1000, CONFIG_DEEP_SLEEP_BURST_COUNT,DEEP_SLEEP_BURST_DELAY); ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(DEEP_SLEEP_BURST_DELAY_MICROS)); esp_deep_sleep_start(); } #endif #endif void app_main() { // delay to make shit to actually fookin work holy shit fuck you asshole bitch // i spit on you // i spit on your mom // if your mom is dead i spit on her grave // shame // shame // anus vTaskDelay(pdMS_TO_TICKS(CONFIG_STARTUP_DELAY_MS)); // validate eid_string length const size_t length = strlen(eid_string); if (length == 0) { ESP_LOGE(TAG, "Advertisement Key is not set. Please set CONFIG_ADVERTISEMENT_KEY in the project configuration."); return; } else if (length != 40) { ESP_LOGE(TAG, "Invalid Advertisement Key length. It must be 40 hexadecimal characters (20 bytes) Length given: %d", length); return; } // only show the key in debug mode ESP_LOGD(TAG, "Advertisement Key (EID): \"%s\"\n", eid_string); // interval infors ESP_LOGI(TAG, "Advertisement Calculated Interval Cycles: %d cycles\n", ADVERTISE_INTERVAL_MIN); ESP_LOGI(TAG, "Advertisement Interval Min: %d Milliseconds\n", CONFIG_ADVERTISEMENT_INTERVAL); ESP_LOGI(TAG, "Advertisement Interval Max: %d Milliseconds (%d ms jitter)\n", CONFIG_ADVERTISEMENT_INTERVAL + CONFIG_ADVERTISEMENT_INTERVAL_JITTER_MS, CONFIG_ADVERTISEMENT_INTERVAL_JITTER_MS); ESP_LOGI(TAG, "BLE Device Name: %s\n", CONFIG_DEVICE_NAME); #if CONFIG_RANDOM_MAC_ADDRESS ESP_LOGI(TAG, "Using Random MAC Address for advertising\n"); #else ESP_LOGI(TAG, "Using Public MAC Address for advertising\n"); #endif // Initialize NVS (required for BLE initialization) esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); // esp32c3, esp32c6, and esp32s3 #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32S3) #if CONFIG_DEEP_SLEEP_BURST_MODE // check if usb is connectedddd bool usb_connected = usb_serial_jtag_is_connected(); if (usb_connected) { ESP_LOGI(TAG, "USB Serial JTAG is connected\nDefaulting to Charging and Flashing Mode"); return; // exit app_main to prevent BLE initialization } // Initialize sleep wait task ESP_LOGI(TAG, "Initializing slweep wait task"); xTaskCreate(deep_sleep_wait_to_sleep, "deep_sleep_wait_to_sleep", 4096, NULL, 6, NULL); // INIt timer wakeup ESP_LOGI(TAG, "Initializing Timer Wakeup"); deep_sleep_register_rtc_timer_wakeup(); #else ble_init(); // initialize BLE normally without deep sleep #endif // esp32 classic #elif defined(CONFIG_IDF_TARGET_ESP32) // Initialize Bluetooth controller esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_bt_controller_init(&bt_cfg)); ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE)); // Initialize Bluedroid stack ESP_ERROR_CHECK(esp_bluedroid_init()); ESP_ERROR_CHECK(esp_bluedroid_enable()); // Set BLE TX power to 9 dBm ESP_ERROR_CHECK(esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, ESP_PWR_LVL_P9)); ESP_ERROR_CHECK(esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, ESP_PWR_LVL_P9)); ESP_LOGI(TAG, "Set BLE TX Power to 9 dBm"); ESP_ERROR_CHECK(esp_ble_gap_config_adv_data_raw(adv_raw_data, sizeof(adv_raw_data))); // Configure advertisement parameters esp_ble_adv_params_t adv_params = { // change those if you want to save power .adv_int_min = ADVERTISE_INTERVAL_MIN, .adv_int_max = ADVERTISE_INTERVAL_MAX, .adv_type = ADV_TYPE_NONCONN_IND, .own_addr_type = BLE_ADDR_TYPE_PUBLIC, .channel_map = ADV_CHNL_ALL, .adv_filter_policy = ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY, }; // Start advertising ESP_ERROR_CHECK(esp_ble_gap_start_advertising(&adv_params)); ESP_LOGI(TAG, "BLE advertising started."); #endif }