/*
 * 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 <zephyr/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/zephyr.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/random/rand32.h>

#include <zephyr/net/net_context.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/net_offload.h>
#include <zephyr/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);
