From 7849cb0b3df194326217a781be9d2b17ded21b42 Mon Sep 17 00:00:00 2001 From: Patrick Desaulniers <52038217+pdesaulniers-vertisoft@users.noreply.github.com> Date: Fri, 24 Nov 2023 12:12:32 -0500 Subject: [PATCH 1/7] Implement `TinyPhone::Join` This method can be used to join two specific calls. It is similar to `TinyPhone::Conference`, except it applies to a specific call, rather than all current calls. --- tinyphone/phone.cpp | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/tinyphone/phone.cpp b/tinyphone/phone.cpp index b43be6a..4fddfd9 100644 --- a/tinyphone/phone.cpp +++ b/tinyphone/phone.cpp @@ -531,5 +531,32 @@ 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 { + // start bidirectional audio + aud_med.startTransmit(aud_med2); + aud_med2.startTransmit(aud_med); + } catch(...) { + PJ_LOG(3, (__FILENAME__, "TinyPhone::Join startTransmit Error")); + return false; + } + return true; + } +} From 9ab910ddcb9e41d343008de923cc0138603e5b0d Mon Sep 17 00:00:00 2001 From: Patrick Desaulniers <52038217+pdesaulniers-vertisoft@users.noreply.github.com> Date: Fri, 24 Nov 2023 12:15:44 -0500 Subject: [PATCH 2/7] Add `/calls//join/` endpoint This endpoint exposes `TinyPhone::Join`. --- tinyphone/server.cpp | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/tinyphone/server.cpp b/tinyphone/server.cpp index d967f49..e32d289 100644 --- a/tinyphone/server.cpp +++ b/tinyphone/server.cpp @@ -591,7 +591,44 @@ 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 } + }); + } + else if (call_to_join == nullptr) { + return tp::response(400, { + { "message", "Call To Join Not Found" }, + { "call_id" , call_to_join_id } + }); + } + else if (call->HoldState() == +HoldStatus::LOCAL_HOLD) { + response["message"] = "Bad Request, CallOnHold Currently"; + response["status"] = "400"; + return tp::response(400, response); + } + else { + json response = { + { "message", "Calls Join Triggered" }, + { "call_id" , call_id }, + { "call_id_ToJoin" , call_to_join_id }, + { "response", phone.Join(call, call_to_join) } + }; + + return tp::response(200, response); + } + }); + CROW_ROUTE(app, "/calls//transfer") .methods("POST"_method) ([&phone](const crow::request& req, int call_id) { From 357706c0b13178cee2bef2fc25edb5e542384673 Mon Sep 17 00:00:00 2001 From: Patrick Desaulniers <52038217+pdesaulniers-vertisoft@users.noreply.github.com> Date: Fri, 24 Nov 2023 12:43:44 -0500 Subject: [PATCH 3/7] Declare `TinyPhone::Join` --- tinyphone/phone.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tinyphone/phone.h b/tinyphone/phone.h index 52f4f62..8659959 100644 --- a/tinyphone/phone.h +++ b/tinyphone/phone.h @@ -122,6 +122,8 @@ namespace tp { bool Conference(SIPCall* call); bool BreakConference(SIPCall* call); + + bool Join(SIPCall* call, SIPCall* call_to_join); void HangupAllCalls(); From c5b79ebb9a2a268d9ad12f5a40fcfa1706d7810b Mon Sep 17 00:00:00 2001 From: Patrick Desaulniers Date: Fri, 24 Nov 2023 13:25:25 -0500 Subject: [PATCH 4/7] Misc fixes --- tinyphone/server.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tinyphone/server.cpp b/tinyphone/server.cpp index e32d289..e35f0bf 100644 --- a/tinyphone/server.cpp +++ b/tinyphone/server.cpp @@ -603,25 +603,32 @@ void TinyPhoneHttpServer::Start() { if (call == nullptr) { return tp::response(400, { { "message", "Current Call Not Found" }, - { "call_id" , call_id } + { "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_to_join_id } + { "call_id" , call_id }, + { "call_to_join_id" , call_to_join_id } }); } else if (call->HoldState() == +HoldStatus::LOCAL_HOLD) { - response["message"] = "Bad Request, CallOnHold Currently"; - response["status"] = "400"; - return tp::response(400, response); + 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_id_ToJoin" , call_to_join_id }, + { "call_to_join_id" , call_to_join_id }, { "response", phone.Join(call, call_to_join) } }; From d5251412243cd1bf59527058af66b53a5fc904f5 Mon Sep 17 00:00:00 2001 From: Patrick Desaulniers <52038217+pdesaulniers-vertisoft@users.noreply.github.com> Date: Fri, 24 Nov 2023 14:10:20 -0500 Subject: [PATCH 5/7] Document `/calls/{call_id}/join/{call_to_join_id}` endpoint --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index be1a445..838cb40 100644 --- a/README.md +++ b/README.md @@ -134,6 +134,12 @@ The softphone exposes the following resources on port `6060`. Break specified call_id out of conference +/calls/{call_id}/join/{call_to_join_id} +POST + +Merges the current call (call_id) with another running call (call_to_join_id) + + /calls/{call_id}/transfer POST From 494d528d222abb70f40b79dfc0661d2a107deecc Mon Sep 17 00:00:00 2001 From: Patrick Desaulniers Date: Sat, 25 Nov 2023 08:27:51 -0500 Subject: [PATCH 6/7] Allow unjoining calls --- README.md | 6 ++++++ tinyphone/phone.cpp | 29 ++++++++++++++++++++++++++++- tinyphone/phone.h | 1 + tinyphone/server.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 79 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 838cb40..eb85a56 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,12 @@ The softphone exposes the following resources on port `6060`. Merges the current call (call_id) with another running call (call_to_join_id) +/calls/{call_id}/unjoin/{call_to_unjoin_id} +POST + +Break specified call_id out of conference with call_to_join_id + + /calls/{call_id}/transfer POST diff --git a/tinyphone/phone.cpp b/tinyphone/phone.cpp index 4fddfd9..be580ec 100644 --- a/tinyphone/phone.cpp +++ b/tinyphone/phone.cpp @@ -549,7 +549,6 @@ namespace tp { } try { - // start bidirectional audio aud_med.startTransmit(aud_med2); aud_med2.startTransmit(aud_med); } catch(...) { @@ -559,4 +558,32 @@ namespace tp { 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 8659959..bd1914d 100644 --- a/tinyphone/phone.h +++ b/tinyphone/phone.h @@ -124,6 +124,7 @@ namespace tp { 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 e35f0bf..5f124cf 100644 --- a/tinyphone/server.cpp +++ b/tinyphone/server.cpp @@ -636,6 +636,50 @@ void TinyPhoneHttpServer::Start() { } }); + 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) { From 7794302619a68201bc3fd701295397bb2782d7e2 Mon Sep 17 00:00:00 2001 From: Patrick Desaulniers Date: Sat, 25 Nov 2023 08:28:38 -0500 Subject: [PATCH 7/7] Fix typo in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eb85a56..cc587bb 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ The softphone exposes the following resources on port `6060`. /calls/{call_id}/unjoin/{call_to_unjoin_id} POST -Break specified call_id out of conference with call_to_join_id +Break specified call_id out of conference with call_to_unjoin_id /calls/{call_id}/transfer