ripplebiz 7 hours ago
parent
commit
efb883d1bc
  1. 145
      cli_commands/index.html
  2. 299
      companion_protocol/index.html
  3. 665
      faq/index.html
  4. 5
      kiss_modem_protocol/index.html
  5. 167
      nrf52_power_management/index.html
  6. 12
      number_allocations/index.html
  7. 4
      payloads/index.html
  8. 2
      search/search_index.json
  9. 26
      sitemap.xml
  10. BIN
      sitemap.xml.gz
  11. 2
      terminal_chat_cli/index.html

145
cli_commands/index.html

@ -694,17 +694,6 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#view-or-change-the-boosted-receive-gain-mode" class="md-nav__link">
<span class="md-ellipsis">
View or change the boosted receive gain mode
</span>
</a>
</li>
<li class="md-nav__item">
@ -730,10 +719,10 @@
</li>
<li class="md-nav__item">
<a href="#view-or-change-this-nodes-rx-boosted-gain-mode-sx12xx-only-v1141" class="md-nav__link">
<a href="#view-or-change-this-nodes-rx-boosted-gain-mode-sx12xx-and-lr1110-v1141" class="md-nav__link">
<span class="md-ellipsis">
View or change this node's rx boosted gain mode (SX12xx only, v1.14.1+)
View or change this node's rx boosted gain mode (SX12xx and LR1110, v1.14.1+)
</span>
</a>
@ -1058,6 +1047,17 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#limit-the-number-of-hops-for-an-unscoped-flood-message" class="md-nav__link">
<span class="md-ellipsis">
Limit the number of hops for an unscoped flood message
</span>
</a>
</li>
</ul>
@ -1213,6 +1213,17 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#define-region-hierarchy-single-line" class="md-nav__link">
<span class="md-ellipsis">
Define region hierarchy (single line)
</span>
</a>
</li>
<li class="md-nav__item">
@ -1349,10 +1360,10 @@
</li>
<li class="md-nav__item">
<a href="#view-or-change-thevalue-of-a-sensor" class="md-nav__link">
<a href="#view-or-change-the-value-of-a-sensor" class="md-nav__link">
<span class="md-ellipsis">
View or change thevalue of a sensor
View or change the value of a sensor
</span>
</a>
@ -2231,17 +2242,6 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#view-or-change-the-boosted-receive-gain-mode" class="md-nav__link">
<span class="md-ellipsis">
View or change the boosted receive gain mode
</span>
</a>
</li>
<li class="md-nav__item">
@ -2267,10 +2267,10 @@
</li>
<li class="md-nav__item">
<a href="#view-or-change-this-nodes-rx-boosted-gain-mode-sx12xx-only-v1141" class="md-nav__link">
<a href="#view-or-change-this-nodes-rx-boosted-gain-mode-sx12xx-and-lr1110-v1141" class="md-nav__link">
<span class="md-ellipsis">
View or change this node's rx boosted gain mode (SX12xx only, v1.14.1+)
View or change this node's rx boosted gain mode (SX12xx and LR1110, v1.14.1+)
</span>
</a>
@ -2595,6 +2595,17 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#limit-the-number-of-hops-for-an-unscoped-flood-message" class="md-nav__link">
<span class="md-ellipsis">
Limit the number of hops for an unscoped flood message
</span>
</a>
</li>
</ul>
@ -2750,6 +2761,17 @@
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#define-region-hierarchy-single-line" class="md-nav__link">
<span class="md-ellipsis">
Define region hierarchy (single line)
</span>
</a>
</li>
<li class="md-nav__item">
@ -2886,10 +2908,10 @@
</li>
<li class="md-nav__item">
<a href="#view-or-change-thevalue-of-a-sensor" class="md-nav__link">
<a href="#view-or-change-the-value-of-a-sensor" class="md-nav__link">
<span class="md-ellipsis">
View or change thevalue of a sensor
View or change the value of a sensor
</span>
</a>
@ -3225,15 +3247,6 @@
<p><strong>Default:</strong> Varies by board</p>
<p><strong>Notes:</strong> This setting only controls the power level of the LoRa chip. Some nodes have an additional power amplifier stage which increases the total output. Refer to the node's manual for the correct setting to use. <strong>Setting a value too high may violate the laws in your country.</strong></p>
<hr />
<h4 id="view-or-change-the-boosted-receive-gain-mode">View or change the boosted receive gain mode</h4>
<p><strong>Usage:</strong>
- <code>get radio.rxgain</code>
- <code>set radio.rxgain &lt;state&gt;</code></p>
<p><strong>Parameters:</strong>
- <code>state</code>: <code>on</code>|<code>off</code></p>
<p><strong>Default:</strong> <code>off</code></p>
<p><strong>Note:</strong> Only available on SX1262 and SX1268 based boards.</p>
<hr />
<h4 id="change-the-radio-parameters-for-a-set-duration">Change the radio parameters for a set duration</h4>
<p><strong>Usage:</strong>
- <code>tempradio &lt;freq&gt;,&lt;bw&gt;,&lt;sf&gt;,&lt;cr&gt;,&lt;timeout_mins&gt;</code></p>
@ -3255,7 +3268,7 @@
<p><strong>Note:</strong> Requires reboot to apply
<strong>Serial Only:</strong> <code>set freq &lt;frequency&gt;</code></p>
<hr />
<h4 id="view-or-change-this-nodes-rx-boosted-gain-mode-sx12xx-only-v1141">View or change this node's rx boosted gain mode (SX12xx only, v1.14.1+)</h4>
<h4 id="view-or-change-this-nodes-rx-boosted-gain-mode-sx12xx-and-lr1110-v1141">View or change this node's rx boosted gain mode (SX12xx and LR1110, v1.14.1+)</h4>
<p><strong>Usage:</strong>
- <code>get radio.rxgain</code>
- <code>set radio.rxgain &lt;state&gt;</code></p>
@ -3331,7 +3344,7 @@
- <code>text</code>: Owner information text</p>
<p><strong>Default:</strong> <code>&lt;blank&gt;</code></p>
<p><strong>Note:</strong> <code>|</code> characters are translated to newlines</p>
<p><strong>Note:</strong> Requires firmware 1.12.+</p>
<p><strong>Note:</strong> Requires firmware 1.12+</p>
<hr />
<h4 id="fine-tune-the-battery-reading">Fine-tune the battery reading</h4>
<p><strong>Usage:</strong>
@ -3359,7 +3372,7 @@
<p><strong>Parameters:</strong>
- <code>on</code>: enable power saving
- <code>off</code>: disable power saving</p>
<p><strong>Default:</strong> <code>on</code></p>
<p><strong>Default:</strong> <code>off</code></p>
<p><strong>Note:</strong> When enabled, device enters sleep mode between radio transmissions</p>
<hr />
<h3 id="routing">Routing</h3>
@ -3383,7 +3396,7 @@
- <code>3</code>: DO NOT USE (Reserved) </p>
<p><strong>Default:</strong> <code>0</code></p>
<p><strong>Note:</strong> the 'path.hash.mode' sets the low-level ID/hash encoding size used when the repeater adverts. This setting has no impact on what packet ID/hash size this repeater forwards, all sizes should be forwarded on firmware &gt;= 1.14. This feature was added in firmware 1.14</p>
<p><strong>Temporary Note:</strong> adverts with ID/hash sizes of 2 or 3 bytes may have limited flood propogation in your network while this feature is new as v1.13.0 firmware and older will drop packets with multibyte path ID/hashes as only 1-byte hashes are suppored. Consider your install base of firmware &gt;=1.14 has reached a criticality for effective network flooding before implementing higher ID/hash sizes. </p>
<p><strong>Temporary Note:</strong> adverts with ID/hash sizes of 2 or 3 bytes may have limited flood propagation in your network while this feature is new as v1.13.0 firmware and older will drop packets with multibyte path ID/hashes as only 1-byte hashes are supported. Consider your install base of firmware &gt;=1.14 has reached a criticality for effective network flooding before implementing higher ID/hash sizes. </p>
<hr />
<h4 id="view-or-change-this-nodes-loop-detection">View or change this node's loop detection</h4>
<p><strong>Usage:</strong>
@ -3396,7 +3409,7 @@
- <code>moderate</code>: packets are dropped if repeater's ID/hash appears 2 or more times (1-byte), 1 or more (2-byte), 1 or more (3-byte)
- <code>strict</code>: packets are dropped if repeater's ID/hash appears 1 or more times (1-byte), 1 or more (2-byte), 1 or more (3-byte)</p>
<p><strong>Default:</strong> <code>off</code></p>
<p><strong>Note:</strong> When it is enabled, repeaters will now reject flood packets which look like they are in a loop. This has been happening recently in some meshes when there is just a single 'bad' repeater firmware out there (prob some forked or custom firmware). If the payload is messed with, then forwarded, the same packet ends up causing a packet storm, repeated up to the max 64 hops. This feature was added in firmware 1.14</p>
<p><strong>Note:</strong> When it is enabled, repeaters will now reject flood packets which look like they are in a loop. This has been happening recently in some meshes when there is just a single 'bad' repeater firmware out there (probably some forked or custom firmware). If the payload is messed with, then forwarded, the same packet ends up causing a packet storm, repeated up to the max 64 hops. This feature was added in firmware 1.14</p>
<p><strong>Example:</strong> If preference is <code>loop.detect minimal</code>, and a 1-byte path size packet is received, the repeater will see if its own ID/hash is already in the path. If it's already encoded 4 times, it will reject the packet. If the packet uses 2-byte path size, and repeater's own ID/hash is already encoded 2 times, it rejects. If the packet uses 3-byte path size, and the repeater's own ID/hash is already encoded 1 time, it rejects. </p>
<hr />
<h4 id="view-or-change-the-retransmit-delay-factor-for-flood-traffic">View or change the retransmit delay factor for flood traffic</h4>
@ -3406,6 +3419,7 @@
<p><strong>Parameters:</strong>
- <code>value</code>: Transmit delay factor (0-2)</p>
<p><strong>Default:</strong> <code>0.5</code></p>
<p><strong>Note:</strong> When multiple nearby repeaters all hear the same flood packet, each waits a random amount of time before retransmitting to avoid simultaneous collisions. This factor scales the size of that random window. Higher values reduce collision risk at the cost of added latency. <code>0</code> disables the window entirely.</p>
<hr />
<h4 id="view-or-change-the-retransmit-delay-factor-for-direct-traffic">View or change the retransmit delay factor for direct traffic</h4>
<p><strong>Usage:</strong>
@ -3414,6 +3428,7 @@
<p><strong>Parameters:</strong>
- <code>value</code>: Direct transmit delay factor (0-2)</p>
<p><strong>Default:</strong> <code>0.2</code></p>
<p><strong>Note:</strong> Same collision-avoidance random window as <code>txdelay</code>, but applied to direct (non-flood, routed) traffic. The default is lower because direct packets are addressed to a specific next hop, so far fewer nodes compete to retransmit them.</p>
<hr />
<h4 id="experimental-view-or-change-the-processing-delay-for-received-traffic">[Experimental] View or change the processing delay for received traffic</h4>
<p><strong>Usage:</strong>
@ -3422,6 +3437,7 @@
<p><strong>Parameters:</strong>
- <code>value</code>: Receive delay base (0-20)</p>
<p><strong>Default:</strong> <code>0.0</code></p>
<p><strong>Note:</strong> When enabled, repeaters that received a flood packet with a weak signal are held in a delay queue before processing, while those that received it with a strong signal process it immediately. This gives strong-signal paths forwarding priority. By the time weak-signal nodes process their copy, the packet may have already propagated and will be suppressed as a duplicate, reducing redundant retransmissions.</p>
<hr />
<h4 id="view-or-change-the-duty-cycle-limit">View or change the duty cycle limit</h4>
<p><strong>Usage:</strong>
@ -3503,6 +3519,15 @@
- <code>value</code>: Maximum flood hop count (0-64)</p>
<p><strong>Default:</strong> <code>64</code></p>
<hr />
<h4 id="limit-the-number-of-hops-for-an-unscoped-flood-message">Limit the number of hops for an unscoped flood message</h4>
<p><strong>Usage:</strong>
- <code>get flood.max.unscoped</code>
- <code>set flood.max.unscoped &lt;value&gt;</code></p>
<p><strong>Parameters:</strong>
- <code>value</code>: Maximum flood hop count (0-64) for a packet without a scope (no region set)</p>
<p><strong>Default:</strong> <code>0xFF</code> - indicates it hasn't been set, will track flood.max until it is.</p>
<p><strong>Note:</strong> An alternative to <code>region denyf *</code>, setting <code>flood.max.unscoped</code> to a lower value such as <code>3</code> would allow for local unscoped messages to propagate, while preventing noisy neighbors from flooding a local region.</p>
<hr />
<h3 id="acl">ACL</h3>
<h4 id="add-update-or-remove-permissions-for-a-companion">Add, update or remove permissions for a companion</h4>
<p><strong>Usage:</strong>
@ -3585,6 +3610,34 @@
- <code>name</code>: Region name
- <code>parent_name</code>: Parent region name (optional, defaults to wildcard)</p>
<hr />
<h4 id="define-region-hierarchy-single-line">Define region hierarchy (single line)</h4>
<p><strong>Usage:</strong>
- <code>region def &lt;token&gt; [&lt;token&gt; ...]</code></p>
<p><strong>Parameters (tokens):</strong> Space-separated. A logical <strong>cursor</strong> starts at the wildcard <code>*</code>.</p>
<ul>
<li><strong><code>name</code></strong> — Create <code>name</code> as a child of the current cursor (equivalent to <code>region put name</code> with the cursor as parent). Cursor moves to <code>name</code>.</li>
<li><strong><code>name|jump</code></strong> <em>(or <code>name,jump</code>)</em> — Create <code>name</code> as a child of the current cursor, then move the cursor to <code>jump</code> (must already exist on the node, or have been created earlier in this command). <code>jump</code> is <strong>not</strong> the parent of <code>name</code>; use this form to pop back up and start another branch.</li>
</ul>
<p><strong>Behavior:</strong> Each created region defaults to flood-allowed (same as <code>region put</code>). The reply is the resulting region tree (same format as bare <code>region</code>); review it before running <code>region save</code> to persist. On error, the reply is <code>Err - ...</code> and any regions placed before the failure remain on the node, just like a partial chain of <code>region put</code>.</p>
<p><strong>Existing regions:</strong> <code>region def</code> does not clear the existing tree — if a name already exists, its parent is updated to the current cursor; otherwise a new region is created. To start from scratch, <code>region remove</code> the unwanted regions first.</p>
<p><strong>Limits:</strong> Repeater serial accepts one line up to <strong>160 characters</strong>. For larger trees, split across multiple <code>region def</code> commands; the cursor resets to <code>*</code> between commands, so lead the next command with <code>child|ancestor</code> to reposition. Each token splits at most once on <code>|</code><code>region def a|b|c|d</code> is not a flat-list shorthand; see the flat-list example below.</p>
<p><strong>Example — linear chain</strong> (each token becomes a child of the previous):</p>
<pre><code>region def a b c d e
region save
</code></pre>
<p><strong>Example — branched tree</strong> (equivalent to <code>region put a</code>, <code>region put b a</code>, <code>region put c b</code>, <code>region put d c</code>, <code>region put e b</code>, <code>region put f e</code>):</p>
<pre><code>region def a b c d|b e f
region save
</code></pre>
<p><strong>Example — error and partial state:</strong></p>
<pre><code>region def a b c|nope d
</code></pre>
<p>The reply is <code>Err - unknown jump: nope</code>. <code>a</code>, <code>b</code>, and <code>c</code> were placed before the failure; <code>d</code> was not. Run <code>region</code> to inspect, then re-run with a corrected jump or repair with <code>region remove</code> / <code>region put</code>.</p>
<p><strong>Example — flat list</strong> (each region a child of <code>*</code>). Use <code>|*</code> after each token to pop the cursor back to the root before the next token:</p>
<pre><code>region def a|* b|* c|* d|* e|* f
region save
</code></pre>
<hr />
<h4 id="remove-a-region">Remove a region</h4>
<p><strong>Usage:</strong>
- <code>region remove &lt;name&gt;</code></p>
@ -3598,7 +3651,7 @@
<p><strong>Serial Only:</strong> Yes</p>
<p><strong>Parameters:</strong>
- <code>filter</code>: <code>allowed</code>|<code>denied</code></p>
<p><strong>Note:</strong> Requires firmware 1.12.+</p>
<p><strong>Note:</strong> Requires firmware 1.12+</p>
<hr />
<h4 id="dump-all-defined-regions-and-flood-permissions">Dump all defined regions and flood permissions</h4>
<p><strong>Usage:</strong>
@ -3712,7 +3765,7 @@ region save
- <code>start</code>: Optional starting index (defaults to 0)</p>
<p><strong>Note:</strong> Output format: <code>&lt;var_name&gt;=&lt;value&gt;\n</code></p>
<hr />
<h4 id="view-or-change-thevalue-of-a-sensor">View or change thevalue of a sensor</h4>
<h4 id="view-or-change-the-value-of-a-sensor">View or change the value of a sensor</h4>
<p><strong>Usage:</strong>
- <code>sensor get &lt;key&gt;</code>
- <code>sensor set &lt;key&gt; &lt;value&gt;</code></p>

299
companion_protocol/index.html

@ -542,13 +542,41 @@
</span>
</a>
<nav class="md-nav" aria-label="6. Send Channel Data Datagram">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#registered-data_type-values" class="md-nav__link">
<span class="md-ellipsis">
Registered data_type values
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#receive-channel-data-datagram" class="md-nav__link">
<span class="md-ellipsis">
Receive Channel Data Datagram
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#6-get-message" class="md-nav__link">
<a href="#7-get-message" class="md-nav__link">
<span class="md-ellipsis">
6. Get Message
7. Get Message
</span>
</a>
@ -556,10 +584,10 @@
</li>
<li class="md-nav__item">
<a href="#7-get-battery-and-storage" class="md-nav__link">
<a href="#8-get-battery-and-storage" class="md-nav__link">
<span class="md-ellipsis">
7. Get Battery and Storage
8. Get Battery and Storage
</span>
</a>
@ -683,6 +711,17 @@
<nav class="md-nav" aria-label="Response Parsing">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#terminology" class="md-nav__link">
<span class="md-ellipsis">
Terminology
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#packet-types" class="md-nav__link">
<span class="md-ellipsis">
@ -1372,13 +1411,41 @@
</span>
</a>
<nav class="md-nav" aria-label="6. Send Channel Data Datagram">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#registered-data_type-values" class="md-nav__link">
<span class="md-ellipsis">
Registered data_type values
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#receive-channel-data-datagram" class="md-nav__link">
<span class="md-ellipsis">
Receive Channel Data Datagram
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#6-get-message" class="md-nav__link">
<a href="#7-get-message" class="md-nav__link">
<span class="md-ellipsis">
6. Get Message
7. Get Message
</span>
</a>
@ -1386,10 +1453,10 @@
</li>
<li class="md-nav__item">
<a href="#7-get-battery-and-storage" class="md-nav__link">
<a href="#8-get-battery-and-storage" class="md-nav__link">
<span class="md-ellipsis">
7. Get Battery and Storage
8. Get Battery and Storage
</span>
</a>
@ -1513,6 +1580,17 @@
<nav class="md-nav" aria-label="Response Parsing">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#terminology" class="md-nav__link">
<span class="md-ellipsis">
Terminology
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#packet-types" class="md-nav__link">
<span class="md-ellipsis">
@ -1807,7 +1885,7 @@
<p><strong>Send Initial Commands</strong></p>
<ul>
<li>Send <code>CMD_APP_START</code> to identify your app to firmware and get radio settings</li>
<li>Send <code>CMD_DEVICE_QEURY</code> to fetch device info and negotiate supported protocol versions</li>
<li>Send <code>CMD_DEVICE_QUERY</code> to fetch device info and negotiate supported protocol versions</li>
<li>Send <code>CMD_SET_DEVICE_TIME</code> to set the firmware clock</li>
<li>Send <code>CMD_GET_CONTACTS</code> to fetch all contacts</li>
<li>Send <code>CMD_GET_CHANNEL</code> multiple times to fetch all channel slots</li>
@ -1967,24 +2045,130 @@ Bytes 7+: Message Text (UTF-8, variable length)
<p><strong>Response</strong>: <code>PACKET_MSG_SENT</code> (0x06) on success</p>
<hr />
<h3 id="6-send-channel-data-datagram">6. Send Channel Data Datagram</h3>
<p><strong>Purpose</strong>: Send binary datagram data to a channel.</p>
<p><strong>Purpose</strong>: Send a binary datagram to a channel. Unlike channel text messages, datagrams carry no built-in sender identity and no timestamp — applications needing either must encode them inside the binary payload.</p>
<p><strong>Command Format</strong>:</p>
<pre><code>Byte 0: 0x3E
Bytes 1-2: Data Type (`data_type`, 16-bit little-endian)
Byte 3: Channel Index (0-7)
Bytes 4+: Binary payload bytes (variable length)
<pre><code>Byte 0: 0x3E
Byte 1: Channel Index (0-7)
Byte 2: Path Length (0xFF = flood, otherwise actual path length)
Bytes 3 .. 2+path_len: Path (omitted when path_len == 0xFF)
Next 2 bytes (little-endian): Data Type (`data_type`, uint16)
Remaining bytes: Binary payload (variable length)
</code></pre>
<p><strong>Example</strong> (flood, <code>DATA_TYPE_DEV</code>, payload <code>A1 B2 C3</code>, channel 1):</p>
<pre><code>3E 01 FF FF FF A1 B2 C3
</code></pre>
<p><strong>Data Type / Transport Mapping</strong>:
- <code>0x0000</code> is invalid for this command.
- <code>0x0000</code> (<code>DATA_TYPE_RESERVED</code>) is invalid and rejected with <code>PACKET_ERROR</code>.
- <code>0xFFFF</code> (<code>DATA_TYPE_DEV</code>) is the developer namespace for experimenting and developing apps.
- Other non-zero values can be used as assigned application/community namespaces.</p>
<p><strong>Note</strong>: Applications that need a timestamp should encode it inside the binary payload.</p>
- Values <code>0x0001</code><code>0xFFFE</code> are available for registered application/community namespaces. See the <a href="#registered-data_type-values">Registered data_type values</a> table below.</p>
<p><strong>Limits</strong>:
- Maximum payload length is <code>163</code> bytes.
- Larger payloads are rejected with <code>PACKET_ERROR</code>.</p>
<p><strong>Response</strong>: <code>PACKET_OK</code> (0x00) on success</p>
- Maximum payload length is <code>MAX_CHANNEL_DATA_LENGTH = MAX_FRAME_SIZE - 9 = 163</code> bytes.
- Larger payloads are rejected with <code>PACKET_ERROR</code> (<code>ERR_CODE_ILLEGAL_ARG</code>).</p>
<p><strong>Response</strong>: <code>PACKET_OK</code> (0x00) on success, or <code>PACKET_ERROR</code> (0x01) with one of:
- <code>ERR_CODE_NOT_FOUND</code> (2) — unknown <code>channel_idx</code>
- <code>ERR_CODE_ILLEGAL_ARG</code> (6) — invalid <code>path_len</code>, reserved <code>data_type</code> (<code>0x0000</code>), or payload larger than <code>MAX_CHANNEL_DATA_LENGTH</code>
- <code>ERR_CODE_TABLE_FULL</code> (3) — outbound send queue is full; retry later</p>
<p><strong>Inbound datagrams</strong> are delivered to the host via <code>RESP_CODE_CHANNEL_DATA_RECV</code> (0x1B); see <a href="#receive-channel-data-datagram">Receive Channel Data Datagram</a>.</p>
<h4 id="registered-data_type-values">Registered <code>data_type</code> values</h4>
<p><code>data_type</code> is an <strong>application identifier</strong>, not a payload-format identifier. Each registered value identifies an application that owns its own internal payload schemas. The firmware does not inspect payload contents — <code>data_type</code> is transported opaquely.</p>
<table>
<thead>
<tr>
<th>Value</th>
<th>Constant</th>
<th>Purpose</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x0000</td>
<td><code>DATA_TYPE_RESERVED</code></td>
<td>Reserved; invalid on send</td>
</tr>
<tr>
<td>0x0001 – 0x00FF</td>
<td></td>
<td>Reserved for internal use</td>
</tr>
<tr>
<td>0x0100 – 0xFEFF</td>
<td></td>
<td>Registered application namespaces (see <a href="../number_allocations/">number_allocations.md</a>)</td>
</tr>
<tr>
<td>0xFF00 – 0xFFFE</td>
<td></td>
<td>Testing/development; no registration required</td>
</tr>
<tr>
<td>0xFFFF</td>
<td><code>DATA_TYPE_DEV</code></td>
<td>Developer/experimental namespace</td>
</tr>
</tbody>
</table>
<p>To register a new application, submit a PR adding a row to the table in <a href="../number_allocations/">docs/number_allocations.md</a>. Internal sub-formats within an allocated application ID are owned by that application and are not tracked in MeshCore firmware or this document.</p>
<hr />
<h3 id="receive-channel-data-datagram">Receive Channel Data Datagram</h3>
<p>Inbound group datagrams (radio-level <code>PAYLOAD_TYPE_GRP_DATA</code>, 0x06) are forwarded to the host as <code>RESP_CODE_CHANNEL_DATA_RECV</code> notifications.</p>
<p><strong>Frame Format</strong> (<code>RESP_CODE_CHANNEL_DATA_RECV</code>, 0x1B):</p>
<pre><code>Byte 0: 0x1B (packet type)
Byte 1: SNR (signed int8, scaled ×4 — divide by 4.0 to recover dB)
Bytes 2-3: Reserved (clients MUST ignore)
Byte 4: Channel Index (0-7)
Byte 5: Path Length (actual path length when flooded, otherwise 0xFF for direct)
Bytes 6-7: Data Type (uint16 little-endian)
Byte 8: Data Length
Bytes 9 .. 8+data_len: Payload
</code></pre>
<p><strong>Path bytes are not forwarded</strong>: Only <code>path_len</code> is reported in the receive frame — the path itself is not copied to the host. There are no path bytes between byte 5 and the data_type field at bytes 6–7, regardless of <code>path_len</code>.</p>
<p><strong>Path Length semantics differ between send and receive</strong>:</p>
<table>
<thead>
<tr>
<th>Direction</th>
<th><code>path_len = 0xFF</code></th>
<th><code>path_len ≠ 0xFF</code></th>
</tr>
</thead>
<tbody>
<tr>
<td>Send</td>
<td>Flood the network</td>
<td>Direct route; the encoded path follows (low 6 bits = hash count, top 2 bits + 1 = hash size; on-wire byte count = <code>hash_count × hash_size</code>)</td>
</tr>
<tr>
<td>Receive</td>
<td>Packet arrived via direct route</td>
<td>Packet was flooded; this is the encoded <code>pkt-&gt;path_len</code> field as observed (no path bytes follow)</td>
</tr>
</tbody>
</table>
<p>In other words, the meaning of <code>0xFF</code> is inverted between the two directions, and on receive the field carries metadata only — never a routable path. <code>path_len</code> is an encoded byte (see <code>Packet::isValidPathLen</code> / <code>Packet::writePath</code> in <code>src/Packet.cpp</code>), not a raw byte count.</p>
<p><strong>Note</strong>: The device may also emit <code>PACKET_MESSAGES_WAITING</code> (0x83) to notify the host that datagrams are queued; poll with <code>CMD_SYNC_NEXT_MESSAGE</code> (0x0A) to retrieve them.</p>
<p><strong>Parsing Pseudocode</strong>:</p>
<pre><code class="language-python">def parse_channel_data_recv(data):
if len(data) &lt; 9:
return None
snr_byte = data[1]
snr = (snr_byte if snr_byte &lt; 128 else snr_byte - 256) / 4.0
channel_idx = data[4]
path_len = data[5]
data_type = int.from_bytes(data[6:8], 'little')
data_len = data[8]
if 9 + data_len &gt; len(data):
return None
payload = data[9:9 + data_len]
return {
'snr': snr,
'channel_idx': channel_idx,
'path_len': path_len,
'data_type': data_type,
'payload': bytes(payload),
}
</code></pre>
<hr />
<h3 id="6-get-message">6. Get Message</h3>
<h3 id="7-get-message">7. Get Message</h3>
<p><strong>Purpose</strong>: Request the next queued message from the device.</p>
<p><strong>Command Format</strong>:</p>
<pre><code>Byte 0: 0x0A
@ -1995,10 +2179,11 @@ Bytes 4+: Binary payload bytes (variable length)
<p><strong>Response</strong>:
- <code>PACKET_CHANNEL_MSG_RECV</code> (0x08) or <code>PACKET_CHANNEL_MSG_RECV_V3</code> (0x11) for channel messages
- <code>PACKET_CONTACT_MSG_RECV</code> (0x07) or <code>PACKET_CONTACT_MSG_RECV_V3</code> (0x10) for contact messages
- <code>PACKET_CHANNEL_DATA_RECV</code> (0x1B) for channel data datagrams
- <code>PACKET_NO_MORE_MSGS</code> (0x0A) if no messages available</p>
<p><strong>Note</strong>: Poll this command periodically to retrieve queued messages. The device may also send <code>PACKET_MESSAGES_WAITING</code> (0x83) as a notification when messages are available.</p>
<hr />
<h3 id="7-get-battery-and-storage">7. Get Battery and Storage</h3>
<h3 id="8-get-battery-and-storage">8. Get Battery and Storage</h3>
<p><strong>Purpose</strong>: Query device battery voltage and storage usage.</p>
<p><strong>Command Format</strong>:</p>
<pre><code>Byte 0: 0x14
@ -2181,6 +2366,13 @@ Bytes 11+: Message Text (UTF-8)
- Include a chunk indicator (e.g., "[1/3] message text")</p>
<hr />
<h2 id="response-parsing">Response Parsing</h2>
<h3 id="terminology">Terminology</h3>
<p>This document uses a spec-level naming convention (<code>PACKET_*</code>) for bytes the firmware sends back to the host. In the firmware source these same values are split across two <code>#define</code> families by purpose:</p>
<ul>
<li><code>RESP_CODE_*</code> — direct replies to a command (e.g. <code>RESP_CODE_CHANNEL_DATA_RECV</code> = <code>PACKET_CHANNEL_DATA_RECV</code> = 0x1B).</li>
<li><code>PUSH_CODE_*</code> — asynchronous notifications not tied to a specific command (e.g. <code>PUSH_CODE_MSG_WAITING</code> = <code>PACKET_MESSAGES_WAITING</code> = 0x83).</li>
</ul>
<p>Byte values are authoritative; names are aliases. When reading firmware source, <code>RESP_CODE_X</code> / <code>PUSH_CODE_X</code> correspond to this doc's <code>PACKET_X</code> of the same numeric value.</p>
<h3 id="packet-types">Packet Types</h3>
<table>
<thead>
@ -2272,6 +2464,11 @@ Bytes 11+: Message Text (UTF-8)
<td>Channel information</td>
</tr>
<tr>
<td>0x1B</td>
<td>PACKET_CHANNEL_DATA_RECV</td>
<td>Channel data datagram</td>
</tr>
<tr>
<td>0x80</td>
<td>PACKET_ADVERTISEMENT</td>
<td>Advertisement packet</td>
@ -2434,58 +2631,49 @@ Bytes 6-9: Suggested Timeout (32-bit little-endian, milliseconds)
Bytes 1-6: ACK Code (6 bytes, hex)
</code></pre>
<h3 id="error-codes">Error Codes</h3>
<p><strong>PACKET_ERROR</strong> (0x01) may include an error code in byte 1:</p>
<p><code>PACKET_ERROR</code> (0x01) carries a single-byte error code in byte 1. Values match the <code>ERR_CODE_*</code> constants defined in <code>examples/companion_radio/MyMesh.cpp</code>:</p>
<table>
<thead>
<tr>
<th>Error Code</th>
<th>Code</th>
<th>Constant (firmware)</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x00</td>
<td>Generic error (no specific code)</td>
</tr>
<tr>
<td>0x01</td>
<td>Invalid command</td>
</tr>
<tr>
<td>0x02</td>
<td>Invalid parameter</td>
</tr>
<tr>
<td>0x03</td>
<td>Channel not found</td>
</tr>
<tr>
<td>0x04</td>
<td>Channel already exists</td>
<td>1</td>
<td><code>ERR_CODE_UNSUPPORTED_CMD</code></td>
<td>Unknown or unsupported command byte / sub-command</td>
</tr>
<tr>
<td>0x05</td>
<td>Channel index out of range</td>
<td>2</td>
<td><code>ERR_CODE_NOT_FOUND</code></td>
<td>Target not found (channel, contact, message, etc.)</td>
</tr>
<tr>
<td>0x06</td>
<td>Secret mismatch</td>
<td>3</td>
<td><code>ERR_CODE_TABLE_FULL</code></td>
<td>Internal queue or table is full — retry later</td>
</tr>
<tr>
<td>0x07</td>
<td>Message too long</td>
<td>4</td>
<td><code>ERR_CODE_BAD_STATE</code></td>
<td>Operation not valid in current device state (e.g. iterator already running)</td>
</tr>
<tr>
<td>0x08</td>
<td>Device busy</td>
<td>5</td>
<td><code>ERR_CODE_FILE_IO_ERROR</code></td>
<td>Filesystem or storage I/O failure</td>
</tr>
<tr>
<td>0x09</td>
<td>Not enough storage</td>
<td>6</td>
<td><code>ERR_CODE_ILLEGAL_ARG</code></td>
<td>Invalid argument (bad length, out-of-range value, reserved field, etc.)</td>
</tr>
</tbody>
</table>
<p><strong>Note</strong>: Error codes may vary by firmware version. Always check byte 1 of <code>PACKET_ERROR</code> response.</p>
<p><strong>Note</strong>: Error codes may vary by firmware version. Always check byte 1 of <code>PACKET_ERROR</code> response, and treat unknown codes as generic errors.</p>
<h3 id="frame-handling">Frame Handling</h3>
<p>BLE implementations enqueue and deliver one protocol frame per BLE write/notification at the firmware layer.</p>
<ul>
@ -2523,7 +2711,8 @@ Bytes 1-6: ACK Code (6 bytes, hex)
<li><code>GET_CHANNEL</code><code>PACKET_CHANNEL_INFO</code></li>
<li><code>SET_CHANNEL</code><code>PACKET_OK</code> or <code>PACKET_ERROR</code></li>
<li><code>SEND_CHANNEL_MESSAGE</code><code>PACKET_MSG_SENT</code></li>
<li><code>GET_MESSAGE</code><code>PACKET_CHANNEL_MSG_RECV</code>, <code>PACKET_CONTACT_MSG_RECV</code>, or <code>PACKET_NO_MORE_MSGS</code></li>
<li><code>GET_MESSAGE</code><code>PACKET_CHANNEL_MSG_RECV</code>, <code>PACKET_CONTACT_MSG_RECV</code>, <code>PACKET_CHANNEL_DATA_RECV</code>, or <code>PACKET_NO_MORE_MSGS</code></li>
<li><code>SEND_CHANNEL_DATA</code><code>PACKET_OK</code> or <code>PACKET_ERROR</code></li>
<li><code>GET_BATTERY</code><code>PACKET_BATTERY</code></li>
</ul>
</li>
@ -2625,7 +2814,7 @@ response = wait_for_response(PACKET_MSG_SENT)
</li>
<li>Send <code>CMD_SYNC_NEXT_MESSAGE</code> when <code>PUSH_CODE_MSG_WAITING</code> is received</li>
<li>
<p>Implement message deduplication to avoid display the same message twice</p>
<p>Implement message deduplication to avoid displaying the same message twice</p>
</li>
<li>
<p><strong>Channel Management</strong>:</p>

665
faq/index.html

File diff suppressed because it is too large

5
kiss_modem_protocol/index.html

@ -1822,6 +1822,11 @@
<td><code>0x06</code></td>
<td>Encryption failed</td>
</tr>
<tr>
<td>TxBusy</td>
<td><code>0x07</code></td>
<td>Transmit busy</td>
</tr>
</tbody>
</table>
<h3 id="unsolicited-events">Unsolicited Events</h3>

167
nrf52_power_management/index.html

@ -1090,13 +1090,38 @@
<li>Allows firmware to determine why it last shut down (user request, low voltage, boot protection)</li>
</ul>
<h3 id="shutdown-reason-tracking">Shutdown Reason Tracking</h3>
<p>Shutdown reason codes (stored in GPREGRET2):
| Code | Name | Description |
|------|------|-------------|
| 0x00 | NONE | Normal boot / no previous shutdown |
| 0x4C | LOW_VOLTAGE | Runtime low voltage threshold reached |
| 0x55 | USER | User requested powerOff() |
| 0x42 | BOOT_PROTECT | Boot voltage protection triggered |</p>
<p>Shutdown reason codes (stored in GPREGRET2):</p>
<table>
<thead>
<tr>
<th>Code</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>0x00</td>
<td>NONE</td>
<td>Normal boot / no previous shutdown</td>
</tr>
<tr>
<td>0x4C</td>
<td>LOW_VOLTAGE</td>
<td>Runtime low voltage threshold reached</td>
</tr>
<tr>
<td>0x55</td>
<td>USER</td>
<td>User requested powerOff()</td>
</tr>
<tr>
<td>0x42</td>
<td>BOOT_PROTECT</td>
<td>Boot voltage protection triggered</td>
</tr>
</tbody>
</table>
<h2 id="supported-boards">Supported Boards</h2>
<table>
<thead>
@ -1292,25 +1317,115 @@
- Use 50mV hysteresis for noise immunity
- Wake the device from SYSTEMOFF when triggered</p>
<p>VBUS wake is enabled via the POWER peripheral USBDETECTED event whenever <code>configureVoltageWake()</code> is used. This requires USB VBUS to be routed to the nRF52 (typical on nRF52840 boards with native USB).</p>
<p><strong>LPCOMP Reference Selection (PWRMGT_LPCOMP_REFSEL)</strong>:
| REFSEL | Fraction | VBAT @ 1M/1M divider (VDD=3.0-3.3) | VBAT @ 1.5M/1M divider (VDD=3.0-3.3) |
|--------|----------|------------------------------------|--------------------------------------|
| 0 | 1/8 | 0.75-0.82 V | 0.94-1.03 V |
| 1 | 2/8 | 1.50-1.65 V | 1.88-2.06 V |
| 2 | 3/8 | 2.25-2.47 V | 2.81-3.09 V |
| 3 | 4/8 | 3.00-3.30 V | 3.75-4.12 V |
| 4 | 5/8 | 3.75-4.12 V | 4.69-5.16 V |
| 5 | 6/8 | 4.50-4.95 V | 5.62-6.19 V |
| 6 | 7/8 | 5.25-5.77 V | 6.56-7.22 V |
| 7 | ARef | - | - |
| 8 | 1/16 | 0.38-0.41 V | 0.47-0.52 V |
| 9 | 3/16 | 1.12-1.24 V | 1.41-1.55 V |
| 10 | 5/16 | 1.88-2.06 V | 2.34-2.58 V |
| 11 | 7/16 | 2.62-2.89 V | 3.28-3.61 V |
| 12 | 9/16 | 3.38-3.71 V | 4.22-4.64 V |
| 13 | 11/16 | 4.12-4.54 V | 5.16-5.67 V |
| 14 | 13/16 | 4.88-5.36 V | 6.09-6.70 V |
| 15 | 15/16 | 5.62-6.19 V | 7.03-7.73 V |</p>
<p><strong>LPCOMP Reference Selection (PWRMGT_LPCOMP_REFSEL)</strong>:</p>
<table>
<thead>
<tr>
<th>REFSEL</th>
<th>Fraction</th>
<th>VBAT @ 1M/1M divider (VDD=3.0-3.3)</th>
<th>VBAT @ 1.5M/1M divider (VDD=3.0-3.3)</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>1/8</td>
<td>0.75-0.82 V</td>
<td>0.94-1.03 V</td>
</tr>
<tr>
<td>1</td>
<td>2/8</td>
<td>1.50-1.65 V</td>
<td>1.88-2.06 V</td>
</tr>
<tr>
<td>2</td>
<td>3/8</td>
<td>2.25-2.47 V</td>
<td>2.81-3.09 V</td>
</tr>
<tr>
<td>3</td>
<td>4/8</td>
<td>3.00-3.30 V</td>
<td>3.75-4.12 V</td>
</tr>
<tr>
<td>4</td>
<td>5/8</td>
<td>3.75-4.12 V</td>
<td>4.69-5.16 V</td>
</tr>
<tr>
<td>5</td>
<td>6/8</td>
<td>4.50-4.95 V</td>
<td>5.62-6.19 V</td>
</tr>
<tr>
<td>6</td>
<td>7/8</td>
<td>5.25-5.77 V</td>
<td>6.56-7.22 V</td>
</tr>
<tr>
<td>7</td>
<td>ARef</td>
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>8</td>
<td>1/16</td>
<td>0.38-0.41 V</td>
<td>0.47-0.52 V</td>
</tr>
<tr>
<td>9</td>
<td>3/16</td>
<td>1.12-1.24 V</td>
<td>1.41-1.55 V</td>
</tr>
<tr>
<td>10</td>
<td>5/16</td>
<td>1.88-2.06 V</td>
<td>2.34-2.58 V</td>
</tr>
<tr>
<td>11</td>
<td>7/16</td>
<td>2.62-2.89 V</td>
<td>3.28-3.61 V</td>
</tr>
<tr>
<td>12</td>
<td>9/16</td>
<td>3.38-3.71 V</td>
<td>4.22-4.64 V</td>
</tr>
<tr>
<td>13</td>
<td>11/16</td>
<td>4.12-4.54 V</td>
<td>5.16-5.67 V</td>
</tr>
<tr>
<td>14</td>
<td>13/16</td>
<td>4.88-5.36 V</td>
<td>6.09-6.70 V</td>
</tr>
<tr>
<td>15</td>
<td>15/16</td>
<td>5.62-6.19 V</td>
<td>7.03-7.73 V</td>
</tr>
</tbody>
</table>
<p><strong>Important</strong>: For boards with a voltage divider on the battery sense pin, LPCOMP measures the divided voltage. Use:
<code>VBAT_threshold ≈ (VDD * fraction) * divider_scale</code>, where <code>divider_scale = (Rtop + Rbottom) / Rbottom</code> (e.g., 2.0 for 1M/1M, 2.5 for 1.5M/1M, 3.0 for XIAO).</p>
<h3 id="softdevice-compatibility">SoftDevice Compatibility</h3>

12
number_allocations/index.html

@ -624,7 +624,7 @@
<h1 id="number-allocations">Number Allocations</h1>
<p>This document lists unique numbers/identifiers used in various MeshCore protcol payloads.</p>
<p>This document lists unique numbers/identifiers used in various MeshCore protocol payloads.</p>
<h1 id="group-data-types">Group Data Types</h1>
<p>The <code>PAYLOAD_TYPE_GRP_DATA</code> payloads have a 16-bit data-type field, which identifies which application the packet is for.</p>
<p>To make sure multiple applications can function without interfering with each other, the table below is for reserving various ranges of data-type values. Just modify this table, adding a row, then submit a PR to have it authorised/merged.</p>
@ -645,6 +645,16 @@
<td></td>
</tr>
<tr>
<td>0100</td>
<td>MeshCore Open</td>
<td>[email protected] — https://github.com/zjs81/meshcore-open</td>
</tr>
<tr>
<td>0110 - 011F</td>
<td>Ripple</td>
<td>[email protected] — https://buymeacoffee.com/ripplebiz</td>
</tr>
<tr>
<td>FF00 - FFFF</td>
<td>-reserved for testing/dev-</td>
<td></td>

4
payloads/index.html

@ -840,7 +840,7 @@
</tbody>
</table>
<h1 id="acknowledgement">Acknowledgement</h1>
<p>An acknowledgement that a message was received. Note that for returned path messages, an acknowledgement can be sent in the "extra" payload (see <a href="#returned-path">Returned Path</a>) instead of as a separate ackowledgement packet. CLI commands do not cause acknowledgement responses, neither discrete nor extra.</p>
<p>An acknowledgement that a message was received. Note that for returned path messages, an acknowledgement can be sent in the "extra" payload (see <a href="#returned-path">Returned Path</a>) instead of as a separate acknowledgement packet. CLI commands do not cause acknowledgement responses, neither discrete nor extra.</p>
<table>
<thead>
<tr>
@ -997,7 +997,7 @@
<p>Not defined in <code>BaseChatMesh</code>.</p>
<h3 id="get-access-list">Get Access List</h3>
<p>Not defined in <code>BaseChatMesh</code>.</p>
<h3 id="get-neighors">Get Neighors</h3>
<h3 id="get-neighbors">Get Neighbors</h3>
<p>Not defined in <code>BaseChatMesh</code>.</p>
<h3 id="get-owner-info">Get Owner Info</h3>
<p>Not defined in <code>BaseChatMesh</code>.</p>

2
search/search_index.json

File diff suppressed because one or more lines are too long

26
sitemap.xml

@ -2,54 +2,54 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://meshcore-dev.github.io/meshcore/</loc>
<lastmod>2026-06-02</lastmod>
<lastmod>2026-06-06</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/cli_commands/</loc>
<lastmod>2026-06-02</lastmod>
<lastmod>2026-06-06</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/companion_protocol/</loc>
<lastmod>2026-06-02</lastmod>
<lastmod>2026-06-06</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/docs/</loc>
<lastmod>2026-06-02</lastmod>
<lastmod>2026-06-06</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/faq/</loc>
<lastmod>2026-06-02</lastmod>
<lastmod>2026-06-06</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/kiss_modem_protocol/</loc>
<lastmod>2026-06-02</lastmod>
<lastmod>2026-06-06</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/nrf52_power_management/</loc>
<lastmod>2026-06-02</lastmod>
<lastmod>2026-06-06</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/number_allocations/</loc>
<lastmod>2026-06-02</lastmod>
<lastmod>2026-06-06</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/packet_format/</loc>
<lastmod>2026-06-02</lastmod>
<lastmod>2026-06-06</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/payloads/</loc>
<lastmod>2026-06-02</lastmod>
<lastmod>2026-06-06</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/qr_codes/</loc>
<lastmod>2026-06-02</lastmod>
<lastmod>2026-06-06</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/stats_binary_frames/</loc>
<lastmod>2026-06-02</lastmod>
<lastmod>2026-06-06</lastmod>
</url>
<url>
<loc>https://meshcore-dev.github.io/meshcore/terminal_chat_cli/</loc>
<lastmod>2026-06-02</lastmod>
<lastmod>2026-06-06</lastmod>
</url>
</urlset>

BIN
sitemap.xml.gz

Binary file not shown.

2
terminal_chat_cli/index.html

@ -658,7 +658,7 @@
<p>Shows the device version and firmware build date.</p>
<pre><code>card
</code></pre>
<p>Displays <em>your</em> 'business card', for other to manually <em>import</em></p>
<p>Displays <em>your</em> 'business card', for others to manually <em>import</em></p>
<pre><code>import {card}
</code></pre>
<p>Imports the given card to your contacts.</p>

Loading…
Cancel
Save