Skip to content

app: Add CoAP client AT commands#283

Merged
juhaylinen merged 1 commit into
nrfconnect:mainfrom
juhaylinen:coap_client_xsocket
May 26, 2026
Merged

app: Add CoAP client AT commands#283
juhaylinen merged 1 commit into
nrfconnect:mainfrom
juhaylinen:coap_client_xsocket

Conversation

@juhaylinen
Copy link
Copy Markdown
Contributor

@juhaylinen juhaylinen commented May 7, 2026

Overview

Adds three new AT commands that expose Zephyr's coap_client library over the Serial Modem UART
interface, enabling host devices to make CoAP requests over an existing DTLS or UDP socket.

New AT commands

AT#XCOAPCREQ

AT#XCOAPCREQ=<handle>,<path>,<method>[,<auto_reception>[,<format>[,<confirmable>[,<content_format>[,<payload_len>[,<opt_num_1>,<opt_val_1>[,<opt_num_2>,<opt_val_2>[...]]]]]]]]]

AT#XCOAPCREQ=?

Sends a CoAP request on the AT socket identified by <handle>.

Parameter Description
<handle> AT socket handle from AT#XSOCKET / AT#XSSOCKET
<path> URI-path string (quoted); query parameters (?key=val) are supported
<method> 1=GET, 2=POST, 3=PUT, 4=DELETE, 5=FETCH, 6=PATCH, 7=iPATCH
<auto_reception> 1=automatic URCs (default), 0=manual pull via AT#XCOAPCDATA
<format> 0=binary payload delivery (default), 1=lower-case ASCII hex string; <length> in URCs always reports the raw byte count
<confirmable> 0=NON-confirmable (default), 1=CON-confirmable
<content_format> CoAP Content-Format integer (default 0 = text/plain)
<payload_len> If > 0, returns OK and enters data mode to receive the payload
<opt_num> CoAP option number (decimal integer, e.g. 35 for Proxy-Uri). Must be paired with <opt_val>. Zero or more pairs may be appended.
<opt_val> Option value (quoted string). A value prefixed with 0x/0X is decoded as raw hex bytes (e.g. "0x3c" → byte 0x3c); the hex part must be non-empty and even-length, otherwise ERROR is returned. Any value without the prefix is used verbatim.

Returns OK immediately. Responses are delivered asynchronously:

Auto receive mode (auto_reception=1, default):

  • #XCOAPCDATA: <handle>,<offset>,<len> followed by <len> raw bytes (binary) or 2×<len> hex chars (hex mode), once per Block2 block
  • #XCOAPCSTAT: <handle>,<status>,<total_bytes> on completion or error (status=-1; <total_bytes> is always the raw byte count)

Manual receive mode (auto_reception=0):

  • #XCOAPCHEAD: <handle>,<code>,<len> — one URC per block (<len> is raw byte count); host must call AT#XCOAPCDATA to pull each block
  • #XCOAPCSTAT: <handle>,<status>,<total_bytes> on completion or error (status=-1; <total_bytes> is always the raw byte count)

Examples:

AT#XCOAPCREQ=0,"/path",1
AT#XCOAPCREQ=0,"proxy",1,1,0,1,0,0,35,"coap://host/path"
AT#XCOAPCREQ=0,"/obs",1,1,0,1,0,0,6,"0x00",17,"0x3c"

AT#XCOAPCCANCEL

AT#XCOAPCCANCEL=<handle>
AT#XCOAPCCANCEL=?

Cancels the active request on the given socket handle. The coap_client library calls the
response callback with a negative result code, which delivers a #XCOAPCSTAT error URC before
OK is returned.


AT#XCOAPCDATA

AT#XCOAPCDATA=<handle>[,<length>]
AT#XCOAPCDATA=?

Pulls one chunk of response body in manual receive mode (auto_reception=0). Must be called after
receiving a #XCOAPCHEAD URC. If <length> is smaller than the block size, repeat calls until
the full block is drained — the firmware's CoAP callback remains blocked until rx_buf is empty.

Parameter Description
<handle> AT socket handle used when issuing the request
<length> Maximum bytes to return (default: CONFIG_COAP_CLIENT_BLOCK_SIZE)

Response:

#XCOAPCDATA: <handle>,<offset>,<len>
<len raw bytes, or 2×<len> ASCII hex chars in hex mode>
OK

Payload handling

Two code paths depending on declared <payload_len>:

Small payloads (≤ CONFIG_COAP_CLIENT_BLOCK_SIZE, default 1024 bytes):

  • Bytes are accumulated into a dynamically allocated staging buffer during data mode.
  • coap_start_request() is called on data mode exit with coap_req.payload pointing to the
    buffer directly — no blockwise upload, no payload_cb, no semaphores.
  • The buffer is kept alive until the final Block2 response block is received, because Zephyr's
    coap_client stores the payload pointer internally and re-reads it when reconstructing
    Block2 continuation request packets.

Large payloads (> CONFIG_COAP_CLIENT_BLOCK_SIZE):

  • Streamed block-by-block using coap_client_payload_cb_t.
  • A single staging buffer (one block, dynamically allocated) is shared between the data mode
    thread and the coap_client background thread via two semaphores:
    • staging_ready: data mode signals that staging is filled
    • staging_consumed: coap_client signals after copying staging to its send buffer
  • The first block triggers coap_start_request() from within data mode; coap_client_req()
    calls payload_cb synchronously for block 0 before returning.
  • For Block2 response-continuation re-sends, coap_client re-invokes payload_cb with
    offset=0. Detected by payload_sent >= payload_len; cached staging contents are returned
    without blocking.

Example

AT#XSOCKET=1,2,0                                                                                                                   
                                                                                                                                   
#XSOCKET: 0,2,17                                                                                                                   
                                                                                                                                   
OK                                                                                                                                 
AT#XCONNECT=0,"coap.me",5683                                                                                                       
                                                                                                                                   
#XCONNECT: 0,1                                                                                                                     

OK
AT#XCOAPCREQ=0,"/test",1,1

OK

#XCOAPCDATA: 0,0,66
welcome to the ETSI plugtest! last change: 2026-05-07 08:31:07 UTC
#XCOAPCSTAT: 0,69,66

Jira: SM-225

@juhaylinen juhaylinen force-pushed the coap_client_xsocket branch 2 times, most recently from 2c9c80c to bfc5317 Compare May 7, 2026 08:34
@juhaylinen juhaylinen force-pushed the coap_client_xsocket branch 3 times, most recently from 5cfcffc to dde17cb Compare May 13, 2026 11:51
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 13, 2026

You can find the documentation preview for this PR here.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds three new AT commands (AT#XCOAPCREQ, AT#XCOAPCDATA, AT#XCOAPCCANCEL) that expose Zephyr's coap_client library over the Serial Modem UART, allowing the host to perform asynchronous CoAP requests on an existing UDP/DTLS socket created via AT#XSOCKET/AT#XSSOCKET. Includes auto and manual response delivery modes, optional CoAP options (with hex/text auto-detection), and small/large request payload paths (in-buffer or streamed via payload_cb).

Changes:

  • New CoAP client backend in app/src/sm_at_coap.c plus Kconfig (SM_COAP) and CMake wiring.
  • prj.conf updates to allow multiple coap_client instances; also enables SM_AUTO_CONNECT and adds commented logging hints.
  • New documentation page doc/app/at_coap.rst (linked from at_commands.rst).

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
app/src/sm_at_coap.c Implementation of the three new AT commands and their request lifecycle.
app/CMakeLists.txt Conditionally compiles the new CoAP source file.
app/Kconfig Adds CONFIG_SM_COAP Kconfig entry (default y, selects COAP/COAP_CLIENT).
app/prj.conf Bumps COAP_CLIENT_MAX_INSTANCES; also enables SM_AUTO_CONNECT and adds debug-log comments.
doc/app/at_coap.rst New AT command reference for XCOAPCREQ/XCOAPCDATA/XCOAPCCANCEL.
doc/app/at_commands.rst Adds toctree entry for the new CoAP page.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/prj.conf Outdated
Comment thread app/prj.conf Outdated
Comment thread app/src/sm_at_coap.c Outdated
Comment thread app/src/sm_at_coap.c
Comment thread app/src/sm_at_coap.c
@juhaylinen juhaylinen force-pushed the coap_client_xsocket branch 3 times, most recently from 58a3c26 to 22a8e7c Compare May 15, 2026 09:01
Copy link
Copy Markdown
Contributor

@MarkusLassila MarkusLassila left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some comments. Continuing on Monday.

Comment thread app/src/sm_at_coap.c Outdated
}

req->nrf_handle = handle;
req->zsock_fd = nrf_modem_lib_nrf_fd_to_zsock_fd(handle);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this something that you have implemented yourself?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it's used for testing the client and will be removed before the PR is merged.

Comment thread doc/app/at_coap.rst Outdated
Comment thread doc/app/at_coap.rst Outdated
Comment thread doc/app/at_coap.rst Outdated
Comment thread doc/app/at_coap.rst Outdated
Comment thread doc/app/at_coap.rst
Comment thread doc/app/at_coap.rst Outdated
Comment thread doc/app/at_coap.rst
Comment thread app/src/sm_at_coap.c
@juhaylinen juhaylinen marked this pull request as ready for review May 18, 2026 06:39
@juhaylinen juhaylinen force-pushed the coap_client_xsocket branch from 22a8e7c to edd552d Compare May 18, 2026 12:19
Copy link
Copy Markdown
Contributor

@MarkusLassila MarkusLassila left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Some comments.

Comment thread app/src/sm_at_coap.c
Comment thread app/src/sm_at_coap.c Outdated
Comment thread app/src/sm_at_coap.c Outdated
Comment thread app/src/sm_at_coap.c
Comment thread app/src/sm_at_coap.c Outdated
Comment thread app/src/sm_at_coap.c
} else if (op == DATAMODE_EXIT) {
struct coap_request *req = coap_pending_req;

if (req && req->payload_len <= CONFIG_COAP_CLIENT_BLOCK_SIZE) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to make the both of these to use the longer way of making the request? There are many places where there is separate logic for the two of these.

Comment thread app/src/sm_at_coap.c Outdated
* #XCOAPCSTAT: <handle>,<status>,<total_bytes>
*
* <handle>: AT socket handle from AT#XSOCKET or AT#XSSOCKET.
* <status>: CoAP response code (e.g. 69 for 2.05 Content); -1 on error/cancel.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This maps to response, not the request. The others in here are specific to request.

Comment thread app/src/sm_at_coap.c Outdated
Comment thread app/src/sm_at_coap.c
Comment thread app/src/sm_at_coap.c Outdated
@juhaylinen juhaylinen force-pushed the coap_client_xsocket branch 4 times, most recently from 6100424 to caed1a4 Compare May 20, 2026 11:12
Comment thread app/overlay-nrf-device-provisioning.conf
Comment thread doc/app/at_coap.rst Outdated
Comment thread doc/app/at_coap.rst Outdated
Comment thread doc/app/at_coap.rst Outdated
Comment thread doc/app/at_coap.rst Outdated
@juhaylinen juhaylinen force-pushed the coap_client_xsocket branch from caed1a4 to 60688cb Compare May 21, 2026 07:47
Copy link
Copy Markdown
Contributor

@SeppoTakalo SeppoTakalo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

🔴 Bugs

1. opt_num type mismatch with at_parser_num_get (sm_at_coap.c ~line 730)

opt_num is declared uint16_t and passed by address to at_parser_num_get. Every other caller in the codebase (sm_at_socket.c, sm_at_httpc.c, sm_at_mqtt.c) passes int *. If the type-generic macro doesn't handle uint16_t *, the parser writes 4 bytes into a 2-byte location and corrupts adjacent stack variables (opt, decoded_len, …). Fix: use a local int tmp_num, pass &tmp_num, and assign opt->code = (uint16_t)tmp_num after range-checking.


🔴 Unrelated behavior change in prj.conf

CONFIG_SM_AUTO_CONNECT=y modifies default product behavior (auto network attach on boot) and has nothing to do with CoAP. Likewise, the commented-out CONFIG_NET_LOG / CONFIG_COAP_LOG_LEVEL_INF lines look like leftover debug artifacts. Both should be removed before merge.


🟡 Design concerns

extern struct sm_socket *find_socket(int fd) without a header

find_socket is an internal symbol of sm_at_socket.c, and this PR accesses it via a bare extern declaration without adding it to sm_at_socket.h. This is fragile — the declaration can silently drift from the definition. Add it to the header.

CONFIG_COAP_CLIENT_MAX_INSTANCES=3 in overlay-nrf-device-provisioning.conf

The comment says "support simultaneous provisioning and AT#XCOAPCREQ", implying 2 instances are needed. Why 3? Either bump with justification (e.g. "one spare for future expansion") or reduce to 2 with a matching comment.

CONFIG_SM_COAP defaults to y

The symbol selects EXPERIMENTAL and brings in the coap_client library in all default builds. Given it is experimental, consider defaulting to n (like CONFIG_SM_GNSS, CONFIG_SM_SMS, CONFIG_SM_PPP). If intentionally always-on, that is fine but worth an explicit note.


🟡 PR description out of sync with code

The overview examples still show bare hex strings without a prefix:

AT#XCOAPCREQ=0,"/obs",1,1,1,0,0,6,"00",17,"3c"

But the code (and RST docs) now require a 0x prefix ("0x00", "0x3c"). Update the PR description so reviewers are not confused.


🟢 What looks good

  • Overall architecture (single in-flight request, two receive modes, small/large payload split via staging buffer + semaphores) is clean and well-documented in both the struct comment and per-function docstrings.
  • Loop bound is correct: (i + 1) < param_count after the odd-count rejection guard.
  • Cancel command now documents the "single shared client" limitation directly in the code comment.
  • parse_option_value is self-contained and readable. The 0x-prefix convention is unambiguous and easier to use than an auto-detect heuristic.
  • RST documentation is thorough with multiple complete examples (including the full AT#XSOCKET + AT#XCONNECT flow).

❌ CI

The Build/build-and-test-in-toolchain-bundle check is failing. Please investigate and fix before requesting a re-review.

@juhaylinen juhaylinen force-pushed the coap_client_xsocket branch 2 times, most recently from 160b1f6 to 51d5856 Compare May 22, 2026 07:58
@juhaylinen juhaylinen force-pushed the coap_client_xsocket branch 2 times, most recently from 38a9fec to 42089e9 Compare May 22, 2026 11:56
@juhaylinen juhaylinen requested a review from divipillai May 22, 2026 11:57
Comment thread doc/app/at_coap.rst Outdated
* Set socket options with ``AT#XSOCKETOPT`` or ``AT#XSSOCKETOPT``.
* Close with ``AT#XCLOSE``.

Only one CoAP request may be active at a time across all sockets.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Only one CoAP request may be active at a time across all sockets.
Only one CoAP request might be active at a time across all sockets.

Comment thread doc/app/at_coap.rst Outdated
-----------

The set command sends a CoAP request and returns ``OK`` immediately.
The server's response is delivered via unsolicited ``#XCOAPCDATA`` and ``#XCOAPCSTAT`` notifications.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The server's response is delivered via unsolicited ``#XCOAPCDATA`` and ``#XCOAPCSTAT`` notifications.
The server's response is delivered through unsolicited ``#XCOAPCDATA`` and ``#XCOAPCSTAT`` notifications.

Comment thread doc/app/at_coap.rst Outdated
It can accept the following values:

* ``1`` - Automatic mode (default).
Response bytes are forwarded to the host automatically via ``#XCOAPCDATA`` URCs.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Response bytes are forwarded to the host automatically via ``#XCOAPCDATA`` URCs.
Response bytes are forwarded to the host automatically through ``#XCOAPCDATA`` URCs.

Comment thread doc/app/at_coap.rst Outdated
* ``0`` - Binary (default).
Response payload bytes are forwarded to the host as raw binary.
* ``1`` - Hex string.
Response payload bytes are encoded as a lower-case ASCII hex string before delivery.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Response payload bytes are encoded as a lower-case ASCII hex string before delivery.
Response payload bytes are encoded as a lowercase ASCII hex string before delivery.

Comment thread doc/app/at_coap.rst Outdated

The host must send exactly this many bytes as the request payload.
Data mode exits and ``#XDATAMODE: 0`` is reported when all bytes have been consumed.
Data mode is the only mechanism for supplying the payload — there is no inline parameter alternative.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Data mode is the only mechanism for supplying the payload there is no inline parameter alternative.
Data mode is the only mechanism for supplying the payload - there is no inline parameter alternative.

Comment thread doc/app/at_coap.rst Outdated
Comment on lines +119 to +130
* The ``<opt_num_X>,<opt_val_X>`` parameters are optional CoAP option pairs.
When present, ``<payload_len>`` must also be present as the positional separator before the first pair.
``<opt_num_X>`` is a decimal integer option number.
``<opt_val_X>`` is a quoted string.
A value prefixed with ``0x`` or ``0X`` is decoded as raw hex bytes (for example ``"0x3c"`` → byte ``0x3c``).
The hex part after the prefix must be non-empty and even-length, otherwise the command returns ``ERROR``.
Any value without the ``0x`` prefix is used verbatim, including strings that look like hex (for example ``"abcd"`` → 4 ASCII bytes).
Common option numbers:

* ``6`` - Observe (``"0x00"`` = register, ``"0x01"`` = deregister).
* ``17`` - Accept (content format the client will accept, hex-encoded).
* ``35`` - Proxy-Uri (full URI passed to a proxy, verbatim string).
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* The ``<opt_num_X>,<opt_val_X>`` parameters are optional CoAP option pairs.
When present, ``<payload_len>`` must also be present as the positional separator before the first pair.
``<opt_num_X>`` is a decimal integer option number.
``<opt_val_X>`` is a quoted string.
A value prefixed with ``0x`` or ``0X`` is decoded as raw hex bytes (for example ``"0x3c"`` → byte ``0x3c``).
The hex part after the prefix must be non-empty and even-length, otherwise the command returns ``ERROR``.
Any value without the ``0x`` prefix is used verbatim, including strings that look like hex (for example ``"abcd"`` → 4 ASCII bytes).
Common option numbers:
* ``6`` - Observe (``"0x00"`` = register, ``"0x01"`` = deregister).
* ``17`` - Accept (content format the client will accept, hex-encoded).
* ``35`` - Proxy-Uri (full URI passed to a proxy, verbatim string).
* The ``<opt_num_X>,<opt_val_X>`` parameters are optional CoAP option pairs:
* When present, ``<payload_len>`` must also be present as the positional separator before the first pair.
* ``<opt_num_X>`` is a decimal integer option number.
* ``<opt_val_X>`` is a quoted string.
* A value prefixed with ``0x`` or ``0X`` is decoded as raw hex bytes (for example, ``"0x3c"`` → byte ``0x3c``).
* The hex part after the prefix must be non-empty and even-length, otherwise, the command returns ``ERROR``.
* Any value without the ``0x`` prefix is used verbatim, including strings that look like hex (for example ``"abcd"`` → 4 ASCII bytes).
* Common option numbers:
* ``6`` - Observe (``"0x00"`` = register, ``"0x01"`` = deregister).
* ``17`` - Accept (content format the client will accept, hex-encoded).
* ``35`` - Proxy-Uri (full URI passed to a proxy, verbatim string).

For readability.

Comment thread doc/app/at_coap.rst Outdated
In hex mode (``<hex_format>=1``), ``AT#XCOAPCDATA`` will deliver ``2×<block_len>`` ASCII hex characters.
The host must call ``AT#XCOAPCDATA`` to retrieve this block before the next one arrives.

``#XCOAPCSTAT`` is emitted when the request completes, fails, or is cancelled
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
``#XCOAPCSTAT`` is emitted when the request completes, fails, or is cancelled
``#XCOAPCSTAT`` is emitted when the request completes, fails, or is cancelled.

Comment thread doc/app/at_coap.rst Outdated

#XCOAPCSTAT: 0,68,0

CoAP GET via proxy with Proxy-Uri option (option 35, value is a plain URI string):
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CoAP GET via proxy with Proxy-Uri option (option 35, value is a plain URI string):
CoAP GET through proxy with Proxy-URI option (option 35, value is a plain URI string):

Comment thread doc/app/at_coap.rst Outdated
Response syntax
~~~~~~~~~~~~~~~

When a block is available
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When a block is available
When a block is available:

Comment thread doc/app/at_coap.rst Outdated
``<length>`` raw response bytes follow immediately with no additional separator.
``OK`` follows on its own line after the response bytes.

When no block has been buffered yet (the firmware is still waiting for the server response)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When no block has been buffered yet (the firmware is still waiting for the server response)
When no block has been buffered yet (the firmware is still waiting for the server response).

Comment thread doc/app/at_coap.rst
Comment on lines +117 to +127
* The ``<opt_num_X>,<opt_val_X>`` parameters are optional CoAP option pairs:
* When present, ``<payload_len>`` must also be present as the positional separator before the first pair.
* ``<opt_num_X>`` is a decimal integer option number.
* ``<opt_val_X>`` is a quoted string.
* A value prefixed with ``0x`` or ``0X`` is decoded as raw hex bytes (for example, ``"0x3c"`` → byte ``0x3c``).
* The hex part after the prefix must be non-empty and even-length, otherwise, the command returns ``ERROR``.
* Any value without the ``0x`` prefix is used verbatim, including strings that look like hex (for example ``"abcd"`` → 4 ASCII bytes).
* Common option numbers:
* ``6`` - Observe (``"0x00"`` = register, ``"0x01"`` = deregister).
* ``17`` - Accept (content format the client will accept, hex-encoded).
* ``35`` - Proxy-Uri (full URI passed to a proxy, verbatim string).
Copy link
Copy Markdown
Collaborator

@divipillai divipillai May 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* The ``<opt_num_X>,<opt_val_X>`` parameters are optional CoAP option pairs:
* When present, ``<payload_len>`` must also be present as the positional separator before the first pair.
* ``<opt_num_X>`` is a decimal integer option number.
* ``<opt_val_X>`` is a quoted string.
* A value prefixed with ``0x`` or ``0X`` is decoded as raw hex bytes (for example, ``"0x3c"`` → byte ``0x3c``).
* The hex part after the prefix must be non-empty and even-length, otherwise, the command returns ``ERROR``.
* Any value without the ``0x`` prefix is used verbatim, including strings that look like hex (for example ``"abcd"`` → 4 ASCII bytes).
* Common option numbers:
* ``6`` - Observe (``"0x00"`` = register, ``"0x01"`` = deregister).
* ``17`` - Accept (content format the client will accept, hex-encoded).
* ``35`` - Proxy-Uri (full URI passed to a proxy, verbatim string).
* The ``<opt_num_X>,<opt_val_X>`` parameters are optional CoAP option pairs:
* When present, ``<payload_len>`` must also be present as the positional separator before the first pair.
* ``<opt_num_X>`` is a decimal integer option number.
* ``<opt_val_X>`` is a quoted string.
* A value prefixed with ``0x`` or ``0X`` is decoded as raw hex bytes (for example, ``"0x3c"`` → byte ``0x3c``).
* The hex part after the prefix must be non-empty and even-length, otherwise, the command returns ``ERROR``.
* Any value without the ``0x`` prefix is used verbatim, including strings that look like hex (for example ``"abcd"`` → 4 ASCII bytes).
* Common option numbers:
* ``6`` - Observe (``"0x00"`` = register, ``"0x01"`` = deregister).
* ``17`` - Accept (content format the client will accept, hex-encoded).
* ``35`` - Proxy-Uri (full URI passed to a proxy, verbatim string).

A break after line no:117, to render correctly. also, after line no:124 - https://ncsbmdoc.z6.web.core.windows.net/addons/addon-serial_modem/PR-283/app/at_coap.html#syntax

@juhaylinen juhaylinen force-pushed the coap_client_xsocket branch 2 times, most recently from f9492cb to 0006a63 Compare May 26, 2026 09:00
Add AT#XCOAPCREQ, AT#XCOAPCCANCEL, and AT#XCOAPCDATA to drive Zephyr
coap_client over a connected UDP/DTLS socket. Responses are delivered
asynchronously via #XCOAPCDATA / #XCOAPCHEAD and #XCOAPCSTAT URCs.

Jira: SM-225

Signed-off-by: Juha Ylinen <juha.ylinen@nordicsemi.no>
@juhaylinen juhaylinen force-pushed the coap_client_xsocket branch from 0006a63 to 1cbd48e Compare May 26, 2026 09:06
@juhaylinen juhaylinen merged commit 854f83f into nrfconnect:main May 26, 2026
3 checks passed
@juhaylinen juhaylinen deleted the coap_client_xsocket branch May 26, 2026 11:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants