< Lab.SCHC FullSDK Documentation /
On this page:
This manual is intended for integrators/developers. It presumes that its readers have some familiarity with embedded software development, and with Internet of Things (IoT) domain.
You may also find the following documents useful:
Lab.SCHC FullSDK was designed with the following characteristics in mind; developers should consider them during the development process:
For more information, please refer to the FullSDK Concepts page.
The following header files are provided for the SCHC
interfaces, located in full-sdk/core/
case.
File Name | API |
---|---|
fullsdkmgt.h |
Management interface |
fullsdkextapi.h |
Management extension interface |
fullsdkdtg.h |
Datagram interface |
fullsdknet.h |
Network interface |
fullsdkl2a.h |
Level 2 adaptation (L2A) interface |
The header file for the Management interface is fullsdkmgt.h
.
The management interface has two roles:
Note: The management interface functions must be used to configure the stack before any functions of any interface are called.
The first function that must be called is mgt_initialize()
.
This function must be provided with:
Each callback will be called for a specific event.
Callback | Event |
---|---|
mgt_processing_required |
Informs the application that one of the layers in the FullSDK stack has to perform some processing. The application must call the mgt_process() function as soon as possible but not from within the callback. |
mgt_connectivity_state |
Informs the application about any modification of the connectivity state. The application should not try to send a message until connectivity is available. |
mgt_start_timer |
Informs the application that a timer should be started. Timer period and ID are specified by the callback parameters. When the timer period expires, the mgt_timer_timeout() function must be called with the same ID used for the start timer. |
mgt_stop_timer |
Informs the application that a timer must be stopped. Timer ID is specified by the callback parameter. |
mgt_sync_bootstrap_result (optional) |
Informs the application about the result of the synchronization with the SCHC gateway. This callback is triggered when a response is received following a call to mgt_sync_boostrap() . Note that synchronization is an extended feature of lab.SCHC FullSDK. This callback can be omitted (i.e. set to NULL) when Sync is not used or when the SCHC gateway does not support it. |
The initialization function must be provided with a pointer to a memory block allocated for the stack and the size of the memory block.
The application that integrates Lab.SCHC FullSDK stack has to allocate some memory (based on a formula, see below) from the volatile memory of the execution environment, and then provide it to the stack.
The formula is the following:
(4 * (max_mtu_size + max_app_payload_len + max_proto_size))
where:
max_mtu_size
is the maximum MTU size of the L2 technology used;max_app_payload_len
is the maximum payload length that the application
expects to send and receive;max_proto_size
is predefined as MGT_PROTO_SIZE
in fullsdkmgt.h.Finally, the initialization function must be completed with:
This function is used to synchronize the SDK with the SCHC gateway. It is optional, and only compatible with Actility’s SCHC IPCore.
mgt_sync_bootstrap()
must be provided with the following parameters:
retransmission_delay
: The delay (in ms) between each request retransmission.max_retrans
: The maximum number of request retransmission before considering
that the synchronization has failed.This section refers to the FullSDK paradigm.
Every time a layer of the FullSDK stack needs to perform a processing as the
result of some event, the mgt_processing_required
callback is called.
It is then up to the application to call the mgt_process()
function as soon as
possible, but not from within the callback. In fact, a callback called by the
lab.SCHC FullSDK must not call any lab.SCHC FullSDK function.
While using L2 technology having quasi-bidirectional links, which is the case with LoRaWAN in class A, polling packets must be send in order to trigger downlink packet reception.
Two functions are dedicated for that purpose:
mgt_enable_polling()
function must be called once after mgt_initialize()
to activate implicit polling mechanism inside the lab.SCHC FullSDK stack. The
aim being to retrieve the downlink packets, in particular when they are
fragmented.mgt_trigger_polling()
function must be called every time the application
wants to trigger explicitly a polling frame. The aim being to generate a
downlink possibility (fport: 0 with no payload for LoRaWAN, etc.).These functions have no use for Class C and the Class B is not supported.
The mgt_get_version()
function returns the version of the FullSDK library as a
null-terminated string.
The header file for the extension of the Management interface is
fullsdkextapi.h
, located in full-sdk/api/<api>
, depending on the application
API.
The extension API provisions SCHC compression and fragmentation rules in binary format.
This function should be called only when the FullSDK library is compiled using dynamic rule loading.
The mgt_provision_header_rules()
function provisions the header rules, and
considers the following parameters:
bin_rules
: SCHC rules in binary format.bin_rules_len
: The length of bin_rules
, in bytes.memory
: A memory area or buffer that can be used by the parser.memory_len
: The length in bytes of the memory area.The mgt_provision_payload_rules()
function provisions payload pattern rules in
a binary format. The following parameters must be provided:
bin_rules
: Payload pattern rules in a binary format.bin_rules_len
: The length of bin_rules
, in bytes.memory
: A memory area or buffer that can be used by the parser.memory_len
: The length of the memory area.The mgt_provision_frag_profile()
function provisions the fragmentation rule
for a single direction. In order to set a specific fragmentation profile for
both directions (uplink and downlink), this function must be called twice with
the selected rules.
The function must be provided with the following parameters:
buffer
: Fragmentation rule in a binary format.size
: The length of the fragmentation rule, in bytes.Template parameters can be set with mgt_set_template_param()
using the
following parameters:
index
: 0-based index corresponding to the template parameters to set.value
: The value to associate to the index.size
: The size of the given value in bytes.Template parameters can also be retrieved using the mgt_get_template_param()
function by providing the corresponding parameter index
in the template.
Other functions related to templates include:
mgt_get_nb_template_params()
: gives the number of configurable parameters in
the provided template.mgt_get_template_id()
: retrieves the template ID of the current template.mgt_reset_template_params()
: clears the template parameters in the memory.Refer to the fullsdkextapi.h
header files for more details.
The header file for the Datagram interface is fullsdkdtg.h
.
NOTE: Use the functions of the Management interface to configure lab.SCHC FullSDK stack before using the Datagram interface.
The datagram interface allows the application to send and receive data packets to and from a remote application.
The interface is similar to the Berkeley datagram socket interface:
The first function that the application must call is dtg_initialize()
to
initialize the the datagram interface before using it.
This function must be provided with the following parameters:
transmission_result
will inform the application of the
end of a send request (success or failure). data_received
will inform the
application when a data packet is received.In order to be able to send or receive data packets, the application must now
call the dtg_socket()
function.
This function must be provided with the following parameters:
socket
: The socket for which transmission result is returned.p_buffer
: A pointer to the buffer where the received packets will be
written.data_size
: The length of this buffer (in bytes).dtg_sockaddr
: The address f the socket.status
: The status of the tramission. No data is raised to the user in case
of error.dtg_socket()
returns a socket structure that needs to be used as parameter for
the following local port binding functions.
dtg_socket()
returns a socket structure that can be used by dtg_bind()
to
bind the application to an IPv6/v4 address and a local port for data packet
reception.
If the application is not supposed to receive data packets from the remote application, it does not have to call
dtg_bind()
.
A send operation is requested by calling the dtg_sendto()
function on the
corresponding socket structure. The function immediately returns a status that
informs the caller whether the request has been accepted or not.
The request can be refused, for example when there is an ongoing send operation, or when the connectivity is not available.
If the request has been accepted, the result of the send operation will be
provided later, by a call to the dtg_transmission_result
callback (which is
provided at initialization by dtg_initialize()
) with the corresponding socket
as parameter.
A new request for the same socket will not be accepted as long as the
dtg_transmission_result
callback with the corresponding socket is called.
When a data packet is received, the dtg_data_received
callback (which is
provided at initialization by dtg_initialize()
) is called.
Check the header file (fullsdkdtg.h
) for information about flow control for
reception.
When a socket is no longer used, it must be closed, by calling dtg_close()
.
Any ongoing fragmentation process that could exist when calling dtg_close()
is
then terminated.
The header file for the Network interface is fullsdknet.h
.
NOTE:: Use the functions of the Management interface to configure lab.SCHC FullSDK stack before using the Network interface.
The network interface allows the application to send and receive raw IPv6 packets to and from a remote application.
In order to be able to use this interface, extension API functions (fullsdkextapi.h) must be formerly used to configure the network information.
The first function that the application must call is net_initialize()
to be
able to send or receive data packets.
This function must be provided with the following callback parameters:
transmission_result
: It will inform the application of the end of a send
request (success or failure).data_received
: It will inform the application when a data packet is
received.net_initialize()
returns a status code indicating whether the initialization
is successful or not.
The configuration of the network interface highly depends on the application that uses it.
Configuration functions are provided in the extension API (fullsdkextapi.h
header file) to meet the integrator’s specific application needs.
A send operation is requested by calling the net_sendto()
function. The
function immediately returns a status that informs the caller whether the
request has been accepted or not.
The request can be refused, for example when there is an ongoing send operation, or when the connectivity is not available.
If the request has been accepted, the result of the send operation will be
provided later, by a call to the net_transmission_result
callback (which is
provided at initialization by net_initialize()
).
A new request will not be accepted until the net_transmission_result
callback
is called.
When a data packet is received, the related callback declared via
net_initialize()
, is called.
Check the header file (fullsdknet.h
) for information about flow control for
reception.
Lab.SCHC FullSDK provides a reference implementation of the L2A layer based on LoRaWAN technology.
The targets of the L2A reference implementation is currently the ST NUCLEO-L476RG microcontroller board, with either the SX1276MB1MAS or SX1272MB2xAS LoRaWAN shields and running the Semtech LoRa stack, in classes A or C. Class B is not supported.
The header file for the L2A interface is fullsdkl2a.h
.
The layer-two adaptation interface (also called L2A) is required to bind the lab.SCHC FullSDK with the L2 stack (LoRa, etc).
The L2A layer is usually provided by the integrator who has to implement the
list of functions available in the fullsdkl2a.h
header file.
Note that these functions are only called by the lab.SCHC FullSDK and must not be called directly from the application code.
When the application calls the mgt_initialize()
function (initialization by
the Management interface), the l2a_initialize()
function is implicitly called
by lab.SCHC FullSDK.
This function can be used by the integrator to initialize the L2 stack and to store the callback functions provided as parameters:
l2a_processing_required
: To be called by the integrator to inform the
lab.SCHC FullSDK when an asynchronous task needs to be handled by the layer.
See l2a_process()
function below for more details.l2a_transmission_result
: To be called by the integrator to inform the
lab.SCHC FullSDK when the uplink packet has been transmitted (with or without
success) by the L2 stack.l2a_data_received
: To be called by the integrator to inform the lab.SCHC
FullSDK when a downlink packet is received from the L2 stack.l2a_connectivity_lost
: To be called by the integrator to inform the lab.SCHC
FullSDK when the L2 connectivity is lost.l2a_connectivity_available
: To be called by the integrator to inform the
lab.SCHC FullSDK when the L2 connectivity is available. For example, in LoRa,
it corresponds to the Join Accept reception.l2a_initialize()
returns a status code indicating whether the initialization
is successful or not.
Lab.SCHC FullSDK calls the l2a_get_technology()
function to get information on
the L2 stack used by the integrator.
The following technology profiles are supported:
Technology Profile | Description |
---|---|
L2A_DEFAULT |
Recommended technology profile for LoRa with class C |
L2A_DEFAULT_CLASS_A |
Recommended technology profile for LoRa with class A |
L2A_LORA |
Technology profile described in RFC 9011 |
L2A_SIGFOX |
Technology profile for Sigfox |
Lab.SCHC FullSDK calls the l2a_send_data()
function to transmit a packet to
the L2 stack. This function requires two parameters:
The integrator should handle the transmission of the packet to the L2 stack. When the size of the packet is set to 1 and the value is 0x00 in hexadecimal, the integrator must send an empty frame (see Polling in the Management interface functions).
Lab.SCHC FullSDK calls the l2a_get_mtu()
function to get information on the
maximum packet size (in bytes) that can be transmitted by the L2 stack.
Lab.SCHC FullSDK calls this function from time to time because the MTU may change. For example, with a LoRa L2 stack, the MTU may change when ADR is enabled according to the radio conditions. It is up to the integrator to retrieve this value from the L2 stack.
Lab.SCHC FullSDK calls the l2a_get_dev_iid()
function when the IPv6 address of
the device is derived from L2 stack information.
It is used for LoRaWAN technology and can be implemented according to the formula referenced in RFC 9011 (section 5.3).
For other technologies, it must be returned false.
Lab.SCHC FullSDK calls the l2a_get_next_tx_delay()
function to get information
on the next uplink transmission slot (in ms) according to the L2 stack type and
its configuration.
The next uplink packet transmitted by Lab.SCHC FullSDK using l2a_send_data()
(see above) will be based on this delay.
For example, with a LoRa L2 stack, there is duty cycle limitation to follow before emitting over the radio.
Lab.SCHC FullSDK calls the l2a_process()
function every time
l2a_processing_required
callback (see above) is called by the integrator.
This function is used to handle asynchronous events received from the L2 stack.
Call the following callbacks inside l2a_process()
:
| Direction | Callback | Description | | Uplink | l2a_transmission_result
|
When the event corresponding to the end of the transmission of an uplink packet
is received from the L2 stack. | | Downlink | l2a_data_received
| When the
event corresponding to the reception of a downlink packet is received from the
L2 stack. |
Handle in the same way any other asynchronous event (timer, etc.) that might need to be implemented by the integrator and can be processed here.
Additional functionalities for the lab.SCHC FullSDK are declared in separate interfaces that enhance and extend the capabilities of the main interfaces and the SDK itself. These interfaces are designed to provide advanced features, improve usability, and offer greater flexibility in integrating with our SDK
The header file for the Statistics interface is fullsdkstats.h
.
This statistics interface is used to provide SCHC information related to the number of SCHC compressed packets and SCHC fragments exchanged in uplink and downlink directions by the lab.SCHC FullSDK stack.
stats_schc_packets_tx_counter()
: Returns the number of SCHC unfragmented
packets that are transmitted by the library.stats_schc_packets_rx_counter()
: Returns the number of SCHC unfragmented
packets received by the library.stats_schc_fragments_tx_counter()
: Returns the number of SCHC fragments
transmitted by the library.stats_schc_fragments_rx_counter()
: Returns th enumber of SCHC fragments
received by the library.These functions do not concern the No-ACK mode.
stats_schc_ack_tx_counter()
: Returns the number of SCHC ACK transmitted by
the library.stats_schc_ack_rx_counter()
: Returns the number of SCHC ACK received by the
library.stats_reset()
: Resets all metrics to 0.The functions defined in the advanced SCHC configuration interface are used for tuning and customization. They will affect the way lab.SCHC FullSDK handle the applicative packets.
The header file for the SCHC Configuration interface is fullsdkschc.h
.
This interface can be used to configure SCHC technology profile and fragmentation parameters.
schc_set_retransmission_timer()
: Allows to modify the value of the
retransmission timer used by the current profile. This function must be
provided with the parameter rt_exp_time
which value is a 32-bits integer.schc_set_inactivity_timer()
: Allows to modify the value of the inactivity
timer used by the current profile. This function must be provided with the
parameter it_exp_time
which value is a 32-bits integer.schc_set_polling_status()
: Allows to activate polling for downlink sessions
as well as suspending uplink sessions in the meanwhile. This function must be
provided with the following boolean parameters:
enable
: true
to activate polling.suspend_uplinks
: true
to suspend uplink sessions.These functions are only used with ACK-Always downlink fragmentation mode.
schc_set_schc_ack_req_dn_opportunity()
: To set the new value of
ACK_REQ_DN_OPPORTUNITY in the computation of the ACK retransmission timer
expiration. This function must be provided with the parameter
ack_req_dn_opportunity
whose value is a 8-bits integer.schc_set_idle_polling_timer()
: To set the value of the idle polling timer
that is used to create downlink opportunities on quasi-bidirectional links.
This function must be provided with the parameter time
whose value is a
32-bits integer.schc_set_ack_retransmission_timer()
: To set the value of the ACK
retransmission timer that is used to create downlink opportunities on
quasi-bidirectional links. This function must be provided with the parameter
time
whose value is a 32-bits integer.schc_set_max_ack_req()
: Allows to set the value of MAX ACK REQUESTS
that
indicates the number of time a sender will send an ACK before sending an ABORT
message. This function must be provided with the parameter max_ack_req
which
value is a 8-bits integer.Sample applications for the embedded device are available in the examples/
folder, within the full-sdk-delivery
repository.
Our Demo examples aim to demonstrate how lab.SCHC software help the communication between heterogeneous protocols and create a bridge between IoT and IP worlds for fluid data exchange.
As the Demo examples are running over LoRa, a LoRa Network Server (LNS) must be configured first. The configuration is similar in many LNS:
Besides the configured LNS and LoRa gateway, you will also need:
lab-schc/examples
repository. Clone it using the following command:
git clone https://gitlab.com/lab-schc/examples.git
This example illustrates an end-to-end communication from a UDP client to a UDP server in a Python environment. It allows to test uplink and downlink packet transmission from a device (a board for the purpose of the Demo) and a destination server.
The example demonstrates how to use the SCHC SDK using the Datagram API through
AT commands with a cloud application expecting IPv6 UDP frames. The demo files
can be found in the /at-modem/udp-client/
directory of the lab-schc-examples
repository.
cd lab-schc-examples/at-modem/udp-client/
head README.md
This example considers a UDP server application with the IPv6 address
abcd::1
running on port22222
and the device configured in the SCHC Gateway with the IPv6 address5454::2
and a UDP port number33333
.
ATModem
example application.cd full-sdk-delivery/
# Build:
cmake -S . -B ./build/ -DAPP_NAME=ATModem \
-DAPP_VERSION=4.0.0 -DFULLSDK_VERSION=3.0.0 \
-DTOOLCHAIN=gcc-arm-none -DTARGET=m4 -DPLATFORM=STM32L476RG-Nucleo \
-DL2_STACK=semtech -DNUCLEO_LORA_SHIELD=SX1272 \
-DEXTENSION_API=template -DTEMPLATE_ID=dynamic && make -C ./build
# Erase and Flash:
OPENOCD_TARGET=stm32l4x.cfg make -C openocd/ erase && \
OPENOCD_TARGET=stm32l4x.cfg BIN_FILE=build/gcc-arm-none/m4/ATModem.bin \
make -C openocd/ flash
At this point you can already make use of the device as AT Modem and manipulate the stack via AT Commands. Open a serial communication program, such as minicom, and type the
AT
andAT?
AT commands to verify the device is working properly. Close this serial communication before proceding with the demo.
cd lab-schc-examples/at-modem/udp-client/
sudo python3 -m cloud -ip abcd::1 -port 22222
cd lab-schc-examples/at-modem/udp-client/
python3 -m device --template device/compression_rules.bin \
--dev-eui fe:ff:ff:ff:fd:ff:00:00 --app-eui 00:00:00:00:00:00:00:00 \
--app-key 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11 \
--ipv6-dev-prefix 5454:0000:0000:0000 --ipv6-dev-iid 0000:0000:0000:0002 \
--ipv6-app-prefix abcd:0000:0000:0000 --ipv6-app-iid 0000:0000:0000:0001 \
--ipv6-dev-port 33333 --ipv6-app-port 22222
If the program shows an error when opening the serial port, or you have multiple devices connected, edit the
device/serial_device.py
file and set theSERIAL_DEVICE
parameter to the correct value.
request : ATZ
request : AT+SCHC=VERSION
response : AT+SCHC=VERSION
response : 3.0.0
response : OK
request : ATE=0
response : ATE=0
response : OK
request : AT+DEUI=fe:ff:ff:ff:fd:ff:00:00
response : OK
request : AT+APPEUI=00:00:00:00:00:00:00:00
response : OK
request : AT+APPKEY=11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11
response : OK
request : AT+JOIN=C
response : OK
response : +JOINED
request : AT+SCHC=TPL,SET,b1008418960186010101010101818302181c8e880c040102000081410602880d080101000081410002880e140101000081440001234502880f100101000081420000028810080101000081411102881108010100008141400288121840010200008100028813184001020000810102881418400102000081020288151840010200008103028816100102000081040288171001020000810502881818100101000081420000028818191001010000814200000224b2
response : OK
request : AT+SCHC=TPLPARAMS,SET,0,5454000000000000
response : OK
request : AT+SCHC=TPLPARAMS,SET,1,0000000000000002
response : OK
request : AT+SCHC=TPLPARAMS,SET,2,abcd000000000000
response : OK
request : AT+SCHC=TPLPARAMS,SET,3,0000000000000001
response : OK
request : AT+SCHC=TPLPARAMS,SET,4,8235
response : OK
request : AT+SCHC=TPLPARAMS,SET,5,56ce
response : OK
request : AT+SCHC=API,D
response : OK
request : AT+SCHC=SOCKET
response : 0
response : OK
request : AT+SCHC=BIND,0,5454:0000:0000:0000:0000:0000:0000:0002,33333
response : OK
Finally, the device and UDP Server Application exchange IP packets.
request : AT+SCHC=SEND,0,ABCD:0000:0000:0000:0000:0000:0000:0001,22222,ZRQXKRGGYUUMOXSSEYEOMHJNQOSARIWFKWVUTYYAMGTYLMVHAZLIAADCIDRNONIE
response : OK
response : +SENDOK,0
response : +RECVOK,0:5A5251584B5247475955554D4F5853534559454F4D484A4E514F5341524957464B575655545959414D4754594C4D5648415A4C49414144434944524E4F4E4945
starting udp server on [abcd::1]:22222
receive uplink packet from the device [5454::2]:33333 b'ZRQXKRGGYUUMOXSSEYEOMHJNQOSARIWFKWVUTYYAMGTYLMVHAZLIAADCIDRNONIE'
send downlink packet to the device [5454::2]:33333 b'ZRQXKRGGYUUMOXSSEYEOMHJNQOSARIWFKWVUTYYAMGTYLMVHAZLIAADCIDRNONIE'