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

#define DT_DRV_COMPAT ublox_sara_r4

#include <logging/log.h>
LOG_MODULE_REGISTER(modem_ublox_sara_r4, CONFIG_MODEM_LOG_LEVEL);

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

#include <net/net_if.h>
#include <net/net_offload.h>
#include <net/socket_offload.h>

#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_APN)
#include <stdio.h>
#endif

#include "modem_context.h"
#include "modem_socket.h"
#include "modem_cmd_handler.h"
#include "modem_iface_uart.h"

#if !defined(CONFIG_MODEM_UBLOX_SARA_R4_MANUAL_MCCMNO)
#define CONFIG_MODEM_UBLOX_SARA_R4_MANUAL_MCCMNO ""
#endif

/* pin settings */
enum mdm_control_pins {
	MDM_POWER = 0,
	MDM_RESET,
#if DT_INST_NODE_HAS_PROP(0, mdm_vint_gpios)
	MDM_VINT,
#endif
};

static struct modem_pin modem_pins[] = {
	/* MDM_POWER */
	MODEM_PIN(DT_INST_GPIO_LABEL(0, mdm_power_gpios),
		  DT_INST_GPIO_PIN(0, mdm_power_gpios),
		  DT_INST_GPIO_FLAGS(0, mdm_power_gpios) | GPIO_OUTPUT),

	/* MDM_RESET */
	MODEM_PIN(DT_INST_GPIO_LABEL(0, mdm_reset_gpios),
		  DT_INST_GPIO_PIN(0, mdm_reset_gpios),
		  DT_INST_GPIO_FLAGS(0, mdm_reset_gpios) | GPIO_OUTPUT),

#if DT_INST_NODE_HAS_PROP(0, mdm_vint_gpios)
	/* MDM_VINT */
	MODEM_PIN(DT_INST_GPIO_LABEL(0, mdm_vint_gpios),
		  DT_INST_GPIO_PIN(0, mdm_vint_gpios),
		  DT_INST_GPIO_FLAGS(0, mdm_vint_gpios) | GPIO_INPUT),
#endif
};

#define MDM_UART_DEV_NAME		DT_INST_BUS_LABEL(0)
#define MDM_UART_NODE			DT_BUS(DT_DRV_INST(0))

#define MDM_POWER_ENABLE		1
#define MDM_POWER_DISABLE		0
#define MDM_RESET_NOT_ASSERTED		1
#define MDM_RESET_ASSERTED		0

#define MDM_CMD_TIMEOUT			K_SECONDS(10)
#define MDM_DNS_TIMEOUT			K_SECONDS(70)
#define MDM_CMD_CONN_TIMEOUT		K_SECONDS(120)
#define MDM_REGISTRATION_TIMEOUT	K_SECONDS(180)
#define MDM_PROMPT_CMD_DELAY		K_MSEC(50)

#define MDM_MAX_DATA_LENGTH		1024
#define MDM_RECV_MAX_BUF		30
#define MDM_RECV_BUF_SIZE		128

#define MDM_MAX_SOCKETS			6
#define MDM_BASE_SOCKET_NUM		0

#define MDM_NETWORK_RETRY_COUNT		3
#define MDM_WAIT_FOR_RSSI_COUNT		10
#define MDM_WAIT_FOR_RSSI_DELAY		K_SECONDS(2)

#define MDM_MANUFACTURER_LENGTH		10
#define MDM_MODEL_LENGTH		16
#define MDM_REVISION_LENGTH		64
#define MDM_IMEI_LENGTH			16
#define MDM_IMSI_LENGTH			16
#define MDM_APN_LENGTH			32

#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_VARIANT)
#define MDM_VARIANT_UBLOX_R4 4
#define MDM_VARIANT_UBLOX_U2 2
#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(modem_rx_stack,
		      CONFIG_MODEM_UBLOX_SARA_R4_RX_STACK_SIZE);
struct k_thread modem_rx_thread;

#if defined(CONFIG_MODEM_UBLOX_SARA_RSSI_WORK)
/* RX thread work queue */
K_KERNEL_STACK_DEFINE(modem_workq_stack,
		      CONFIG_MODEM_UBLOX_SARA_R4_RX_WORKQ_STACK_SIZE);
static struct k_work_q modem_workq;
#endif

/* socket read callback data */
struct socket_read_data {
	char *recv_buf;
	size_t recv_buf_len;
	struct sockaddr *recv_addr;
	uint16_t recv_read_len;
};

/* driver data */
struct modem_data {
	struct net_if *net_iface;
	uint8_t mac_addr[6];

	/* modem interface */
	struct modem_iface_uart_data iface_data;
	uint8_t iface_rb_buf[MDM_MAX_DATA_LENGTH];

	/* modem cmds */
	struct modem_cmd_handler_data cmd_handler_data;
	uint8_t cmd_match_buf[MDM_RECV_BUF_SIZE + 1];

	/* socket data */
	struct modem_socket_config socket_config;
	struct modem_socket sockets[MDM_MAX_SOCKETS];

#if defined(CONFIG_MODEM_UBLOX_SARA_RSSI_WORK)
	/* RSSI work */
	struct k_delayed_work rssi_query_work;
#endif

	/* 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];
	char mdm_imsi[MDM_IMSI_LENGTH];

#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_VARIANT)
	/* modem variant */
	int mdm_variant;
#endif
#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_APN)
	/* APN */
	char mdm_apn[MDM_APN_LENGTH];
#endif

	/* modem state */
	int ev_creg;

	/* bytes written to socket in last transaction */
	int sock_written;

	/* response semaphore */
	struct k_sem sem_response;

	/* prompt semaphore */
	struct k_sem sem_prompt;
};

static struct modem_data mdata;
static struct modem_context mctx;

#if defined(CONFIG_DNS_RESOLVER)
static struct zsock_addrinfo result;
static struct sockaddr result_addr;
static char result_canonname[DNS_MAX_NAME_SIZE + 1];
#endif

/* helper macro to keep readability */
#define ATOI(s_, value_, desc_) modem_atoi(s_, value_, desc_, __func__)

/**
 * @brief  Convert string to long integer, but handle errors
 *
 * @param  s: string with representation of integer number
 * @param  err_value: on error return this value instead
 * @param  desc: name the string being converted
 * @param  func: function where this is called (typically __func__)
 *
 * @retval return integer conversion on success, or err_value on error
 */
static int modem_atoi(const char *s, const int err_value,
		      const char *desc, const char *func)
{
	int ret;
	char *endptr;

	ret = (int)strtol(s, &endptr, 10);
	if (!endptr || *endptr != '\0') {
		LOG_ERR("bad %s '%s' in %s", log_strdup(s), log_strdup(desc),
			log_strdup(func));
		return err_value;
	}

	return ret;
}

#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_APN)

/* the list of SIM profiles. Global scope, so the app can change it */
const char *modem_sim_profiles =
	CONFIG_MODEM_UBLOX_SARA_AUTODETECT_APN_PROFILES;

int find_apn(char *apn, int apnlen, const char *profiles, const char *imsi)
{
	int rc = -1;

	/* try to find a match */
	char *s = strstr(profiles, imsi);

	if (s) {
		char *eos;

		/* find the assignment operator preceding the match */
		while (s >= profiles && !strchr("=", *s)) {
			s--;
		}
		/* find the apn preceding the assignment operator */
		while (s >= profiles && strchr(" =", *s)) {
			s--;
		}

		/* mark end of apn string */
		eos = s+1;

		/* find first character of the apn */
		while (s >= profiles && !strchr(" ,", *s)) {
			s--;
		}
		s++;

		/* copy the key */
		if (s >= profiles) {
			int len = eos - s;

			if (len < apnlen) {
				memcpy(apn, s, len);
				apn[len] = '\0';
				rc = 0;
			} else {
				LOG_ERR("buffer overflow");
			}
		}
	}

	return rc;
}

/* try to detect APN automatically, based on IMSI */
int modem_detect_apn(const char *imsi)
{
	int rc = -1;

	if (imsi != NULL && strlen(imsi) >= 5) {

		/* extract MMC and MNC from IMSI */
		char mmcmnc[6];
		*mmcmnc = 0;
		strncat(mmcmnc, imsi, sizeof(mmcmnc)-1);

		/* try to find a matching IMSI, and assign the APN */
		rc = find_apn(mdata.mdm_apn,
			sizeof(mdata.mdm_apn),
			modem_sim_profiles,
			mmcmnc);
		if (rc < 0) {
			rc = find_apn(mdata.mdm_apn,
				sizeof(mdata.mdm_apn),
				modem_sim_profiles,
				"*");
		}
	}

	if (rc == 0) {
		LOG_INF("Assign APN: \"%s\"", log_strdup(mdata.mdm_apn));
	}

	return rc;
}
#endif

/* Forward declaration */
MODEM_CMD_DEFINE(on_cmd_sockwrite);

/* send binary data via the +USO[ST/WR] commands */
static ssize_t send_socket_data(void *obj,
				const struct msghdr *msg,
				k_timeout_t timeout)
{
	int ret;
	char send_buf[sizeof("AT+USO**=#,!###.###.###.###!,#####,####\r\n")];
	uint16_t dst_port = 0U;
	struct modem_socket *sock = (struct modem_socket *)obj;
	const struct modem_cmd handler_cmds[] = {
		MODEM_CMD("+USOST: ", on_cmd_sockwrite, 2U, ","),
		MODEM_CMD("+USOWR: ", on_cmd_sockwrite, 2U, ","),
	};
	struct sockaddr *dst_addr = msg->msg_name;
	size_t buf_len = 0;

	for (int i = 0; i < msg->msg_iovlen; i++) {
		if (!msg->msg_iov[i].iov_base || msg->msg_iov[i].iov_len == 0) {
			errno = EINVAL;
			return -1;
		}
		buf_len += msg->msg_iov[i].iov_len;
	}

	if (!sock->is_connected && sock->ip_proto != IPPROTO_UDP) {
		errno = ENOTCONN;
		return -1;
	}

	if (!dst_addr && sock->ip_proto == IPPROTO_UDP) {
		dst_addr = &sock->dst;
	}

	if (!sock) {
		return -EINVAL;
	}

	/*
	 * Binary and ASCII mode allows sending MDM_MAX_DATA_LENGTH bytes to
	 * the socket in one command
	 */
	if (buf_len > MDM_MAX_DATA_LENGTH) {
		buf_len = MDM_MAX_DATA_LENGTH;
	}

	/* The number of bytes written will be reported by the modem */
	mdata.sock_written = 0;

	if (sock->ip_proto == IPPROTO_UDP) {
		ret = modem_context_get_addr_port(dst_addr, &dst_port);
		snprintk(send_buf, sizeof(send_buf),
			 "AT+USOST=%d,\"%s\",%u,%zu", sock->id,
			 modem_context_sprint_ip_addr(dst_addr),
			 dst_port, buf_len);
	} else {
		snprintk(send_buf, sizeof(send_buf), "AT+USOWR=%d,%zu",
			 sock->id, buf_len);
	}

	k_sem_take(&mdata.cmd_handler_data.sem_tx_lock, K_FOREVER);

	/* Reset prompt '@' semaphore */
	k_sem_reset(&mdata.sem_prompt);

	ret = modem_cmd_send_nolock(&mctx.iface, &mctx.cmd_handler,
				    NULL, 0U, send_buf, NULL, K_NO_WAIT);
	if (ret < 0) {
		goto exit;
	}

	/* set command handlers */
	ret = modem_cmd_handler_update_cmds(&mdata.cmd_handler_data,
					    handler_cmds,
					    ARRAY_SIZE(handler_cmds),
					    true);
	if (ret < 0) {
		goto exit;
	}

	/* Wait for prompt '@' */
	ret = k_sem_take(&mdata.sem_prompt, K_SECONDS(1));
	if (ret != 0) {
		ret = -ETIMEDOUT;
		LOG_ERR("No @ prompt received");
		goto exit;
	}

	/*
	 * The AT commands manual requires a 50 ms wait
	 * after '@' prompt if using AT+USOWR, but not
	 * if using AT+USOST. This if condition is matched with
	 * the command selection above.
	 */
	if (sock->ip_proto != IPPROTO_UDP) {
		k_sleep(MDM_PROMPT_CMD_DELAY);
	}

	/* Reset response semaphore before sending data
	 * So that we are sure that we won't use a previously pending one
	 * And we won't miss the one that is going to be freed
	 */
	k_sem_reset(&mdata.sem_response);

	/* Send data directly on modem iface */
	for (int i = 0; i < msg->msg_iovlen; i++) {
		int len = MIN(buf_len, msg->msg_iov[i].iov_len);

		if (len == 0) {
			break;
		}
		mctx.iface.write(&mctx.iface, msg->msg_iov[i].iov_base, len);
		buf_len -= len;
	}

	if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) {
		ret = 0;
		goto exit;
	}
	ret = k_sem_take(&mdata.sem_response, timeout);

	if (ret == 0) {
		ret = modem_cmd_handler_get_error(&mdata.cmd_handler_data);
	} else if (ret == -EAGAIN) {
		ret = -ETIMEDOUT;
	}

exit:
	/* unset handler commands and ignore any errors */
	(void)modem_cmd_handler_update_cmds(&mdata.cmd_handler_data,
					    NULL, 0U, false);
	k_sem_give(&mdata.cmd_handler_data.sem_tx_lock);

	if (ret < 0) {
		return ret;
	}

	return mdata.sock_written;
}

/*
 * Modem Response Command Handlers
 */

/* Handler: OK */
MODEM_CMD_DEFINE(on_cmd_ok)
{
	modem_cmd_handler_set_error(data, 0);
	k_sem_give(&mdata.sem_response);
	return 0;
}

/* Handler: @ */
MODEM_CMD_DEFINE(on_prompt)
{
	k_sem_give(&mdata.sem_prompt);

	/* A direct cmd should return the number of byte processed.
	 * Therefore, here we always return 1
	 */
	return 1;
}

/* Handler: ERROR */
MODEM_CMD_DEFINE(on_cmd_error)
{
	modem_cmd_handler_set_error(data, -EIO);
	k_sem_give(&mdata.sem_response);
	return 0;
}

/* Handler: +CME Error: <err>[0] */
MODEM_CMD_DEFINE(on_cmd_exterror)
{
	/* TODO: map extended error codes to values */
	modem_cmd_handler_set_error(data, -EIO);
	k_sem_give(&mdata.sem_response);
	return 0;
}

/*
 * Modem Info Command Handlers
 */

/* Handler: <manufacturer> */
MODEM_CMD_DEFINE(on_cmd_atcmdinfo_manufacturer)
{
	size_t out_len;

	out_len = net_buf_linearize(mdata.mdm_manufacturer,
				    sizeof(mdata.mdm_manufacturer) - 1,
				    data->rx_buf, 0, len);
	mdata.mdm_manufacturer[out_len] = '\0';
	LOG_INF("Manufacturer: %s", log_strdup(mdata.mdm_manufacturer));
	return 0;
}

/* Handler: <model> */
MODEM_CMD_DEFINE(on_cmd_atcmdinfo_model)
{
	size_t out_len;

	out_len = net_buf_linearize(mdata.mdm_model,
				    sizeof(mdata.mdm_model) - 1,
				    data->rx_buf, 0, len);
	mdata.mdm_model[out_len] = '\0';
	LOG_INF("Model: %s", log_strdup(mdata.mdm_model));

#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_VARIANT)
	/* Set modem type */
	if (strstr(mdata.mdm_model, "R4")) {
		mdata.mdm_variant = MDM_VARIANT_UBLOX_R4;
	} else {
		if (strstr(mdata.mdm_model, "U2")) {
			mdata.mdm_variant = MDM_VARIANT_UBLOX_U2;
		}
	}
	LOG_INF("Variant: %d", mdata.mdm_variant);
#endif

	return 0;
}

/* Handler: <rev> */
MODEM_CMD_DEFINE(on_cmd_atcmdinfo_revision)
{
	size_t out_len;

	out_len = net_buf_linearize(mdata.mdm_revision,
				    sizeof(mdata.mdm_revision) - 1,
				    data->rx_buf, 0, len);
	mdata.mdm_revision[out_len] = '\0';
	LOG_INF("Revision: %s", log_strdup(mdata.mdm_revision));
	return 0;
}

/* Handler: <IMEI> */
MODEM_CMD_DEFINE(on_cmd_atcmdinfo_imei)
{
	size_t out_len;

	out_len = net_buf_linearize(mdata.mdm_imei, sizeof(mdata.mdm_imei) - 1,
				    data->rx_buf, 0, len);
	mdata.mdm_imei[out_len] = '\0';
	LOG_INF("IMEI: %s", log_strdup(mdata.mdm_imei));
	return 0;
}

/* Handler: <IMSI> */
MODEM_CMD_DEFINE(on_cmd_atcmdinfo_imsi)
{
	size_t out_len;

	out_len = net_buf_linearize(mdata.mdm_imsi, sizeof(mdata.mdm_imsi) - 1,
				    data->rx_buf, 0, len);
	mdata.mdm_imsi[out_len] = '\0';
	LOG_INF("IMSI: %s", log_strdup(mdata.mdm_imsi));

#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_APN)
	/* set the APN automatically */
	modem_detect_apn(mdata.mdm_imsi);
#endif

	return 0;
}

#if !defined(CONFIG_MODEM_UBLOX_SARA_U2)
/*
 * Handler: +CESQ: <rxlev>[0],<ber>[1],<rscp>[2],<ecn0>[3],<rsrq>[4],<rsrp>[5]
 */
MODEM_CMD_DEFINE(on_cmd_atcmdinfo_rssi_cesq)
{
	int rsrp, rxlev;

	rsrp = ATOI(argv[5], 0, "rsrp");
	rxlev = ATOI(argv[0], 0, "rxlev");
	if (rsrp >= 0 && rsrp <= 97) {
		mctx.data_rssi = -140 + (rsrp - 1);
		LOG_INF("RSRP: %d", mctx.data_rssi);
	} else if (rxlev >= 0 && rxlev <= 63) {
		mctx.data_rssi = -110 + (rxlev - 1);
		LOG_INF("RSSI: %d", mctx.data_rssi);
	} else {
		mctx.data_rssi = -1000;
		LOG_INF("RSRP/RSSI not known");
	}

	return 0;
}
#endif

#if defined(CONFIG_MODEM_UBLOX_SARA_U2) \
	|| defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_VARIANT)
/* Handler: +CSQ: <signal_power>[0],<qual>[1] */
MODEM_CMD_DEFINE(on_cmd_atcmdinfo_rssi_csq)
{
	int rssi;

	rssi = ATOI(argv[0], 0, "signal_power");
	if (rssi == 31) {
		mctx.data_rssi = -46;
	} else if (rssi >= 0 && rssi <= 31) {
		/* FIXME: This value depends on the RAT */
		mctx.data_rssi = -110 + ((rssi * 2) + 1);
	} else {
		mctx.data_rssi = -1000;
	}

	LOG_INF("RSSI: %d", mctx.data_rssi);
	return 0;
}
#endif

/*
 * Modem Socket Command Handlers
 */

/* Handler: +USOCR: <socket_id>[0] */
MODEM_CMD_DEFINE(on_cmd_sockcreate)
{
	struct modem_socket *sock = NULL;

	/* look up new socket by special id */
	sock = modem_socket_from_newid(&mdata.socket_config);
	if (sock) {
		sock->id = ATOI(argv[0],
				mdata.socket_config.base_socket_num - 1,
				"socket_id");
		/* on error give up modem socket */
		if (sock->id == mdata.socket_config.base_socket_num - 1) {
			modem_socket_put(&mdata.socket_config, sock->sock_fd);
		}
	}

	/* don't give back semaphore -- OK to follow */
	return 0;
}

/* Handler: +USO[WR|ST]: <socket_id>[0],<length>[1] */
MODEM_CMD_DEFINE(on_cmd_sockwrite)
{
	mdata.sock_written = ATOI(argv[1], 0, "length");
	LOG_DBG("bytes written: %d", mdata.sock_written);
	return 0;
}

/* Common code for +USOR[D|F]: "<data>" */
static int on_cmd_sockread_common(int socket_id,
				  struct modem_cmd_handler_data *data,
				  int socket_data_length, uint16_t len)
{
	struct modem_socket *sock = NULL;
	struct socket_read_data *sock_data;
	int ret;

	if (!len) {
		LOG_ERR("Short +USOR[D|F] value.  Aborting!");
		return -EAGAIN;
	}

	/*
	 * make sure we still have buf data and next char in the buffer is a
	 * quote.
	 */
	if (!data->rx_buf || *data->rx_buf->data != '\"') {
		LOG_ERR("Incorrect format! Ignoring data!");
		return -EINVAL;
	}

	/* zero length */
	if (socket_data_length <= 0) {
		LOG_ERR("Length problem (%d).  Aborting!", socket_data_length);
		return -EAGAIN;
	}

	/* check to make sure we have all of the data (minus quotes) */
	if ((net_buf_frags_len(data->rx_buf) - 2) < socket_data_length) {
		LOG_DBG("Not enough data -- wait!");
		return -EAGAIN;
	}

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

	sock = modem_socket_from_id(&mdata.socket_config, socket_id);
	if (!sock) {
		LOG_ERR("Socket not found! (%d)", socket_id);
		ret = -EINVAL;
		goto exit;
	}

	sock_data = (struct socket_read_data *)sock->data;
	if (!sock_data) {
		LOG_ERR("Socket data not found! Skip handling (%d)", socket_id);
		ret = -EINVAL;
		goto exit;
	}

	ret = net_buf_linearize(sock_data->recv_buf, sock_data->recv_buf_len,
				data->rx_buf, 0, (uint16_t)socket_data_length);
	data->rx_buf = net_buf_skip(data->rx_buf, ret);
	sock_data->recv_read_len = ret;
	if (ret != socket_data_length) {
		LOG_ERR("Total copied data is different then received data!"
			" copied:%d vs. received:%d", ret, socket_data_length);
		ret = -EINVAL;
	}

exit:
	/* remove packet from list (ignore errors) */
	(void)modem_socket_packet_size_update(&mdata.socket_config, sock,
					      -socket_data_length);

	/* don't give back semaphore -- OK to follow */
	return ret;
}

/*
 * Handler: +USORF: <socket_id>[0],<remote_ip_addr>[1],<remote_port>[2],
 *          <length>[3],"<data>"
*/
MODEM_CMD_DEFINE(on_cmd_sockreadfrom)
{
	/* TODO: handle remote_ip_addr */

	return on_cmd_sockread_common(ATOI(argv[0], 0, "socket_id"), data,
				      ATOI(argv[3], 0, "length"), len);
}

/* Handler: +USORD: <socket_id>[0],<length>[1],"<data>" */
MODEM_CMD_DEFINE(on_cmd_sockread)
{
	return on_cmd_sockread_common(ATOI(argv[0], 0, "socket_id"), data,
				      ATOI(argv[1], 0, "length"), len);
}

#if defined(CONFIG_DNS_RESOLVER)
/* Handler: +UDNSRN: "<resolved_ip_address>"[0], "<resolved_ip_address>"[1] */
MODEM_CMD_DEFINE(on_cmd_dns)
{
	/* chop off end quote */
	argv[0][strlen(argv[0]) - 1] = '\0';

	/* FIXME: Hard-code DNS on SARA-R4 to return IPv4 */
	result_addr.sa_family = AF_INET;
	/* skip beginning quote when parsing */
	(void)net_addr_pton(result.ai_family, &argv[0][1],
			    &((struct sockaddr_in *)&result_addr)->sin_addr);
	return 0;
}
#endif

/*
 * MODEM UNSOLICITED NOTIFICATION HANDLERS
 */

/* Handler: +UUSOCL: <socket_id>[0] */
MODEM_CMD_DEFINE(on_cmd_socknotifyclose)
{
	struct modem_socket *sock;

	sock = modem_socket_from_id(&mdata.socket_config,
				    ATOI(argv[0], 0, "socket_id"));
	if (sock) {
		sock->is_connected = false;
	}

	return 0;
}

/* Handler: +UUSOR[D|F]: <socket_id>[0],<length>[1] */
MODEM_CMD_DEFINE(on_cmd_socknotifydata)
{
	int ret, socket_id, new_total;
	struct modem_socket *sock;

	socket_id = ATOI(argv[0], 0, "socket_id");
	new_total = ATOI(argv[1], 0, "length");
	sock = modem_socket_from_id(&mdata.socket_config, socket_id);
	if (!sock) {
		return 0;
	}

	ret = modem_socket_packet_size_update(&mdata.socket_config, sock,
					      new_total);
	if (ret < 0) {
		LOG_ERR("socket_id:%d left_bytes:%d err: %d", socket_id,
			new_total, ret);
	}

	if (new_total > 0) {
		modem_socket_data_ready(&mdata.socket_config, sock);
	}

	return 0;
}

/* Handler: +CREG: <stat>[0] */
MODEM_CMD_DEFINE(on_cmd_socknotifycreg)
{
	mdata.ev_creg = ATOI(argv[0], 0, "stat");
	LOG_DBG("CREG:%d", mdata.ev_creg);
	return 0;
}

/* RX thread */
static void modem_rx(void)
{
	while (true) {
		/* wait for incoming data */
		k_sem_take(&mdata.iface_data.rx_sem, K_FOREVER);

		mctx.cmd_handler.process(&mctx.cmd_handler, &mctx.iface);

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

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

	LOG_DBG("MDM_RESET_PIN -> NOT_ASSERTED");
	modem_pin_write(&mctx, MDM_RESET, MDM_RESET_NOT_ASSERTED);

	LOG_DBG("MDM_POWER_PIN -> ENABLE");
	modem_pin_write(&mctx, MDM_POWER, MDM_POWER_ENABLE);
	k_sleep(K_SECONDS(4));

	LOG_DBG("MDM_POWER_PIN -> DISABLE");
	modem_pin_write(&mctx, MDM_POWER, MDM_POWER_DISABLE);
#if defined(CONFIG_MODEM_UBLOX_SARA_U2)
	k_sleep(K_SECONDS(1));
#else
	k_sleep(K_SECONDS(4));
#endif
	LOG_DBG("MDM_POWER_PIN -> ENABLE");
	modem_pin_write(&mctx, MDM_POWER, MDM_POWER_ENABLE);
	k_sleep(K_SECONDS(1));

	/* make sure module is powered off */
#if DT_INST_NODE_HAS_PROP(0, mdm_vint_gpios)
	LOG_DBG("Waiting for MDM_VINT_PIN = 0");

	while (modem_pin_read(&mctx, MDM_VINT) > 0) {
#if defined(CONFIG_MODEM_UBLOX_SARA_U2)
		/* try to power off again */
		LOG_DBG("MDM_POWER_PIN -> DISABLE");
		modem_pin_write(&mctx, MDM_POWER, MDM_POWER_DISABLE);
		k_sleep(K_SECONDS(1));
		LOG_DBG("MDM_POWER_PIN -> ENABLE");
		modem_pin_write(&mctx, MDM_POWER, MDM_POWER_ENABLE);
#endif
		k_sleep(K_MSEC(100));
	}
#else
	k_sleep(K_SECONDS(8));
#endif

	LOG_DBG("MDM_POWER_PIN -> DISABLE");

	unsigned int irq_lock_key = irq_lock();

	modem_pin_write(&mctx, MDM_POWER, MDM_POWER_DISABLE);
#if defined(CONFIG_MODEM_UBLOX_SARA_U2)
	k_usleep(50);		/* 50-80 microseconds */
#else
	k_sleep(K_SECONDS(1));
#endif
	modem_pin_write(&mctx, MDM_POWER, MDM_POWER_ENABLE);

	irq_unlock(irq_lock_key);

	LOG_DBG("MDM_POWER_PIN -> ENABLE");

#if DT_INST_NODE_HAS_PROP(0, mdm_vint_gpios)
	LOG_DBG("Waiting for MDM_VINT_PIN = 1");
	do {
		k_sleep(K_MSEC(100));
	} while (modem_pin_read(&mctx, MDM_VINT) == 0);
#else
	k_sleep(K_SECONDS(10));
#endif

	modem_pin_config(&mctx, MDM_POWER, false);

	LOG_INF("... Done!");

	return 0;
}

#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_VARIANT)
static void modem_rssi_query_work(struct k_work *work)
{
	static const struct modem_cmd cmds[] = {
		  MODEM_CMD("+CSQ: ", on_cmd_atcmdinfo_rssi_csq, 2U, ","),
		  MODEM_CMD("+CESQ: ", on_cmd_atcmdinfo_rssi_cesq, 6U, ","),
	};
	const char *send_cmd_u2 = "AT+CSQ";
	const char *send_cmd_r4 = "AT+CESQ";
	int ret;

	/* choose cmd according to variant */
	const char *send_cmd = send_cmd_r4;

	if (mdata.mdm_variant == MDM_VARIANT_UBLOX_U2) {
		send_cmd = send_cmd_u2;
	}

	/* query modem RSSI */
	ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
		cmds, ARRAY_SIZE(cmds),
		send_cmd,
		&mdata.sem_response,
		MDM_CMD_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("AT+C[E]SQ ret:%d", ret);
	}

#if defined(CONFIG_MODEM_UBLOX_SARA_RSSI_WORK)
	/* re-start RSSI query work */
	if (work) {
		k_delayed_work_submit_to_queue(&modem_workq,
			&mdata.rssi_query_work,
			K_SECONDS(CONFIG_MODEM_UBLOX_SARA_RSSI_WORK_PERIOD));
	}
#endif
}
#else
static void modem_rssi_query_work(struct k_work *work)
{
	static const struct modem_cmd cmd =
#if defined(CONFIG_MODEM_UBLOX_SARA_U2)
		MODEM_CMD("+CSQ: ", on_cmd_atcmdinfo_rssi_csq, 2U, ",");
	static char *send_cmd = "AT+CSQ";
#else
		MODEM_CMD("+CESQ: ", on_cmd_atcmdinfo_rssi_cesq, 6U, ",");
	static char *send_cmd = "AT+CESQ";
#endif
	int ret;

	/* query modem RSSI */
	ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
			     &cmd, 1U, send_cmd, &mdata.sem_response,
			     MDM_CMD_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("AT+C[E]SQ ret:%d", ret);
	}

#if defined(CONFIG_MODEM_UBLOX_SARA_RSSI_WORK)
	/* re-start RSSI query work */
	if (work) {
		k_delayed_work_submit_to_queue(&modem_workq,
					       &mdata.rssi_query_work,
					       K_SECONDS(CONFIG_MODEM_UBLOX_SARA_RSSI_WORK_PERIOD));
	}
#endif
}
#endif

static void modem_reset(void)
{
	int ret = 0, retry_count = 0, counter = 0;
	static const struct setup_cmd setup_cmds[] = {
		/* turn off echo */
		SETUP_CMD_NOHANDLE("ATE0"),
		/* stop functionality */
		SETUP_CMD_NOHANDLE("AT+CFUN=0"),
		/* extended error numbers */
		SETUP_CMD_NOHANDLE("AT+CMEE=1"),
#if defined(CONFIG_BOARD_PARTICLE_BORON)
		/* use external SIM */
		SETUP_CMD_NOHANDLE("AT+UGPIOC=23,0,0"),
#endif
#if defined(CONFIG_MODEM_UBLOX_SARA_R4_NET_STATUS_PIN)
		/* enable the network status indication */
		SETUP_CMD_NOHANDLE("AT+UGPIOC="
			STRINGIFY(CONFIG_MODEM_UBLOX_SARA_R4_NET_STATUS_PIN)
			",2"),
#endif
		/* UNC messages for registration */
		SETUP_CMD_NOHANDLE("AT+CREG=1"),
		/* query modem info */
		SETUP_CMD("AT+CGMI", "", on_cmd_atcmdinfo_manufacturer, 0U, ""),
		SETUP_CMD("AT+CGMM", "", on_cmd_atcmdinfo_model, 0U, ""),
		SETUP_CMD("AT+CGMR", "", on_cmd_atcmdinfo_revision, 0U, ""),
		SETUP_CMD("AT+CGSN", "", on_cmd_atcmdinfo_imei, 0U, ""),
		SETUP_CMD("AT+CIMI", "", on_cmd_atcmdinfo_imsi, 0U, ""),
#if !defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_APN)
		/* setup PDP context definition */
		SETUP_CMD_NOHANDLE("AT+CGDCONT=1,\"IP\",\""
					CONFIG_MODEM_UBLOX_SARA_R4_APN "\""),
		/* start functionality */
		SETUP_CMD_NOHANDLE("AT+CFUN=1"),
#endif
	};

#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_VARIANT)
	static const struct setup_cmd post_setup_cmds_u2[] = {
#if !defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_APN)
		/* set the APN */
		SETUP_CMD_NOHANDLE("AT+UPSD=0,1,\""
				CONFIG_MODEM_UBLOX_SARA_R4_APN "\""),
#endif
		/* set dynamic IP */
		SETUP_CMD_NOHANDLE("AT+UPSD=0,7,\"0.0.0.0\""),
		/* activate the GPRS connection */
		SETUP_CMD_NOHANDLE("AT+UPSDA=0,3"),
	};
#endif

	static const struct setup_cmd post_setup_cmds[] = {
#if defined(CONFIG_MODEM_UBLOX_SARA_U2)
		/* set the APN */
		SETUP_CMD_NOHANDLE("AT+UPSD=0,1,\""
				CONFIG_MODEM_UBLOX_SARA_R4_APN "\""),
		/* set dynamic IP */
		SETUP_CMD_NOHANDLE("AT+UPSD=0,7,\"0.0.0.0\""),
		/* activate the GPRS connection */
		SETUP_CMD_NOHANDLE("AT+UPSDA=0,3"),
#else
		/* activate the PDP context */
		SETUP_CMD_NOHANDLE("AT+CGACT=1,1"),
#endif
	};

restart:

#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_APN)
	mdata.mdm_apn[0] = '\0';
	strncat(mdata.mdm_apn,
		CONFIG_MODEM_UBLOX_SARA_R4_APN,
		sizeof(mdata.mdm_apn)-1);
#endif

#if defined(CONFIG_MODEM_UBLOX_SARA_RSSI_WORK)
	/* stop RSSI delay work */
	k_delayed_work_cancel(&mdata.rssi_query_work);
#endif

	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 = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
				     NULL, 0, "AT", &mdata.sem_response,
				     MDM_CMD_TIMEOUT);
		if (ret < 0 && ret != -ETIMEDOUT) {
			break;
		}
	}

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

	ret = modem_cmd_handler_setup_cmds(&mctx.iface, &mctx.cmd_handler,
					   setup_cmds, ARRAY_SIZE(setup_cmds),
					   &mdata.sem_response,
					   MDM_REGISTRATION_TIMEOUT);
	if (ret < 0) {
		goto error;
	}

#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_APN)
	/* autodetect APN from IMSI */
	char cmd[sizeof("AT+CGDCONT=1,\"IP\",\"\"")+MDM_APN_LENGTH];

	snprintf(cmd, sizeof(cmd), "AT+CGDCONT=1,\"IP\",\"%s\"", mdata.mdm_apn);

	/* setup PDP context definition */
	ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
		NULL, 0,
		(const char *)cmd,
		&mdata.sem_response,
		MDM_REGISTRATION_TIMEOUT);

	ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
		NULL, 0,
		"AT+CFUN=1",
		&mdata.sem_response,
		MDM_REGISTRATION_TIMEOUT);
#endif

	if (strlen(CONFIG_MODEM_UBLOX_SARA_R4_MANUAL_MCCMNO) > 0) {
		/* use manual MCC/MNO entry */
		ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
				     NULL, 0,
				     "AT+COPS=1,2,\""
					CONFIG_MODEM_UBLOX_SARA_R4_MANUAL_MCCMNO
					"\"",
				     &mdata.sem_response,
				     MDM_REGISTRATION_TIMEOUT);
	} else {
		/* register operator automatically */
		ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
				     NULL, 0, "AT+COPS=0,0",
				     &mdata.sem_response,
				     MDM_REGISTRATION_TIMEOUT);
	}

	if (ret < 0) {
		LOG_ERR("AT+COPS ret:%d", ret);
		goto error;
	}

	LOG_INF("Waiting for network");

	/*
	 * TODO: A lot of this should be setup as a 3GPP module to handle
	 * basic connection to the network commands / polling
	 */

	/* wait for +CREG: 1(normal) or 5(roaming) */
	counter = 0;
	while (counter++ < 40 && mdata.ev_creg != 1 && mdata.ev_creg != 5) {
		if (counter == 20) {
			LOG_WRN("Force restart of RF functionality");

			/* Disable RF temporarily */
			ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
				NULL, 0, "AT+CFUN=0", &mdata.sem_response,
				MDM_CMD_TIMEOUT);

			k_sleep(K_SECONDS(1));

			/* Enable RF */
			ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
				NULL, 0, "AT+CFUN=1", &mdata.sem_response,
				MDM_CMD_TIMEOUT);
		}

		k_sleep(K_SECONDS(1));
	}

	/* query modem RSSI */
	modem_rssi_query_work(NULL);
	k_sleep(MDM_WAIT_FOR_RSSI_DELAY);

	counter = 0;
	/* wait for RSSI < 0 and > -1000 */
	while (counter++ < MDM_WAIT_FOR_RSSI_COUNT &&
	       (mctx.data_rssi >= 0 ||
		mctx.data_rssi <= -1000)) {
		modem_rssi_query_work(NULL);
		k_sleep(MDM_WAIT_FOR_RSSI_DELAY);
	}

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

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

#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_VARIANT)
	if (mdata.mdm_variant == MDM_VARIANT_UBLOX_U2) {

#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_APN)
		/* setup PDP context definition */
		char cmd[sizeof("AT+UPSD=0,1,\"%s\"")+MDM_APN_LENGTH];

		snprintf(cmd, sizeof(cmd), "AT+UPSD=0,1,\"%s\"", mdata.mdm_apn);
		ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
			NULL, 0,
			(const char *)cmd,
			&mdata.sem_response,
			MDM_REGISTRATION_TIMEOUT);
#endif
		ret = modem_cmd_handler_setup_cmds(&mctx.iface,
			&mctx.cmd_handler,
			post_setup_cmds_u2,
			ARRAY_SIZE(post_setup_cmds_u2),
			&mdata.sem_response,
			MDM_REGISTRATION_TIMEOUT);
	} else {
#endif
		ret = modem_cmd_handler_setup_cmds(&mctx.iface,
					   &mctx.cmd_handler,
					   post_setup_cmds,
					   ARRAY_SIZE(post_setup_cmds),
					   &mdata.sem_response,
					   MDM_REGISTRATION_TIMEOUT);
#if defined(CONFIG_MODEM_UBLOX_SARA_AUTODETECT_VARIANT)
	}
#endif
	if (ret < 0) {
		goto error;
	}

	LOG_INF("Network is ready.");

#if defined(CONFIG_MODEM_UBLOX_SARA_RSSI_WORK)
	/* start RSSI query */
	k_delayed_work_submit_to_queue(&modem_workq,
				       &mdata.rssi_query_work,
				       K_SECONDS(CONFIG_MODEM_UBLOX_SARA_RSSI_WORK_PERIOD));
#endif

error:
	return;
}

/*
 * generic socket creation function
 * which can be called in bind() or connect()
 */
static int create_socket(struct modem_socket *sock, const struct sockaddr *addr)
{
	int ret;
	static const struct modem_cmd cmd =
		MODEM_CMD("+USOCR: ", on_cmd_sockcreate, 1U, "");
	char buf[sizeof("AT+USOCR=#,#####\r")];
	uint16_t local_port = 0U, proto = 6U;

	if (addr) {
		if (addr->sa_family == AF_INET6) {
			local_port = ntohs(net_sin6(addr)->sin6_port);
		} else if (addr->sa_family == AF_INET) {
			local_port = ntohs(net_sin(addr)->sin_port);
		}
	}

	if (sock->ip_proto == IPPROTO_UDP) {
		proto = 17U;
	}

	if (local_port > 0U) {
		snprintk(buf, sizeof(buf), "AT+USOCR=%d,%u", proto, local_port);
	} else {
		snprintk(buf, sizeof(buf), "AT+USOCR=%d", proto);
	}

	/* create socket */
	ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
			     &cmd, 1U, buf,
			     &mdata.sem_response, MDM_CMD_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("%s ret:%d", log_strdup(buf), ret);
		modem_socket_put(&mdata.socket_config, sock->sock_fd);
		errno = -ret;
		return -1;
	}

	errno = 0;
	return 0;
}

/*
 * Socket Offload OPS
 */

static const struct socket_op_vtable offload_socket_fd_op_vtable;

static int offload_socket(int family, int type, int proto)
{
	int ret;

	/* defer modem's socket create call to bind() */
	ret = modem_socket_get(&mdata.socket_config, family, type, proto);
	if (ret < 0) {
		errno = -ret;
		return -1;
	}

	errno = 0;
	return ret;
}

static int offload_close(void *obj)
{
	struct modem_socket *sock = (struct modem_socket *)obj;
	char buf[sizeof("AT+USOCL=#\r")];
	int ret;

	/* make sure we assigned an id */
	if (sock->id < mdata.socket_config.base_socket_num) {
		return 0;
	}

	if (sock->is_connected || sock->ip_proto == IPPROTO_UDP) {
		snprintk(buf, sizeof(buf), "AT+USOCL=%d", sock->id);

		ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
				     NULL, 0U, buf,
				     &mdata.sem_response, MDM_CMD_TIMEOUT);
		if (ret < 0) {
			LOG_ERR("%s ret:%d", log_strdup(buf), ret);
		}
	}

	modem_socket_put(&mdata.socket_config, sock->sock_fd);
	return 0;
}

static int offload_bind(void *obj, const struct sockaddr *addr,
			socklen_t addrlen)
{
	struct modem_socket *sock = (struct modem_socket *)obj;

	/* save bind address information */
	memcpy(&sock->src, addr, sizeof(*addr));

	/* make sure we've created the socket */
	if (sock->id == mdata.socket_config.sockets_len + 1) {
		if (create_socket(sock, addr) < 0) {
			return -1;
		}
	}

	return 0;
}

static int offload_connect(void *obj, const struct sockaddr *addr,
			   socklen_t addrlen)
{
	struct modem_socket *sock = (struct modem_socket *)obj;
	int ret;
	char buf[sizeof("AT+USOCO=#,!###.###.###.###!,#####,#\r")];
	uint16_t dst_port = 0U;

	if (!addr) {
		errno = EINVAL;
		return -1;
	}

	if (sock->id < mdata.socket_config.base_socket_num - 1) {
		LOG_ERR("Invalid socket_id(%d) from fd:%d",
			sock->id, sock->sock_fd);
		errno = EINVAL;
		return -1;
	}

	/* make sure we've created the socket */
	if (sock->id == mdata.socket_config.sockets_len + 1) {
		if (create_socket(sock, NULL) < 0) {
			return -1;
		}
	}

	memcpy(&sock->dst, addr, sizeof(*addr));
	if (addr->sa_family == AF_INET6) {
		dst_port = ntohs(net_sin6(addr)->sin6_port);
	} else if (addr->sa_family == AF_INET) {
		dst_port = ntohs(net_sin(addr)->sin_port);
	} else {
		errno = EAFNOSUPPORT;
		return -1;
	}

	/* skip socket connect if UDP */
	if (sock->ip_proto == IPPROTO_UDP) {
		errno = 0;
		return 0;
	}

	snprintk(buf, sizeof(buf), "AT+USOCO=%d,\"%s\",%d", sock->id,
		 modem_context_sprint_ip_addr(addr), dst_port);
	ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
			     NULL, 0U, buf,
			     &mdata.sem_response, MDM_CMD_CONN_TIMEOUT);
	if (ret < 0) {
		LOG_ERR("%s ret:%d", log_strdup(buf), ret);
		errno = -ret;
		return -1;
	}

	sock->is_connected = true;
	errno = 0;
	return 0;
}

/* support for POLLIN only for now. */
static int offload_poll(struct zsock_pollfd *fds, int nfds, int msecs)
{
	int i;
	void *obj;

	/* Only accept modem sockets. */
	for (i = 0; i < nfds; i++) {
		if (fds[i].fd < 0) {
			continue;
		}

		/* If vtable matches, then it's modem socket. */
		obj = z_get_fd_obj(fds[i].fd,
				   (const struct fd_op_vtable *)
						&offload_socket_fd_op_vtable,
				   EINVAL);
		if (obj == NULL) {
			return -1;
		}
	}

	return modem_socket_poll(&mdata.socket_config, fds, nfds, msecs);
}

static ssize_t offload_recvfrom(void *obj, void *buf, size_t len,
				int flags, struct sockaddr *from,
				socklen_t *fromlen)
{
	struct modem_socket *sock = (struct modem_socket *)obj;
	int ret, next_packet_size;
	static const struct modem_cmd cmd[] = {
		MODEM_CMD("+USORF: ", on_cmd_sockreadfrom, 4U, ","),
		MODEM_CMD("+USORD: ", on_cmd_sockread, 2U, ","),
	};
	char sendbuf[sizeof("AT+USORF=#,#####\r")];
	struct socket_read_data sock_data;

	if (!buf || len == 0) {
		errno = EINVAL;
		return -1;
	}

	if (flags & ZSOCK_MSG_PEEK) {
		errno = ENOTSUP;
		return -1;
	}

	next_packet_size = modem_socket_next_packet_size(&mdata.socket_config,
							 sock);
	if (!next_packet_size) {
		if (flags & ZSOCK_MSG_DONTWAIT) {
			errno = EAGAIN;
			return -1;
		}

		if (!sock->is_connected && sock->ip_proto != IPPROTO_UDP) {
			errno = 0;
			return 0;
		}

		modem_socket_wait_data(&mdata.socket_config, sock);
		next_packet_size = modem_socket_next_packet_size(
			&mdata.socket_config, sock);
	}

	/*
	 * Binary and ASCII mode allows sending MDM_MAX_DATA_LENGTH bytes to
	 * the socket in one command
	 */
	if (next_packet_size > MDM_MAX_DATA_LENGTH) {
		next_packet_size = MDM_MAX_DATA_LENGTH;
	}

	snprintk(sendbuf, sizeof(sendbuf), "AT+USO%s=%d,%d",
		 sock->ip_proto == IPPROTO_UDP ? "RF" : "RD", sock->id,
		 len < next_packet_size ? len : next_packet_size);

	/* socket read settings */
	(void)memset(&sock_data, 0, sizeof(sock_data));
	sock_data.recv_buf = buf;
	sock_data.recv_buf_len = len;
	sock_data.recv_addr = from;
	sock->data = &sock_data;

	ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
			     cmd, ARRAY_SIZE(cmd), sendbuf, &mdata.sem_response,
			     MDM_CMD_TIMEOUT);
	if (ret < 0) {
		errno = -ret;
		ret = -1;
		goto exit;
	}

	/* HACK: use dst address as from */
	if (from && fromlen) {
		*fromlen = sizeof(sock->dst);
		memcpy(from, &sock->dst, *fromlen);
	}

	/* return length of received data */
	errno = 0;
	ret = sock_data.recv_read_len;

exit:
	/* clear socket data */
	sock->data = NULL;
	return ret;
}

static ssize_t offload_sendto(void *obj, const void *buf, size_t len,
			      int flags, const struct sockaddr *to,
			      socklen_t tolen)
{
	struct iovec msg_iov = {
		.iov_base = (void *)buf,
		.iov_len = len,
	};
	struct msghdr msg = {
		.msg_iovlen = 1,
		.msg_name = (struct sockaddr *)to,
		.msg_namelen = tolen,
		.msg_iov = &msg_iov,
	};

	int ret = send_socket_data(obj, &msg, MDM_CMD_TIMEOUT);
	if (ret < 0) {
		errno = -ret;
		return -1;
	}

	errno = 0;
	return ret;
}

static int offload_ioctl(void *obj, unsigned int request, va_list args)
{
	switch (request) {
	case ZFD_IOCTL_POLL_PREPARE:
		return -EXDEV;

	case ZFD_IOCTL_POLL_UPDATE:
		return -EOPNOTSUPP;

	case ZFD_IOCTL_POLL_OFFLOAD: {
		struct zsock_pollfd *fds;
		int nfds;
		int timeout;

		fds = va_arg(args, struct zsock_pollfd *);
		nfds = va_arg(args, int);
		timeout = va_arg(args, int);

		return offload_poll(fds, nfds, timeout);
	}

	default:
		errno = EINVAL;
		return -1;
	}
}

static ssize_t offload_read(void *obj, void *buffer, size_t count)
{
	return offload_recvfrom(obj, buffer, count, 0, NULL, 0);
}

static ssize_t offload_write(void *obj, const void *buffer, size_t count)
{
	return offload_sendto(obj, buffer, count, 0, NULL, 0);
}

static ssize_t offload_sendmsg(void *obj, const struct msghdr *msg, int flags)
{
	ssize_t sent = 0;
	int bkp_iovec_idx;
	struct iovec bkp_iovec = {0};
	struct msghdr crafted_msg = {
		.msg_name = msg->msg_name,
		.msg_namelen = msg->msg_namelen,
	};
	size_t full_len = 0;
	int ret;

	/* Compute the full length to be send and check for invalid values */
	for (int i = 0; i < msg->msg_iovlen; i++) {
		if (!msg->msg_iov[i].iov_base || msg->msg_iov[i].iov_len == 0) {
			errno = EINVAL;
			return -1;
		}
		full_len += msg->msg_iov[i].iov_len;
	}

	LOG_DBG("msg_iovlen:%d flags:%d, full_len:%d",
		msg->msg_iovlen, flags, full_len);

	while (full_len > sent) {
		int removed = 0;
		int i = 0;

		crafted_msg.msg_iovlen = msg->msg_iovlen;
		crafted_msg.msg_iov = &msg->msg_iov[0];

		bkp_iovec_idx = -1;
		/*  Iterate on iovec to remove the bytes already sent */
		while (removed < sent) {
			int to_removed = sent - removed;

			if (to_removed >= msg->msg_iov[i].iov_len) {
				crafted_msg.msg_iovlen -= 1;
				crafted_msg.msg_iov = &msg->msg_iov[i + 1];

				removed += msg->msg_iov[i].iov_len;
			} else {
				/* Backup msg->msg_iov[i] before "removing"
				 * starting bytes already send.
				 */
				bkp_iovec_idx = i;
				bkp_iovec.iov_len = msg->msg_iov[i].iov_len;
				bkp_iovec.iov_base = msg->msg_iov[i].iov_base;

				/* Update msg->msg_iov[i] to "remove"
				 * starting bytes already send.
				 */
				msg->msg_iov[i].iov_len -= to_removed;
				msg->msg_iov[i].iov_base = &(((uint8_t *)msg->msg_iov[i].iov_base)[to_removed]);

				removed += to_removed;
			}

			i++;
		}

		ret = send_socket_data(obj, &crafted_msg, MDM_CMD_TIMEOUT);

		/* Restore backup iovec when necessary */
		if (bkp_iovec_idx != -1) {
			msg->msg_iov[bkp_iovec_idx].iov_len = bkp_iovec.iov_len;
			msg->msg_iov[bkp_iovec_idx].iov_base = bkp_iovec.iov_base;
		}

		/* Handle send_socket_data() returned value */
		if (ret < 0) {
			errno = -ret;
			return -1;
		}

		sent += ret;
	}

	return (ssize_t)sent;
}

static const struct socket_op_vtable offload_socket_fd_op_vtable = {
	.fd_vtable = {
		.read = offload_read,
		.write = offload_write,
		.close = offload_close,
		.ioctl = offload_ioctl,
	},
	.bind = offload_bind,
	.connect = offload_connect,
	.sendto = offload_sendto,
	.recvfrom = offload_recvfrom,
	.listen = NULL,
	.accept = NULL,
	.sendmsg = offload_sendmsg,
	.getsockopt = NULL,
	.setsockopt = NULL,
};

static bool offload_is_supported(int family, int type, int proto)
{
	/* TODO offloading always enabled for now. */
	return true;
}

NET_SOCKET_REGISTER(ublox_sara_r4, AF_UNSPEC, offload_is_supported,
		    offload_socket);

#if defined(CONFIG_DNS_RESOLVER)
/* TODO: This is a bare-bones implementation of DNS handling
 * We ignore most of the hints like ai_family, ai_protocol and ai_socktype.
 * Later, we can add additional handling if it makes sense.
 */
static int offload_getaddrinfo(const char *node, const char *service,
			       const struct zsock_addrinfo *hints,
			       struct zsock_addrinfo **res)
{
	static const struct modem_cmd cmd =
		MODEM_CMD("+UDNSRN: ", on_cmd_dns, 1U, ",");
	uint32_t port = 0U;
	int ret;
	/* DNS command + 128 bytes for domain name parameter */
	char sendbuf[sizeof("AT+UDNSRN=#,'[]'\r") + 128];

	/* init result */
	(void)memset(&result, 0, sizeof(result));
	(void)memset(&result_addr, 0, sizeof(result_addr));
	/* FIXME: Hard-code DNS to return only IPv4 */
	result.ai_family = AF_INET;
	result_addr.sa_family = AF_INET;
	result.ai_addr = &result_addr;
	result.ai_addrlen = sizeof(result_addr);
	result.ai_canonname = result_canonname;
	result_canonname[0] = '\0';

	if (service) {
		port = ATOI(service, 0U, "port");
		if (port < 1 || port > USHRT_MAX) {
			return DNS_EAI_SERVICE;
		}
	}

	if (port > 0U) {
		/* FIXME: DNS is hard-coded to return only IPv4 */
		if (result.ai_family == AF_INET) {
			net_sin(&result_addr)->sin_port = htons(port);
		}
	}

	/* check to see if node is an IP address */
	if (net_addr_pton(result.ai_family, node,
			  &((struct sockaddr_in *)&result_addr)->sin_addr)
	    == 0) {
		*res = &result;
		return 0;
	}

	/* user flagged node as numeric host, but we failed net_addr_pton */
	if (hints && hints->ai_flags & AI_NUMERICHOST) {
		return DNS_EAI_NONAME;
	}

	snprintk(sendbuf, sizeof(sendbuf), "AT+UDNSRN=0,\"%s\"", node);
	ret = modem_cmd_send(&mctx.iface, &mctx.cmd_handler,
			     &cmd, 1U, sendbuf, &mdata.sem_response,
			     MDM_DNS_TIMEOUT);
	if (ret < 0) {
		return ret;
	}

	LOG_DBG("DNS RESULT: %s",
		log_strdup(net_addr_ntop(result.ai_family,
					 &net_sin(&result_addr)->sin_addr,
					 sendbuf, NET_IPV4_ADDR_LEN)));

	*res = (struct zsock_addrinfo *)&result;
	return 0;
}

static void offload_freeaddrinfo(struct zsock_addrinfo *res)
{
	/* using static result from offload_getaddrinfo() -- no need to free */
	res = NULL;
}

const struct socket_dns_offload offload_dns_ops = {
	.getaddrinfo = offload_getaddrinfo,
	.freeaddrinfo = offload_freeaddrinfo,
};
#endif

static int net_offload_dummy_get(sa_family_t family,
				 enum net_sock_type type,
				 enum net_ip_protocol ip_proto,
				 struct net_context **context)
{

	LOG_ERR("CONFIG_NET_SOCKETS_OFFLOAD must be enabled for this driver");

	return -ENOTSUP;
}

/* placeholders, until Zepyr IP stack updated to handle a NULL net_offload */
static struct net_offload modem_net_offload = {
	.get = net_offload_dummy_get,
};

#define HASH_MULTIPLIER		37
static uint32_t hash32(char *str, int len)
{
	uint32_t h = 0;
	int i;

	for (i = 0; i < len; ++i) {
		h = (h * HASH_MULTIPLIER) + str[i];
	}

	return h;
}

static inline uint8_t *modem_get_mac(const struct device *dev)
{
	struct modem_data *data = dev->data;
	uint32_t hash_value;

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

	/* use IMEI for mac_addr */
	hash_value = hash32(mdata.mdm_imei, strlen(mdata.mdm_imei));

	UNALIGNED_PUT(hash_value, (uint32_t *)(data->mac_addr + 2));

	return data->mac_addr;
}

static void modem_net_iface_init(struct net_if *iface)
{
	const struct device *dev = net_if_get_device(iface);
	struct modem_data *data = dev->data;

	/* Direct socket offload used instead of net offload: */
	iface->if_dev->offload = &modem_net_offload;
	net_if_set_link_addr(iface, modem_get_mac(dev),
			     sizeof(data->mac_addr),
			     NET_LINK_ETHERNET);
	data->net_iface = iface;
#ifdef CONFIG_DNS_RESOLVER
	socket_offload_dns_register(&offload_dns_ops);
#endif
}

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

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("+CME ERROR: ", on_cmd_exterror, 1U, ""),
	MODEM_CMD_DIRECT("@", on_prompt),
};

static const struct modem_cmd unsol_cmds[] = {
	MODEM_CMD("+UUSOCL: ", on_cmd_socknotifyclose, 1U, ""),
	MODEM_CMD("+UUSORD: ", on_cmd_socknotifydata, 2U, ","),
	MODEM_CMD("+UUSORF: ", on_cmd_socknotifydata, 2U, ","),
	MODEM_CMD("+CREG: ", on_cmd_socknotifycreg, 1U, ""),
};

static int modem_init(const struct device *dev)
{
	int ret = 0;

	ARG_UNUSED(dev);

	k_sem_init(&mdata.sem_response, 0, 1);
	k_sem_init(&mdata.sem_prompt, 0, 1);

#if defined(CONFIG_MODEM_UBLOX_SARA_RSSI_WORK)
	/* initialize the work queue */
	k_work_q_start(&modem_workq,
		       modem_workq_stack,
		       K_KERNEL_STACK_SIZEOF(modem_workq_stack),
		       K_PRIO_COOP(7));
#endif

	/* socket config */
	mdata.socket_config.sockets = &mdata.sockets[0];
	mdata.socket_config.sockets_len = ARRAY_SIZE(mdata.sockets);
	mdata.socket_config.base_socket_num = MDM_BASE_SOCKET_NUM;
	ret = modem_socket_init(&mdata.socket_config,
				&offload_socket_fd_op_vtable);
	if (ret < 0) {
		goto error;
	}

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

	/* modem interface */
	mdata.iface_data.hw_flow_control = DT_PROP(MDM_UART_NODE,
						   hw_flow_control);
	mdata.iface_data.rx_rb_buf = &mdata.iface_rb_buf[0];
	mdata.iface_data.rx_rb_buf_len = sizeof(mdata.iface_rb_buf);
	ret = modem_iface_uart_init(&mctx.iface, &mdata.iface_data,
				    MDM_UART_DEV_NAME);
	if (ret < 0) {
		goto error;
	}

	/* modem data storage */
	mctx.data_manufacturer = mdata.mdm_manufacturer;
	mctx.data_model = mdata.mdm_model;
	mctx.data_revision = mdata.mdm_revision;
	mctx.data_imei = mdata.mdm_imei;

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

	mctx.driver_data = &mdata;

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

	/* start RX thread */
	k_thread_create(&modem_rx_thread, modem_rx_stack,
			K_KERNEL_STACK_SIZEOF(modem_rx_stack),
			(k_thread_entry_t) modem_rx,
			NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT);

#if defined(CONFIG_MODEM_UBLOX_SARA_RSSI_WORK)
	/* init RSSI query */
	k_delayed_work_init(&mdata.rssi_query_work, modem_rssi_query_work);
#endif

	modem_reset();

error:
	return ret;
}

NET_DEVICE_OFFLOAD_INIT(modem_sara, CONFIG_MODEM_UBLOX_SARA_R4_NAME,
			modem_init, device_pm_control_nop, &mdata, NULL,
			CONFIG_MODEM_UBLOX_SARA_R4_INIT_PRIORITY, &api_funcs,
			MDM_MAX_DATA_LENGTH);
