Browse Source

Merge pull request #747 from paullouisageneau/capi-close

Add rtcClosePeerConnection and rtcDelete to C API
Paul-Louis Ageneau 2 years ago
parent
commit
ca9db92d3d
5 changed files with 117 additions and 10 deletions
  1. 35 5
      DOC.md
  2. 2 0
      include/rtc/rtc.h
  3. 35 5
      pages/content/pages/reference.md
  4. 41 0
      src/capi.cpp
  5. 4 0
      test/capi_connectivity.cpp

+ 35 - 5
DOC.md

@@ -120,13 +120,27 @@ The `proxyServer` URI, if present, must match the format `[("http"|"socks5") (":
 
 If the username or password of an URI contains reserved special characters, they must be percent-encoded. In particular, ":" must be encoded as "%3A" and "@" must by encoded as "%40".
 
+#### rtcClosePeerConnection
+
+```
+int rtcClosePeerConnection(int pc)
+```
+
+Closes the Peer Connection.
+
+Arguments:
+
+- `pc`: the Peer Connection identifier
+
+Return value: `RTC_ERR_SUCCESS` or a negative error code
+
 #### rtcDeletePeerConnection
 
 ```
 int rtcDeletePeerConnection(int pc)
 ```
 
-Deletes the specified Peer Connection.
+Deletes the Peer Connection.
 
 Arguments:
 
@@ -134,7 +148,7 @@ Arguments:
 
 Return value: `RTC_ERR_SUCCESS` or a negative error code
 
-After this function has been called, `pc` must not be used in a function call anymore. This function will block until all scheduled callbacks of `pc` return (except the one this function might be called in) and no other callback will be called for `pc` after it returns.
+If it is not already closed, the Peer Connection is implicitly closed before being deleted. After this function has been called, `pc` must not be used in a function call anymore. This function will block until all scheduled callbacks of `pc` return (except the one this function might be called in) and no other callback will be called for `pc` after it returns.
 
 #### rtcSetXCallback
 
@@ -463,6 +477,22 @@ Return value: `RTC_ERR_SUCCESS` or a negative error code
 
 WebSocket: Like with the JavaScript API, the state will first change to closing, then closed only after the connection has been actually closed.
 
+#### rtcDelete
+
+```
+int rtcDelete(int id)
+```
+
+Deletes the channel.
+
+Arguments:
+
+- `id`: the channel identifier
+
+Return value: `RTC_ERR_SUCCESS` or a negative error code
+
+If it is not already closed, the channel is implicitly closed before being deleted. After this function has been called, `id` must not be used in a function call anymore. This function will block until all scheduled callbacks of `id` return (except the one this function might be called in) and no other callback will be called for `id` after it returns.
+
 #### rtcIsOpen
 
 ```
@@ -595,7 +625,7 @@ Arguments:
 
 Return value: the identifier of the new Data Channel or a negative error code.
 
-The Data Channel must be deleted with `rtcDeleteDataChannel`.
+The Data Channel must be deleted with `rtcDeleteDataChannel` (or `rtcDelete`).
 
 If `disableAutoNegotiation` was not set in `rtcConfiguration`, the library will automatically initiate the negotiation by calling `rtcSetLocalDescription` internally. Otherwise, the user must call `rtcSetLocalDescription` to initiate the negotiation after creating the first Data Channel.
 
@@ -695,7 +725,7 @@ Arguments:
 
 Return value: the identifier of the new Track or a negative error code
 
-The new track must be deleted with `rtcDeleteTrack`.
+The new track must be deleted with `rtcDeleteTrack` (or `rtcDelete`).
 
 The user must call `rtcSetLocalDescription` to negotiate the track.
 
@@ -799,7 +829,7 @@ Arguments:
 
 Return value: the identifier of the new WebSocket or a negative error code
 
-The new WebSocket must be deleted with `rtcDeleteWebSocket`. The scheme of the URL must be either `ws` or `wss`.
+The new WebSocket must be deleted with `rtcDeleteWebSocket` (or `rtcDelete`). The scheme of the URL must be either `ws` or `wss`.
 
 #### rtcDeleteWebSocket
 

+ 2 - 0
include/rtc/rtc.h

@@ -166,6 +166,7 @@ typedef struct {
 } rtcConfiguration;
 
 RTC_EXPORT int rtcCreatePeerConnection(const rtcConfiguration *config); // returns pc id
+RTC_EXPORT int rtcClosePeerConnection(int pc);
 RTC_EXPORT int rtcDeletePeerConnection(int pc);
 
 RTC_EXPORT int rtcSetLocalDescriptionCallback(int pc, rtcDescriptionCallbackFunc cb);
@@ -200,6 +201,7 @@ RTC_EXPORT int rtcSetErrorCallback(int id, rtcErrorCallbackFunc cb);
 RTC_EXPORT int rtcSetMessageCallback(int id, rtcMessageCallbackFunc cb);
 RTC_EXPORT int rtcSendMessage(int id, const char *data, int size);
 RTC_EXPORT int rtcClose(int id);
+RTC_EXPORT int rtcDelete(int id);
 RTC_EXPORT bool rtcIsOpen(int id);
 RTC_EXPORT bool rtcIsClosed(int id);
 

+ 35 - 5
pages/content/pages/reference.md

@@ -123,13 +123,27 @@ The `proxyServer` URI, if present, must match the format `[("http"|"socks5") (":
 
 If the username or password of an URI contains reserved special characters, they must be percent-encoded. In particular, ":" must be encoded as "%3A" and "@" must by encoded as "%40".
 
+#### rtcClosePeerConnection
+
+```
+int rtcClosePeerConnection(int pc)
+```
+
+Closes the Peer Connection.
+
+Arguments:
+
+- `pc`: the Peer Connection identifier
+
+Return value: `RTC_ERR_SUCCESS` or a negative error code
+
 #### rtcDeletePeerConnection
 
 ```
 int rtcDeletePeerConnection(int pc)
 ```
 
-Deletes the specified Peer Connection.
+Deletes the Peer Connection.
 
 Arguments:
 
@@ -137,7 +151,7 @@ Arguments:
 
 Return value: `RTC_ERR_SUCCESS` or a negative error code
 
-After this function has been called, `pc` must not be used in a function call anymore. This function will block until all scheduled callbacks of `pc` return (except the one this function might be called in) and no other callback will be called for `pc` after it returns.
+If it is not already closed, the Peer Connection is implicitly closed before being deleted. After this function has been called, `pc` must not be used in a function call anymore. This function will block until all scheduled callbacks of `pc` return (except the one this function might be called in) and no other callback will be called for `pc` after it returns.
 
 #### rtcSetXCallback
 
@@ -466,6 +480,22 @@ Return value: `RTC_ERR_SUCCESS` or a negative error code
 
 WebSocket: Like with the JavaScript API, the state will first change to closing, then closed only after the connection has been actually closed.
 
+#### rtcDelete
+
+```
+int rtcDelete(int id)
+```
+
+Deletes the channel.
+
+Arguments:
+
+- `id`: the channel identifier
+
+Return value: `RTC_ERR_SUCCESS` or a negative error code
+
+If it is not already closed, the channel is implicitly closed before being deleted. After this function has been called, `id` must not be used in a function call anymore. This function will block until all scheduled callbacks of `id` return (except the one this function might be called in) and no other callback will be called for `id` after it returns.
+
 #### rtcIsOpen
 
 ```
@@ -598,7 +628,7 @@ Arguments:
 
 Return value: the identifier of the new Data Channel or a negative error code.
 
-The Data Channel must be deleted with `rtcDeleteDataChannel`.
+The Data Channel must be deleted with `rtcDeleteDataChannel` (or `rtcDelete`).
 
 If `disableAutoNegotiation` was not set in `rtcConfiguration`, the library will automatically initiate the negotiation by calling `rtcSetLocalDescription` internally. Otherwise, the user must call `rtcSetLocalDescription` to initiate the negotiation after creating the first Data Channel.
 
@@ -698,7 +728,7 @@ Arguments:
 
 Return value: the identifier of the new Track or a negative error code
 
-The new track must be deleted with `rtcDeleteTrack`.
+The new track must be deleted with `rtcDeleteTrack` (or `rtcDelete`).
 
 The user must call `rtcSetLocalDescription` to negotiate the track.
 
@@ -802,7 +832,7 @@ Arguments:
 
 Return value: the identifier of the new WebSocket or a negative error code
 
-The new WebSocket must be deleted with `rtcDeleteWebSocket`. The scheme of the URL must be either `ws` or `wss`.
+The new WebSocket must be deleted with `rtcDeleteWebSocket` (or `rtcDelete`). The scheme of the URL must be either `ws` or `wss`.
 
 #### rtcDeleteWebSocket
 

+ 41 - 0
src/capi.cpp

@@ -170,6 +170,30 @@ shared_ptr<Channel> getChannel(int id) {
 	throw std::invalid_argument("DataChannel, Track, or WebSocket ID does not exist");
 }
 
+void eraseChannel(int id) {
+	std::lock_guard lock(mutex);
+	if (dataChannelMap.erase(id) != 0) {
+		userPointerMap.erase(id);
+		return;
+	}
+	if (trackMap.erase(id) != 0) {
+		userPointerMap.erase(id);
+#if RTC_ENABLE_MEDIA
+		rtcpSrReporterMap.erase(id);
+		rtcpChainableHandlerMap.erase(id);
+		rtpConfigMap.erase(id);
+#endif
+		return;
+	}
+#if RTC_ENABLE_WEBSOCKET
+	if (webSocketMap.erase(id) != 0) {
+		userPointerMap.erase(id);
+		return;
+	}
+#endif
+	throw std::invalid_argument("DataChannel, Track, or WebSocket ID does not exist");
+}
+
 int copyAndReturn(string s, char *buffer, int size) {
 	if (!buffer)
 		return int(s.size() + 1);
@@ -382,6 +406,14 @@ int rtcCreatePeerConnection(const rtcConfiguration *config) {
 	});
 }
 
+int rtcClosePeerConnection(int pc) {
+	return wrap([pc] {
+		auto peerConnection = getPeerConnection(pc);
+		peerConnection->close();
+		return RTC_ERR_SUCCESS;
+	});
+}
+
 int rtcDeletePeerConnection(int pc) {
 	return wrap([pc] {
 		auto peerConnection = getPeerConnection(pc);
@@ -708,6 +740,15 @@ int rtcClose(int id) {
 	});
 }
 
+int rtcDelete(int id) {
+	return wrap([id] {
+		auto channel = getChannel(id);
+		channel->close();
+		eraseChannel(id);
+		return RTC_ERR_SUCCESS;
+	});
+}
+
 bool rtcIsOpen(int id) {
 	return wrap([id] { return getChannel(id)->isOpen() ? 0 : 1; }) == 0 ? true : false;
 }

+ 4 - 0
test/capi_connectivity.cpp

@@ -350,6 +350,10 @@ int test_capi_connectivity_main() {
 		goto error;
 	}
 
+	rtcClose(peer1->dc); // optional
+
+	rtcClosePeerConnection(peer1->pc); // optional
+
 	deletePeer(peer1);
 	sleep(1);
 	deletePeer(peer2);