Skip to content

Commit bf6ee37

Browse files
committed
Added signaling_serializer component
- It helps packing and unpacking of signaling messages - These serialized messages then can be transfered on any transport
1 parent 27a4d24 commit bf6ee37

18 files changed

+1164
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
set(srcs
2+
"src/signaling_serializer.c"
3+
"src/json_serializer.c"
4+
"src/protobuf_serializer.c"
5+
"src/raw_serializer.c"
6+
"proto/signaling.pb-c.c"
7+
)
8+
9+
if (LINUX_BUILD)
10+
# Use local protobuf-c sources from ESP components
11+
set(PROTOBUF_C_SRCS
12+
"${CMAKE_CURRENT_SOURCE_DIR}/../../components/esp_hosted/common/protobuf-c/protobuf-c/protobuf-c.c"
13+
)
14+
15+
set(PROTOBUF_C_INCLUDE_DIRS
16+
"${CMAKE_CURRENT_SOURCE_DIR}/../../components/esp_hosted/common/protobuf-c"
17+
)
18+
19+
add_library(signaling_serializer STATIC ${srcs} ${PROTOBUF_C_SRCS})
20+
21+
target_include_directories(signaling_serializer
22+
PUBLIC
23+
"include"
24+
PRIVATE
25+
"proto"
26+
# Include jsmn from the kvswebrtc_main component
27+
"${CMAKE_CURRENT_SOURCE_DIR}/../kvswebrtc_main/lib/amazon-kinesis-video-streams-webrtc-sdk-c/src/source/Json"
28+
# Include protobuf-c headers
29+
${PROTOBUF_C_INCLUDE_DIRS}
30+
)
31+
32+
# Add a definition for Linux builds
33+
target_compile_definitions(signaling_serializer PRIVATE KVS_PLAT_LINUX_UNIX)
34+
else()
35+
# ESP-IDF specific build
36+
idf_component_register(
37+
SRCS ${srcs}
38+
PRIV_INCLUDE_DIRS "proto"
39+
INCLUDE_DIRS "include"
40+
PRIV_REQUIRES protobuf-c mbedtls
41+
)
42+
endif()
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
choice KVS_SERIALIZATION_METHOD
2+
prompt "Signaling message serialization method"
3+
default KVS_USE_PROTOBUF_SERIALIZATION
4+
help
5+
When WebRTC is used in a split mode, the signaling messages needs to be exchanged between signaling_only and streaming_only applications.
6+
This requires a serialization/deserialization method that is compatible with both applications.
7+
Note: The same serialization method should be used for both the signaling and streaming applications.
8+
9+
config KVS_USE_PROTOBUF_SERIALIZATION
10+
bool "Protocol Buffers"
11+
help
12+
Use Protocol Buffers for signaling message serialization.
13+
This reduces message size but requires more ROM.
14+
15+
config KVS_USE_JSON_SERIALIZATION
16+
bool "JSON"
17+
help
18+
Use JSON for signaling message serialization.
19+
This uses more bandwidth but requires less ROM.
20+
21+
config KVS_USE_RAW_SERIALIZATION
22+
bool "Raw"
23+
help
24+
Use non-standardraw serialization, i.e. the payload is appended to the signaling message.
25+
This is the most efficient serialization method but may bump into tricky issues.
26+
endchoice
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Signaling Serializer
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
description: signaling_serializer
2+
version: "0.0.1"
3+
4+
dependencies:
5+
espressif/jsmn:
6+
version: "*"
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#ifdef __cplusplus
10+
extern "C" {
11+
#endif
12+
13+
#include <stdint.h>
14+
#include <stddef.h>
15+
#include <stdbool.h>
16+
17+
#if defined(LINUX_BUILD) || defined(KVS_PLAT_LINUX_UNIX)
18+
// For Linux builds
19+
// #include <stdio.h>
20+
// #include <stdlib.h>
21+
// #include "esp_err_compat.h"
22+
typedef int esp_err_t;
23+
#else
24+
// For ESP builds
25+
#include <esp_err.h>
26+
#endif
27+
28+
typedef enum {
29+
SERIALIZER_TYPE_JSON = 0,
30+
SERIALIZER_TYPE_PROTOBUF,
31+
SERIALIZER_TYPE_RAW
32+
} signaling_serializer_type;
33+
34+
/**
35+
* @brief Enum defining the type of signaling message
36+
*
37+
* This intentionally matches the enum defined in the signaling protocol defined in kvs
38+
* https://docs.aws.amazon.com/kinesisvideostreams-webrtc-dg/latest/devguide/kvswebrtc-websocket-apis3.html
39+
*/
40+
typedef enum {
41+
SIGNALING_MSG_TYPE_OFFER,
42+
SIGNALING_MSG_TYPE_ANSWER,
43+
SIGNALING_MSG_TYPE_ICE_CANDIDATE,
44+
} signaling_msg_type;
45+
46+
// Must match with the defines in the signaling protocol defined in kvs
47+
#define SS_MAX_CORRELATION_ID_LEN 256
48+
#define SS_MAX_SIGNALING_CLIENT_ID_LEN 256
49+
/**
50+
* @brief Structure defining the signaling message
51+
*
52+
* This intentionally matches the structure defined in the signaling protocol defined in kvs
53+
* https://docs.aws.amazon.com/kinesisvideostreams-webrtc-dg/latest/devguide/kvswebrtc-websocket-apis3.html
54+
*/
55+
typedef struct {
56+
uint32_t version; //!< Current version of the structure
57+
signaling_msg_type messageType; //!< Type of signaling message.
58+
char correlationId[SS_MAX_CORRELATION_ID_LEN + 1]; //!< Correlation Id string
59+
char peerClientId[SS_MAX_SIGNALING_CLIENT_ID_LEN + 1]; //!< Sender client id
60+
uint32_t payloadLen; //!< Optional payload length. If 0, the length will be calculated
61+
char *payload; //!< Actual signaling message payload
62+
} signaling_msg_t;
63+
64+
/**
65+
* @brief Serialize a SignalingMsg to a string format
66+
*
67+
* @param pSignalingMessage Message to serialize
68+
* @param outLen Length of the serialized data
69+
* @return char* Serialized message (must be freed by caller), NULL on error
70+
*/
71+
char* serialize_signaling_message(signaling_msg_t *pSignalingMessage, size_t* outLen);
72+
73+
/**
74+
* @brief Deserialize a string into a SignalingMsg
75+
*
76+
* @param data Input data to deserialize
77+
* @param len Length of input data
78+
* @param pSignalingMessage Output message structure
79+
* @return STATUS STATUS_SUCCESS on success
80+
*/
81+
esp_err_t deserialize_signaling_message(const char* data, size_t len, signaling_msg_t *pSignalingMessage);
82+
83+
/**
84+
* @brief Initialize the signaling serializer
85+
*/
86+
void signaling_serializer_init(void);
87+
88+
#ifdef __cplusplus
89+
}
90+
#endif
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/* Generated by the protocol buffer compiler. DO NOT EDIT! */
2+
/* Generated from: signaling.proto */
3+
4+
/* Do not generate deprecated warnings for self */
5+
#ifndef PROTOBUF_C__NO_DEPRECATED
6+
#define PROTOBUF_C__NO_DEPRECATED
7+
#endif
8+
9+
#include "signaling.pb-c.h"
10+
void kvs__signaling__signaling_message__init
11+
(Kvs__Signaling__SignalingMessage *message)
12+
{
13+
static const Kvs__Signaling__SignalingMessage init_value = KVS__SIGNALING__SIGNALING_MESSAGE__INIT;
14+
*message = init_value;
15+
}
16+
size_t kvs__signaling__signaling_message__get_packed_size
17+
(const Kvs__Signaling__SignalingMessage *message)
18+
{
19+
assert(message->base.descriptor == &kvs__signaling__signaling_message__descriptor);
20+
return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message));
21+
}
22+
size_t kvs__signaling__signaling_message__pack
23+
(const Kvs__Signaling__SignalingMessage *message,
24+
uint8_t *out)
25+
{
26+
assert(message->base.descriptor == &kvs__signaling__signaling_message__descriptor);
27+
return protobuf_c_message_pack ((const ProtobufCMessage*)message, out);
28+
}
29+
size_t kvs__signaling__signaling_message__pack_to_buffer
30+
(const Kvs__Signaling__SignalingMessage *message,
31+
ProtobufCBuffer *buffer)
32+
{
33+
assert(message->base.descriptor == &kvs__signaling__signaling_message__descriptor);
34+
return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer);
35+
}
36+
Kvs__Signaling__SignalingMessage *
37+
kvs__signaling__signaling_message__unpack
38+
(ProtobufCAllocator *allocator,
39+
size_t len,
40+
const uint8_t *data)
41+
{
42+
return (Kvs__Signaling__SignalingMessage *)
43+
protobuf_c_message_unpack (&kvs__signaling__signaling_message__descriptor,
44+
allocator, len, data);
45+
}
46+
void kvs__signaling__signaling_message__free_unpacked
47+
(Kvs__Signaling__SignalingMessage *message,
48+
ProtobufCAllocator *allocator)
49+
{
50+
if(!message)
51+
return;
52+
assert(message->base.descriptor == &kvs__signaling__signaling_message__descriptor);
53+
protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator);
54+
}
55+
static const ProtobufCFieldDescriptor kvs__signaling__signaling_message__field_descriptors[6] =
56+
{
57+
{
58+
"version",
59+
1,
60+
PROTOBUF_C_LABEL_NONE,
61+
PROTOBUF_C_TYPE_UINT32,
62+
0, /* quantifier_offset */
63+
offsetof(Kvs__Signaling__SignalingMessage, version),
64+
NULL,
65+
NULL,
66+
0, /* flags */
67+
0,NULL,NULL /* reserved1,reserved2, etc */
68+
},
69+
{
70+
"messageType",
71+
2,
72+
PROTOBUF_C_LABEL_NONE,
73+
PROTOBUF_C_TYPE_UINT32,
74+
0, /* quantifier_offset */
75+
offsetof(Kvs__Signaling__SignalingMessage, messagetype),
76+
NULL,
77+
NULL,
78+
0, /* flags */
79+
0,NULL,NULL /* reserved1,reserved2, etc */
80+
},
81+
{
82+
"peerClientId",
83+
3,
84+
PROTOBUF_C_LABEL_NONE,
85+
PROTOBUF_C_TYPE_STRING,
86+
0, /* quantifier_offset */
87+
offsetof(Kvs__Signaling__SignalingMessage, peerclientid),
88+
NULL,
89+
&protobuf_c_empty_string,
90+
0, /* flags */
91+
0,NULL,NULL /* reserved1,reserved2, etc */
92+
},
93+
{
94+
"correlationId",
95+
4,
96+
PROTOBUF_C_LABEL_NONE,
97+
PROTOBUF_C_TYPE_STRING,
98+
0, /* quantifier_offset */
99+
offsetof(Kvs__Signaling__SignalingMessage, correlationid),
100+
NULL,
101+
&protobuf_c_empty_string,
102+
0, /* flags */
103+
0,NULL,NULL /* reserved1,reserved2, etc */
104+
},
105+
{
106+
"payload",
107+
5,
108+
PROTOBUF_C_LABEL_NONE,
109+
PROTOBUF_C_TYPE_BYTES,
110+
0, /* quantifier_offset */
111+
offsetof(Kvs__Signaling__SignalingMessage, payload),
112+
NULL,
113+
NULL,
114+
0, /* flags */
115+
0,NULL,NULL /* reserved1,reserved2, etc */
116+
},
117+
{
118+
"payloadLen",
119+
6,
120+
PROTOBUF_C_LABEL_NONE,
121+
PROTOBUF_C_TYPE_UINT32,
122+
0, /* quantifier_offset */
123+
offsetof(Kvs__Signaling__SignalingMessage, payloadlen),
124+
NULL,
125+
NULL,
126+
0, /* flags */
127+
0,NULL,NULL /* reserved1,reserved2, etc */
128+
},
129+
};
130+
static const unsigned kvs__signaling__signaling_message__field_indices_by_name[] = {
131+
3, /* field[3] = correlationId */
132+
1, /* field[1] = messageType */
133+
4, /* field[4] = payload */
134+
5, /* field[5] = payloadLen */
135+
2, /* field[2] = peerClientId */
136+
0, /* field[0] = version */
137+
};
138+
static const ProtobufCIntRange kvs__signaling__signaling_message__number_ranges[1 + 1] =
139+
{
140+
{ 1, 0 },
141+
{ 0, 6 }
142+
};
143+
const ProtobufCMessageDescriptor kvs__signaling__signaling_message__descriptor =
144+
{
145+
PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC,
146+
"kvs.signaling.SignalingMessage",
147+
"SignalingMessage",
148+
"Kvs__Signaling__SignalingMessage",
149+
"kvs.signaling",
150+
sizeof(Kvs__Signaling__SignalingMessage),
151+
6,
152+
kvs__signaling__signaling_message__field_descriptors,
153+
kvs__signaling__signaling_message__field_indices_by_name,
154+
1, kvs__signaling__signaling_message__number_ranges,
155+
(ProtobufCMessageInit) kvs__signaling__signaling_message__init,
156+
NULL,NULL,NULL /* reserved[123] */
157+
};

0 commit comments

Comments
 (0)