<commit_before>// Includes from ESP-IDF
#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "tcpip_adapter.h"


#include "jsinteractive.h"
#include "network.h"
#include "jswrap_esp32_network.h"

static void sendWifiCompletionCB(
  JsVar **g_jsCallback,  //!< Pointer to the global callback variable
  char  *reason          //!< NULL if successful, error string otherwise
);

// Tag for ESP-IDF logging
static char *tag = "jswrap_esp32_network";

// A callback function to be invoked on a disconnect response.
static JsVar *g_jsDisconnectCallback;

// A callback function to be invoked when we have an IP address.
static JsVar *g_jsGotIpCallback;

// Format of a MAC address.
static char macFmt[] = "%02x:%02x:%02x:%02x:%02x:%02x";

#define EXPECT_CB_EXCEPTION(jsCB)   jsExceptionHere(JSET_ERROR, "Expecting callback function but got %v", jsCB)
#define EXPECT_OPT_EXCEPTION(jsOPT) jsExceptionHere(JSET_ERROR, "Expecting options object but got %t", jsOPT)

/**
 * Wifi event handler
 * Here we get invoked whenever a WiFi event is received from the ESP32 WiFi
 * subsystem.  The events include:
 * * SYSTEM_EVENT_STA_DISCONNECTED - As a station, we were disconnected.
 */
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
  ESP_LOGD(tag, ">> event_handler");
  if (event->event_id == SYSTEM_EVENT_STA_DISCONNECTED) {
    if (jsvIsFunction(g_jsDisconnectCallback)) {
      jsiQueueEvents(NULL, g_jsDisconnectCallback, NULL, 0);
      jsvUnLock(g_jsDisconnectCallback);
      g_jsDisconnectCallback = NULL;
    }
    ESP_LOGD(tag, "<< event_handler - STA DISCONNECTED");
    return ESP_OK;
  } // End of handle SYSTEM_EVENT_STA_DISCONNECTED


  if (event->event_id == SYSTEM_EVENT_STA_GOT_IP) {
    sendWifiCompletionCB(&g_jsGotIpCallback, NULL);
    ESP_LOGD(tag, "<< event_handler - STA GOT IP");
    return ESP_OK;
  } // End of handle SYSTEM_EVENT_STA_GOT_IP

  ESP_LOGD(tag, "<< event_handler");
  return ESP_OK;
} // End of event_handler


/**
 * Initialize the one time ESP32 wifi components including the event
 * handler.
 */
void esp32_wifi_init() {
  ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL));
  wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
} // End of esp32_wifi_init


/**<commit_msg>Implementation of wifi.on(disconnect)<commit_after>// Includes from ESP-IDF
#include "esp_log.h"
#include "esp_wifi.h"
#include "esp_event_loop.h"
#include "tcpip_adapter.h"


#include "jsinteractive.h"
#include "network.h"
#include "jswrap_modules.h"
#include "jswrap_esp32_network.h"

static void sendWifiCompletionCB(
  JsVar **g_jsCallback,  //!< Pointer to the global callback variable
  char  *reason          //!< NULL if successful, error string otherwise
);

// Tag for ESP-IDF logging
static char *tag = "jswrap_esp32_network";

// A callback function to be invoked on a disconnect response.
static JsVar *g_jsDisconnectCallback;

// A callback function to be invoked when we have an IP address.
static JsVar *g_jsGotIpCallback;

// Format of a MAC address.
static char macFmt[] = "%02x:%02x:%02x:%02x:%02x:%02x";

#define EXPECT_CB_EXCEPTION(jsCB)   jsExceptionHere(JSET_ERROR, "Expecting callback function but got %v", jsCB)
#define EXPECT_OPT_EXCEPTION(jsOPT) jsExceptionHere(JSET_ERROR, "Expecting options object but got %t", jsOPT)

/*JSON{
  "type" : "event",
  "class" : "Wifi",
  "name" : "disconnected",
  "params" : [
    ["details","JsVar","An object with event details"]
  ]
}
The 'disconnected' event is called when an association with an access point has been lost.
The details include:

* ssid - The SSID of the access point from which the association was lost
* mac - The BSSID/mac address of the access point
* reason - The reason for the disconnection (string)

*/

/** Get the global object for the Wifi library/module, this is used in order to send the
 * "on event" callbacks to the handlers.
 */
static JsVar *getWifiModule() {
  JsVar *moduleName = jsvNewFromString("Wifi");
  JsVar *m = jswrap_require(moduleName);
  jsvUnLock(moduleName);
  return m;
}


static char *wifiGetEvent(uint32_t event) {
  switch(event) {
  case SYSTEM_EVENT_AP_PROBEREQRECVED:
    return "#onprobe_recv";
  case SYSTEM_EVENT_AP_STACONNECTED:
    return "#onsta_joined";
  case SYSTEM_EVENT_AP_STADISCONNECTED:
    return "#onsta_left";
  case SYSTEM_EVENT_AP_START:
    break;
  case SYSTEM_EVENT_AP_STOP:
    break;
  case SYSTEM_EVENT_SCAN_DONE:
    break;
  case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
    return "#onauth_change";
  case SYSTEM_EVENT_STA_CONNECTED:
    return "#onassociated";
  case SYSTEM_EVENT_STA_DISCONNECTED:
    return "#ondisconnected";
  case SYSTEM_EVENT_STA_GOT_IP:
    return "#onconnected";
  case SYSTEM_EVENT_STA_START:
    break;
  case SYSTEM_EVENT_STA_STOP:
    break;
  case SYSTEM_EVENT_WIFI_READY:
    break;
  }
  ESP_LOGW(tag, "Unhandled event type: %d", event);
  return NULL;
}

/**
 * Invoke the JavaScript callback to notify the program that an ESP8266
 * WiFi event has occurred.
 */
static void sendWifiEvent(
    uint32_t eventType, //!< The ESP32 WiFi event type.
    JsVar *jsDetails  //!< The JS object to be passed as a parameter to the callback.
) {
  JsVar *module = getWifiModule();
  if (!module) {
    return; // out of memory?
  }

  // get event name as string and compose param list
  JsVar *params[1];
  params[0] = jsDetails;
  char *eventName = wifiGetEvent(eventType);
  if (eventName == NULL) {
    return;
  }
  ESP_LOGD(tag, "wifi.on(%s)\n", eventName);
  jsiQueueObjectCallbacks(module, eventName, params, 1);
  jsvUnLock(module);
  return;
}

/**
 * Wifi event handler
 * Here we get invoked whenever a WiFi event is received from the ESP32 WiFi
 * subsystem.  The events include:
 * * SYSTEM_EVENT_STA_DISCONNECTED - As a station, we were disconnected.
 */
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
  ESP_LOGD(tag, ">> event_handler");
  if (event->event_id == SYSTEM_EVENT_STA_DISCONNECTED) {
    if (jsvIsFunction(g_jsDisconnectCallback)) {
      jsiQueueEvents(NULL, g_jsDisconnectCallback, NULL, 0);
      jsvUnLock(g_jsDisconnectCallback);
      g_jsDisconnectCallback = NULL;
    }
    JsVar *jsDetails = jsvNewObject();

    char temp[33];
    memcpy(temp, event->event_info.disconnected.ssid, 32);
    temp[32] = '\0';
    jsvObjectSetChildAndUnLock(jsDetails, "ssid", jsvNewFromString(temp));
    sprintf(temp, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
        event->event_info.disconnected.bssid[0],
        event->event_info.disconnected.bssid[1],
        event->event_info.disconnected.bssid[2],
        event->event_info.disconnected.bssid[3],
        event->event_info.disconnected.bssid[4],
        event->event_info.disconnected.bssid[5]);
    jsvObjectSetChildAndUnLock(jsDetails, "mac", jsvNewFromString(temp));
    sprintf(temp, "%d", event->event_info.disconnected.reason);
    jsvObjectSetChildAndUnLock(jsDetails, "reason", jsvNewFromString(temp));
    sendWifiEvent(event->event_id, jsDetails);
    ESP_LOGD(tag, "<< event_handler - STA DISCONNECTED");
    return ESP_OK;
  } // End of handle SYSTEM_EVENT_STA_DISCONNECTED


  if (event->event_id == SYSTEM_EVENT_STA_GOT_IP) {
    sendWifiCompletionCB(&g_jsGotIpCallback, NULL);
    ESP_LOGD(tag, "<< event_handler - STA GOT IP");
    return ESP_OK;
  } // End of handle SYSTEM_EVENT_STA_GOT_IP

  ESP_LOGD(tag, "<< event_handler");
  return ESP_OK;
} // End of event_handler


/**
 * Initialize the one time ESP32 wifi components including the event
 * handler.
 */
void esp32_wifi_init() {
  ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL));
  wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
} // End of esp32_wifi_init


/**
{'fraction_non_alphanumeric': 0.1106031746031746, 'fraction_numerical': 0.010412698412698413, 'mean_word_length': 4.458073458073458, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7308233', 'n_tokens_mistral': 2821, 'n_tokens_neox': 2713, 'n_words': 679}