diff --git a/README.md b/README.md
index be1a445..cc587bb 100644
--- a/README.md
+++ b/README.md
@@ -134,6 +134,18 @@ The softphone exposes the following resources on port `6060`.
/calls/{call_id}/transfer |
POST |
diff --git a/tinyphone/phone.cpp b/tinyphone/phone.cpp
index b43be6a..be580ec 100644
--- a/tinyphone/phone.cpp
+++ b/tinyphone/phone.cpp
@@ -531,5 +531,59 @@ namespace tp {
return true;
}
-}
+ bool TinyPhone::Join(SIPCall* call, SIPCall* call_to_join) {
+ try {
+ call_to_join->UnHoldCall();
+ } catch(...) {
+ PJ_LOG(3, (__FILENAME__, "TinyPhone::Join UnHoldCall Error"));
+ return false;
+ }
+
+ AudioMedia aud_med, aud_med2;
+ try {
+ aud_med = call->getAudioMedia(-1);
+ aud_med2 = call_to_join->getAudioMedia(-1);
+ } catch(...) {
+ PJ_LOG(3, (__FILENAME__, "TinyPhone::Join getAudioMedia Error"));
+ return false;
+ }
+
+ try {
+ aud_med.startTransmit(aud_med2);
+ aud_med2.startTransmit(aud_med);
+ } catch(...) {
+ PJ_LOG(3, (__FILENAME__, "TinyPhone::Join startTransmit Error"));
+ return false;
+ }
+
+ return true;
+ }
+ bool TinyPhone::Unjoin(SIPCall* call, SIPCall* call_to_unjoin) {
+ try {
+ call_to_unjoin->HoldCall();
+ } catch(...) {
+ PJ_LOG(3, (__FILENAME__, "TinyPhone::Unjoin HoldCall Error"));
+ return false;
+ }
+
+ AudioMedia aud_med, aud_med2;
+ try {
+ aud_med = call->getAudioMedia(-1);
+ aud_med2 = call_to_unjoin->getAudioMedia(-1);
+ } catch(...) {
+ PJ_LOG(3, (__FILENAME__, "TinyPhone::Unjoin getAudioMedia Error"));
+ return false;
+ }
+
+ try {
+ aud_med.stopTransmit(aud_med2);
+ aud_med2.stopTransmit(aud_med);
+ } catch(...) {
+ PJ_LOG(3, (__FILENAME__, "TinyPhone::Unjoin stopTransmit Error"));
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/tinyphone/phone.h b/tinyphone/phone.h
index 52f4f62..bd1914d 100644
--- a/tinyphone/phone.h
+++ b/tinyphone/phone.h
@@ -122,6 +122,9 @@ namespace tp {
bool Conference(SIPCall* call);
bool BreakConference(SIPCall* call);
+
+ bool Join(SIPCall* call, SIPCall* call_to_join);
+ bool Unjoin(SIPCall* call, SIPCall* call_to_unjoin);
void HangupAllCalls();
diff --git a/tinyphone/server.cpp b/tinyphone/server.cpp
index d967f49..5f124cf 100644
--- a/tinyphone/server.cpp
+++ b/tinyphone/server.cpp
@@ -591,7 +591,95 @@ void TinyPhoneHttpServer::Start() {
return tp::response(200, response);
}
});
-
+
+ CROW_ROUTE(app, "/calls//join/")
+ .methods("POST"_method)
+ ([&phone](int call_id, int call_to_join_id) {
+ pj_thread_auto_register();
+
+ SIPCall* call = phone.CallById(call_id);
+ SIPCall* call_to_join = phone.CallById(call_to_join_id);
+
+ if (call == nullptr) {
+ return tp::response(400, {
+ { "message", "Current Call Not Found" },
+ { "call_id" , call_id },
+ { "call_to_join_id" , call_to_join_id },
+ });
+ }
+ else if (call_to_join == nullptr) {
+ return tp::response(400, {
+ { "message", "Call To Join Not Found" },
+ { "call_id" , call_id },
+ { "call_to_join_id" , call_to_join_id }
+ });
+ }
+ else if (call->HoldState() == +HoldStatus::LOCAL_HOLD) {
+ json response = {
+ { "message", "Bad Request, CallOnHold Currently" },
+ { "call_id" , call_id },
+ { "call_to_join_id" , call_to_join_id },
+ { "status", "400" }
+ };
+
+ return tp::response(400, response);
+ }
+ else {
+ json response = {
+ { "message", "Calls Join Triggered" },
+ { "call_id" , call_id },
+ { "call_to_join_id" , call_to_join_id },
+ { "response", phone.Join(call, call_to_join) }
+ };
+
+ return tp::response(200, response);
+ }
+ });
+
+ CROW_ROUTE(app, "/calls//unjoin/")
+ .methods("POST"_method)
+ ([&phone](int call_id, int call_to_unjoin_id) {
+ pj_thread_auto_register();
+
+ SIPCall* call = phone.CallById(call_id);
+ SIPCall* call_to_unjoin = phone.CallById(call_to_unjoin_id);
+
+ if (call == nullptr) {
+ return tp::response(400, {
+ { "message", "Current Call Not Found" },
+ { "call_id" , call_id },
+ { "call_to_unjoin_id" , call_to_unjoin_id },
+ });
+ }
+ else if (call_to_unjoin == nullptr) {
+ return tp::response(400, {
+ { "message", "Call To Unjoin Not Found" },
+ { "call_id" , call_id },
+ { "call_to_unjoin_id" , call_to_unjoin_id }
+ });
+ }
+ else if (call->HoldState() == +HoldStatus::LOCAL_HOLD) {
+ json response = {
+ { "message", "Bad Request, CallOnHold Currently" },
+ { "call_id" , call_id },
+ { "call_to_unjoin_id" , call_to_unjoin_id },
+ { "status", "400" }
+ };
+
+ return tp::response(400, response);
+ }
+ else {
+ json response = {
+ { "message", "Calls Unjoin Triggered" },
+ { "call_id" , call_id },
+ { "call_to_unjoin_id" , call_to_unjoin_id },
+ { "response", phone.Unjoin(call, call_to_unjoin) }
+ };
+
+ return tp::response(200, response);
+ }
+ });
+
CROW_ROUTE(app, "/calls//transfer")
.methods("POST"_method)
([&phone](const crow::request& req, int call_id) {
|