Wi-SUN NCP Application#
Overview#
The Wi-SUN NCP (Network Co-Processor) application provides a production-ready implementation for handling Wi-SUN stack communication through a message-based interface. The NCP acts as a bridge between a host processor and the Wi-SUN stack.
Message Flow#
Requests#
Host Application → Transport/driver → NCP Task → Wi-SUN Stack
Confirmations/Indications#
Wi-SUN Stack → NCP Task → Transport/driver → Host application
The NCP receives complete messages from the transport layer, validates them, forwards to the Wi-SUN stack, and returns confirmations and asynchronous indications.
Buffer Format Requirements#
Message Structure#
All messages sent to the NCP transport layer must follow this format:
┌─────────────────┬─────────────────────────────────────────────────────────────┬───────────────────────────────────────────────────────────┐
│ Header (8B) │ Message Body (varies according to the request/confirmation) │ Variable Data (varies according to trailing data size) │
└─────────────────┴─────────────────────────────────────────────────────────────┴───────────────────────────────────────────────────────────
Header Format#
typedef struct {
uint16_t length;
uint8_t id;
uint8_t info;
} sl_wisun_msg_header_t;
Critical Requirements:
header.lengthmust equal the total message sizeheader.idmust be a valid Wi-SUN message IDMessage must be complete
Buffer Size Configuration#
Configure SL_WSNCP_BUFFER_SIZE in your .slcp file:
- name: "SL_WSNCP_BUFFER_SIZE"
value: "1500"
Usage Examples#
1. Basic Request#
// Example: Get IP address
sl_wisun_msg_get_ip_address_req_t req = {0};
// Initialize request
req.header.id = SL_WISUN_MSG_GET_IP_ADDRESS_REQ_ID;
req.header.length = sizeof(req); // Must match actual size
req.body.address_type = SL_WISUN_IP_ADDRESS_TYPE_GLOBAL;
// Send to the ncp host
2. Socket Operations#
// Example: Open UDP socket
sl_wisun_msg_open_socket_req_t open_req = {0};
open_req.header.id = SL_WISUN_MSG_OPEN_SOCKET_REQ_ID;
open_req.header.length = sizeof(open_req);
open_req.body.domain = AF_INET6;
open_req.body.type = SOCK_DGRAM;
open_req.body.protocol = IPPROTO_UDP;
// send to the ncp host
3. Variable Data Messages#
// Example: Send data to socket
uint16_t data_length = 100; // Example payload size
uint8_t *sendto_buffer = malloc(sizeof(sl_wisun_msg_sendto_on_socket_req_t) + data_length);
sl_wisun_msg_sendto_on_socket_req_t *sendto_req = (sl_wisun_msg_sendto_on_socket_req_t *)sendto_buffer;
// Initialize request
sendto_req->header.id = SL_WISUN_MSG_SENDTO_ON_SOCKET_REQ_ID;
sendto_req->header.length = sizeof(sl_wisun_msg_sendto_on_socket_req_t) + data_length;
sendto_req->body.socket_id = socket_id;
sendto_req->body.remote_address = remote_ipv6_address;
sendto_req->body.remote_port = remote_port;
sendto_req->body.data_length = data_length;
// Copy data after the fixed structure
memcpy(sendto_req->body.data, payload_data, data_length);
// send to the ncp host
Confirmation Handling#
What You Need to Do:#
Configure
SL_WSNCP_BUFFER_SIZEin your.slcpto sufficiently hold all you intended confirmations plus any trailing data.
Minimum confirmation buffer size: sizeof(sl_wisun_msg_header_t) + sizeof(uint32_t) (12 bytes) for status field.
Confirmation Reception#
// Handle confirmation from transport layer
void handle_confirmation(uint16_t len, const uint8_t *data) {
if (len < sizeof(sl_wisun_msg_header_t) + sizeof(uint32_t)) {
printf("Confirmation too small\n");
return;
}
const sl_wisun_msg_header_t *header = (const sl_wisun_msg_header_t *)data;
const uint32_t *status = (const uint32_t *)(data + sizeo(sl_wisun_msg_header_t));
if (*status == SL_STATUS_OK) {
// Process successful confirmation
printf("Request ID:0x%02X successful\n", header->id);
// Access confirmation data based on message type
} else {
// Handle error
printf("Request ID:0x%02X failed with status: 0x%08X\n", *status);
}
}
Validation and Error Handling#
Buffer Validation#
The NCP performs these checks:
Size Check:
Message must fit in configured buffer size
For request messages, message length should be the size of the request (hdr + body + trailing data if any)
For confirmation messages, length should be sufficient to hold the confirmation (hdr + body + trailing data if any)
Header Validation: Valid message ID and length consistency
Completeness Check: Message must be complete (no fragmentation)
Error Responses#
// Handle common errors
if (status == SL_STATUS_WOULD_OVERFLOW) {
// Message too large - increase buffer size
printf("Message too large for buffer\n");
}
if (status == SL_STATUS_INVALID_PARAMETER) {
// Invalid message format - check header.length
printf("Invalid message format\n");
}
Best Practices#
Always set
header.lengthcorrectly - must match total message sizeUse appropriate buffer sizes for your message types
Send complete messages - no fragmentation
Allocate sufficient confirmation buffers - account for variable data
Common Issues#
Buffer Overflow: Increase
SL_WSNCP_BUFFER_SIZEHeader Length Mismatch: Ensure
header.lengthequals actual message sizeInvalid Message ID: Use correct Wi-SUN message IDs
Incomplete Messages: Send complete messages in single transmission
Confirmation Buffer Too Small: Allocate sufficient space for confirmation + variable data