Skip to content

Commit 3483d80

Browse files
samples: modules: libsrtp: rtpw: An RTPW example is added.
An RTPW is added to test the libSRTP module a hardware with a network connectivity should be connected to a PC and run the example as described in the README.rst file. Signed-off-by: Sayed Naser Moravej <seyednasermoravej@gmail.com>
1 parent 382417e commit 3483d80

File tree

6 files changed

+384
-0
lines changed

6 files changed

+384
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
cmake_minimum_required(VERSION 3.20.0)
2+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
3+
project(rtpw)
4+
target_sources(app PRIVATE src/main.c)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright (c) 2025 Sayed Naser Moravej <seyednasermoravej@gmail.com>
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
mainmenu "RTPW Sample Application"
5+
6+
config NET_SAMPLE_SRTP_KEY
7+
string "SRTP master key for RTPW example."
8+
default "c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451"
9+
help
10+
This key in hexadecimal which is used by the application. You can override it in prj.conf
11+
or via menuconfig / guiconfig.
12+
13+
choice
14+
prompt "Program mode"
15+
default NET_SAMPLE_SENDER
16+
help
17+
Select whether this application runs as sender or receiver.
18+
19+
config NET_SAMPLE_SENDER
20+
bool "Sender mode"
21+
help
22+
Build the application as an RTP sender.
23+
24+
config NET_SAMPLE_RECEIVER
25+
bool "Receiver mode"
26+
help
27+
Build the application as an RTP receiver.
28+
29+
endchoice
30+
31+
config NET_CONFIG_PEER_IPV4_ADDR
32+
string
33+
default "10.42.0.1" if NET_SAMPLE_SENDER
34+
default "0.0.0.0" if NET_SAMPLE_RECEIVER
35+
help
36+
Peer IPv4 address used by the RTPW example.
37+
38+
config NET_SAMPLE_SRTP_SERVER_PORT
39+
int "SRTP port"
40+
default 9999
41+
help
42+
SRTP port that the application sends or receives over that port.
43+
44+
source "Kconfig.zephyr"
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
.. zephyr:code-sample:: rtpw
2+
:name: SRTP client and server
3+
4+
Send and receive data using (S)RTP protocol.
5+
6+
Overveiw
7+
********
8+
9+
A simple demo of using (S)RTP protocol to send and receive data over network. The sample could be sender or receiver.
10+
11+
To test (S)RTP via a Linux machine, you should build the libsrtp.
12+
13+
To test the sender while PC is receiver, the peer IP address should be set in Kconfig file. Next open a terminal and enter command:
14+
15+
.. code-block:: shell
16+
17+
~/libsrtp/test$ ./rtpw -r -k c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451 -e 128 -a 0.0.0.0 9999
18+
19+
You should see in PC side:
20+
21+
.. code-block:: console
22+
23+
Using libsrtp3 3.0.0-pre [0x3000000]
24+
security services: confidentiality message authentication
25+
set master key/salt to c1eec3717da76195bb878578790af71c/4ee9f859e197a414a78d5abc7451
26+
word: SRTP test0.
27+
word: SRTP test1.
28+
word: SRTP test2.
29+
word: SRTP test3.
30+
31+
You should see in device side:
32+
33+
.. code-block:: console
34+
35+
*** Booting Zephyr OS build v4.2.0-5032-g84d1da7ea2a6 ***
36+
[00:00:00.060,000] <inf> net_config: Initializing network
37+
[00:00:00.068,000] <inf> net_config: Waiting interface 1 (0x341b0380) to be up...
38+
[00:00:01.651,000] <inf> phy_mii: PHY (0) Link speed 100 Mb, full duplex
39+
[00:00:01.660,000] <inf> net_config: Interface 1 (0x341b0380) coming up
40+
[00:00:01.670,000] <inf> net_config: IPv4 address: 10.42.0.2
41+
[00:00:01.678,000] <inf> rtpw_sample: Using Zephyr 1.0.0 [0x1000000]
42+
[00:00:01.770,000] <inf> rtpw_sample: peer IPv4 address: 10.42.0.1.
43+
[00:00:01.779,000] <inf> rtpw_sample: my IPv4 address: 10.42.0.2.
44+
[00:00:01.788,000] <inf> rtpw_sample: sending word: SRTP test0.
45+
[00:00:02.297,000] <inf> rtpw_sample: sending word: SRTP test1.
46+
[00:00:02.806,000] <inf> rtpw_sample: sending word: SRTP test2.
47+
[00:00:03.315,000] <inf> rtpw_sample: sending word: SRTP test3.
48+
49+
To test (S)RTP via a Linux machine, you should build the libsrtp.
50+
To test the receiver while PC is sender, the peer IP address should be set in Kconfig file. Next open a terminal and enter command:
51+
52+
.. code-block:: shell
53+
54+
~/libsrtp/test$ ./rtpw -s -k c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451 -e 128 -a <CONFIG_NET_CONFIG_MY_IPV4_ADDR> 9999
55+
56+
for example:
57+
58+
.. code-block:: shell
59+
60+
~/libsrtp/test$ ./rtpw -s -k c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451 -e 128 -a 10.42.0.2 9999
61+
62+
You should see in PC side:
63+
64+
.. code-block:: console
65+
66+
Using libsrtp3 3.0.0-pre [0x3000000]
67+
security services: confidentiality message authentication
68+
set master key/salt to c1eec3717da76195bb878578790af71c/4ee9f859e197a414a78d5abc7451
69+
sending word: abducing
70+
sending word: acidheads
71+
sending word: acidness
72+
sending word: actons
73+
74+
You should see in device side:
75+
76+
.. code-block:: console
77+
78+
*** Booting Zephyr OS build v4.2.0-5032-g84d1da7ea2a6 ***
79+
[00:00:00.060,000] <inf> net_config: Initializing network
80+
[00:00:00.068,000] <inf> net_config: Waiting interface 1 (0x341b04c0) to be up...
81+
[00:00:01.651,000] <inf> phy_mii: PHY (0) Link speed 100 Mb, full duplex
82+
[00:00:01.660,000] <inf> net_config: Interface 1 (0x341b04c0) coming up
83+
[00:00:01.670,000] <inf> net_config: IPv4 address: 10.42.0.2
84+
[00:00:01.678,000] <inf> rtpw_sample: Using Zephyr 1.0.0 [0x1000000]
85+
[00:00:01.770,000] <inf> rtpw_sample: peer IPv4 address: 0.0.0.0.
86+
[00:00:01.779,000] <inf> rtpw_sample: my IPv4 address: 10.42.0.2.
87+
[00:00:18.010,000] <inf> rtpw_sample: receiving word: abducing
88+
[00:00:18.510,000] <inf> rtpw_sample: receiving word: acidheads
89+
[00:00:19.010,000] <inf> rtpw_sample: receiving word: acidness
90+
[00:00:19.510,000] <inf> rtpw_sample: receiving word: actons
91+
92+
Configuration
93+
*************
94+
95+
The sender/receiver type and the SRTP key can be changed via Kconfig file.
96+
97+
Building and Running
98+
********************
99+
100+
This application can be built as follows:
101+
102+
.. zephyr-app-commands::
103+
:zephyr-app: samples/modules/rtpw
104+
:host-os: unix
105+
:board: frdm_mcxn947/mcxn947/cpu0
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#network
2+
CONFIG_NETWORKING=y
3+
CONFIG_NET_IPV4=y
4+
CONFIG_NET_IPV6=n
5+
CONFIG_NET_DHCPV4=n
6+
CONFIG_NET_ARP=y
7+
CONFIG_NET_CONFIG_SETTINGS=y
8+
CONFIG_NET_CONFIG_MY_IPV4_ADDR="10.42.0.2"
9+
CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0"
10+
CONFIG_NET_L2_ETHERNET=y
11+
CONFIG_NET_UDP=y
12+
CONFIG_NET_MGMT_EVENT_INFO=y
13+
CONFIG_NET_MGMT=y
14+
CONFIG_NET_MGMT_EVENT_STACK_SIZE=2048
15+
CONFIG_NET_MGMT_EVENT=y
16+
CONFIG_SLIP_STATISTICS=n
17+
CONFIG_NET_SOCKETS=y
18+
19+
CONFIG_ENTROPY_GENERATOR=y
20+
CONFIG_TEST_RANDOM_GENERATOR=y
21+
CONFIG_NET_LOG=y
22+
CONFIG_NET_SHELL=y
23+
CONFIG_POSIX_API=y
24+
25+
# Logging
26+
CONFIG_LOG=y
27+
CONFIG_LOG_DEFAULT_LEVEL=3
28+
29+
# Console
30+
CONFIG_SERIAL=y
31+
CONFIG_CONSOLE=y
32+
CONFIG_UART_CONSOLE=y
33+
34+
# Crypto (mbedTLS)
35+
CONFIG_MBEDTLS=y
36+
CONFIG_MBEDTLS_BUILTIN=y
37+
CONFIG_MBEDTLS_ENABLE_HEAP=y
38+
CONFIG_MBEDTLS_HEAP_SIZE=60000
39+
CONFIG_MBEDTLS_MD=y
40+
CONFIG_HEAP_MEM_POOL_SIZE=65536
41+
CONFIG_MBEDTLS_SHA1=y
42+
43+
# LibSRTP
44+
CONFIG_LIBSRTP=y
45+
46+
CONFIG_MAIN_STACK_SIZE=4096
47+
CONFIG_IDLE_STACK_SIZE=2048
48+
CONFIG_LOG_MODE_IMMEDIATE=y
49+
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=8192
50+
CONFIG_NET_MGMT_EVENT_STACK_SIZE=8192
51+
CONFIG_NET_RX_STACK_SIZE=4096
52+
CONFIG_NET_TX_STACK_SIZE=2048
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
sample:
2+
name: sender and receiver (S)RTP protocol
3+
tests:
4+
samples.modules.libsrtp.rtpw:
5+
depends_on: netif
6+
tags:
7+
- net
8+
build_only: true
9+
platform_type:
10+
- mcu
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*
2+
* Copyright 2025 Sayed Naser Moravej <seyednasermoravej@gmail.com>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/net/socket.h>
9+
#include <zephyr/logging/log.h>
10+
#include <zephyr/net/net_ip.h>
11+
12+
#include <config.h>
13+
#include "srtp.h"
14+
#include "rtp.h"
15+
#include "util.h"
16+
17+
#define MAX_WORD_LEN 128
18+
#define MAX_KEY_LEN 96
19+
20+
LOG_MODULE_REGISTER(rtpw_sample, LOG_LEVEL_INF);
21+
22+
int main(void)
23+
{
24+
char word[MAX_WORD_LEN];
25+
int sock, ret;
26+
struct in_addr rcvr_addr;
27+
struct sockaddr_in name;
28+
char key[MAX_KEY_LEN];
29+
srtp_policy_t policy;
30+
srtp_err_status_t status;
31+
uint32_t ssrc = 0xdeadbeef; /* ssrc value hardcoded for now */
32+
33+
memset(&policy, 0x0, sizeof(srtp_policy_t));
34+
35+
LOG_INF("Using %s [0x%x]\n", srtp_get_version_string(), srtp_get_version());
36+
37+
/* initialize srtp library */
38+
status = srtp_init();
39+
if (status) {
40+
LOG_ERR("srtp initialization failed with error code %d.", status);
41+
return 0;
42+
}
43+
44+
/* set address */
45+
LOG_INF("peer IPv4 address: %s.", CONFIG_NET_CONFIG_PEER_IPV4_ADDR);
46+
LOG_INF("my IPv4 address: %s.", CONFIG_NET_CONFIG_MY_IPV4_ADDR);
47+
48+
if (inet_pton(AF_INET, CONFIG_NET_CONFIG_PEER_IPV4_ADDR, &rcvr_addr) != 1) {
49+
LOG_ERR("Invalid IPv4 address: %s.", CONFIG_NET_CONFIG_PEER_IPV4_ADDR);
50+
return 0;
51+
}
52+
53+
/* open socket */
54+
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
55+
if (sock < 0) {
56+
LOG_ERR("couldn't open socket.");
57+
return 0;
58+
}
59+
60+
memset(&name, 0, sizeof(struct sockaddr_in));
61+
name.sin_addr = rcvr_addr;
62+
name.sin_family = PF_INET;
63+
name.sin_port = htons(CONFIG_NET_SAMPLE_SRTP_SERVER_PORT);
64+
65+
/* set up the srtp policy and master key
66+
* create policy structure, using the default mechanisms.
67+
*/
68+
srtp_crypto_policy_set_rtp_default(&policy.rtp);
69+
srtp_crypto_policy_set_rtcp_default(&policy.rtcp);
70+
policy.ssrc.type = ssrc_specific;
71+
policy.ssrc.value = ssrc;
72+
policy.key = (uint8_t *)key;
73+
policy.next = NULL;
74+
policy.window_size = 128;
75+
policy.allow_repeat_tx = 0;
76+
policy.rtp.sec_serv = sec_serv_conf_and_auth;
77+
policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */
78+
size_t key_len = hex2bin(CONFIG_NET_SAMPLE_SRTP_KEY,
79+
strlen(CONFIG_NET_SAMPLE_SRTP_KEY), key, sizeof(key));
80+
81+
/* check that hex string is the right length */
82+
if (key_len != policy.rtp.cipher_key_len) {
83+
LOG_ERR("wrong number of digits in key (should be %d digits, found %d).",
84+
2 * policy.rtp.cipher_key_len, 2 * key_len);
85+
return 0;
86+
}
87+
88+
#ifdef CONFIG_NET_SAMPLE_SENDER
89+
/* initialize sender's rtp and srtp contexts */
90+
rtp_sender_t snd;
91+
92+
snd = rtp_sender_alloc();
93+
if (snd == NULL) {
94+
LOG_ERR("malloc() failed.");
95+
return 0;
96+
}
97+
rtp_sender_init(snd, sock, name, ssrc);
98+
status = rtp_sender_init_srtp(snd, &policy);
99+
if (status) {
100+
LOG_ERR("srtp_create() failed with code %d.", status);
101+
return 0;
102+
}
103+
104+
size_t word_len;
105+
/* Up-count the buffer, then send them off */
106+
for (int i = 0; i < 1000; i++) {
107+
sprintf(word, "SRTP test%d.", i);
108+
word_len = strlen(word) + 1; /* plus one for null */
109+
110+
if (word_len > MAX_WORD_LEN) {
111+
LOG_ERR("word %s too large to send.", word);
112+
} else {
113+
rtp_sendto(snd, word, word_len);
114+
LOG_INF("sending word: %s", word);
115+
}
116+
k_msleep(500);
117+
}
118+
119+
rtp_sender_deinit_srtp(snd);
120+
rtp_sender_dealloc(snd);
121+
122+
#elif defined(CONFIG_NET_SAMPLE_RECEIVER)
123+
rtp_receiver_t rcvr;
124+
125+
if (bind(sock, (struct sockaddr *)&name, sizeof(name)) < 0) {
126+
close(sock);
127+
LOG_ERR("socket bind error.");
128+
return 0;
129+
}
130+
131+
rcvr = rtp_receiver_alloc();
132+
if (rcvr == NULL) {
133+
LOG_ERR("malloc() failed.");
134+
return 0;
135+
}
136+
rtp_receiver_init(rcvr, sock, name, ssrc);
137+
status = rtp_receiver_init_srtp(rcvr, &policy);
138+
if (status) {
139+
LOG_ERR("srtp_create() failed with code %d.", status);
140+
return 0;
141+
}
142+
143+
/* get next word and loop */
144+
size_t word_len;
145+
146+
while (true) {
147+
len = MAX_WORD_LEN;
148+
if (rtp_recvfrom(rcvr, word, &word_len) > -1) {
149+
LOG_INF("receiving word: %s", word);
150+
}
151+
}
152+
153+
rtp_receiver_deinit_srtp(rcvr);
154+
rtp_receiver_dealloc(rcvr);
155+
#else
156+
#error "Either SENDER or RECEIVER should be defined."
157+
#endif
158+
ret = close(sock);
159+
if (ret < 0) {
160+
LOG_ERR("Failed to close socket");
161+
}
162+
163+
status = srtp_shutdown();
164+
if (status) {
165+
LOG_ERR("srtp shutdown failed with error code %d.", status);
166+
return 0;
167+
}
168+
return 0;
169+
}

0 commit comments

Comments
 (0)