Browse Source

Merge pull request #94 from paullouisageneau/capi-log-callback

Optional log callback in C API
Paul-Louis Ageneau 5 years ago
parent
commit
5752b17a6f
5 changed files with 91 additions and 55 deletions
  1. 8 8
      examples/copy-paste-capi/answerer.c
  2. 8 8
      examples/copy-paste-capi/offerer.c
  3. 24 23
      include/rtc/rtc.h
  4. 50 15
      src/rtc.cpp
  5. 1 1
      test/capi.cpp

+ 8 - 8
examples/copy-paste-capi/answerer.c

@@ -64,16 +64,16 @@ char* state_print(rtcState state);
 char* rtcGatheringState_print(rtcState state);
 
 int main(int argc, char **argv) {
-        rtcInitLogger(RTC_LOG_DEBUG);
+	rtcInitLogger(RTC_LOG_DEBUG, NULL);
 
-        // Create peer
-        rtcConfiguration config;
-        memset(&config, 0, sizeof(config));
+	// Create peer
+	rtcConfiguration config;
+	memset(&config, 0, sizeof(config));
 
-        Peer *peer = (Peer *)malloc(sizeof(Peer));
-        if (!peer) {
-		    fprintf(stderr, "Error allocating memory for peer\n");
-		    return -1;
+	Peer *peer = (Peer *)malloc(sizeof(Peer));
+	if (!peer) {
+		fprintf(stderr, "Error allocating memory for peer\n");
+		return -1;
 	    }
         memset(peer, 0, sizeof(Peer));
 

+ 8 - 8
examples/copy-paste-capi/offerer.c

@@ -65,16 +65,16 @@ static void deletePeer(Peer *peer);
 int all_space(const char *str);
 
 int main(int argc, char **argv){
-        rtcInitLogger(RTC_LOG_DEBUG);
+	rtcInitLogger(RTC_LOG_DEBUG, NULL);
 
-        // Create peer
-        rtcConfiguration config;
-        memset(&config, 0, sizeof(config));
+	// Create peer
+	rtcConfiguration config;
+	memset(&config, 0, sizeof(config));
 
-        Peer *peer = (Peer *)malloc(sizeof(Peer));
-	    if (!peer) {
-		    fprintf(stderr, "Error allocating memory for peer\n");
-		    return -1;
+	Peer *peer = (Peer *)malloc(sizeof(Peer));
+	if (!peer) {
+		fprintf(stderr, "Error allocating memory for peer\n");
+		return -1;
 	    }
 	    memset(peer, 0, sizeof(Peer));
 

+ 24 - 23
include/rtc/rtc.h

@@ -71,20 +71,21 @@ typedef struct {
 	uint16_t portRangeEnd;
 } rtcConfiguration;
 
-typedef void (*dataChannelCallbackFunc)(int dc, void *ptr);
-typedef void (*descriptionCallbackFunc)(const char *sdp, const char *type, void *ptr);
-typedef void (*candidateCallbackFunc)(const char *cand, const char *mid, void *ptr);
-typedef void (*stateChangeCallbackFunc)(rtcState state, void *ptr);
-typedef void (*gatheringStateCallbackFunc)(rtcGatheringState state, void *ptr);
-typedef void (*openCallbackFunc)(void *ptr);
-typedef void (*closedCallbackFunc)(void *ptr);
-typedef void (*errorCallbackFunc)(const char *error, void *ptr);
-typedef void (*messageCallbackFunc)(const char *message, int size, void *ptr);
-typedef void (*bufferedAmountLowCallbackFunc)(void *ptr);
-typedef void (*availableCallbackFunc)(void *ptr);
+typedef void (*rtcLogCallbackFunc)(rtcLogLevel level, const char *message);
+typedef void (*rtcDataChannelCallbackFunc)(int dc, void *ptr);
+typedef void (*rtcDescriptionCallbackFunc)(const char *sdp, const char *type, void *ptr);
+typedef void (*rtcCandidateCallbackFunc)(const char *cand, const char *mid, void *ptr);
+typedef void (*rtcStateChangeCallbackFunc)(rtcState state, void *ptr);
+typedef void (*rtcGatheringStateCallbackFunc)(rtcGatheringState state, void *ptr);
+typedef void (*rtcOpenCallbackFunc)(void *ptr);
+typedef void (*rtcClosedCallbackFunc)(void *ptr);
+typedef void (*rtcErrorCallbackFunc)(const char *error, void *ptr);
+typedef void (*rtcMessageCallbackFunc)(const char *message, int size, void *ptr);
+typedef void (*rtcBufferedAmountLowCallbackFunc)(void *ptr);
+typedef void (*rtcAvailableCallbackFunc)(void *ptr);
 
 // Log
-void rtcInitLogger(rtcLogLevel level);
+void rtcInitLogger(rtcLogLevel level, rtcLogCallbackFunc cb); // NULL cb to log to stdout
 
 // User pointer
 void rtcSetUserPointer(int id, void *ptr);
@@ -93,11 +94,11 @@ void rtcSetUserPointer(int id, void *ptr);
 int rtcCreatePeerConnection(const rtcConfiguration *config); // returns pc id
 int rtcDeletePeerConnection(int pc);
 
-int rtcSetDataChannelCallback(int pc, dataChannelCallbackFunc cb);
-int rtcSetLocalDescriptionCallback(int pc, descriptionCallbackFunc cb);
-int rtcSetLocalCandidateCallback(int pc, candidateCallbackFunc cb);
-int rtcSetStateChangeCallback(int pc, stateChangeCallbackFunc cb);
-int rtcSetGatheringStateChangeCallback(int pc, gatheringStateCallbackFunc cb);
+int rtcSetDataChannelCallback(int pc, rtcDataChannelCallbackFunc cb);
+int rtcSetLocalDescriptionCallback(int pc, rtcDescriptionCallbackFunc cb);
+int rtcSetLocalCandidateCallback(int pc, rtcCandidateCallbackFunc cb);
+int rtcSetStateChangeCallback(int pc, rtcStateChangeCallbackFunc cb);
+int rtcSetGatheringStateChangeCallback(int pc, rtcGatheringStateCallbackFunc cb);
 
 int rtcSetRemoteDescription(int pc, const char *sdp, const char *type);
 int rtcAddRemoteCandidate(int pc, const char *cand, const char *mid);
@@ -118,19 +119,19 @@ int rtcDeleteWebsocket(int ws);
 #endif
 
 // DataChannel and WebSocket common API
-int rtcSetOpenCallback(int id, openCallbackFunc cb);
-int rtcSetClosedCallback(int id, closedCallbackFunc cb);
-int rtcSetErrorCallback(int id, errorCallbackFunc cb);
-int rtcSetMessageCallback(int id, messageCallbackFunc cb);
+int rtcSetOpenCallback(int id, rtcOpenCallbackFunc cb);
+int rtcSetClosedCallback(int id, rtcClosedCallbackFunc cb);
+int rtcSetErrorCallback(int id, rtcErrorCallbackFunc cb);
+int rtcSetMessageCallback(int id, rtcMessageCallbackFunc cb);
 int rtcSendMessage(int id, const char *data, int size);
 
 int rtcGetBufferedAmount(int id); // total size buffered to send
 int rtcSetBufferedAmountLowThreshold(int id, int amount);
-int rtcSetBufferedAmountLowCallback(int id, bufferedAmountLowCallbackFunc cb);
+int rtcSetBufferedAmountLowCallback(int id, rtcBufferedAmountLowCallbackFunc cb);
 
 // DataChannel and WebSocket common extended API
 int rtcGetAvailableAmount(int id); // total size available to receive
-int rtcSetAvailableCallback(int id, availableCallbackFunc cb);
+int rtcSetAvailableCallback(int id, rtcAvailableCallbackFunc cb);
 int rtcReceiveMessage(int id, char *buffer, int *size);
 
 // Optional preload and cleanup

+ 50 - 15
src/rtc.cpp

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019 Paul-Louis Ageneau
+ * Copyright (c) 2019-2020 Paul-Louis Ageneau
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,14 +18,16 @@
 
 #include "include.hpp"
 
+#include "rtc.h"
+
 #include "datachannel.hpp"
+#include "log.hpp"
 #include "peerconnection.hpp"
-
 #if RTC_ENABLE_WEBSOCKET
 #include "websocket.hpp"
 #endif
 
-#include <rtc.h>
+#include "plog/Formatters/FuncMessageFormatter.h"
 
 #include <exception>
 #include <mutex>
@@ -160,9 +162,42 @@ template <typename F> int wrap(F func) {
 		return RTC_ERR_SUCCESS;                                                                    \
 	})
 
+class plog_appender : public plog::IAppender {
+public:
+	plog_appender(rtcLogCallbackFunc cb = nullptr) { set_callback(cb); }
+
+	void set_callback(rtcLogCallbackFunc cb) {
+		std::lock_guard lock(mutex);
+		callback = cb;
+	}
+
+	void write(const plog::Record &record) override {
+		plog::Severity severity = record.getSeverity();
+		std::string formatted = plog::FuncMessageFormatter::format(record);
+		formatted.pop_back(); // remove newline
+
+		std::lock_guard lock(mutex);
+		if (callback)
+			callback(static_cast<rtcLogLevel>(record.getSeverity()), formatted.c_str());
+		else
+			std::cout << plog::severityToString(severity) << " " << formatted << std::endl;
+	}
+
+private:
+	rtcLogCallbackFunc callback;
+};
+
 } // namespace
 
-void rtcInitLogger(rtcLogLevel level) { InitLogger(static_cast<LogLevel>(level)); }
+void rtcInitLogger(rtcLogLevel level, rtcLogCallbackFunc cb) {
+	static std::optional<plog_appender> appender;
+	if (appender)
+		appender->set_callback(cb);
+	else if (cb)
+		appender.emplace(plog_appender(cb));
+
+	InitLogger(static_cast<plog::Severity>(level), appender ? &appender.value() : nullptr);
+}
 
 void rtcSetUserPointer(int i, void *ptr) { setUserPointer(i, ptr); }
 
@@ -241,7 +276,7 @@ int rtcDeleteWebsocket(int ws) {
 }
 #endif
 
-int rtcSetDataChannelCallback(int pc, dataChannelCallbackFunc cb) {
+int rtcSetDataChannelCallback(int pc, rtcDataChannelCallbackFunc cb) {
 	return WRAP({
 		auto peerConnection = getPeerConnection(pc);
 		if (cb)
@@ -256,7 +291,7 @@ int rtcSetDataChannelCallback(int pc, dataChannelCallbackFunc cb) {
 	});
 }
 
-int rtcSetLocalDescriptionCallback(int pc, descriptionCallbackFunc cb) {
+int rtcSetLocalDescriptionCallback(int pc, rtcDescriptionCallbackFunc cb) {
 	return WRAP({
 		auto peerConnection = getPeerConnection(pc);
 		if (cb)
@@ -268,7 +303,7 @@ int rtcSetLocalDescriptionCallback(int pc, descriptionCallbackFunc cb) {
 	});
 }
 
-int rtcSetLocalCandidateCallback(int pc, candidateCallbackFunc cb) {
+int rtcSetLocalCandidateCallback(int pc, rtcCandidateCallbackFunc cb) {
 	return WRAP({
 		auto peerConnection = getPeerConnection(pc);
 		if (cb)
@@ -280,7 +315,7 @@ int rtcSetLocalCandidateCallback(int pc, candidateCallbackFunc cb) {
 	});
 }
 
-int rtcSetStateChangeCallback(int pc, stateChangeCallbackFunc cb) {
+int rtcSetStateChangeCallback(int pc, rtcStateChangeCallbackFunc cb) {
 	return WRAP({
 		auto peerConnection = getPeerConnection(pc);
 		if (cb)
@@ -292,7 +327,7 @@ int rtcSetStateChangeCallback(int pc, stateChangeCallbackFunc cb) {
 	});
 }
 
-int rtcSetGatheringStateChangeCallback(int pc, gatheringStateCallbackFunc cb) {
+int rtcSetGatheringStateChangeCallback(int pc, rtcGatheringStateCallbackFunc cb) {
 	return WRAP({
 		auto peerConnection = getPeerConnection(pc);
 		if (cb)
@@ -385,7 +420,7 @@ int rtcGetDataChannelLabel(int dc, char *buffer, int size) {
 	});
 }
 
-int rtcSetOpenCallback(int id, openCallbackFunc cb) {
+int rtcSetOpenCallback(int id, rtcOpenCallbackFunc cb) {
 	return WRAP({
 		auto channel = getChannel(id);
 		if (cb)
@@ -395,7 +430,7 @@ int rtcSetOpenCallback(int id, openCallbackFunc cb) {
 	});
 }
 
-int rtcSetClosedCallback(int id, closedCallbackFunc cb) {
+int rtcSetClosedCallback(int id, rtcClosedCallbackFunc cb) {
 	return WRAP({
 		auto channel = getChannel(id);
 		if (cb)
@@ -405,7 +440,7 @@ int rtcSetClosedCallback(int id, closedCallbackFunc cb) {
 	});
 }
 
-int rtcSetErrorCallback(int id, errorCallbackFunc cb) {
+int rtcSetErrorCallback(int id, rtcErrorCallbackFunc cb) {
 	return WRAP({
 		auto channel = getChannel(id);
 		if (cb)
@@ -416,7 +451,7 @@ int rtcSetErrorCallback(int id, errorCallbackFunc cb) {
 	});
 }
 
-int rtcSetMessageCallback(int id, messageCallbackFunc cb) {
+int rtcSetMessageCallback(int id, rtcMessageCallbackFunc cb) {
 	return WRAP({
 		auto channel = getChannel(id);
 		if (cb)
@@ -464,7 +499,7 @@ int rtcSetBufferedAmountLowThreshold(int id, int amount) {
 	});
 }
 
-int rtcSetBufferedAmountLowCallback(int id, bufferedAmountLowCallbackFunc cb) {
+int rtcSetBufferedAmountLowCallback(int id, rtcBufferedAmountLowCallbackFunc cb) {
 	return WRAP({
 		auto channel = getChannel(id);
 		if (cb)
@@ -478,7 +513,7 @@ int rtcGetAvailableAmount(int id) {
 	return WRAP({ return int(getChannel(id)->availableAmount()); });
 }
 
-int rtcSetAvailableCallback(int id, availableCallbackFunc cb) {
+int rtcSetAvailableCallback(int id, rtcAvailableCallbackFunc cb) {
 	return WRAP({
 		auto channel = getChannel(id);
 		if (cb)

+ 1 - 1
test/capi.cpp

@@ -136,7 +136,7 @@ static void deletePeer(Peer *peer) {
 int test_capi_main() {
 	int attempts;
 
-	rtcInitLogger(RTC_LOG_DEBUG);
+	rtcInitLogger(RTC_LOG_DEBUG, nullptr);
 
 	// Create peer 1
 	rtcConfiguration config1;