/*
 * Copyright (c) 2019 Tobias Svehagen
 * Copyright (c) 2020 Grinn
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT espressif_esp_at

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(wifi_esp_at, CONFIG_WIFI_LOG_LEVEL);

#include <zephyr/kernel.h>
#include <ctype.h>
#include <errno.h>
#include <zephyr/zephyr.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <stdlib.h>

#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/uart.h>

#include <zephyr/net/dns_resolve.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_ip.h>
#include <zephyr/net/net_offload.h>
#include <zephyr/net/wifi_mgmt.h>

#include "esp.h"

/* pin settings */
enum modem_control_pins {
#if DT_INST_NODE_HAS_PROP(0, power_gpios)
	ESP_POWER,
#endif
#if DT_INST_NODE_HAS_PROP(0, reset_gpios)
	ESP_RESET,
#endif
	NUM_PINS,
};

static struct modem_pin modem_pins[] = {
#if DT_INST_NODE_HAS_PROP(0, power_gpios)
	MODEM_PIN(DT_INST_GPIO_LABEL(0, power_gpios),
		  DT_INST_GPIO_PIN(0, power_gpios),
		  DT_INST_GPIO_FLAGS(0, power_gpios) | GPIO_OUTPUT_INACTIVE),
#endif
#if DT_INST_NODE_HAS_PROP(0, reset_gpios)
	MODEM_PIN(DT_INST_GPIO_LABEL(0, reset_gpios),
		  DT_INST_GPIO_PIN(0, reset_gpios),
		  DT_INST_GPIO_FLAGS(0, reset_gpios) | GPIO_OUTPUT_INACTIVE),
#endif
};

NET_BUF_POOL_DEFINE(mdm_recv_pool, MDM_RECV_MAX_BUF, MDM_RECV_BUF_SIZE,
		    0, NULL);

/* RX thread structures */
K_KERNEL_STACK_DEFINE(esp_rx_stack,
		      CONFIG_WIFI_ESP_AT_RX_STACK_SIZE);
struct k_thread esp_rx_thread;

/* RX thread work queue */
K_KERNEL_STACK_DEFINE(esp_workq_stack,
		      CONFIG_WIFI_ESP_AT_WORKQ_STACK_SIZE);

struct esp_data esp_driver_data;

static void esp_configure_hostname(struct esp_data *data)
{
#if defined(CONFIG_NET_HOSTNAME_ENABLE)
	char cmd[sizeof("AT+CWHOSTNAME=\"\"") + NET_HOSTNAME_MAX_LEN];

	snprintk(cmd, sizeof(cmd), "AT+CWHOSTNAME=\"%s\"", net_hostname_get());
	cmd[sizeof(cmd) - 1] = '\0';

	esp_cmd_send(data, NULL, 0, cmd, ESP_CMD_TIMEOUT);
#else
	ARG_UNUSED(data);
#endif
}

static inline uint8_t esp_mode_from_flags(struct esp_data *data)
{
	uint8_t flags = data->flags;
	uint8_t mode = 0;

	if (flags & (EDF_STA_CONNECTED | EDF_STA_LOCK)) {
		mode |= ESP_MODE_STA;
	}

	if (flags & EDF_AP_ENABLED) {
		mode |= ESP_MODE_AP;
	}

	/*
	 * ESP AT 1.7 does not allow to disable radio, so enter STA mode
	 * instead.
	 */
	if (IS_ENABLED(CONFIG_WIFI_ESP_AT_VERSION_1_7) &&
	    mode == ESP_MODE_NONE) {
		mode = ESP_MODE_STA;
	}

	return mode;
}

static int esp_mode_switch(struct esp_data *data, uint8_t mode)
{
	char cmd[] = "AT+"_CWMODE"=X";
	int err;

	cmd[sizeof(cmd) - 2] = ('0' + mode);
	LOG_DBG("Switch to mode %hhu", mode);

	err = esp_cmd_send(data, NULL, 0, cmd, ESP_CMD_TIMEOUT);
	if (err) {
		LOG_WRN("Failed to switch to mode %d: %d", (int) mode, err);
	}

	return err;
}

static int esp_mode_switch_if_needed(struct esp_data *data)
{
	uint8_t new_mode = esp_mode_from_flags(data);
	uint8_t old_mode = data->mode;
	int err;

	if (old_mode == new_mode) {
		return 0;
	}

	data->mode = new_mode;

	err = esp_mode_switch(data, new_mode);
	if (err) {
		return err;
	}

	if (!(old_mode & ESP_MODE_STA) && (new_mode & ESP_MODE_STA)) {
		/*
		 * Hostname change is applied only when STA is enabled.
		 */
		esp_configure_hostname(data);
	}

	return 0;
}

static void esp_mode_switch_submit_if_needed(struct esp_data *data)
{
	if (data->mode != esp_mode_from_flags(data)) {
		k_work_submit_to_queue(&data->workq, &data->mode_switch_work);
	}
}

static void esp_mode_switch_work(struct k_work *work)
{
	struct esp_data *data =
		CONTAINER_OF(work, struct esp_data, mode_switch_work);

	(void)esp_mode_switch_if_needed(data);
}

static inline int esp_mode_flags_set(struct esp_data *data, uint8_t flags)
{
	esp_flags_set(data, flags);

	return esp_mode_switch_if_needed(data);
}

static inline int esp_mode_flags_clear(struct esp_data *data, uint8_t flags)
{
	esp_flags_clear(data, flags);

	return esp_mode_switch_if_needed(data);
}

/*
 * Modem Response Command Handlers
 */

/* Handler: OK */
MODEM_CMD_DEFINE(on_cmd_ok)
{
	struct esp_data *dev = CONTAINER_OF(data, struct esp_data,
					    cmd_handler_data);

	modem_cmd_handler_set_error(data, 0);
	k_sem_give(&dev->sem_response);

	return 0;
}

/* Handler: ERROR */
MODEM_CMD_DEFINE(on_cmd_error)
{
	struct esp_data *dev = CONTAINER_OF(data, struct esp_data,
					    cmd_handler_data);

	modem_cmd_handler_set_error(data, -EIO);
	k_sem_give(&dev->sem_response);

	return 0;
}

/* RX thread */
static void esp_rx(struct esp_data *data)
{
	while (true) {
		/* wait for incoming data */
		k_sem_take(&data->iface_data.rx_sem, K_FOREVER);

		data->mctx.cmd_handler.process(&data->mctx.cmd_handler,
					       &data->mctx.iface);

		/* give up time if we have a solid stream of data */
		k_yield();
	}
}

static char *str_unquote(char *str)
{
	char *end;

	if (str[0] != '"') {
		return str;
	}

	str++;

	end = strrchr(str, '"');
	if (end != NULL) {
		*end = 0;
	}

	return str;
}

/* +CIPSTAMAC:"xx:xx:xx:xx:xx:xx" */
MODEM_CMD_DEFINE(on_cmd_cipstamac)
{
	struct esp_data *dev = CONTAINER_OF(data, struct esp_data,
					    cmd_handler_data);
	char *mac;

	mac = str_unquote(argv[0]);
	net_bytes_from_str(dev->mac_addr, sizeof(dev->mac_addr), mac);

	return 0;
}

/* +CWLAP:(sec,ssid,rssi,channel) */
/* with: CONFIG_WIFI_ESP_AT_SCAN_MAC_ADDRESS: +CWLAP:<ecn>,<ssid>,<rssi>,<mac>,<ch>*/
MODEM_CMD_DEFINE(on_cmd_cwlap)
{
	struct esp_data *dev = CONTAINER_OF(data, struct esp_data,
					    cmd_handler_data);
	struct wifi_scan_result res = { 0 };
	int i;

	i = strtol(&argv[0][1], NULL, 10);
	if (i == 0) {
		res.security = WIFI_SECURITY_TYPE_NONE;
	} else {
		res.security = WIFI_SECURITY_TYPE_PSK;
	}

	argv[1] = str_unquote(argv[1]);
	i = strlen(argv[1]);
	if (i > sizeof(res.ssid)) {
		i = sizeof(res.ssid);
	}

	memcpy(res.ssid, argv[1], i);
	res.ssid_length = i;
	res.rssi = strtol(argv[2], NULL, 10);

	if (IS_ENABLED(CONFIG_WIFI_ESP_AT_SCAN_MAC_ADDRESS)) {
		argv[3] = str_unquote(argv[3]);
		res.mac_length = WIFI_MAC_ADDR_LEN;
		if (net_bytes_from_str(res.mac, sizeof(res.mac), argv[3]) < 0) {
			LOG_ERR("Invalid MAC address");
			res.mac_length = 0;
		}
		res.channel = (argc > 4) ? strtol(argv[4], NULL, 10) : -1;
	} else {
		res.channel = strtol(argv[3], NULL, 10);
	}

	if (dev->scan_cb) {
		dev->scan_cb(dev->net_iface, 0, &res);
	}

	return 0;
}

static void esp_dns_work(struct k_work *work)
{
	struct esp_data *data = CONTAINER_OF(work, struct esp_data, dns_work);
	struct dns_resolve_context *dnsctx;
	struct sockaddr_in *addrs = data->dns_addresses;
	const struct sockaddr *dns_servers[ESP_MAX_DNS + 1] = {};
	size_t i;
	int err;

	for (i = 0; i < ESP_MAX_DNS; i++) {
		if (!addrs[i].sin_addr.s_addr) {
			break;
		}
		dns_servers[i] = (struct sockaddr *) &addrs[i];
	}

	dnsctx = dns_resolve_get_default();
	err = dns_resolve_reconfigure(dnsctx, NULL, dns_servers);
	if (err) {
		LOG_ERR("Could not set DNS servers: %d", err);
	}

	LOG_DBG("DNS resolver reconfigured");
}

/* +CIPDNS:enable[,"DNS IP1"[,"DNS IP2"[,"DNS IP3"]]] */
MODEM_CMD_DEFINE(on_cmd_cipdns)
{
	struct esp_data *dev = CONTAINER_OF(data, struct esp_data,
					    cmd_handler_data);
	struct sockaddr_in *addrs = dev->dns_addresses;
	char **servers = (char **)argv + 1;
	size_t num_servers = argc - 1;
	size_t valid_servers = 0;
	size_t i;
	int err;

	for (i = 0; i < ESP_MAX_DNS; i++) {
		if (i >= num_servers) {
			addrs[i].sin_addr.s_addr = 0;
			break;
		}

		servers[i] = str_unquote(servers[i]);
		LOG_DBG("DNS[%zu]: %s", i, log_strdup(servers[i]));

		err = net_addr_pton(AF_INET, servers[i], &addrs[i].sin_addr);
		if (err) {
			LOG_ERR("Invalid DNS address: %s",
				log_strdup(servers[i]));
			addrs[i].sin_addr.s_addr = 0;
			break;
		}

		addrs[i].sin_family = AF_INET;
		addrs[i].sin_port = htons(53);

		valid_servers++;
	}

	if (valid_servers) {
		k_work_submit(&dev->dns_work);
	}

	return 0;
}

static const struct modem_cmd response_cmds[] = {
	MODEM_CMD("OK", on_cmd_ok, 0U, ""), /* 3GPP */
	MODEM_CMD("ERROR", on_cmd_error, 0U, ""), /* 3GPP */
};

MODEM_CMD_DEFINE(on_cmd_wifi_connected)
{
	struct esp_data *dev = CONTAINER_OF(data, struct esp_data,
					    cmd_handler_data);

	if (esp_flags_are_set(dev, EDF_STA_CONNECTED)) {
		return 0;
	}

	esp_flags_set(dev, EDF_STA_CONNECTED);
	wifi_mgmt_raise_connect_result_event(dev->net_iface, 0);

	return 0;
}

static void esp_mgmt_disconnect_work(struct k_work *work)
{
	struct esp_socket *sock;
	struct esp_data *dev;

	dev = CONTAINER_OF(work, struct esp_data, disconnect_work);

	/* Cleanup any sockets that weren't closed */
	for (int i = 0; i < ARRAY_SIZE(dev->sockets); i++) {
		sock = &dev->sockets[i];
		if (esp_socket_connected(sock)) {
			LOG_WRN("Socket %d left open, manually closing", i);
			esp_socket_close(sock);
		}
	}

	esp_flags_clear(dev, EDF_STA_CONNECTED);
	esp_mode_switch_submit_if_needed(dev);

	net_if_ipv4_addr_rm(dev->net_iface, &dev->ip);
	wifi_mgmt_raise_disconnect_result_event(dev->net_iface, 0);
}

MODEM_CMD_DEFINE(on_cmd_wifi_disconnected)
{
	struct esp_data *dev = CONTAINER_OF(data, struct esp_data,
					    cmd_handler_data);

	if (esp_flags_are_set(dev, EDF_STA_CONNECTED)) {
		k_work_submit_to_queue(&dev->workq, &dev->disconnect_work);
	}

	return 0;
}

/*
 * +CIPSTA:ip:"<ip>"
 * +CIPSTA:gateway:"<ip>"
 * +CIPSTA:netmask:"<ip>"
 */
MODEM_CMD_DEFINE(on_cmd_cipsta)
{
	struct esp_data *dev = CONTAINER_OF(data, struct esp_data,
					    cmd_handler_data);
	char *ip;

	ip = str_unquote(argv[1]);

	if (!strcmp(argv[0], "ip")) {
		net_addr_pton(AF_INET, ip, &dev->ip);
	} else if (!strcmp(argv[0], "gateway")) {
		net_addr_pton(AF_INET, ip, &dev->gw);
	} else if (!strcmp(argv[0], "netmask")) {
		net_addr_pton(AF_INET, ip, &dev->nm);
	} else {
		LOG_WRN("Unknown IP type %s", log_strdup(argv[0]));
	}

	return 0;
}

static void esp_ip_addr_work(struct k_work *work)
{
	struct k_work_delayable *dwork = k_work_delayable_from_work(work);
	struct esp_data *dev = CONTAINER_OF(dwork, struct esp_data,
					    ip_addr_work);
	int ret;

	static const struct modem_cmd cmds[] = {
		MODEM_CMD("+"_CIPSTA":", on_cmd_cipsta, 2U, ":"),
	};
	static const struct modem_cmd dns_cmds[] = {
		MODEM_CMD_ARGS_MAX("+CIPDNS:", on_cmd_cipdns, 1U, 3U, ","),
	};

	ret = esp_cmd_send(dev, cmds, ARRAY_SIZE(cmds), "AT+"_CIPSTA"?",
			   ESP_CMD_TIMEOUT);
	if (ret < 0) {
		LOG_WRN("Failed to query IP settings: ret %d", ret);
		k_work_reschedule_for_queue(&dev->workq, &dev->ip_addr_work,
					    K_SECONDS(5));
		return;
	}

	/* update interface addresses */
	net_if_ipv4_set_gw(dev->net_iface, &dev->gw);
	net_if_ipv4_set_netmask(dev->net_iface, &dev->nm);
#if defined(CONFIG_WIFI_ESP_AT_IP_STATIC)
	net_if_ipv4_addr_add(dev->net_iface, &dev->ip, NET_ADDR_MANUAL, 0);
#else
	net_if_ipv4_addr_add(dev->net_iface, &dev->ip, NET_ADDR_DHCP, 0);
#endif

	if (IS_ENABLED(CONFIG_WIFI_ESP_AT_DNS_USE)) {
		ret = esp_cmd_send(dev, dns_cmds, ARRAY_SIZE(dns_cmds),
				   "AT+CIPDNS?", ESP_CMD_TIMEOUT);
		if (ret) {
			LOG_WRN("DNS fetch failed: %d", ret);
		}
	}
}

MODEM_CMD_DEFINE(on_cmd_got_ip)
{
	struct esp_data *dev = CONTAINER_OF(data, struct esp_data,
					    cmd_handler_data);

	k_work_reschedule_for_queue(&dev->workq, &dev->ip_addr_work,
				    K_SECONDS(1));

	return 0;
}

MODEM_CMD_DEFINE(on_cmd_connect)
{
	struct esp_socket *sock;
	struct esp_data *dev;
	uint8_t link_id;

	link_id = data->match_buf[0] - '0';

	dev = CONTAINER_OF(data, struct esp_data, cmd_handler_data);
	sock = esp_socket_ref_from_link_id(dev, link_id);
	if (!sock) {
		LOG_ERR("No socket for link %d", link_id);
		return 0;
	}

	esp_socket_unref(sock);

	return 0;
}

MODEM_CMD_DEFINE(on_cmd_closed)
{
	struct esp_socket *sock;
	struct esp_data *dev;
	uint8_t link_id;
	atomic_val_t old_flags;

	link_id = data->match_buf[0] - '0';

	LOG_DBG("Link %d closed", link_id);

	dev = CONTAINER_OF(data, struct esp_data, cmd_handler_data);
	sock = esp_socket_ref_from_link_id(dev, link_id);
	if (!sock) {
		LOG_ERR("No socket for link %d", link_id);
		return 0;
	}

	old_flags = esp_socket_flags_clear_and_set(sock,
				ESP_SOCK_CONNECTED, ESP_SOCK_CLOSE_PENDING);

	if (!(old_flags & ESP_SOCK_CONNECTED)) {
		LOG_DBG("Link %d already closed", link_id);
		goto socket_unref;
	}

	if (!(old_flags & ESP_SOCK_CLOSE_PENDING)) {
		esp_socket_work_submit(sock, &sock->close_work);
	}

socket_unref:
	esp_socket_unref(sock);

	return 0;
}

/*
 * Passive mode: "+IPD,<id>,<len>\r\n"
 * Other:        "+IPD,<id>,<len>:<data>"
 */
#define MIN_IPD_LEN (sizeof("+IPD,I,0E") - 1)
#define MAX_IPD_LEN (sizeof("+IPD,I,4294967295E") - 1)

static int cmd_ipd_parse_hdr(struct net_buf *buf, uint16_t len,
			     uint8_t *link_id,
			     int *data_offset, int *data_len,
			     char *end)
{
	char *endptr, ipd_buf[MAX_IPD_LEN + 1];
	size_t frags_len;
	size_t match_len;

	frags_len = net_buf_frags_len(buf);

	/* Wait until minimum cmd length is available */
	if (frags_len < MIN_IPD_LEN) {
		return -EAGAIN;
	}

	match_len = net_buf_linearize(ipd_buf, MAX_IPD_LEN,
				      buf, 0, MAX_IPD_LEN);

	ipd_buf[match_len] = 0;
	if (ipd_buf[len] != ',' || ipd_buf[len + 2] != ',') {
		LOG_ERR("Invalid IPD: %s", log_strdup(ipd_buf));
		return -EBADMSG;
	}

	*link_id = ipd_buf[len + 1] - '0';

	*data_len = strtol(&ipd_buf[len + 3], &endptr, 10);

	if (endptr == &ipd_buf[len + 3] ||
	    (*endptr == 0 && match_len >= MAX_IPD_LEN)) {
		LOG_ERR("Invalid IPD len: %s", log_strdup(ipd_buf));
		return -EBADMSG;
	} else if (*endptr == 0) {
		return -EAGAIN;
	}

	*end = *endptr;
	*data_offset = (endptr - ipd_buf) + 1;

	return 0;
}

static int cmd_ipd_check_hdr_end(struct esp_socket *sock, char actual)
{
	char expected;

	/* When using passive mode, the +IPD command ends with \r\n */
	if (ESP_PROTO_PASSIVE(esp_socket_ip_proto(sock))) {
		expected = '\r';
	} else {
		expected = ':';
	}

	if (expected != actual) {
		LOG_ERR("Invalid cmd end 0x%02x, expected 0x%02x", actual,
			expected);
		return -EBADMSG;
	}

	return 0;
}

MODEM_CMD_DIRECT_DEFINE(on_cmd_ipd)
{
	struct esp_data *dev = CONTAINER_OF(data, struct esp_data,
					    cmd_handler_data);
	struct esp_socket *sock;
	int data_offset, data_len;
	uint8_t link_id;
	char cmd_end;
	int err;
	int ret;

	err = cmd_ipd_parse_hdr(data->rx_buf, len, &link_id, &data_offset,
				&data_len, &cmd_end);
	if (err) {
		if (err == -EAGAIN) {
			return -EAGAIN;
		}

		return len;
	}

	sock = esp_socket_ref_from_link_id(dev, link_id);
	if (!sock) {
		LOG_ERR("No socket for link %d", link_id);
		return len;
	}

	err = cmd_ipd_check_hdr_end(sock, cmd_end);
	if (err) {
		ret = len;
		goto socket_unref;
	}

	/*
	 * When using passive TCP, the data itself is not included in the +IPD
	 * command but must be polled with AT+CIPRECVDATA.
	 */
	if (ESP_PROTO_PASSIVE(esp_socket_ip_proto(sock))) {
		esp_socket_work_submit(sock, &sock->recvdata_work);
		ret = data_offset;
		goto socket_unref;
	}

	/* Do we have the whole message? */
	if (data_offset + data_len > net_buf_frags_len(data->rx_buf)) {
		ret = -EAGAIN;
		goto socket_unref;
	}

	esp_socket_rx(sock, data->rx_buf, data_offset, data_len);

	ret = data_offset + data_len;

socket_unref:
	esp_socket_unref(sock);

	return ret;
}

MODEM_CMD_DEFINE(on_cmd_busy_sending)
{
	LOG_WRN("Busy sending");
	return 0;
}

MODEM_CMD_DEFINE(on_cmd_busy_processing)
{
	LOG_WRN("Busy processing");
	return 0;
}

/*
 * The 'ready' command is sent when device has booted and is ready to receive
 * commands. It is only expected after a reset of the device.
 */
MODEM_CMD_DEFINE(on_cmd_ready)
{
	struct esp_data *dev = CONTAINER_OF(data, struct esp_data,
					    cmd_handler_data);
	k_sem_give(&dev->sem_if_ready);

	if (net_if_is_up(dev->net_iface)) {
		net_if_down(dev->net_iface);
		LOG_ERR("Unexpected reset");
	}

	if (esp_flags_are_set(dev, EDF_STA_CONNECTING)) {
		wifi_mgmt_raise_connect_result_event(dev->net_iface, -1);
	} else if (esp_flags_are_set(dev, EDF_STA_CONNECTED)) {
		wifi_mgmt_raise_disconnect_result_event(dev->net_iface, 0);
	}

	dev->flags = 0;
	dev->mode = 0;

	net_if_ipv4_addr_rm(dev->net_iface, &dev->ip);
	k_work_submit_to_queue(&dev->workq, &dev->init_work);

	return 0;
}

static const struct modem_cmd unsol_cmds[] = {
	MODEM_CMD("WIFI CONNECTED", on_cmd_wifi_connected, 0U, ""),
	MODEM_CMD("WIFI DISCONNECT", on_cmd_wifi_disconnected, 0U, ""),
	MODEM_CMD("WIFI GOT IP", on_cmd_got_ip, 0U, ""),
	MODEM_CMD("0,CONNECT", on_cmd_connect, 0U, ""),
	MODEM_CMD("1,CONNECT", on_cmd_connect, 0U, ""),
	MODEM_CMD("2,CONNECT", on_cmd_connect, 0U, ""),
	MODEM_CMD("3,CONNECT", on_cmd_connect, 0U, ""),
	MODEM_CMD("4,CONNECT", on_cmd_connect, 0U, ""),
	MODEM_CMD("0,CLOSED", on_cmd_closed, 0U, ""),
	MODEM_CMD("1,CLOSED", on_cmd_closed, 0U, ""),
	MODEM_CMD("2,CLOSED", on_cmd_closed, 0U, ""),
	MODEM_CMD("3,CLOSED", on_cmd_closed, 0U, ""),
	MODEM_CMD("4,CLOSED", on_cmd_closed, 0U, ""),
	MODEM_CMD("busy s...", on_cmd_busy_sending, 0U, ""),
	MODEM_CMD("busy p...", on_cmd_busy_processing, 0U, ""),
	MODEM_CMD("ready", on_cmd_ready, 0U, ""),
	MODEM_CMD_DIRECT("+IPD", on_cmd_ipd),
};

static void esp_mgmt_scan_work(struct k_work *work)
{
	struct esp_data *dev;
	int ret;
	static const struct modem_cmd cmds[] = {
#if defined(CONFIG_WIFI_ESP_AT_SCAN_MAC_ADDRESS)
		MODEM_CMD("+CWLAP:", on_cmd_cwlap, 5U, ","),
#else
		MODEM_CMD("+CWLAP:", on_cmd_cwlap, 4U, ","),
#endif
	};

	dev = CONTAINER_OF(work, struct esp_data, scan_work);

	ret = esp_mode_flags_set(dev, EDF_STA_LOCK);
	if (ret < 0) {
		goto out;
	}
	ret = esp_cmd_send(dev,
			   cmds, ARRAY_SIZE(cmds),
			   ESP_CMD_CWLAP,
			   ESP_SCAN_TIMEOUT);
	esp_mode_flags_clear(dev, EDF_STA_LOCK);
	LOG_DBG("ESP Wi-Fi scan: cmd = %s", ESP_CMD_CWLAP);

	if (ret < 0) {
		LOG_ERR("Failed to scan: ret %d", ret);
	}

out:
	dev->scan_cb(dev->net_iface, 0, NULL);
	dev->scan_cb = NULL;
}

static int esp_mgmt_scan(const struct device *dev, scan_result_cb_t cb)
{
	struct esp_data *data = dev->data;

	if (data->scan_cb != NULL) {
		return -EINPROGRESS;
	}

	if (!net_if_is_up(data->net_iface)) {
		return -EIO;
	}

	data->scan_cb = cb;

	k_work_submit_to_queue(&data->workq, &data->scan_work);

	return 0;
};

MODEM_CMD_DEFINE(on_cmd_fail)
{
	struct esp_data *dev = CONTAINER_OF(data, struct esp_data,
					    cmd_handler_data);

	modem_cmd_handler_set_error(data, -EIO);
	k_sem_give(&dev->sem_response);

	return 0;
}

static void esp_mgmt_connect_work(struct k_work *work)
{
	struct esp_data *dev;
	int ret;
	static const struct modem_cmd cmds[] = {
		MODEM_CMD("FAIL", on_cmd_fail, 0U, ""),
	};

	dev = CONTAINER_OF(work, struct esp_data, connect_work);

	ret = esp_mode_flags_set(dev, EDF_STA_LOCK);
	if (ret < 0) {
		goto out;
	}

	ret = esp_cmd_send(dev, cmds, ARRAY_SIZE(cmds), dev->conn_cmd,
			   ESP_CONNECT_TIMEOUT);

	memset(dev->conn_cmd, 0, sizeof(dev->conn_cmd));

	if (ret < 0) {
		if (esp_flags_are_set(dev, EDF_STA_CONNECTED)) {
			esp_flags_clear(dev, EDF_STA_CONNECTED);
			wifi_mgmt_raise_disconnect_result_event(dev->net_iface,
								0);
		} else {
			wifi_mgmt_raise_connect_result_event(dev->net_iface,
							     ret);
		}
	} else if (!esp_flags_are_set(dev, EDF_STA_CONNECTED)) {
		esp_flags_set(dev, EDF_STA_CONNECTED);
		wifi_mgmt_raise_connect_result_event(dev->net_iface, 0);
	}

	esp_mode_flags_clear(dev, EDF_STA_LOCK);

out:
	esp_flags_clear(dev, EDF_STA_CONNECTING);
}

static int esp_mgmt_connect(const struct device *dev,
			    struct wifi_connect_req_params *params)
{
	struct esp_data *data = dev->data;
	int len;

	if (!net_if_is_up(data->net_iface)) {
		return -EIO;
	}

	if (esp_flags_are_set(data, EDF_STA_CONNECTED | EDF_STA_CONNECTING)) {
		return -EALREADY;
	}

	esp_flags_set(data, EDF_STA_CONNECTING);

	len = snprintk(data->conn_cmd, sizeof(data->conn_cmd),
		       "AT+"_CWJAP"=\"");
	memcpy(&data->conn_cmd[len], params->ssid, params->ssid_length);
	len += params->ssid_length;

	len += snprintk(&data->conn_cmd[len],
				sizeof(data->conn_cmd) - len, "\",\"");

	if (params->security == WIFI_SECURITY_TYPE_PSK) {
		memcpy(&data->conn_cmd[len], params->psk, params->psk_length);
		len += params->psk_length;
	}

	len += snprintk(&data->conn_cmd[len], sizeof(data->conn_cmd) - len,
			"\"");

	k_work_submit_to_queue(&data->workq, &data->connect_work);

	return 0;
}

static int esp_mgmt_disconnect(const struct device *dev)
{
	struct esp_data *data = dev->data;
	int ret;

	ret = esp_cmd_send(data, NULL, 0, "AT+CWQAP", ESP_CMD_TIMEOUT);

	return ret;
}

static int esp_mgmt_ap_enable(const struct device *dev,
			      struct wifi_connect_req_params *params)
{
	char cmd[sizeof("AT+"_CWSAP"=\"\",\"\",xx,x") + WIFI_SSID_MAX_LEN +
		 WIFI_PSK_MAX_LEN];
	struct esp_data *data = dev->data;
	int ecn = 0, len, ret;

	ret = esp_mode_flags_set(data, EDF_AP_ENABLED);
	if (ret < 0) {
		LOG_ERR("Failed to enable AP mode, ret %d", ret);
		return ret;
	}

	len = snprintk(cmd, sizeof(cmd), "AT+"_CWSAP"=\"");
	memcpy(&cmd[len], params->ssid, params->ssid_length);
	len += params->ssid_length;

	if (params->security == WIFI_SECURITY_TYPE_PSK) {
		len += snprintk(&cmd[len], sizeof(cmd) - len, "\",\"");
		memcpy(&cmd[len], params->psk, params->psk_length);
		len += params->psk_length;
		ecn = 3;
	} else {
		len += snprintk(&cmd[len], sizeof(cmd) - len, "\",\"");
	}

	snprintk(&cmd[len], sizeof(cmd) - len, "\",%d,%d", params->channel,
		 ecn);

	ret = esp_cmd_send(data, NULL, 0, cmd, ESP_CMD_TIMEOUT);

	return ret;
}

static int esp_mgmt_ap_disable(const struct device *dev)
{
	struct esp_data *data = dev->data;

	return esp_mode_flags_clear(data, EDF_AP_ENABLED);
}

static void esp_init_work(struct k_work *work)
{
	struct esp_data *dev;
	int ret;
	static const struct setup_cmd setup_cmds[] = {
		SETUP_CMD_NOHANDLE("AT"),
		/* turn off echo */
		SETUP_CMD_NOHANDLE("ATE0"),
		SETUP_CMD_NOHANDLE("AT+UART_CUR="_UART_CUR),
#if DT_INST_NODE_HAS_PROP(0, target_speed)
	};
	static const struct setup_cmd setup_cmds_target_baudrate[] = {
		SETUP_CMD_NOHANDLE("AT"),
#endif
#if defined(CONFIG_WIFI_ESP_AT_VERSION_1_7)
		SETUP_CMD_NOHANDLE(ESP_CMD_CWMODE(STA)),
#endif
#if defined(CONFIG_WIFI_ESP_AT_IP_STATIC)
		/* enable Static IP Config */
		SETUP_CMD_NOHANDLE(ESP_CMD_DHCP_ENABLE(STATION, 0)),
		SETUP_CMD_NOHANDLE(ESP_CMD_SET_IP(CONFIG_WIFI_ESP_AT_IP_ADDRESS,
						  CONFIG_WIFI_ESP_AT_IP_GATEWAY,
						  CONFIG_WIFI_ESP_AT_IP_MASK)),
#else
		/* enable DHCP */
		SETUP_CMD_NOHANDLE(ESP_CMD_DHCP_ENABLE(STATION, 1)),
#endif
		/* enable multiple socket support */
		SETUP_CMD_NOHANDLE("AT+CIPMUX=1"),

		SETUP_CMD_NOHANDLE(
			ESP_CMD_CWLAPOPT(ESP_CMD_CWLAPOPT_ORDERED, ESP_CMD_CWLAPOPT_MASK)),

#if !defined(CONFIG_WIFI_ESP_AT_VERSION_1_7)
		SETUP_CMD_NOHANDLE(ESP_CMD_CWMODE(STA)),
		SETUP_CMD_NOHANDLE("AT+CWAUTOCONN=0"),
		SETUP_CMD_NOHANDLE(ESP_CMD_CWMODE(NONE)),
#endif
#if defined(CONFIG_WIFI_ESP_AT_PASSIVE_MODE)
		SETUP_CMD_NOHANDLE("AT+CIPRECVMODE=1"),
#endif
		SETUP_CMD("AT+"_CIPSTAMAC"?", "+"_CIPSTAMAC":",
			  on_cmd_cipstamac, 1U, ""),
	};

	dev = CONTAINER_OF(work, struct esp_data, init_work);

	ret = modem_cmd_handler_setup_cmds(&dev->mctx.iface,
					   &dev->mctx.cmd_handler, setup_cmds,
					   ARRAY_SIZE(setup_cmds),
					   &dev->sem_response,
					   ESP_INIT_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("Init failed %d", ret);
		return;
	}

#if DT_INST_NODE_HAS_PROP(0, target_speed)
	static const struct uart_config uart_config = {
		.baudrate = DT_INST_PROP(0, target_speed),
		.parity = UART_CFG_PARITY_NONE,
		.stop_bits = UART_CFG_STOP_BITS_1,
		.data_bits = UART_CFG_DATA_BITS_8,
		.flow_ctrl = DT_PROP(ESP_BUS, hw_flow_control) ?
			UART_CFG_FLOW_CTRL_RTS_CTS : UART_CFG_FLOW_CTRL_NONE,
	};

	ret = uart_configure(device_get_binding(DT_INST_BUS_LABEL(0)),
			     &uart_config);
	if (ret < 0) {
		LOG_ERR("Baudrate change failed %d", ret);
		return;
	}

	/* arbitrary sleep period to give ESP enough time to reconfigure */
	k_sleep(K_MSEC(100));

	ret = modem_cmd_handler_setup_cmds(&dev->mctx.iface,
				&dev->mctx.cmd_handler,
				setup_cmds_target_baudrate,
				ARRAY_SIZE(setup_cmds_target_baudrate),
				&dev->sem_response,
				ESP_INIT_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("Init failed %d", ret);
		return;
	}
#endif

	net_if_set_link_addr(dev->net_iface, dev->mac_addr,
			     sizeof(dev->mac_addr), NET_LINK_ETHERNET);

	if (IS_ENABLED(CONFIG_WIFI_ESP_AT_VERSION_1_7)) {
		/* This is the mode entered in above setup commands */
		dev->mode = ESP_MODE_STA;

		/*
		 * In case of ESP 1.7 this is the first time CWMODE is entered
		 * STA mode, so request hostname change now.
		 */
		esp_configure_hostname(dev);
	}

	LOG_INF("ESP Wi-Fi ready");

	net_if_up(dev->net_iface);
}

static int esp_reset(struct esp_data *dev)
{
	if (net_if_is_up(dev->net_iface)) {
		net_if_down(dev->net_iface);
	}

#if DT_INST_NODE_HAS_PROP(0, power_gpios)
	modem_pin_write(&dev->mctx, ESP_POWER, 0);
	k_sleep(K_MSEC(100));
	modem_pin_write(&dev->mctx, ESP_POWER, 1);
#elif DT_INST_NODE_HAS_PROP(0, reset_gpios)
	modem_pin_write(&dev->mctx, ESP_RESET, 1);
	k_sleep(K_MSEC(100));
	modem_pin_write(&dev->mctx, ESP_RESET, 0);
#else
	int ret;
	int retries = 3;

	while (retries--) {
		ret = modem_cmd_send(&dev->mctx.iface, &dev->mctx.cmd_handler,
				     NULL, 0, "AT+RST", &dev->sem_if_ready,
				     K_MSEC(CONFIG_WIFI_ESP_AT_RESET_TIMEOUT));
		if (ret == 0 || ret != -ETIMEDOUT) {
			break;
		}
	}

	if (ret < 0) {
		LOG_ERR("Failed to reset device: %d", ret);
		return -EAGAIN;
	}
#endif
	return 0;
}

static void esp_iface_init(struct net_if *iface)
{
	net_if_flag_set(iface, NET_IF_NO_AUTO_START);
	esp_offload_init(iface);
}

static const struct net_wifi_mgmt_offload esp_api = {
	.iface_api.init = esp_iface_init,
	.scan		= esp_mgmt_scan,
	.connect	= esp_mgmt_connect,
	.disconnect	= esp_mgmt_disconnect,
	.ap_enable	= esp_mgmt_ap_enable,
	.ap_disable	= esp_mgmt_ap_disable,
};

static int esp_init(const struct device *dev);

/* The network device must be instantiated above the init function in order
 * for the struct net_if that the macro declares to be visible inside the
 * function. An `extern` declaration does not work as the struct is static.
 */
NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, esp_init, NULL,
				  &esp_driver_data, NULL,
				  CONFIG_WIFI_INIT_PRIORITY, &esp_api,
				  ESP_MTU);

static int esp_init(const struct device *dev)
{
	struct esp_data *data = dev->data;
	int ret = 0;

	k_sem_init(&data->sem_tx_ready, 0, 1);
	k_sem_init(&data->sem_response, 0, 1);
	k_sem_init(&data->sem_if_ready, 0, 1);

	k_work_init(&data->init_work, esp_init_work);
	k_work_init_delayable(&data->ip_addr_work, esp_ip_addr_work);
	k_work_init(&data->scan_work, esp_mgmt_scan_work);
	k_work_init(&data->connect_work, esp_mgmt_connect_work);
	k_work_init(&data->disconnect_work, esp_mgmt_disconnect_work);
	k_work_init(&data->mode_switch_work, esp_mode_switch_work);
	if (IS_ENABLED(CONFIG_WIFI_ESP_AT_DNS_USE)) {
		k_work_init(&data->dns_work, esp_dns_work);
	}

	esp_socket_init(data);

	/* initialize the work queue */
	k_work_queue_start(&data->workq, esp_workq_stack,
			   K_KERNEL_STACK_SIZEOF(esp_workq_stack),
			   K_PRIO_COOP(CONFIG_WIFI_ESP_AT_WORKQ_THREAD_PRIORITY),
			   NULL);
	k_thread_name_set(&data->workq.thread, "esp_workq");

	/* cmd handler */
	data->cmd_handler_data.cmds[CMD_RESP] = response_cmds;
	data->cmd_handler_data.cmds_len[CMD_RESP] = ARRAY_SIZE(response_cmds);
	data->cmd_handler_data.cmds[CMD_UNSOL] = unsol_cmds;
	data->cmd_handler_data.cmds_len[CMD_UNSOL] = ARRAY_SIZE(unsol_cmds);
	data->cmd_handler_data.match_buf = &data->cmd_match_buf[0];
	data->cmd_handler_data.match_buf_len = sizeof(data->cmd_match_buf);
	data->cmd_handler_data.buf_pool = &mdm_recv_pool;
	data->cmd_handler_data.alloc_timeout = K_NO_WAIT;
	data->cmd_handler_data.eol = "\r\n";
	ret = modem_cmd_handler_init(&data->mctx.cmd_handler,
				       &data->cmd_handler_data);
	if (ret < 0) {
		goto error;
	}

	/* modem interface */
	data->iface_data.hw_flow_control = DT_PROP(ESP_BUS, hw_flow_control);
	data->iface_data.rx_rb_buf = &data->iface_rb_buf[0];
	data->iface_data.rx_rb_buf_len = sizeof(data->iface_rb_buf);
	ret = modem_iface_uart_init(&data->mctx.iface, &data->iface_data,
				    DEVICE_DT_GET(DT_INST_BUS(0)));
	if (ret < 0) {
		goto error;
	}

	/* pin setup */
	data->mctx.pins = modem_pins;
	data->mctx.pins_len = ARRAY_SIZE(modem_pins);

	data->mctx.driver_data = data;

	ret = modem_context_register(&data->mctx);
	if (ret < 0) {
		LOG_ERR("Error registering modem context: %d", ret);
		goto error;
	}

	/* start RX thread */
	k_thread_create(&esp_rx_thread, esp_rx_stack,
			K_KERNEL_STACK_SIZEOF(esp_rx_stack),
			(k_thread_entry_t)esp_rx,
			data, NULL, NULL,
			K_PRIO_COOP(CONFIG_WIFI_ESP_AT_RX_THREAD_PRIORITY), 0,
			K_NO_WAIT);
	k_thread_name_set(&esp_rx_thread, "esp_rx");

	/* Retrieve associated network interface so asynchronous messages can be processed early */
	data->net_iface = NET_IF_GET(Z_DEVICE_DT_DEV_NAME(DT_DRV_INST(0)), 0);

	/* Reset the modem */
	ret = esp_reset(data);

error:
	return ret;
}
