1 /**
2  * Copyright (c) 2019-2021 Paul-Louis Ageneau
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #ifndef RTC_C_API
20 #define RTC_C_API
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 #ifdef _WIN32
27 #define RTC_EXPORT __declspec(dllexport)
28 #ifdef CAPI_STDCALL
29 #define RTC_API __stdcall
30 #else
31 #define RTC_API
32 #endif
33 #else // not WIN32
34 #define RTC_EXPORT
35 #define RTC_API
36 #endif
37 
38 #ifndef RTC_ENABLE_WEBSOCKET
39 #define RTC_ENABLE_WEBSOCKET 1
40 #endif
41 
42 #ifndef RTC_ENABLE_MEDIA
43 #define RTC_ENABLE_MEDIA 1
44 #endif
45 
46 #define RTC_DEFAULT_MTU 1280 // IPv6 minimum guaranteed MTU
47 
48 #if RTC_ENABLE_MEDIA
49 #define RTC_DEFAULT_MAXIMUM_FRAGMENT_SIZE                                                          \
50 	((uint16_t)(RTC_DEFAULT_MTU - 12 - 8 - 40)) // SRTP/UDP/IPv6
51 #define RTC_DEFAULT_MAXIMUM_PACKET_COUNT_FOR_NACK_CACHE ((unsigned)512)
52 #endif
53 
54 #include <stdbool.h>
55 #include <stdint.h>
56 
57 // libdatachannel C API
58 
59 typedef enum {
60 	RTC_NEW = 0,
61 	RTC_CONNECTING = 1,
62 	RTC_CONNECTED = 2,
63 	RTC_DISCONNECTED = 3,
64 	RTC_FAILED = 4,
65 	RTC_CLOSED = 5
66 } rtcState;
67 
68 typedef enum {
69 	RTC_GATHERING_NEW = 0,
70 	RTC_GATHERING_INPROGRESS = 1,
71 	RTC_GATHERING_COMPLETE = 2
72 } rtcGatheringState;
73 
74 typedef enum {
75 	RTC_SIGNALING_STABLE = 0,
76 	RTC_SIGNALING_HAVE_LOCAL_OFFER = 1,
77 	RTC_SIGNALING_HAVE_REMOTE_OFFER = 2,
78 	RTC_SIGNALING_HAVE_LOCAL_PRANSWER = 3,
79 	RTC_SIGNALING_HAVE_REMOTE_PRANSWER = 4,
80 } rtcSignalingState;
81 
82 typedef enum { // Don't change, it must match plog severity
83 	RTC_LOG_NONE = 0,
84 	RTC_LOG_FATAL = 1,
85 	RTC_LOG_ERROR = 2,
86 	RTC_LOG_WARNING = 3,
87 	RTC_LOG_INFO = 4,
88 	RTC_LOG_DEBUG = 5,
89 	RTC_LOG_VERBOSE = 6
90 } rtcLogLevel;
91 
92 typedef enum {
93 	RTC_CERTIFICATE_DEFAULT = 0, // ECDSA
94 	RTC_CERTIFICATE_ECDSA = 1,
95 	RTC_CERTIFICATE_RSA = 2,
96 } rtcCertificateType;
97 
98 typedef enum {
99 	// video
100 	RTC_CODEC_H264 = 0,
101 	RTC_CODEC_VP8 = 1,
102 	RTC_CODEC_VP9 = 2,
103 
104 	// audio
105 	RTC_CODEC_OPUS = 128
106 } rtcCodec;
107 
108 typedef enum {
109 	RTC_DIRECTION_UNKNOWN = 0,
110 	RTC_DIRECTION_SENDONLY = 1,
111 	RTC_DIRECTION_RECVONLY = 2,
112 	RTC_DIRECTION_SENDRECV = 3,
113 	RTC_DIRECTION_INACTIVE = 4
114 } rtcDirection;
115 
116 typedef enum { RTC_TRANSPORT_POLICY_ALL = 0, RTC_TRANSPORT_POLICY_RELAY = 1 } rtcTransportPolicy;
117 
118 #define RTC_ERR_SUCCESS 0
119 #define RTC_ERR_INVALID -1   // invalid argument
120 #define RTC_ERR_FAILURE -2   // runtime error
121 #define RTC_ERR_NOT_AVAIL -3 // element not available
122 #define RTC_ERR_TOO_SMALL -4 // buffer too small
123 
124 typedef void(RTC_API *rtcLogCallbackFunc)(rtcLogLevel level, const char *message);
125 typedef void(RTC_API *rtcDescriptionCallbackFunc)(int pc, const char *sdp, const char *type,
126                                                   void *ptr);
127 typedef void(RTC_API *rtcCandidateCallbackFunc)(int pc, const char *cand, const char *mid,
128                                                 void *ptr);
129 typedef void(RTC_API *rtcStateChangeCallbackFunc)(int pc, rtcState state, void *ptr);
130 typedef void(RTC_API *rtcGatheringStateCallbackFunc)(int pc, rtcGatheringState state, void *ptr);
131 typedef void(RTC_API *rtcSignalingStateCallbackFunc)(int pc, rtcSignalingState state, void *ptr);
132 typedef void(RTC_API *rtcDataChannelCallbackFunc)(int pc, int dc, void *ptr);
133 typedef void(RTC_API *rtcTrackCallbackFunc)(int pc, int tr, void *ptr);
134 typedef void(RTC_API *rtcOpenCallbackFunc)(int id, void *ptr);
135 typedef void(RTC_API *rtcClosedCallbackFunc)(int id, void *ptr);
136 typedef void(RTC_API *rtcErrorCallbackFunc)(int id, const char *error, void *ptr);
137 typedef void(RTC_API *rtcMessageCallbackFunc)(int id, const char *message, int size, void *ptr);
138 typedef void(RTC_API *rtcBufferedAmountLowCallbackFunc)(int id, void *ptr);
139 typedef void(RTC_API *rtcAvailableCallbackFunc)(int id, void *ptr);
140 
141 // Log
142 
143 // NULL cb on the first call will log to stdout
144 RTC_EXPORT void rtcInitLogger(rtcLogLevel level, rtcLogCallbackFunc cb);
145 
146 // User pointer
147 RTC_EXPORT void rtcSetUserPointer(int id, void *ptr);
148 RTC_EXPORT void *rtcGetUserPointer(int i);
149 
150 // PeerConnection
151 
152 typedef struct {
153 	const char **iceServers;
154 	int iceServersCount;
155 	const char *bindAddress; // libjuice only, NULL means any
156 	rtcCertificateType certificateType;
157 	rtcTransportPolicy iceTransportPolicy;
158 	bool enableIceTcp;
159 	bool disableAutoNegotiation;
160 	uint16_t portRangeBegin; // 0 means automatic
161 	uint16_t portRangeEnd;   // 0 means automatic
162 	int mtu;                 // <= 0 means automatic
163 	int maxMessageSize;      // <= 0 means default
164 } rtcConfiguration;
165 
166 RTC_EXPORT int rtcCreatePeerConnection(const rtcConfiguration *config); // returns pc id
167 RTC_EXPORT int rtcDeletePeerConnection(int pc);
168 
169 RTC_EXPORT int rtcSetLocalDescriptionCallback(int pc, rtcDescriptionCallbackFunc cb);
170 RTC_EXPORT int rtcSetLocalCandidateCallback(int pc, rtcCandidateCallbackFunc cb);
171 RTC_EXPORT int rtcSetStateChangeCallback(int pc, rtcStateChangeCallbackFunc cb);
172 RTC_EXPORT int rtcSetGatheringStateChangeCallback(int pc, rtcGatheringStateCallbackFunc cb);
173 RTC_EXPORT int rtcSetSignalingStateChangeCallback(int pc, rtcSignalingStateCallbackFunc cb);
174 
175 RTC_EXPORT int rtcSetLocalDescription(int pc, const char *type);
176 RTC_EXPORT int rtcSetRemoteDescription(int pc, const char *sdp, const char *type);
177 RTC_EXPORT int rtcAddRemoteCandidate(int pc, const char *cand, const char *mid);
178 
179 RTC_EXPORT int rtcGetLocalDescription(int pc, char *buffer, int size);
180 RTC_EXPORT int rtcGetRemoteDescription(int pc, char *buffer, int size);
181 
182 RTC_EXPORT int rtcGetLocalDescriptionType(int pc, char *buffer, int size);
183 RTC_EXPORT int rtcGetRemoteDescriptionType(int pc, char *buffer, int size);
184 
185 RTC_EXPORT int rtcGetLocalAddress(int pc, char *buffer, int size);
186 RTC_EXPORT int rtcGetRemoteAddress(int pc, char *buffer, int size);
187 
188 RTC_EXPORT int rtcGetSelectedCandidatePair(int pc, char *local, int localSize, char *remote,
189                                            int remoteSize);
190 
191 // DataChannel, Track, and WebSocket common API
192 
193 RTC_EXPORT int rtcSetOpenCallback(int id, rtcOpenCallbackFunc cb);
194 RTC_EXPORT int rtcSetClosedCallback(int id, rtcClosedCallbackFunc cb);
195 RTC_EXPORT int rtcSetErrorCallback(int id, rtcErrorCallbackFunc cb);
196 RTC_EXPORT int rtcSetMessageCallback(int id, rtcMessageCallbackFunc cb);
197 RTC_EXPORT int rtcSendMessage(int id, const char *data, int size);
198 RTC_EXPORT bool rtcIsOpen(int id);
199 RTC_EXPORT bool rtcIsClosed(int id);
200 
201 RTC_EXPORT int rtcGetBufferedAmount(int id); // total size buffered to send
202 RTC_EXPORT int rtcSetBufferedAmountLowThreshold(int id, int amount);
203 RTC_EXPORT int rtcSetBufferedAmountLowCallback(int id, rtcBufferedAmountLowCallbackFunc cb);
204 
205 // DataChannel, Track, and WebSocket common extended API
206 
207 RTC_EXPORT int rtcGetAvailableAmount(int id); // total size available to receive
208 RTC_EXPORT int rtcSetAvailableCallback(int id, rtcAvailableCallbackFunc cb);
209 RTC_EXPORT int rtcReceiveMessage(int id, char *buffer, int *size);
210 
211 // DataChannel
212 
213 typedef struct {
214 	bool unordered;
215 	bool unreliable;
216 	int maxPacketLifeTime; // ignored if reliable
217 	int maxRetransmits;    // ignored if reliable
218 } rtcReliability;
219 
220 typedef struct {
221 	rtcReliability reliability;
222 	const char *protocol; // empty string if NULL
223 	bool negotiated;
224 	bool manualStream;
225 	uint16_t stream; // numeric ID 0-65534, ignored if manualStream is false
226 } rtcDataChannelInit;
227 
228 RTC_EXPORT int rtcSetDataChannelCallback(int pc, rtcDataChannelCallbackFunc cb);
229 RTC_EXPORT int rtcCreateDataChannel(int pc, const char *label); // returns dc id
230 RTC_EXPORT int rtcCreateDataChannelEx(int pc, const char *label,
231                                       const rtcDataChannelInit *init); // returns dc id
232 RTC_EXPORT int rtcDeleteDataChannel(int dc);
233 
234 RTC_EXPORT int rtcGetDataChannelStream(int dc);
235 RTC_EXPORT int rtcGetDataChannelLabel(int dc, char *buffer, int size);
236 RTC_EXPORT int rtcGetDataChannelProtocol(int dc, char *buffer, int size);
237 RTC_EXPORT int rtcGetDataChannelReliability(int dc, rtcReliability *reliability);
238 
239 // Track
240 
241 typedef struct {
242 	rtcDirection direction;
243 	rtcCodec codec;
244 	int payloadType;
245 	uint32_t ssrc;
246 	const char *mid;
247 	const char *name;    // optional
248 	const char *msid;    // optional
249 	const char *trackId; // optional, track ID used in MSID
250 } rtcTrackInit;
251 
252 RTC_EXPORT int rtcSetTrackCallback(int pc, rtcTrackCallbackFunc cb);
253 RTC_EXPORT int rtcAddTrack(int pc, const char *mediaDescriptionSdp); // returns tr id
254 RTC_EXPORT int rtcAddTrackEx(int pc, const rtcTrackInit *init);      // returns tr id
255 RTC_EXPORT int rtcDeleteTrack(int tr);
256 
257 RTC_EXPORT int rtcGetTrackDescription(int tr, char *buffer, int size);
258 
259 #if RTC_ENABLE_MEDIA
260 
261 // Media
262 
263 // Define how NAL units are separated in a H264 sample
264 typedef enum {
265 	RTC_NAL_SEPARATOR_LENGTH = 0,               // first 4 bytes are NAL unit length
266 	RTC_NAL_SEPARATOR_LONG_START_SEQUENCE = 1,  // 0x00, 0x00, 0x00, 0x01
267 	RTC_NAL_SEPARATOR_SHORT_START_SEQUENCE = 2, // 0x00, 0x00, 0x01
268 	RTC_NAL_SEPARATOR_START_SEQUENCE = 3,       // long or short start sequence
269 } rtcNalUnitSeparator;
270 
271 typedef struct {
272 	uint32_t ssrc;
273 	const char *cname;
274 	uint8_t payloadType;
275 	uint32_t clockRate;
276 	uint16_t sequenceNumber;
277 	uint32_t timestamp;
278 
279 	// H264
280 	rtcNalUnitSeparator nalSeparator; // NAL unit separator
281 	uint16_t maxFragmentSize;         // Maximum NAL unit fragment size
282 
283 } rtcPacketizationHandlerInit;
284 
285 typedef struct {
286 	double seconds;     // Start time in seconds
287 	bool since1970;     // true if seconds since 1970
288 	                    // false if seconds since 1900
289 	uint32_t timestamp; // Start timestamp
290 } rtcStartTime;
291 
292 typedef struct {
293 	uint32_t ssrc;
294 	const char *name;    // optional
295 	const char *msid;    // optional
296 	const char *trackId; // optional, track ID used in MSID
297 } rtcSsrcForTypeInit;
298 
299 // Set H264PacketizationHandler for track
300 RTC_EXPORT int rtcSetH264PacketizationHandler(int tr, const rtcPacketizationHandlerInit *init);
301 
302 // Set OpusPacketizationHandler for track
303 RTC_EXPORT int rtcSetOpusPacketizationHandler(int tr, const rtcPacketizationHandlerInit *init);
304 
305 // Chain RtcpSrReporter to handler chain for given track
306 RTC_EXPORT int rtcChainRtcpSrReporter(int tr);
307 
308 // Chain RtcpNackResponder to handler chain for given track
309 RTC_EXPORT int rtcChainRtcpNackResponder(int tr, unsigned int maxStoredPacketsCount);
310 
311 /// Set start time for RTP stream
312 RTC_EXPORT int rtcSetRtpConfigurationStartTime(int id, const rtcStartTime *startTime);
313 
314 // Start stats recording for RTCP Sender Reporter
315 RTC_EXPORT int rtcStartRtcpSenderReporterRecording(int id);
316 
317 // Transform seconds to timestamp using track's clock rate, result is written to timestamp
318 RTC_EXPORT int rtcTransformSecondsToTimestamp(int id, double seconds, uint32_t *timestamp);
319 
320 // Transform timestamp to seconds using track's clock rate, result is written to seconds
321 RTC_EXPORT int rtcTransformTimestampToSeconds(int id, uint32_t timestamp, double *seconds);
322 
323 // Get current timestamp, result is written to timestamp
324 RTC_EXPORT int rtcGetCurrentTrackTimestamp(int id, uint32_t *timestamp);
325 
326 // Get start timestamp for track identified by given id, result is written to timestamp
327 RTC_EXPORT int rtcGetTrackStartTimestamp(int id, uint32_t *timestamp);
328 
329 // Set RTP timestamp for track identified by given id
330 RTC_EXPORT int rtcSetTrackRtpTimestamp(int id, uint32_t timestamp);
331 
332 // Get timestamp of previous RTCP SR, result is written to timestamp
333 RTC_EXPORT int rtcGetPreviousTrackSenderReportTimestamp(int id, uint32_t *timestamp);
334 
335 // Set NeedsToReport flag in RtcpSrReporter handler identified by given track id
336 RTC_EXPORT int rtcSetNeedsToSendRtcpSr(int id);
337 
338 // Get all available payload types for given codec and stores them in buffer, does nothing if
339 // buffer is NULL
340 int rtcGetTrackPayloadTypesForCodec(int tr, const char *ccodec, int *buffer, int size);
341 
342 // Get all SSRCs for given track
343 int rtcGetSsrcsForTrack(int tr, uint32_t *buffer, int count);
344 
345 // Get CName for SSRC
346 int rtcGetCNameForSsrc(int tr, uint32_t ssrc, char *cname, int cnameSize);
347 
348 // Get all SSRCs for given media type in given SDP
349 int rtcGetSsrcsForType(const char *mediaType, const char *sdp, uint32_t *buffer, int bufferSize);
350 
351 // Set SSRC for given media type in given SDP
352 int rtcSetSsrcForType(const char *mediaType, const char *sdp, char *buffer, const int bufferSize,
353                       rtcSsrcForTypeInit *init);
354 
355 #endif // RTC_ENABLE_MEDIA
356 
357 #if RTC_ENABLE_WEBSOCKET
358 
359 // WebSocket
360 
361 typedef struct {
362 	bool disableTlsVerification; // if true, don't verify the TLS certificate
363 } rtcWsConfiguration;
364 
365 RTC_EXPORT int rtcCreateWebSocket(const char *url); // returns ws id
366 RTC_EXPORT int rtcCreateWebSocketEx(const char *url, const rtcWsConfiguration *config);
367 RTC_EXPORT int rtcDeleteWebSocket(int ws);
368 
369 RTC_EXPORT int rtcGetWebSocketRemoteAddress(int ws, char *buffer, int size);
370 RTC_EXPORT int rtcGetWebSocketPath(int ws, char *buffer, int size);
371 
372 // WebSocketServer
373 
374 typedef void(RTC_API *rtcWebSocketClientCallbackFunc)(int wsserver, int ws, void *ptr);
375 
376 typedef struct {
377 	uint16_t port;                  // 0 means automatic selection
378 	bool enableTls;                 // if true, enable TLS (WSS)
379 	const char *certificatePemFile; // NULL for autogenerated certificate
380 	const char *keyPemFile;         // NULL for autogenerated certificate
381 	const char *keyPemPass;         // NULL if no pass
382 } rtcWsServerConfiguration;
383 
384 RTC_EXPORT int rtcCreateWebSocketServer(const rtcWsServerConfiguration *config,
385                                         rtcWebSocketClientCallbackFunc cb); // returns wsserver id
386 RTC_EXPORT int rtcDeleteWebSocketServer(int wsserver);
387 
388 RTC_EXPORT int rtcGetWebSocketServerPort(int wsserver);
389 
390 #endif
391 
392 // Optional global preload and cleanup
393 
394 RTC_EXPORT void rtcPreload(void);
395 RTC_EXPORT void rtcCleanup(void);
396 
397 // SCTP global settings
398 
399 typedef struct {
400 	int recvBufferSize;             // in bytes, <= 0 means optimized default
401 	int sendBufferSize;             // in bytes, <= 0 means optimized default
402 	int maxChunksOnQueue;           // in chunks, <= 0 means optimized default
403 	int initialCongestionWindow;    // in MTUs, <= 0 means optimized default
404 	int maxBurst;                   // in MTUs, 0 means optimized default, < 0 means disabled
405 	int congestionControlModule;    // 0: RFC2581 (default), 1: HSTCP, 2: H-TCP, 3: RTCC
406 	int delayedSackTimeMs;          // in msecs, 0 means optimized default, < 0 means disabled
407 	int minRetransmitTimeoutMs;     // in msecs, <= 0 means optimized default
408 	int maxRetransmitTimeoutMs;     // in msecs, <= 0 means optimized default
409 	int initialRetransmitTimeoutMs; // in msecs, <= 0 means optimized default
410 	int maxRetransmitAttempts;      // number of retransmissions, <= 0 means optimized default
411 	int heartbeatIntervalMs;        // in msecs, <= 0 means optimized default
412 } rtcSctpSettings;
413 
414 // Note: SCTP settings apply to newly-created PeerConnections only
415 RTC_EXPORT int rtcSetSctpSettings(const rtcSctpSettings *settings);
416 
417 #ifdef __cplusplus
418 } // extern "C"
419 #endif
420 
421 #endif
422