You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
2.6 KiB
136 lines
2.6 KiB
/** @file |
|
* @brief Modem context helper driver |
|
* |
|
* A modem context driver allowing application to handle all |
|
* aspects of received protocol data. |
|
*/ |
|
|
|
/* |
|
* Copyright (c) 2019 Foundries.io |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#include <zephyr/logging/log.h> |
|
LOG_MODULE_REGISTER(modem_context, CONFIG_MODEM_LOG_LEVEL); |
|
|
|
#include <zephyr/kernel.h> |
|
|
|
#include "modem_context.h" |
|
|
|
static struct modem_context *contexts[CONFIG_MODEM_CONTEXT_MAX_NUM]; |
|
|
|
int modem_context_sprint_ip_addr(const struct sockaddr *addr, char *buf, size_t buf_size) |
|
{ |
|
static const char unknown_str[] = "unk"; |
|
|
|
if (addr->sa_family == AF_INET6) { |
|
if (buf_size < NET_IPV6_ADDR_LEN) { |
|
return -ENOMEM; |
|
} |
|
|
|
if (net_addr_ntop(AF_INET6, &net_sin6(addr)->sin6_addr, |
|
buf, buf_size) == NULL) { |
|
return -ENOMEM; |
|
} |
|
return 0; |
|
} |
|
|
|
if (addr->sa_family == AF_INET) { |
|
if (buf_size < NET_IPV4_ADDR_LEN) { |
|
return -ENOMEM; |
|
} |
|
if (net_addr_ntop(AF_INET, &net_sin(addr)->sin_addr, |
|
buf, buf_size) == NULL) { |
|
return -ENOMEM; |
|
} |
|
return 0; |
|
} |
|
|
|
LOG_ERR("Unknown IP address family:%d", addr->sa_family); |
|
|
|
if (buf_size < sizeof(unknown_str)) { |
|
return -ENOMEM; |
|
} |
|
strcpy(buf, unknown_str); |
|
return 0; |
|
} |
|
|
|
int modem_context_get_addr_port(const struct sockaddr *addr, uint16_t *port) |
|
{ |
|
if (!addr || !port) { |
|
return -EINVAL; |
|
} |
|
|
|
if (addr->sa_family == AF_INET6) { |
|
*port = ntohs(net_sin6(addr)->sin6_port); |
|
return 0; |
|
} else if (addr->sa_family == AF_INET) { |
|
*port = ntohs(net_sin(addr)->sin_port); |
|
return 0; |
|
} |
|
|
|
return -EPROTONOSUPPORT; |
|
} |
|
|
|
/** |
|
* @brief Finds modem context which owns the iface device. |
|
* |
|
* @param dev: device used by the modem iface. |
|
* |
|
* @retval Modem context or NULL. |
|
*/ |
|
struct modem_context *modem_context_from_iface_dev(const struct device *dev) |
|
{ |
|
int i; |
|
|
|
for (i = 0; i < ARRAY_SIZE(contexts); i++) { |
|
if (contexts[i] && contexts[i]->iface.dev == dev) { |
|
return contexts[i]; |
|
} |
|
} |
|
|
|
return NULL; |
|
} |
|
|
|
/** |
|
* @brief Assign a modem context if there is free space. |
|
* |
|
* @note Amount of stored modem contexts is determined by |
|
* CONFIG_MODEM_CONTEXT_MAX_NUM. |
|
* |
|
* @param ctx: modem context to persist. |
|
* |
|
* @retval 0 if ok, < 0 if error. |
|
*/ |
|
static int modem_context_get(struct modem_context *ctx) |
|
{ |
|
int i; |
|
|
|
for (i = 0; i < ARRAY_SIZE(contexts); i++) { |
|
if (!contexts[i]) { |
|
contexts[i] = ctx; |
|
return 0; |
|
} |
|
} |
|
|
|
return -ENOMEM; |
|
} |
|
|
|
struct modem_context *modem_context_from_id(int id) |
|
{ |
|
if (id >= 0 && id < ARRAY_SIZE(contexts)) { |
|
return contexts[id]; |
|
} else { |
|
return NULL; |
|
} |
|
} |
|
|
|
int modem_context_register(struct modem_context *ctx) |
|
{ |
|
if (!ctx) { |
|
return -EINVAL; |
|
} |
|
|
|
return modem_context_get(ctx); |
|
}
|
|
|