Skip to content

Commit 0fd85f7

Browse files
samples: modules: libsrtp: rtpw: An RTPW example added.
To test the SRTP protocol an RTPW example added. Signed-off-by: Sayed Naser Moravej <seyednasermoravej@gmail.com>
1 parent 3d54b38 commit 0fd85f7

File tree

6 files changed

+362
-0
lines changed

6 files changed

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

0 commit comments

Comments
 (0)