/*
 * Copyright (c) 2018 Foundries.io
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT wnc_m14a2a

#define LOG_DOMAIN modem_wncm14a2a
#define LOG_LEVEL CONFIG_MODEM_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(LOG_DOMAIN);

#include <zephyr/types.h>
#include <stddef.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <zephyr.h>
#include <drivers/gpio.h>
#include <device.h>
#include <init.h>
#include <random/rand32.h>

#include <net/net_context.h>
#include <net/net_if.h>
#include <net/net_offload.h>
#include <net/net_pkt.h>
#if defined(CONFIG_NET_IPV6)
#include "ipv6.h"
#endif
#if defined(CONFIG_NET_IPV4)
#include "ipv4.h"
#endif
#if defined(CONFIG_NET_UDP)
#include "udp_internal.h"
#endif

#include "modem_receiver.h"

/* Uncomment the #define below to enable a hexdump of all incoming
 * data from the modem receiver
 */
/* #define ENABLE_VERBOSE_MODEM_RECV_HEXDUMP	1 */

struct mdm_control_pinconfig {
	char *dev_name;
	gpio_pin_t pin;
	gpio_flags_t flags;
};

#define PINCONFIG(name_, pin_, flags_) { \
	.dev_name = name_, \
	.pin = pin_, \
	.flags = flags_ \
}

/* pin settings */
enum mdm_control_pins {
	MDM_BOOT_MODE_SEL = 0,
	MDM_POWER,
	MDM_KEEP_AWAKE,
	MDM_RESET,
	SHLD_3V3_1V8_SIG_TRANS_ENA,
#if DT_INST_NODE_HAS_PROP(0, mdm_send_ok_gpios)
	MDM_SEND_OK,
#endif
	MAX_MDM_CONTROL_PINS,
};

static const struct mdm_control_pinconfig pinconfig[] = {
	/* MDM_BOOT_MODE_SEL */
	PINCONFIG(DT_INST_GPIO_LABEL(0, mdm_boot_mode_sel_gpios),
		  DT_INST_GPIO_PIN(0, mdm_boot_mode_sel_gpios),
		  DT_INST_GPIO_FLAGS(0, mdm_boot_mode_sel_gpios)),

	/* MDM_POWER */
	PINCONFIG(DT_INST_GPIO_LABEL(0, mdm_power_gpios),
		  DT_INST_GPIO_PIN(0, mdm_power_gpios),
		  DT_INST_GPIO_FLAGS(0, mdm_power_gpios)),

	/* MDM_KEEP_AWAKE */
	PINCONFIG(DT_INST_GPIO_LABEL(0, mdm_keep_awake_gpios),
		  DT_INST_GPIO_PIN(0, mdm_keep_awake_gpios),
		  DT_INST_GPIO_FLAGS(0, mdm_keep_awake_gpios)),

	/* MDM_RESET */
	PINCONFIG(DT_INST_GPIO_LABEL(0, mdm_reset_gpios),
		  DT_INST_GPIO_PIN(0, mdm_reset_gpios),
		  DT_INST_GPIO_FLAGS(0, mdm_reset_gpios)),

	/* SHLD_3V3_1V8_SIG_TRANS_ENA */
	PINCONFIG(DT_INST_GPIO_LABEL(0, mdm_shld_trans_ena_gpios),
		  DT_INST_GPIO_PIN(0, mdm_shld_trans_ena_gpios),
		  DT_INST_GPIO_FLAGS(0, mdm_shld_trans_ena_gpios)),

#if DT_INST_NODE_HAS_PROP(0, mdm_send_ok_gpios)
	/* MDM_SEND_OK */
	PINCONFIG(DT_INST_GPIO_LABEL(0, mdm_send_ok_gpios),
		  DT_INST_GPIO_PIN(0, mdm_send_ok_gpios),
		  DT_INST_GPIO_FLAGS(0, mdm_send_ok_gpios)),
#endif
};

#define MDM_UART_DEV			DEVICE_DT_GET(DT_INST_BUS(0))

#define MDM_BOOT_MODE_SPECIAL		0
#define MDM_BOOT_MODE_NORMAL		1
#define MDM_POWER_ENABLE		0
#define MDM_POWER_DISABLE		1
#define MDM_KEEP_AWAKE_DISABLED		0
#define MDM_KEEP_AWAKE_ENABLED		1
#define MDM_RESET_NOT_ASSERTED		0
#define MDM_RESET_ASSERTED		1
#define SHLD_3V3_1V8_SIG_TRANS_DISABLED	0
#define SHLD_3V3_1V8_SIG_TRANS_ENABLED	1
#define MDM_SEND_OK_ENABLED		0
#define MDM_SEND_OK_DISABLED		1

#define MDM_CMD_TIMEOUT			(5 * MSEC_PER_SEC)
#define MDM_CMD_SEND_TIMEOUT		(10 * MSEC_PER_SEC)
#define MDM_CMD_CONN_TIMEOUT		(31 * MSEC_PER_SEC)

#define MDM_MAX_DATA_LENGTH		1500

#define MDM_RECV_MAX_BUF		30
#define MDM_RECV_BUF_SIZE		128

#define MDM_MAX_SOCKETS			6

#define BUF_ALLOC_TIMEOUT K_SECONDS(1)

#define CMD_HANDLER(cmd_, cb_) { \
	.cmd = cmd_, \
	.cmd_len = (uint16_t)sizeof(cmd_)-1, \
	.func = on_cmd_ ## cb_ \
}

#define MDM_MANUFACTURER_LENGTH		10
#define MDM_MODEL_LENGTH		16
#define MDM_REVISION_LENGTH		64
#define MDM_IMEI_LENGTH			16

#define RSSI_TIMEOUT_SECS		30

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

static uint8_t mdm_recv_buf[MDM_MAX_DATA_LENGTH];

/* RX thread structures */
K_KERNEL_STACK_DEFINE(wncm14a2a_rx_stack,
		       CONFIG_MODEM_WNCM14A2A_RX_STACK_SIZE);
struct k_thread wncm14a2a_rx_thread;

/* RX thread work queue */
K_KERNEL_STACK_DEFINE(wncm14a2a_workq_stack,
		      CONFIG_MODEM_WNCM14A2A_RX_WORKQ_STACK_SIZE);
static struct k_work_q wncm14a2a_workq;

struct wncm14a2a_socket {
	struct net_context *context;
	sa_family_t family;
	enum net_sock_type type;
	enum net_ip_protocol ip_proto;
	struct sockaddr src;
	struct sockaddr dst;

	int socket_id;

	/** semaphore */
	struct k_sem sock_send_sem;

	/** socket callbacks */
	struct k_work recv_cb_work;
	net_context_recv_cb_t recv_cb;
	struct net_pkt *recv_pkt;
	void *recv_user_data;
};

struct wncm14a2a_iface_ctx {
	struct net_if *iface;
	uint8_t mac_addr[6];

	/* GPIO PORT devices */
	const struct device *gpio_port_dev[MAX_MDM_CONTROL_PINS];

	/* RX specific attributes */
	struct mdm_receiver_context mdm_ctx;

	/* socket data */
	struct wncm14a2a_socket sockets[MDM_MAX_SOCKETS];
	int last_socket_id;
	int last_error;

	/* semaphores */
	struct k_sem response_sem;

	/* RSSI work */
	struct k_work_delayable rssi_query_work;

	/* modem data */
	char mdm_manufacturer[MDM_MANUFACTURER_LENGTH];
	char mdm_model[MDM_MODEL_LENGTH];
	char mdm_revision[MDM_REVISION_LENGTH];
	char mdm_imei[MDM_IMEI_LENGTH];
	int mdm_rssi;

	/* modem state */
	int ev_csps;
	int ev_rrcstate;
};

struct cmd_handler {
	const char *cmd;
	uint16_t cmd_len;
	void (*func)(struct net_buf **buf, uint16_t len);
};

static struct wncm14a2a_iface_ctx ictx;

static void wncm14a2a_read_rx(struct net_buf **buf);

/*** Verbose Debugging Functions ***/
#if defined(ENABLE_VERBOSE_MODEM_RECV_HEXDUMP)
static inline void hexdump(const uint8_t *packet, size_t length)
{
	char output[sizeof("xxxxyyyy xxxxyyyy")];
	int n = 0, k = 0;
	uint8_t byte;

	while (length--) {
		if (n % 16 == 0) {
			printk(" %08X ", n);
		}

		byte = *packet++;

		printk("%02X ", byte);

		if (byte < 0x20 || byte > 0x7f) {
			output[k++] = '.';
		} else {
			output[k++] = byte;
		}

		n++;
		if (n % 8 == 0) {
			if (n % 16 == 0) {
				output[k] = '\0';
				printk(" [%s]\n", output);
				k = 0;
			} else {
				printk(" ");
			}
		}
	}

	if (n % 16) {
		int i;

		output[k] = '\0';

		for (i = 0; i < (16 - (n % 16)); i++) {
			printk("   ");
		}

		if ((n % 16) < 8) {
			printk(" "); /* one extra delimiter after 8 chars */
		}

		printk(" [%s]\n", output);
	}
}
#else
#define hexdump(...)
#endif

static struct wncm14a2a_socket *socket_get(void)
{
	int i;
	struct wncm14a2a_socket *sock = NULL;

	for (i = 0; i < MDM_MAX_SOCKETS; i++) {
		if (!ictx.sockets[i].context) {
			sock = &ictx.sockets[i];
			break;
		}
	}

	return sock;
}

static struct wncm14a2a_socket *socket_from_id(int socket_id)
{
	int i;
	struct wncm14a2a_socket *sock = NULL;

	if (socket_id < 1) {
		return NULL;
	}

	for (i = 0; i < MDM_MAX_SOCKETS; i++) {
		if (ictx.sockets[i].socket_id == socket_id) {
			sock = &ictx.sockets[i];
			break;
		}
	}

	return sock;
}

static void socket_put(struct wncm14a2a_socket *sock)
{
	if (!sock) {
		return;
	}

	sock->context = NULL;
	sock->socket_id = 0;
	(void)memset(&sock->src, 0, sizeof(struct sockaddr));
	(void)memset(&sock->dst, 0, sizeof(struct sockaddr));
}

char *wncm14a2a_sprint_ip_addr(const struct sockaddr *addr)
{
	static char buf[NET_IPV6_ADDR_LEN];

#if defined(CONFIG_NET_IPV6)
	if (addr->sa_family == AF_INET6) {
		return net_addr_ntop(AF_INET6, &net_sin6(addr)->sin6_addr,
				     buf, sizeof(buf));
	} else
#endif
#if defined(CONFIG_NET_IPV4)
	if (addr->sa_family == AF_INET) {
		return net_addr_ntop(AF_INET, &net_sin(addr)->sin_addr,
				     buf, sizeof(buf));
	} else
#endif
	{
		LOG_ERR("Unknown IP address family:%d", addr->sa_family);
		return NULL;
	}
}

/* Send an AT command with a series of response handlers */
static int send_at_cmd(struct wncm14a2a_socket *sock,
			const uint8_t *data, int timeout)
{
	int ret;

	ictx.last_error = 0;

	LOG_DBG("OUT: [%s]", data);
	mdm_receiver_send(&ictx.mdm_ctx, data, strlen(data));
	mdm_receiver_send(&ictx.mdm_ctx, "\r\n", 2);

	if (timeout == 0) {
		return 0;
	}

	if (!sock) {
		k_sem_reset(&ictx.response_sem);
		ret = k_sem_take(&ictx.response_sem, K_MSEC(timeout));
	} else {
		k_sem_reset(&sock->sock_send_sem);
		ret = k_sem_take(&sock->sock_send_sem, K_MSEC(timeout));
	}

	if (ret == 0) {
		ret = ictx.last_error;
	} else if (ret == -EAGAIN) {
		ret = -ETIMEDOUT;
	}

	return ret;
}

static int send_data(struct wncm14a2a_socket *sock, struct net_pkt *pkt)
{
	int ret;
	struct net_buf *frag;
	char buf[sizeof("AT@SOCKWRITE=#,####,1\r")];

	if (!sock) {
		return -EINVAL;
	}

	ictx.last_error = 0;

	frag = pkt->frags;
	/* use SOCKWRITE with binary mode formatting */
	snprintk(buf, sizeof(buf), "AT@SOCKWRITE=%d,%zu,1\r",
		 sock->socket_id, net_buf_frags_len(frag));
	mdm_receiver_send(&ictx.mdm_ctx, buf, strlen(buf));

	/* Loop through packet data and send */
	while (frag) {
		mdm_receiver_send(&ictx.mdm_ctx,
				  frag->data, frag->len);
		frag = frag->frags;
	}

	mdm_receiver_send(&ictx.mdm_ctx, "\r\n", 2);
	k_sem_reset(&sock->sock_send_sem);
	ret = k_sem_take(&sock->sock_send_sem, K_MSEC(MDM_CMD_SEND_TIMEOUT));
	if (ret == 0) {
		ret = ictx.last_error;
	} else if (ret == -EAGAIN) {
		ret = -ETIMEDOUT;
	}

	return ret;
}

/*** NET_BUF HELPERS ***/

static bool is_crlf(uint8_t c)
{
	if (c == '\n' || c == '\r') {
		return true;
	} else {
		return false;
	}
}

static void net_buf_skipcrlf(struct net_buf **buf)
{
	/* chop off any /n or /r */
	while (*buf && is_crlf(*(*buf)->data)) {
		net_buf_pull_u8(*buf);
		if (!(*buf)->len) {
			*buf = net_buf_frag_del(NULL, *buf);
		}
	}
}

static uint16_t net_buf_findcrlf(struct net_buf *buf, struct net_buf **frag,
			      uint16_t *offset)
{
	uint16_t len = 0U, pos = 0U;

	while (buf && !is_crlf(*(buf->data + pos))) {
		if (pos + 1 >= buf->len) {
			len += buf->len;
			buf = buf->frags;
			pos = 0U;
		} else {
			pos++;
		}
	}

	if (buf && is_crlf(*(buf->data + pos))) {
		len += pos;
		*offset = pos;
		*frag = buf;
		return len;
	}

	return 0;
}

/*** UDP / TCP Helper Function ***/

/* Setup IP header data to be used by some network applications.
 * While much is dummy data, some fields such as dst, port and family are
 * important.
 * Return the IP + protocol header length.
 */
static int pkt_setup_ip_data(struct net_pkt *pkt,
			     struct wncm14a2a_socket *sock)
{
	int hdr_len = 0;
	uint16_t src_port = 0U, dst_port = 0U;

#if defined(CONFIG_NET_IPV6)
	if (net_pkt_family(pkt) == AF_INET6) {
		if (net_ipv6_create(
			    pkt,
			    &((struct sockaddr_in6 *)&sock->dst)->sin6_addr,
			    &((struct sockaddr_in6 *)&sock->src)->sin6_addr)) {
			return -1;
		}
		src_port = ntohs(net_sin6(&sock->src)->sin6_port);
		dst_port = ntohs(net_sin6(&sock->dst)->sin6_port);

		hdr_len = sizeof(struct net_ipv6_hdr);
	} else
#endif
#if defined(CONFIG_NET_IPV4)
	if (net_pkt_family(pkt) == AF_INET) {
		if (net_ipv4_create(
			    pkt,
			    &((struct sockaddr_in *)&sock->dst)->sin_addr,
			    &((struct sockaddr_in *)&sock->src)->sin_addr)) {
			return -1;
		}
		src_port = ntohs(net_sin(&sock->src)->sin_port);
		dst_port = ntohs(net_sin(&sock->dst)->sin_port);

		hdr_len = sizeof(struct net_ipv4_hdr);
	} else
#endif
	{
		/* no error here as hdr_len is checked later for 0 value */
	}

#if defined(CONFIG_NET_UDP)
	if (sock->ip_proto == IPPROTO_UDP) {
		if (net_udp_create(pkt, dst_port, src_port)) {
			return -1;
		}

		hdr_len += NET_UDPH_LEN;
	} else
#endif
#if defined(CONFIG_NET_TCP)
	if (sock->ip_proto == IPPROTO_TCP) {
		NET_PKT_DATA_ACCESS_DEFINE(tcp_access, struct net_tcp_hdr);
		struct net_tcp_hdr *tcp;

		tcp = (struct net_tcp_hdr *)net_pkt_get_data(pkt, &tcp_access);
		if (!tcp) {
			return -1;
		}

		(void)memset(tcp, 0, NET_TCPH_LEN);

		/* Setup TCP header */
		tcp->src_port = dst_port;
		tcp->dst_port = src_port;

		if (net_pkt_set_data(pkt, &tcp_access)) {
			return -1;
		}

		hdr_len += NET_TCPH_LEN;
	} else
#endif /* CONFIG_NET_TCP */
	{
		/* no error here as hdr_len is checked later for 0 value */
	}

	return hdr_len;
}

/*** MODEM RESPONSE HANDLERS ***/

/* Last Socket ID Handler */
static void on_cmd_atcmdecho(struct net_buf **buf, uint16_t len)
{
	char value[2];
	/* make sure only a single digit is picked up for socket_id */
	value[0] = net_buf_pull_u8(*buf);
	ictx.last_socket_id = atoi(value);
}

/* Echo Handler for commands without related sockets */
static void on_cmd_atcmdecho_nosock(struct net_buf **buf, uint16_t len)
{
	/* clear last_socket_id */
	ictx.last_socket_id = 0;
}

static void on_cmd_atcmdinfo_manufacturer(struct net_buf **buf, uint16_t len)
{
	size_t out_len;

	out_len = net_buf_linearize(ictx.mdm_manufacturer,
				    sizeof(ictx.mdm_manufacturer) - 1,
				    *buf, 0, len);
	ictx.mdm_manufacturer[out_len] = 0;
	LOG_INF("Manufacturer: %s", ictx.mdm_manufacturer);
}

static void on_cmd_atcmdinfo_model(struct net_buf **buf, uint16_t len)
{
	size_t out_len;

	out_len = net_buf_linearize(ictx.mdm_model,
				    sizeof(ictx.mdm_model) - 1,
				    *buf, 0, len);
	ictx.mdm_model[out_len] = 0;
	LOG_INF("Model: %s", ictx.mdm_model);
}

static void on_cmd_atcmdinfo_revision(struct net_buf **buf, uint16_t len)
{
	size_t out_len;

	out_len = net_buf_linearize(ictx.mdm_revision,
				    sizeof(ictx.mdm_revision) - 1,
				    *buf, 0, len);
	ictx.mdm_revision[out_len] = 0;
	LOG_INF("Revision: %s", ictx.mdm_revision);
}

static void on_cmd_atcmdecho_nosock_imei(struct net_buf **buf, uint16_t len)
{
	struct net_buf *frag = NULL;
	uint16_t offset;
	size_t out_len;

	/* make sure IMEI data is received */
	if (len < MDM_IMEI_LENGTH) {
		LOG_DBG("Waiting for data");
		/* wait for more data */
		k_sleep(K_MSEC(500));
		wncm14a2a_read_rx(buf);
	}

	net_buf_skipcrlf(buf);
	if (!*buf) {
		LOG_DBG("Unable to find IMEI (net_buf_skipcrlf)");
		return;
	}

	frag = NULL;
	len = net_buf_findcrlf(*buf, &frag, &offset);
	if (!frag) {
		LOG_DBG("Unable to find IMEI (net_buf_findcrlf)");
		return;
	}

	out_len = net_buf_linearize(ictx.mdm_imei, sizeof(ictx.mdm_imei) - 1,
				    *buf, 0, len);
	ictx.mdm_imei[out_len] = 0;

	LOG_INF("IMEI: %s", ictx.mdm_imei);
}

/* Handler: %MEAS: RSSI:Reported= -68, Ant0= -63, Ant1= -251 */
static void on_cmd_atcmdinfo_rssi(struct net_buf **buf, uint16_t len)
{
	int start = 0, i = 0;
	size_t value_size;
	char value[64];

	value_size = sizeof(value);
	(void)memset(value, 0, value_size);
	while (*buf && len > 0 && i < value_size) {
		value[i] = net_buf_pull_u8(*buf);
		if (!(*buf)->len) {
			*buf = net_buf_frag_del(NULL, *buf);
		}

		/* 2nd "=" marks the beginning of the RSSI value */
		if (start < 2) {
			if (value[i] == '=') {
				start++;
			}

			continue;
		}

		/* "," marks the end of the RSSI value */
		if (value[i] == ',') {
			value[i] = '\0';
			break;
		}

		i++;
	}

	if (i > 0) {
		ictx.mdm_rssi = atoi(value);
		LOG_INF("RSSI: %d", ictx.mdm_rssi);
	} else {
		LOG_WRN("Bad format found for RSSI");
	}
}

/* Handler: OK */
static void on_cmd_sockok(struct net_buf **buf, uint16_t len)
{
	struct wncm14a2a_socket *sock = NULL;

	ictx.last_error = 0;
	sock = socket_from_id(ictx.last_socket_id);
	if (!sock) {
		k_sem_give(&ictx.response_sem);
	} else {
		k_sem_give(&sock->sock_send_sem);
	}
}

/* Handler: ERROR */
static void on_cmd_sockerror(struct net_buf **buf, uint16_t len)
{
	struct wncm14a2a_socket *sock = NULL;

	ictx.last_error = -EIO;
	sock = socket_from_id(ictx.last_socket_id);
	if (!sock) {
		k_sem_give(&ictx.response_sem);
	} else {
		k_sem_give(&sock->sock_send_sem);
	}
}

/* Handler: @EXTERR:<exterror_id> */
static void on_cmd_sockexterror(struct net_buf **buf, uint16_t len)
{
	char value[8];
	size_t out_len;

	struct wncm14a2a_socket *sock = NULL;

	out_len = net_buf_linearize(value, sizeof(value) - 1, *buf, 0, len);
	value[out_len] = 0;
	ictx.last_error = -atoi(value);
	LOG_ERR("@EXTERR:%d", ictx.last_error);
	sock = socket_from_id(ictx.last_socket_id);
	if (!sock) {
		k_sem_give(&ictx.response_sem);
	} else {
		k_sem_give(&sock->sock_send_sem);
	}
}

/* Handler: @SOCKDIAL:<status> */
static void on_cmd_sockdial(struct net_buf **buf, uint16_t len)
{
	char value[8];
	size_t out_len;

	out_len = net_buf_linearize(value, sizeof(value) - 1, *buf, 0, len);
	value[out_len] = 0;
	ictx.last_error = atoi(value);
	k_sem_give(&ictx.response_sem);
}

/* Handler: @SOCKCREAT:<socket_id> */
static void on_cmd_sockcreat(struct net_buf **buf, uint16_t len)
{
	char value[2];
	struct wncm14a2a_socket *sock = NULL;

	/* look up new socket by special id */
	sock = socket_from_id(MDM_MAX_SOCKETS + 1);
	if (sock) {
	/* make sure only a single digit is picked up for socket_id */
		value[0] = net_buf_pull_u8(*buf);
		sock->socket_id = atoi(value);
	}
	/* don't give back semaphore -- OK to follow */
}

/* Handler: @SOCKWRITE:<actual_length> */
static void on_cmd_sockwrite(struct net_buf **buf, uint16_t len)
{
	char value[8];
	size_t out_len;
	int write_len;
	struct wncm14a2a_socket *sock = NULL;

	/* TODO: check against what we wanted to send */
	out_len = net_buf_linearize(value, sizeof(value) - 1, *buf, 0, len);
	value[out_len] = 0;
	write_len = atoi(value);
	if (write_len <= 0) {
		return;
	}

	sock = socket_from_id(ictx.last_socket_id);
	if (sock) {
		k_sem_give(&sock->sock_send_sem);
	}
}

static void sockreadrecv_cb_work(struct k_work *work)
{
	struct wncm14a2a_socket *sock = NULL;
	struct net_pkt *pkt;

	sock = CONTAINER_OF(work, struct wncm14a2a_socket, recv_cb_work);

	/* return data */
	pkt = sock->recv_pkt;
	sock->recv_pkt = NULL;
	if (sock->recv_cb) {
		sock->recv_cb(sock->context, pkt, NULL, NULL,
			      0, sock->recv_user_data);
	} else {
		net_pkt_unref(pkt);
	}
}

/* Handler: @SOCKREAD:<actual_length>,"<hex encoded binary>" */
static void on_cmd_sockread(struct net_buf **buf, uint16_t len)
{
	struct wncm14a2a_socket *sock = NULL;
	uint8_t c = 0U;
	int i, actual_length, hdr_len = 0;
	size_t value_size;
	char value[10];

	/* first comma marks the end of actual_length */
	i = 0;
	value_size = sizeof(value);
	(void)memset(value, 0, value_size);
	while (*buf && i < value_size - 1) {
		value[i++] = net_buf_pull_u8(*buf);
		len--;
		if (!(*buf)->len) {
			*buf = net_buf_frag_del(NULL, *buf);
		}

		if (value[i-1] == ',') {
			i--;
			break;
		}
	}

	/* make sure we still have buf data, the last pulled character was
	 * a comma and that the next char in the buffer is a quote.
	 */
	if (!*buf || value[i] != ',' || *(*buf)->data != '\"') {
		LOG_ERR("Incorrect format! Ignoring data!");
		return;
	}

	/* clear the comma */
	value[i] = '\0';
	actual_length = atoi(value);

	/* skip quote */
	len--;
	net_buf_pull_u8(*buf);
	if (!(*buf)->len) {
		*buf = net_buf_frag_del(NULL, *buf);
	}

	/* check that we have enough data */
	if (!*buf || len > (actual_length * 2) + 1) {
		LOG_ERR("Incorrect format! Ignoring data!");
		return;
	}

	sock = socket_from_id(ictx.last_socket_id);
	if (!sock) {
		LOG_ERR("Socket not found! (%d)", ictx.last_socket_id);
		return;
	}

	/* allocate an RX pkt */
	sock->recv_pkt = net_pkt_rx_alloc_with_buffer(
			net_context_get_iface(sock->context),
			actual_length, sock->family, sock->ip_proto,
			BUF_ALLOC_TIMEOUT);
	if (!sock->recv_pkt) {
		LOG_ERR("Failed net_pkt_get_reserve_rx!");
		return;
	}

	/* set pkt data */
	net_pkt_set_context(sock->recv_pkt, sock->context);

	/* add IP / protocol headers */
	hdr_len = pkt_setup_ip_data(sock->recv_pkt, sock);

	/* move hex encoded data from the buffer to the recv_pkt */
	for (i = 0; i < actual_length * 2; i++) {
		char c2 = *(*buf)->data;

		if (isdigit(c2)) {
			c += c2 - '0';
		} else if (isalpha(c2)) {
			c += c2 - (isupper(c2) ? 'A' - 10 : 'a' - 10);
		} else {
			/* TODO: unexpected input! skip? */
		}

		if (i % 2) {
			if (net_pkt_write_u8(sock->recv_pkt, c)) {
				LOG_ERR("Unable to add data! Aborting!");
				net_pkt_unref(sock->recv_pkt);
				sock->recv_pkt = NULL;
				return;
			}

			c = 0U;
		} else {
			c = c << 4;
		}

		/* pull data from buf and advance to the next frag if needed */
		net_buf_pull_u8(*buf);
		if (!(*buf)->len) {
			*buf = net_buf_frag_del(NULL, *buf);
		}
	}

	net_pkt_cursor_init(sock->recv_pkt);
	net_pkt_set_overwrite(sock->recv_pkt, true);

	if (hdr_len > 0) {
		net_pkt_skip(sock->recv_pkt, hdr_len);
	}

	/* Let's do the callback processing in a different work queue in
	 * case the app takes a long time.
	 */
	k_work_submit_to_queue(&wncm14a2a_workq, &sock->recv_cb_work);
}

/* Handler: @SOCKDATAIND: <socket_id>,<session_status>,<left_bytes> */
static void on_cmd_sockdataind(struct net_buf **buf, uint16_t len)
{
	int socket_id, session_status, left_bytes;
	size_t out_len;
	char *delim1, *delim2;
	char value[sizeof("#,#,#####\r")];
	char sendbuf[sizeof("AT@SOCKREAD=#,#####\r")];
	struct wncm14a2a_socket *sock = NULL;

	out_len = net_buf_linearize(value, sizeof(value) - 1, *buf, 0, len);
	value[out_len] = 0;

	/* First comma separator marks the end of socket_id */
	delim1 = strchr(value, ',');
	if (!delim1) {
		LOG_ERR("Missing 1st comma");
		return;
	}

	*delim1++ = '\0';
	socket_id = atoi(value);

	/* Second comma separator marks the end of session_status */
	/* TODO: ignore for now, but maybe this is useful? */
	delim2 = strchr(delim1, ',');
	if (!delim2) {
		LOG_ERR("Missing 2nd comma");
		return;
	}

	*delim2++ = '\0';
	session_status = atoi(delim1);

	/* Third param is for left_bytes */
	/* TODO: ignore for now because we ask for max data len
	 * but maybe this is useful in the future?
	 */
	left_bytes = atoi(delim2);

	sock = socket_from_id(socket_id);
	if (!sock) {
		LOG_ERR("Unable to find socket_id:%d", socket_id);
		return;
	}

	if (left_bytes > 0) {
		LOG_DBG("socket_id:%d left_bytes:%d", socket_id, left_bytes);
		snprintk(sendbuf, sizeof(sendbuf), "AT@SOCKREAD=%d,%d",
			 sock->socket_id, left_bytes);

		/* We entered this trigger due to an unsolicited modem response.
		 * When we send the AT@SOCKREAD command it won't generate an
		 * "OK" response directly.  The modem will respond with
		 * "@SOCKREAD ..." and the data requested and then "OK" or
		 * "ERROR".  Let's not wait here by passing in a timeout to
		 * send_at_cmd().  Instead, when the resulting response is
		 * received, we trigger on_cmd_sockread() to handle it.
		 */
		send_at_cmd(sock, sendbuf, 0);
	}
}

static void on_cmd_socknotifyev(struct net_buf **buf, uint16_t len)
{
	char value[40];
	size_t out_len;
	int p1 = 0, p2 = 0;

	out_len = net_buf_linearize(value, sizeof(value) - 1, *buf, 0, len);
	value[out_len] = 0;

	/* walk value till 1st quote */
	while (p1 < len && value[p1] != '\"') {
		p1++;
	}

	if (value[p1] != '\"') {
		/* 1st quote not found */
		return;
	}

	p1++;
	p2 = p1;
	while (p2 < len && value[p2] != '\"') {
		p2++;
	}

	if (value[p2] != '\"') {
		/* 2nd quote not found */
		return;
	}

	/* clear quote */
	value[p2] = '\0';
	p2++;

	/* skip comma if present */
	if (value[p2] == ',') {
		p2++;
	}

	/* CSPS: 0: Moved to PS mode, 1: Moved to CS/PS mode */
	if (!strncmp(&value[p1], "CSPS", 4)) {
		ictx.ev_csps = atoi(&value[p2]);
		/* This also signifies that RRCSTATE = 1 */
		ictx.ev_rrcstate = 1;
		LOG_DBG("CSPS:%d", ictx.ev_csps);
	/* RRCSTATE: 0: RRC Idle, 1: RRC Connected, 2: RRC Unknown */
	} else if (!strncmp(&value[p1], "RRCSTATE", 8)) {
		ictx.ev_rrcstate = atoi(&value[p2]);
		LOG_DBG("RRCSTATE:%d", ictx.ev_rrcstate);
	} else if (!strncmp(&value[p1], "LTIME", 5)) {
		/* local time from network */
		LOG_INF("LTIME:%s", &value[p2]);
	} else if (!strncmp(&value[p1], "SIB1", 4)) {
		/* do nothing? */
		LOG_DBG("SIB1");
	} else {
		LOG_DBG("UNHANDLED: [%s:%s]", &value[p1], &value[p2]);
	}
}

static int net_buf_ncmp(struct net_buf *buf, const uint8_t *s2, size_t n)
{
	struct net_buf *frag = buf;
	uint16_t offset = 0U;

	while ((n > 0) && (*(frag->data + offset) == *s2) && (*s2 != '\0')) {
		if (offset == frag->len) {
			if (!frag->frags) {
				break;
			}
			frag = frag->frags;
			offset = 0U;
		} else {
			offset++;
		}

		s2++;
		n--;
	}

	return (n == 0) ? 0 : (*(frag->data + offset) - *s2);
}

static inline struct net_buf *read_rx_allocator(k_timeout_t timeout,
						void *user_data)
{
	return net_buf_alloc((struct net_buf_pool *)user_data, timeout);
}

static void wncm14a2a_read_rx(struct net_buf **buf)
{
	uint8_t uart_buffer[MDM_RECV_BUF_SIZE];
	size_t bytes_read = 0;
	int ret;
	uint16_t rx_len;

	/* read all of the data from mdm_receiver */
	while (true) {
		ret = mdm_receiver_recv(&ictx.mdm_ctx,
					uart_buffer,
					sizeof(uart_buffer),
					&bytes_read);
		if (ret < 0 || bytes_read == 0) {
			/* mdm_receiver buffer is empty */
			break;
		}

		hexdump(uart_buffer, bytes_read);

		/* make sure we have storage */
		if (!*buf) {
			*buf = net_buf_alloc(&mdm_recv_pool, BUF_ALLOC_TIMEOUT);
			if (!*buf) {
				LOG_ERR("Can't allocate RX data! "
					    "Skipping data!");
				break;
			}
		}

		rx_len = net_buf_append_bytes(*buf, bytes_read, uart_buffer,
					      BUF_ALLOC_TIMEOUT,
					      read_rx_allocator,
					      &mdm_recv_pool);
		if (rx_len < bytes_read) {
			LOG_ERR("Data was lost! read %u of %zu!",
				    rx_len, bytes_read);
		}
	}
}

/* RX thread */
static void wncm14a2a_rx(void)
{
	struct net_buf *rx_buf = NULL;
	struct net_buf *frag = NULL;
	int i;
	uint16_t offset, len;

	static const struct cmd_handler handlers[] = {
		/* NON-SOCKET COMMAND ECHOES to clear last_socket_id */
		CMD_HANDLER("ATE1", atcmdecho_nosock),
		CMD_HANDLER("AT%PDNSET=", atcmdecho_nosock),
		CMD_HANDLER("ATI", atcmdecho_nosock),
		CMD_HANDLER("AT+CGSN", atcmdecho_nosock_imei),
		CMD_HANDLER("AT%MEAS=", atcmdecho_nosock),
		CMD_HANDLER("AT@INTERNET=", atcmdecho_nosock),
		CMD_HANDLER("AT@SOCKDIAL=", atcmdecho_nosock),
		CMD_HANDLER("AT@SOCKCREAT=", atcmdecho_nosock),

		/* SOCKET COMMAND ECHOES for last_socket_id processing */
		CMD_HANDLER("AT@SOCKCONN=", atcmdecho),
		CMD_HANDLER("AT@SOCKWRITE=", atcmdecho),
		CMD_HANDLER("AT@SOCKREAD=", atcmdecho),
		CMD_HANDLER("AT@SOCKCLOSE=", atcmdecho),

		/* MODEM Information */
		CMD_HANDLER("Manufacturer: ", atcmdinfo_manufacturer),
		CMD_HANDLER("Model: ", atcmdinfo_model),
		CMD_HANDLER("Revision: ", atcmdinfo_revision),
		CMD_HANDLER("%MEAS: RSSI:", atcmdinfo_rssi),

		/* SOLICITED SOCKET RESPONSES */
		CMD_HANDLER("OK", sockok),
		CMD_HANDLER("ERROR", sockerror),
		CMD_HANDLER("@EXTERR:", sockexterror),
		CMD_HANDLER("@SOCKDIAL:", sockdial),
		CMD_HANDLER("@SOCKCREAT:", sockcreat),
		CMD_HANDLER("@OCKCREAT:", sockcreat), /* seeing this a lot */
		CMD_HANDLER("@SOCKWRITE:", sockwrite),
		CMD_HANDLER("@SOCKREAD:", sockread),

		/* UNSOLICITED SOCKET RESPONSES */
		CMD_HANDLER("@SOCKDATAIND:", sockdataind),
		CMD_HANDLER("%NOTIFYEV:", socknotifyev),
	};

	while (true) {
		/* wait for incoming data */
		(void)k_sem_take(&ictx.mdm_ctx.rx_sem, K_FOREVER);

		wncm14a2a_read_rx(&rx_buf);

		while (rx_buf) {
			net_buf_skipcrlf(&rx_buf);
			if (!rx_buf) {
				break;
			}

			frag = NULL;
			len = net_buf_findcrlf(rx_buf, &frag, &offset);
			if (!frag) {
				break;
			}

			/* look for matching data handlers */
			i = -1;
			for (i = 0; i < ARRAY_SIZE(handlers); i++) {
				if (net_buf_ncmp(rx_buf, handlers[i].cmd,
						 handlers[i].cmd_len) == 0) {
					/* found a matching handler */
					LOG_DBG("MATCH %s (len:%u)",
						    handlers[i].cmd, len);

					/* skip cmd_len */
					rx_buf = net_buf_skip(rx_buf,
							handlers[i].cmd_len);

					/* locate next cr/lf */
					frag = NULL;
					len = net_buf_findcrlf(rx_buf,
							       &frag, &offset);
					if (!frag) {
						break;
					}

					/* call handler */
					if (handlers[i].func) {
						handlers[i].func(&rx_buf, len);
					}

					frag = NULL;
					/* make sure buf still has data */
					if (!rx_buf) {
						break;
					}

					/*
					 * We've handled the current line
					 * and need to exit the "search for
					 * handler loop".  Let's skip any
					 * "extra" data and look for the next
					 * CR/LF, leaving us ready for the
					 * next handler search.  Ignore the
					 * length returned.
					 */
					(void)net_buf_findcrlf(rx_buf,
							       &frag, &offset);
					break;
				}
			}

			if (frag && rx_buf) {
				/* clear out processed line (buffers) */
				while (frag && rx_buf != frag) {
					rx_buf = net_buf_frag_del(NULL, rx_buf);
				}

				net_buf_pull(rx_buf, offset);
			}
		}

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

static int modem_pin_init(void)
{
	LOG_INF("Setting Modem Pins");

	/* Hard reset the modem (>5 seconds required)
	 * (doesn't go through the signal level translator)
	 */
	LOG_DBG("MDM_RESET_PIN -> ASSERTED");
	gpio_pin_set_raw(ictx.gpio_port_dev[MDM_RESET],
			 pinconfig[MDM_RESET].pin, MDM_RESET_ASSERTED);
	k_sleep(K_SECONDS(7));
	LOG_DBG("MDM_RESET_PIN -> NOT_ASSERTED");
	gpio_pin_set_raw(ictx.gpio_port_dev[MDM_RESET],
			 pinconfig[MDM_RESET].pin, MDM_RESET_NOT_ASSERTED);

	/* disable signal level translator (necessary
	 * for the modem to boot properly).  All signals
	 * except mdm_reset go through the level translator
	 * and have internal pull-up/down in the module. While
	 * the level translator is disabled, these pins will
	 * be in the correct state.
	 */
	LOG_DBG("SIG_TRANS_ENA_PIN -> DISABLED");
	gpio_pin_set_raw(ictx.gpio_port_dev[SHLD_3V3_1V8_SIG_TRANS_ENA],
			 pinconfig[SHLD_3V3_1V8_SIG_TRANS_ENA].pin,
			 SHLD_3V3_1V8_SIG_TRANS_DISABLED);

	/* While the level translator is disabled and output pins
	 * are tristated, make sure the inputs are in the same state
	 * as the WNC Module pins so that when the level translator is
	 * enabled, there are no differences.
	 */
	LOG_DBG("MDM_BOOT_MODE_SEL_PIN -> NORMAL");
	gpio_pin_set_raw(ictx.gpio_port_dev[MDM_BOOT_MODE_SEL],
			 pinconfig[MDM_BOOT_MODE_SEL].pin,
			 MDM_BOOT_MODE_NORMAL);
	LOG_DBG("MDM_POWER_PIN -> ENABLE");
	gpio_pin_set_raw(ictx.gpio_port_dev[MDM_POWER],
			 pinconfig[MDM_POWER].pin,
			 MDM_POWER_ENABLE);
	LOG_DBG("MDM_KEEP_AWAKE_PIN -> ENABLED");
	gpio_pin_set_raw(ictx.gpio_port_dev[MDM_KEEP_AWAKE],
			 pinconfig[MDM_KEEP_AWAKE].pin,
			 MDM_KEEP_AWAKE_ENABLED);
#if DT_INST_NODE_HAS_PROP(0, mdm_send_ok_gpios)
	LOG_DBG("MDM_SEND_OK_PIN -> ENABLED");
	gpio_pin_set_raw(ictx.gpio_port_dev[MDM_SEND_OK],
			 pinconfig[MDM_SEND_OK].pin,
			 MDM_SEND_OK_ENABLED);
#endif

	/* wait for the WNC Module to perform its initial boot correctly */
	k_sleep(K_SECONDS(1));

	/* Enable the level translator.
	 * The input pins should now be the same as how the M14A module is
	 * driving them with internal pull ups/downs.
	 * When enabled, there will be no changes in the above 4 pins...
	 */
	LOG_DBG("SIG_TRANS_ENA_PIN -> ENABLED");
	gpio_pin_set_raw(ictx.gpio_port_dev[SHLD_3V3_1V8_SIG_TRANS_ENA],
			 pinconfig[SHLD_3V3_1V8_SIG_TRANS_ENA].pin,
			 SHLD_3V3_1V8_SIG_TRANS_ENABLED);

	LOG_INF("... Done!");

	return 0;
}

static void modem_wakeup_pin_fix(void)
{
	/* AT&T recommend toggling the KEEP_AWAKE signal to reduce missed
	 * UART characters.
	 */
	LOG_DBG("Toggling MDM_KEEP_AWAKE_PIN to avoid missed characters");
	k_sleep(K_MSEC(20));
	LOG_DBG("MDM_KEEP_AWAKE_PIN -> DISABLED");
	gpio_pin_set_raw(ictx.gpio_port_dev[MDM_KEEP_AWAKE],
			 pinconfig[MDM_KEEP_AWAKE].pin,
			 MDM_KEEP_AWAKE_DISABLED);
	k_sleep(K_SECONDS(2));
	LOG_DBG("MDM_KEEP_AWAKE_PIN -> ENABLED");
	gpio_pin_set_raw(ictx.gpio_port_dev[MDM_KEEP_AWAKE],
			 pinconfig[MDM_KEEP_AWAKE].pin,
			 MDM_KEEP_AWAKE_ENABLED);
	k_sleep(K_MSEC(20));
}

static void wncm14a2a_rssi_query_work(struct k_work *work)
{
	int ret;

	/* query modem RSSI */
	ret = send_at_cmd(NULL, "AT%MEAS=\"23\"", MDM_CMD_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("AT%%MEAS ret:%d", ret);
	}

	/* re-start RSSI query work */
	k_work_reschedule_for_queue(&wncm14a2a_workq, &ictx.rssi_query_work,
				    K_SECONDS(RSSI_TIMEOUT_SECS));
}

static void wncm14a2a_modem_reset(void)
{
	int ret = 0, retry_count = 0, counter = 0;

	/* bring down network interface */
	net_if_flag_clear(ictx.iface, NET_IF_UP);

restart:
	/* stop RSSI delay work */
	k_work_cancel_delayable(&ictx.rssi_query_work);

	modem_pin_init();

	LOG_INF("Waiting for modem to respond");

	/* Give the modem a while to start responding to simple 'AT' commands.
	 * Also wait for CSPS=1 or RRCSTATE=1 notification
	 */
	ret = -1;
	while (counter++ < 50 && ret < 0) {
		k_sleep(K_SECONDS(2));
		ret = send_at_cmd(NULL, "AT", MDM_CMD_TIMEOUT);
		if (ret < 0 && ret != -ETIMEDOUT) {
			break;
		}
	}

	if (ret < 0) {
		LOG_ERR("MODEM WAIT LOOP ERROR: %d", ret);
		goto error;
	}

	LOG_INF("Setting modem to always stay awake");
	modem_wakeup_pin_fix();

	ret = send_at_cmd(NULL, "ATE1", MDM_CMD_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("ATE1 ret:%d", ret);
		goto error;
	}

	ret = send_at_cmd(NULL, "AT%PDNSET=1,\"" CONFIG_MODEM_WNCM14A2A_APN_NAME
			  "\",\"IPV4V6\"", MDM_CMD_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("AT%%PDNSET ret:%d", ret);
		goto error;
	}

	/* query modem info */
	LOG_INF("Querying modem information");
	ret = send_at_cmd(NULL, "ATI", MDM_CMD_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("ATI ret:%d", ret);
		goto error;
	}

	/* query modem IMEI */
	ret = send_at_cmd(NULL, "AT+CGSN", MDM_CMD_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("AT+CGSN ret:%d", ret);
		goto error;
	}

	LOG_INF("Waiting for network");

	/* query modem RSSI */
	wncm14a2a_rssi_query_work(NULL);
	k_sleep(K_SECONDS(2));

	counter = 0;
	/* wait for RSSI > -1000 and != 0 */
	while (counter++ < 15 &&
	       (ictx.mdm_rssi <= -1000 ||
		ictx.mdm_rssi == 0)) {
		/* stop RSSI delay work */
		k_work_cancel_delayable(&ictx.rssi_query_work);
		wncm14a2a_rssi_query_work(NULL);
		k_sleep(K_SECONDS(2));
	}

	if (ictx.mdm_rssi <= -1000 || ictx.mdm_rssi == 0) {
		retry_count++;
		if (retry_count > 3) {
			LOG_ERR("Failed network init.  Too many attempts!");
			ret = -ENETUNREACH;
			goto error;
		}

		LOG_ERR("Failed network init.  Restarting process.");
		goto restart;
	}

	LOG_INF("Network is ready.");

	ret = send_at_cmd(NULL, "AT@INTERNET=1", MDM_CMD_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("AT@INTERNET ret:%d", ret);
		goto error;
	}

	ret = send_at_cmd(NULL, "AT@SOCKDIAL=1", MDM_CMD_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("SOCKDIAL=1 CHECK ret:%d", ret);
		/* don't report this as an error, we retry later */
		ret = 0;
	}

	/* Set iface up */
	net_if_up(ictx.iface);

error:
	return;
}

static int wncm14a2a_init(const struct device *dev)
{
	int i, ret = 0;

	ARG_UNUSED(dev);

	/* check for valid pinconfig */
	__ASSERT(ARRAY_SIZE(pinconfig) == MAX_MDM_CONTROL_PINS,
	       "Incorrect modem pinconfig!");

	(void)memset(&ictx, 0, sizeof(ictx));
	for (i = 0; i < MDM_MAX_SOCKETS; i++) {
		k_work_init(&ictx.sockets[i].recv_cb_work,
			    sockreadrecv_cb_work);
		k_sem_init(&ictx.sockets[i].sock_send_sem, 0, 1);
	}
	k_sem_init(&ictx.response_sem, 0, 1);

	/* initialize the work queue */
	k_work_queue_start(&wncm14a2a_workq, wncm14a2a_workq_stack,
			   K_KERNEL_STACK_SIZEOF(wncm14a2a_workq_stack),
			   K_PRIO_COOP(7), NULL);

	ictx.last_socket_id = 0;

	/* setup port devices and pin directions */
	for (i = 0; i < MAX_MDM_CONTROL_PINS; i++) {
		ictx.gpio_port_dev[i] =
				device_get_binding(pinconfig[i].dev_name);
		if (!ictx.gpio_port_dev[i]) {
			LOG_ERR("gpio port (%s) not found!",
				    pinconfig[i].dev_name);
			return -ENODEV;
		}

		gpio_pin_configure(ictx.gpio_port_dev[i], pinconfig[i].pin,
				   pinconfig[i].flags | GPIO_OUTPUT);
	}

	/* Set modem data storage */
	ictx.mdm_ctx.data_manufacturer = ictx.mdm_manufacturer;
	ictx.mdm_ctx.data_model = ictx.mdm_model;
	ictx.mdm_ctx.data_revision = ictx.mdm_revision;
#ifdef CONFIG_MODEM_SIM_NUMBERS
	ictx.mdm_ctx.data_imei = ictx.mdm_imei;
#endif
	ictx.mdm_ctx.data_rssi = &ictx.mdm_rssi;

	ret = mdm_receiver_register(&ictx.mdm_ctx, MDM_UART_DEV,
				    mdm_recv_buf, sizeof(mdm_recv_buf));
	if (ret < 0) {
		LOG_ERR("Error registering modem receiver (%d)!", ret);
		goto error;
	}

	/* start RX thread */
	k_thread_create(&wncm14a2a_rx_thread, wncm14a2a_rx_stack,
			K_KERNEL_STACK_SIZEOF(wncm14a2a_rx_stack),
			(k_thread_entry_t) wncm14a2a_rx,
			NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);

	/* init RSSI query */
	k_work_init_delayable(&ictx.rssi_query_work, wncm14a2a_rssi_query_work);

	wncm14a2a_modem_reset();

error:
	return ret;
}

/*** OFFLOAD FUNCTIONS ***/

static int offload_get(sa_family_t family,
		       enum net_sock_type type,
		       enum net_ip_protocol ip_proto,
		       struct net_context **context)
{
	int ret;
	char buf[sizeof("AT@SOCKCREAT=#,#\r")];
	struct wncm14a2a_socket *sock = NULL;

	/* new socket */
	sock = socket_get();
	if (!sock) {
		return -ENOMEM;
	}

	(*context)->offload_context = sock;
	sock->family = family;
	sock->type = type;
	sock->ip_proto = ip_proto;
	sock->context = *context;
	sock->socket_id = MDM_MAX_SOCKETS + 1; /* socket # needs assigning */

	snprintk(buf, sizeof(buf), "AT@SOCKCREAT=%d,%d", type,
		 family == AF_INET ? 0 : 1);
	ret = send_at_cmd(NULL, buf, MDM_CMD_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("AT@SOCKCREAT ret:%d", ret);
		socket_put(sock);
	}

	return ret;
}

static int offload_bind(struct net_context *context,
			const struct sockaddr *addr,
			socklen_t addrlen)
{
	struct wncm14a2a_socket *sock = NULL;

	if (!context) {
		return -EINVAL;
	}

	sock = (struct wncm14a2a_socket *)context->offload_context;
	if (!sock) {
		LOG_ERR("Can't locate socket for net_ctx:%p!", context);
		return -EINVAL;
	}

	/* save bind address information */
	sock->src.sa_family = addr->sa_family;
#if defined(CONFIG_NET_IPV6)
	if (addr->sa_family == AF_INET6) {
		net_ipaddr_copy(&net_sin6(&sock->src)->sin6_addr,
				&net_sin6(addr)->sin6_addr);
		net_sin6(&sock->src)->sin6_port = net_sin6(addr)->sin6_port;
	} else
#endif
#if defined(CONFIG_NET_IPV4)
	if (addr->sa_family == AF_INET) {
		net_ipaddr_copy(&net_sin(&sock->src)->sin_addr,
				&net_sin(addr)->sin_addr);
		net_sin(&sock->src)->sin_port = net_sin(addr)->sin_port;
	} else
#endif
	{
		return -EPFNOSUPPORT;
	}

	return 0;
}

static int offload_listen(struct net_context *context, int backlog)
{
	/* NOT IMPLEMENTED */
	return -ENOTSUP;
}

static int offload_connect(struct net_context *context,
			   const struct sockaddr *addr,
			   socklen_t addrlen,
			   net_context_connect_cb_t cb,
			   int32_t timeout,
			   void *user_data)
{
	int ret, dst_port = -1;
	int32_t timeout_sec = -1; /* if not changed, this will be min timeout */
	char buf[sizeof("AT@SOCKCONN=#,###.###.###.###,#####,#####\r")];
	struct wncm14a2a_socket *sock;

	if (timeout > 0) {
		timeout_sec = timeout / MSEC_PER_SEC;
	}

	if (!context || !addr) {
		return -EINVAL;
	}

	sock = (struct wncm14a2a_socket *)context->offload_context;
	if (!sock) {
		LOG_ERR("Can't locate socket for net_ctx:%p!", context);
		return -EINVAL;
	}

	if (sock->socket_id < 1) {
		LOG_ERR("Invalid socket_id(%d) for net_ctx:%p!",
			    sock->socket_id, context);
		return -EINVAL;
	}

	sock->dst.sa_family = addr->sa_family;

#if defined(CONFIG_NET_IPV6)
	if (addr->sa_family == AF_INET6) {
		net_ipaddr_copy(&net_sin6(&sock->dst)->sin6_addr,
				&net_sin6(addr)->sin6_addr);
		dst_port = ntohs(net_sin6(addr)->sin6_port);
		net_sin6(&sock->dst)->sin6_port = dst_port;
	} else
#endif
#if defined(CONFIG_NET_IPV4)
	if (addr->sa_family == AF_INET) {
		net_ipaddr_copy(&net_sin(&sock->dst)->sin_addr,
				&net_sin(addr)->sin_addr);
		dst_port = ntohs(net_sin(addr)->sin_port);
		net_sin(&sock->dst)->sin_port = dst_port;
	} else
#endif
	{
		return -EINVAL;
	}

	if (dst_port < 0) {
		LOG_ERR("Invalid port: %d", dst_port);
		return -EINVAL;
	}

	/*
	 * AT@SOCKCONN timeout param has minimum value of 30 seconds and
	 * maximum value of 360 seconds, otherwise an error is generated
	 */
	timeout_sec = CLAMP(timeout_sec, 30, 360);

	snprintk(buf, sizeof(buf), "AT@SOCKCONN=%d,\"%s\",%d,%d",
		 sock->socket_id, wncm14a2a_sprint_ip_addr(addr),
		 dst_port, timeout_sec);
	ret = send_at_cmd(sock, buf, MDM_CMD_CONN_TIMEOUT);
	if (!ret) {
		net_context_set_state(sock->context, NET_CONTEXT_CONNECTED);
	} else {
		LOG_ERR("AT@SOCKCONN ret:%d", ret);
	}

	if (cb) {
		cb(context, ret, user_data);
	}

	return ret;
}

static int offload_accept(struct net_context *context,
			  net_tcp_accept_cb_t cb,
			  int32_t timeout,
			  void *user_data)
{
	/* NOT IMPLEMENTED */
	return -ENOTSUP;
}

static int offload_sendto(struct net_pkt *pkt,
			  const struct sockaddr *dst_addr,
			  socklen_t addrlen,
			  net_context_send_cb_t cb,
			  int32_t timeout,
			  void *user_data)
{
	struct net_context *context = net_pkt_context(pkt);
	struct wncm14a2a_socket *sock;
	int ret = 0;

	if (!context) {
		return -EINVAL;
	}

	sock = (struct wncm14a2a_socket *)context->offload_context;
	if (!sock) {
		LOG_ERR("Can't locate socket for net_ctx:%p!", context);
		return -EINVAL;
	}

	ret = send_data(sock, pkt);
	if (ret < 0) {
		LOG_ERR("send_data error: %d", ret);
	} else {
		net_pkt_unref(pkt);
	}

	if (cb) {
		cb(context, ret, user_data);
	}

	return ret;
}

static int offload_send(struct net_pkt *pkt,
			net_context_send_cb_t cb,
			int32_t timeout,
			void *user_data)
{
	struct net_context *context = net_pkt_context(pkt);
	socklen_t addrlen;

	addrlen = 0;
#if defined(CONFIG_NET_IPV6)
	if (net_pkt_family(pkt) == AF_INET6) {
		addrlen = sizeof(struct sockaddr_in6);
	} else
#endif /* CONFIG_NET_IPV6 */
#if defined(CONFIG_NET_IPV4)
	if (net_pkt_family(pkt) == AF_INET) {
		addrlen = sizeof(struct sockaddr_in);
	} else
#endif /* CONFIG_NET_IPV4 */
	{
		return -EPFNOSUPPORT;
	}

	return offload_sendto(pkt, &context->remote, addrlen, cb,
			      timeout, user_data);
}

static int offload_recv(struct net_context *context,
			net_context_recv_cb_t cb,
			int32_t timeout,
			void *user_data)
{
	struct wncm14a2a_socket *sock;

	if (!context) {
		return -EINVAL;
	}

	sock = (struct wncm14a2a_socket *)context->offload_context;
	if (!sock) {
		LOG_ERR("Can't locate socket for net_ctx:%p!", context);
		return -EINVAL;
	}

	sock->recv_cb = cb;
	sock->recv_user_data = user_data;

	return 0;
}

static int offload_put(struct net_context *context)
{
	struct wncm14a2a_socket *sock;
	char buf[sizeof("AT@SOCKCLOSE=#\r")];
	int ret;

	if (!context) {
		return -EINVAL;
	}

	sock = (struct wncm14a2a_socket *)context->offload_context;
	if (!sock) {
		/* socket was already closed?  Exit quietly here. */
		return 0;
	}

	snprintk(buf, sizeof(buf), "AT@SOCKCLOSE=%d", sock->socket_id);

	ret = send_at_cmd(sock, buf, MDM_CMD_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("AT@SOCKCLOSE ret:%d", ret);
	}

	/* clear last_socket_id */
	ictx.last_socket_id = 0;

	socket_put(sock);
	net_context_unref(context);
	if (sock->type == SOCK_STREAM) {
		/* TCP contexts are referenced twice,
		 *  once for the app and once for the stack.
		 *  Since TCP stack is not used for offload,
		 *  unref a second time.
		 */
		net_context_unref(context);
	}

	return 0;
}

static struct net_offload offload_funcs = {
	.get = offload_get,
	.bind = offload_bind,
	.listen = offload_listen,	/* TODO */
	.connect = offload_connect,
	.accept = offload_accept,	/* TODO */
	.send = offload_send,
	.sendto = offload_sendto,
	.recv = offload_recv,
	.put = offload_put,
};

static inline uint8_t *wncm14a2a_get_mac(const struct device *dev)
{
	struct wncm14a2a_iface_ctx *ctx = dev->data;

	ctx->mac_addr[0] = 0x00;
	ctx->mac_addr[1] = 0x10;

	UNALIGNED_PUT(sys_cpu_to_be32(sys_rand32_get()),
		      (uint32_t *)(ctx->mac_addr + 2));

	return ctx->mac_addr;
}

static void offload_iface_init(struct net_if *iface)
{
	const struct device *dev = net_if_get_device(iface);
	struct wncm14a2a_iface_ctx *ctx = dev->data;

	iface->if_dev->offload = &offload_funcs;
	net_if_set_link_addr(iface, wncm14a2a_get_mac(dev),
			     sizeof(ctx->mac_addr),
			     NET_LINK_ETHERNET);
	ctx->iface = iface;
}

static struct net_if_api api_funcs = {
	.init	= offload_iface_init,
};

NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, wncm14a2a_init, NULL,
				  &ictx, NULL,
				  CONFIG_MODEM_WNCM14A2A_INIT_PRIORITY,
				  &api_funcs,
				  MDM_MAX_DATA_LENGTH);
