Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion app/src/sm_at_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "sm_at_host.h"
#include "sm_at_socket.h"
#include "sm_sockopt.h"
#include "sm_ppp.h"

LOG_MODULE_REGISTER(sm_sock, CONFIG_SM_LOG_LEVEL);

Expand Down Expand Up @@ -155,7 +156,7 @@ static int bind_to_pdn(struct sm_socket *sock)
ret = nrf_setsockopt(sock->fd, NRF_SOL_SOCKET, NRF_SO_BINDTOPDN, &cid_int,
sizeof(int));
if (ret < 0) {
LOG_ERR("nrf_setsockopt(%d) error: %d", NRF_SO_BINDTOPDN, -errno);
LOG_ERR("nrf_setsockopt(NRF_SO_BINDTOPDN) error: %d", -errno);
ret = -errno;
}
}
Expand Down Expand Up @@ -1104,6 +1105,41 @@ static int socket_datamode_callback(uint8_t op, const uint8_t *data, int len, ui
return ret;
}

/* Two RAW sockets cannot share the same CID. PPP is in practice a RAW socket.
* This function checks if a new socket can be created on the given CID.
* The CID cannot have a RAW sockets already, and if the new socket is RAW,
* the CID cannot have any other sockets already.
*/
static bool cid_validity_raw_socket_check(uint16_t cid, int type)
{
#if defined(CONFIG_SM_PPP)
/* PPP is raw socket so new socket cannot be created on the same CID */
if (sm_ppp_is_running_on_cid(cid)) {
LOG_ERR("Socket creation not allowed on PPP PDN (%d) when PPP is not stopped", cid);
return false;
}
#endif
for (int i = 0; i < SM_MAX_SOCKET_COUNT; i++) {
if (socks[i].cid == cid) {
/* If the CID is used for RAW sockets*/
if (type == NRF_SOCK_RAW) {
LOG_ERR("Raw socket creation not allowed on PDN (%d) "
"which already has another socket", cid);
return false;
}

/* If the CID is used for a RAW socket */
if (socks[i].type == NRF_SOCK_RAW) {
LOG_ERR("Socket creation not allowed on PDN (%d) "
"which already has RAW socket", cid);
return false;
}
}
}

return true;
}

SM_AT_CMD_CUSTOM(xsocket, "AT#XSOCKET", handle_at_socket);
static int handle_at_socket(enum at_parser_cmd_type cmd_type, struct at_parser *parser,
uint32_t param_count)
Expand Down Expand Up @@ -1145,6 +1181,10 @@ static int handle_at_socket(enum at_parser_cmd_type cmd_type, struct at_parser *
goto error;
}
}
if (!cid_validity_raw_socket_check(sock->cid, sock->type)) {
err = -EFAULT;
goto error;
}
err = do_socket_open(sock);
if (err) {
LOG_ERR("do_socket_open() failed: %d", err);
Expand Down Expand Up @@ -1255,6 +1295,10 @@ static int handle_at_secure_socket(enum at_parser_cmd_type cmd_type,
goto error;
}
}
if (!cid_validity_raw_socket_check(sock->cid, sock->type)) {
err = -EINVAL;
goto error;
}
err = do_secure_socket_open(sock, peer_verify);
if (err) {
LOG_ERR("do_secure_socket_open() failed: %d", err);
Expand Down
8 changes: 8 additions & 0 deletions app/src/sm_ppp.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,14 @@ bool sm_ppp_is_stopped(void)
return (ppp_state == PPP_STATE_STOPPED);
}

bool sm_ppp_is_running_on_cid(uint16_t cid)
{
if (!sm_ppp_is_stopped() && cid == ppp_pdn_cid) {
return true;
}
return false;
}

static int ppp_stop(enum ppp_reason reason)
{
if (ppp_state == PPP_STATE_STOPPED) {
Expand Down
3 changes: 3 additions & 0 deletions app/src/sm_ppp.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define SM_PPP_

#include <stdbool.h>
#include <zephyr/kernel.h>

/* Whether to forward CGEV notifications to the Serial Modem UART. */
extern bool sm_fwd_cgev_notifs;
Expand All @@ -16,4 +17,6 @@ int sm_ppp_init(void);

bool sm_ppp_is_stopped(void);

bool sm_ppp_is_running_on_cid(uint16_t cid);

#endif
5 changes: 5 additions & 0 deletions doc/app/PPP_AT_commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ The set command allows you to start and stop PPP, and optionally define the PDN
When a PPP start has been issued, the PPP connection is automatically activated and deactivated when the PDN connection requested for PPP is established and lost, respectively.
This will continue until a PPP stop is issued by either the user by the ``AT#XPPP=0`` command or by the remote peer disconnecting the PPP using LCP termination.

.. note::

PPP cannot be started on a PDN connection that is already in use by another socket.
The reason is that PPP is a raw socket, which intercepts all downlink data intended for other sockets on the same PDN, which disrupts normal socket operations.

Syntax
~~~~~~

Expand Down
13 changes: 13 additions & 0 deletions doc/app/SOCKET_AT_commands.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ Socket #XSOCKET

The ``#XSOCKET`` command allows you to open a socket and to check the socket handle.

.. note::

A socket cannot be created on a PDN connection that is already in use by a raw socket.
A raw socket cannot be created on a PDN connection that is already in use by another socket.
The reason is that a raw socket cannot keep its data separate from the data of another IP socket when both are operating on the same PDN.
When a raw socket is active, it intercepts all downlink data intended for other sockets on the same PDN, which disrupts normal socket operations.

Set command
-----------

Expand Down Expand Up @@ -182,6 +189,12 @@ The ``#XSSOCKET`` command allows you to open a secure socket and to check the so
.. note::
TLS and DTLS servers are currently not supported.

.. note::

A secure socket cannot be created on a PDN connection that is already in use by a raw socket.
The reason is that a raw socket cannot keep its data separate from the data of another IP socket when both are operating on the same PDN.
When a raw socket is active, it intercepts all downlink data intended for other sockets on the same PDN, which disrupts normal socket operations.

Set command
-----------

Expand Down