2
/* Ekiga -- A VoIP and Video-Conferencing application
3
* Copyright (C) 2000-2006 Damien Sandras
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20
* Ekiga is licensed under the GPL license and as a special exc_managertion,
21
* you have permission to link or otherwise combine this program with the
22
* programs OPAL, OpenH323 and PWLIB, and distribute the combination,
23
* without applying the requirements of the GNU GPL to the OPAL, OpenH323
24
* and PWLIB programs, as long as you do follow the requirements of the
25
* GNU GPL for all the rest of the software thus combined.
30
* sipendpoint.cpp - description
31
* --------------------------------
32
* begin : Wed 8 Dec 2004
33
* copyright : (C) 2000-2006 by Damien Sandras
34
* description : This file contains the SIP Endpoint class.
44
#include "sip-endpoint.h"
46
#include "opal-bank.h"
47
#include "opal-call.h"
49
#include "presence-core.h"
50
#include "account-core.h"
51
#include "chat-core.h"
52
#include "personal-details.h"
53
#include "opal-account.h"
56
presence_status_in_main (Ekiga::PresenceFetcher* fetcher,
61
fetcher->presence_received.emit (uri, presence);
62
fetcher->status_received.emit (uri, status);
66
push_message_in_main (SIP::Dialect* dialect,
67
const std::string uri,
68
const std::string name,
69
const std::string msg)
71
dialect->push_message (uri, name, msg);
75
push_notice_in_main (SIP::Dialect* dialect,
76
const std::string uri,
77
const std::string name,
78
const std::string msg)
80
dialect->push_notice (uri, name, msg);
87
class dialer : public PThread
89
PCLASSINFO(dialer, PThread);
93
dialer (const std::string & uri, Opal::CallManager & _manager)
94
: PThread (1000, AutoDeleteThread),
104
manager.SetUpCall ("pc:*", dial_uri, token);
108
const std::string dial_uri;
109
Opal::CallManager & manager;
113
class subscriber : public PThread
115
PCLASSINFO(subscriber, PThread);
118
subscriber (const Opal::Account & _account,
119
Opal::Sip::EndPoint & _manager)
120
: PThread (1000, AutoDeleteThread),
129
manager.Register (account);
133
const Opal::Account & account;
134
Opal::Sip::EndPoint & manager;
142
Opal::Sip::EndPoint::EndPoint (Opal::CallManager & _manager,
143
Ekiga::ServiceCore & _core,
144
unsigned _listen_port)
145
: SIPEndPoint (_manager),
148
presence_core (*(dynamic_cast<Ekiga::PresenceCore *> (core.get ("presence-core")))),
149
runtime (*(dynamic_cast<Ekiga::Runtime *> (core.get ("runtime")))),
150
account_core (*(dynamic_cast<Ekiga::AccountCore *> (core.get ("account-core"))))
152
Ekiga::ChatCore* chat_core;
154
protocol_name = "sip";
156
listen_port = _listen_port;
158
chat_core = dynamic_cast<Ekiga::ChatCore *> (core.get ("chat-core"));
159
dialect = new SIP::Dialect (core, sigc::mem_fun (this, &Opal::Sip::EndPoint::send_message));
160
chat_core->add_dialect (*dialect);
163
SetAckTimeout (PTimeInterval (0, 32));
164
SetPduCleanUpTimeout (PTimeInterval (0, 1));
165
SetInviteTimeout (PTimeInterval (0, 6));
166
SetNonInviteTimeout (PTimeInterval (0, 6));
167
SetRetryTimeouts (500, 4000);
171
set_listen_port (listen_port);
173
/* Update the User Agent */
174
SetUserAgent ("Ekiga/" PACKAGE_VERSION);
176
/* Ready to take calls */
177
manager.AddRouteEntry("sip:.* = pc:<db>");
178
manager.AddRouteEntry("pc:.* = sip:<da>");
181
SetNATBindingRefreshMethod (SIPEndPoint::EmptyRequest);
183
Ekiga::PersonalDetails *details = dynamic_cast<Ekiga::PersonalDetails *> (_core.get ("personal-details"));
189
Opal::Sip::EndPoint::~EndPoint ()
195
bool Opal::Sip::EndPoint::populate_menu (Ekiga::Contact &contact,
196
const std::string uri,
197
Ekiga::MenuBuilder &builder)
199
return menu_builder_add_actions (contact.get_name (), uri, builder);
203
bool Opal::Sip::EndPoint::populate_menu (Ekiga::Presentity& presentity,
204
const std::string uri,
205
Ekiga::MenuBuilder & builder)
207
return menu_builder_add_actions (presentity.get_name (), uri, builder);
211
bool Opal::Sip::EndPoint::menu_builder_add_actions (const std::string& fullname,
212
const std::string& uri,
213
Ekiga::MenuBuilder & builder)
215
bool populated = false;
218
std::list<std::string> uris;
219
std::list<std::string> accounts;
221
if (!(uri.find ("sip:") == 0 || uri.find (":") == string::npos))
224
if (uri.find ("@") == string::npos) {
226
Opal::Bank *bank = dynamic_cast<Opal::Bank*> (core.get ("opal-account-store"));
230
for (Opal::Bank::iterator it = bank->begin ();
234
if (it->get_protocol_name () == "SIP" && it->is_active ()) {
236
std::stringstream uristr;
237
std::string str = uri;
239
for (unsigned i = 0 ; i < str.length() ; i++) {
241
if (str [i] == ' ' || str [i] == '-') {
247
if (str.find ("sip:") == string::npos)
248
uristr << "sip:" << str;
252
uristr << "@" << it->get_host ();
254
uris.push_back (uristr.str ());
255
accounts.push_back (it->get_name ());
261
uris.push_back (uri);
262
accounts.push_back ("");
265
std::list<std::string>::iterator ita = accounts.begin ();
266
for (std::list<std::string>::iterator it = uris.begin ();
270
std::stringstream call_action;
271
std::stringstream transfer_action;
272
if (!(*ita).empty ()) {
273
call_action << _("Call") << " [" << (*ita) << "]";
274
transfer_action << _("Transfer") << " [" << (*ita) << "]";
277
call_action << _("Call");
278
transfer_action << _("Transfer");
281
if (0 == GetConnectionCount ())
282
builder.add_action ("call", call_action.str (),
283
sigc::bind (sigc::mem_fun (this, &Opal::Sip::EndPoint::on_dial), (*it)));
285
builder.add_action ("transfer", transfer_action.str (),
286
sigc::bind (sigc::mem_fun (this, &Opal::Sip::EndPoint::on_transfer), (*it)));
291
ita = accounts.begin ();
292
for (std::list<std::string>::iterator it = uris.begin ();
296
std::stringstream msg_action;
297
if (!(*ita).empty ())
298
msg_action << _("Message") << " [" << (*ita) << "]";
300
msg_action << _("Message");
302
builder.add_action ("message", msg_action.str (),
303
sigc::bind (sigc::mem_fun (this, &Opal::Sip::EndPoint::on_message), (*it), fullname));
314
void Opal::Sip::EndPoint::fetch (const std::string _uri)
316
std::string::size_type loc = _uri.find ("@", 0);
319
if (loc != string::npos)
320
domain = _uri.substr (loc+1);
322
// It is not in the list of uris for which a subscribe is active
323
if (std::find (subscribed_uris.begin (), subscribed_uris.end (), _uri) == subscribed_uris.end ()) {
325
// We are registered yet
326
if (std::find (domains.begin (), domains.end (), domain) != domains.end ()) {
328
Subscribe (SIPSubscribe::Presence, 300, PString (_uri.c_str ()));
329
subscribed_uris.push_back (_uri);
333
to_subscribe_uris.push_back (_uri);
339
void Opal::Sip::EndPoint::unfetch (const std::string uri)
341
if (std::find (subscribed_uris.begin (), subscribed_uris.end (), uri) != subscribed_uris.end ()) {
343
Subscribe (SIPSubscribe::Presence, 0, PString (uri.c_str ()));
344
subscribed_uris.remove (uri);
349
void Opal::Sip::EndPoint::publish (const Ekiga::PersonalDetails & details)
351
std::string hostname = (const char *) PIPSocket::GetHostName ();
352
std::string short_status = ((Ekiga::PersonalDetails &) (details)).get_short_status ();
353
std::string long_status = ((Ekiga::PersonalDetails &) (details)).get_long_status ();
355
for (std::list<std::string>::iterator it = aors.begin ();
358
std::string to = it->substr (4);
360
data += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
362
data += "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" entity=\"pres:";
366
data += "<tuple id=\"";
373
data += short_status.c_str ();
374
if (!long_status.empty ()) {
376
data += long_status.c_str ();
378
data += "</note>\r\n";
380
data += "<status>\r\n";
383
data += "</basic>\r\n";
384
data += "</status>\r\n";
386
data += "<contact priority=\"1\">sip:";
388
data += "</contact>\r\n";
390
data += "</tuple>\r\n";
391
data += "</presence>\r\n";
393
Publish (to, data, 300); // TODO: allow to change the 500
398
bool Opal::Sip::EndPoint::send_message (const std::string & _uri,
399
const std::string & _message)
401
if (!_uri.empty () && (_uri.find ("sip:") == 0 || _uri.find (':') == string::npos) && !_message.empty ()) {
403
SIPEndPoint::Message (_uri, _message);
412
bool Opal::Sip::EndPoint::dial (const std::string & uri)
414
std::stringstream ustr;
416
if (uri.find ("sip:") == 0 || uri.find (":") == string::npos) {
418
if (uri.find (":") == string::npos)
419
ustr << "sip:" << uri;
423
new Opal::Sip::dialer (ustr.str (), manager);
432
const std::string & Opal::Sip::EndPoint::get_protocol_name () const
434
return protocol_name;
438
void Opal::Sip::EndPoint::set_dtmf_mode (unsigned mode)
444
SetSendUserInputMode (OpalConnection::SendUserInputAsTone);
449
SetSendUserInputMode (OpalConnection::SendUserInputAsInlineRFC2833);
457
unsigned Opal::Sip::EndPoint::get_dtmf_mode () const
460
if (GetSendUserInputMode () == OpalConnection::SendUserInputAsTone)
464
if (GetSendUserInputMode () == OpalConnection::SendUserInputAsInlineRFC2833)
471
bool Opal::Sip::EndPoint::set_listen_port (unsigned port)
473
unsigned udp_min, udp_max;
475
listen_iface.protocol = "udp";
476
listen_iface.voip_protocol = "sip";
477
listen_iface.id = "*";
479
manager.get_udp_ports (udp_min, udp_max);
481
if (port > 0 && port >= udp_min && port <= udp_max) {
483
std::stringstream str;
484
RemoveListener (NULL);
486
str << "udp$*:" << port;
487
if (!StartListeners (PStringArray (str.str ()))) {
490
str << "udp$*:" << port;
491
while (port <= udp_max) {
493
if (StartListeners (PStringArray (str.str ()))) {
495
listen_iface.port = port;
503
listen_iface.port = port;
510
const Ekiga::CallProtocolManager::Interface & Opal::Sip::EndPoint::get_listen_interface () const
517
void Opal::Sip::EndPoint::set_forward_uri (const std::string & uri)
523
const std::string & Opal::Sip::EndPoint::get_forward_uri () const
529
void Opal::Sip::EndPoint::set_outbound_proxy (const std::string & uri)
531
outbound_proxy = uri;
532
SetProxy (SIPURL (outbound_proxy));
536
const std::string & Opal::Sip::EndPoint::get_outbound_proxy () const
538
return outbound_proxy;
542
void Opal::Sip::EndPoint::set_nat_binding_delay (unsigned delay)
544
SetNATBindingTimeout (PTimeInterval (0, delay));
548
unsigned Opal::Sip::EndPoint::get_nat_binding_delay ()
550
return GetNATBindingTimeout ().GetSeconds ();
554
bool Opal::Sip::EndPoint::subscribe (const Opal::Account & account)
556
if (account.get_protocol_name () != "SIP" || account.is_active ())
559
new subscriber (account, *this);
564
bool Opal::Sip::EndPoint::unsubscribe (const Opal::Account & account)
566
if (account.get_protocol_name () != "SIP" || !account.is_active ())
569
new subscriber (account, *this);
574
void Opal::Sip::EndPoint::ShutDown ()
576
listeners.RemoveAll ();
578
for (PSafePtr<SIPTransaction> transaction(transactions, PSafeReference); transaction != NULL; ++transaction)
579
transaction->WaitForCompletion();
581
while (activeSIPHandlers.GetSize() > 0) {
582
PSafePtr<SIPHandler> handler = activeSIPHandlers;
583
activeSIPHandlers.Remove(handler);
586
SIPEndPoint::ShutDown ();
590
void Opal::Sip::EndPoint::Register (const Opal::Account & account)
592
std::stringstream aor;
593
std::string host = account.get_host ();
594
std::string::size_type loc = host.find (":", 0);
595
if (loc != std::string::npos)
596
host = host.substr (0, loc);
598
if (account.get_username ().find ("@") == std::string::npos)
599
aor << account.get_username () << "@" << host;
601
aor << account.get_username ();
603
SIPRegister::Params params;
604
params.m_addressOfRecord = aor.str ();
605
params.m_registrarAddress = account.get_host ();
606
params.m_authID = account.get_authentication_username ();
607
params.m_password = account.get_password ();
608
params.m_expire = (account.is_enabled () ? account.get_timeout () : 0);
609
params.m_minRetryTime = 0;
610
params.m_maxRetryTime = 0;
612
if (!SIPEndPoint::Register (params))
613
OnRegistrationFailed (aor.str (), SIP_PDU::MaxStatusCode, account.is_enabled ());
617
void Opal::Sip::EndPoint::OnRegistered (const PString & _aor,
618
bool was_registering)
620
std::string aor = (const char *) _aor;
621
std::string::size_type found;
622
std::string::size_type loc = aor.find ("@", 0);
624
std::stringstream strm;
626
if (aor.find (uri_prefix) == std::string::npos)
627
strm << uri_prefix << aor;
631
std::list<std::string>::iterator it = find (aors.begin (), aors.end (), aor);
633
if (was_registering) {
635
if (it == aors.end ())
636
aors.push_back (strm.str ());
640
if (it != aors.end ())
641
aors.remove (strm.str ());
644
if (loc != string::npos) {
646
server = aor.substr (loc+1);
651
if (was_registering && std::find (domains.begin (), domains.end (), server) == domains.end ())
652
domains.push_back (server);
654
if (!was_registering && std::find (domains.begin (), domains.end (), server) != domains.end ())
655
domains.remove (server);
657
if (was_registering) {
658
for (std::list<std::string>::const_iterator iter = to_subscribe_uris.begin ();
659
iter != to_subscribe_uris.end () ; ) {
661
found = (*iter).find (server, 0);
662
if (found != string::npos) {
664
Subscribe (SIPSubscribe::Presence, 300, PString ((*iter).c_str ()));
665
subscribed_uris.push_back (*iter);
666
to_subscribe_uris.remove (*iter++);
673
for (std::list<std::string>::const_iterator iter = subscribed_uris.begin ();
674
iter != subscribed_uris.end () ; ) {
676
found = (*iter).find (server, 0);
677
if (found != string::npos) {
679
Unsubscribe (SIPSubscribe::Presence, PString ((*iter).c_str ()));
680
to_subscribe_uris.push_back (*iter);
681
subscribed_uris.remove (*iter++);
689
/* Subscribe for MWI */
690
if (!IsSubscribed (SIPSubscribe::MessageSummary, aor))
691
Subscribe (SIPSubscribe::MessageSummary, 3600, aor);
694
Ekiga::Account *account = account_core.find_account (strm.str ());
696
runtime.run_in_main (sigc::bind (account->registration_event.make_slot (),
697
was_registering ? Ekiga::AccountCore::Registered : Ekiga::AccountCore::Unregistered,
702
void Opal::Sip::EndPoint::OnRegistrationFailed (const PString & _aor,
703
SIP_PDU::StatusCodes r,
706
std::stringstream strm;
708
std::string aor = (const char *) _aor;
710
if (aor.find (uri_prefix) == std::string::npos)
711
strm << uri_prefix << aor;
717
case SIP_PDU::Failure_BadRequest:
718
info = _("Bad request");
721
case SIP_PDU::Failure_PaymentRequired:
722
info = _("Payment required");
725
case SIP_PDU::Failure_UnAuthorised:
726
info = _("Unauthorized");
729
case SIP_PDU::Failure_Forbidden:
730
info = _("Forbidden");
733
case SIP_PDU::Failure_RequestTimeout:
737
case SIP_PDU::Failure_Conflict:
738
info = _("Conflict");
741
case SIP_PDU::Failure_TemporarilyUnavailable:
742
info = _("Temporarily unavailable");
745
case SIP_PDU::Failure_NotAcceptable:
746
info = _("Not acceptable");
749
case SIP_PDU::IllegalStatusCode:
750
info = _("Illegal status code");
753
case SIP_PDU::Redirection_MultipleChoices:
754
info = _("Multiple choices");
757
case SIP_PDU::Redirection_MovedPermanently:
758
info = _("Moved permanently");
761
case SIP_PDU::Redirection_MovedTemporarily:
762
info = _("Moved temporarily");
765
case SIP_PDU::Redirection_UseProxy:
766
info = _("Use proxy");
769
case SIP_PDU::Redirection_AlternativeService:
770
info = _("Alternative service");
773
case SIP_PDU::Failure_NotFound:
774
info = _("Not found");
777
case SIP_PDU::Failure_MethodNotAllowed:
778
info = _("Method not allowed");
781
case SIP_PDU::Failure_ProxyAuthenticationRequired:
782
info = _("Proxy auth. required");
785
case SIP_PDU::Failure_LengthRequired:
786
info = _("Length required");
789
case SIP_PDU::Failure_RequestEntityTooLarge:
790
info = _("Request entity too big");
793
case SIP_PDU::Failure_RequestURITooLong:
794
info = _("Request URI too long");
797
case SIP_PDU::Failure_UnsupportedMediaType:
798
info = _("Unsupported media type");
801
case SIP_PDU::Failure_UnsupportedURIScheme:
802
info = _("Unsupported URI scheme");
805
case SIP_PDU::Failure_BadExtension:
806
// Translators : The extension we are trying to register does not exist
807
info = _("Bad extension");
810
case SIP_PDU::Failure_ExtensionRequired:
811
info = _("Extension required");
814
case SIP_PDU::Failure_IntervalTooBrief:
815
info = _("Interval too brief");
818
case SIP_PDU::Failure_LoopDetected:
819
info = _("Loop detected");
822
case SIP_PDU::Failure_TooManyHops:
823
info = _("Too many hops");
826
case SIP_PDU::Failure_AddressIncomplete:
827
info = _("Address incomplete");
830
case SIP_PDU::Failure_Ambiguous:
831
info = _("Ambiguous");
834
case SIP_PDU::Failure_BusyHere:
835
info = _("Busy Here");
838
case SIP_PDU::Failure_RequestTerminated:
839
info = _("Request terminated");
842
case SIP_PDU::Failure_NotAcceptableHere:
843
info = _("Not acceptable here");
846
case SIP_PDU::Failure_BadEvent:
847
info = _("Bad event");
850
case SIP_PDU::Failure_RequestPending:
851
info = _("Request pending");
854
case SIP_PDU::Failure_Undecipherable:
855
info = _("Undecipherable");
858
case SIP_PDU::Failure_InternalServerError:
859
info = _("Internal server error");
862
case SIP_PDU::Failure_NotImplemented:
863
info = _("Not implemented");
866
case SIP_PDU::Failure_BadGateway:
867
info = _("Bad gateway");
870
case SIP_PDU::Failure_ServiceUnavailable:
871
info = _("Service unavailable");
874
case SIP_PDU::Failure_ServerTimeout:
875
info = _("Server timeout");
878
case SIP_PDU::Failure_SIPVersionNotSupported:
879
info = _("SIP version not supported");
882
case SIP_PDU::Failure_MessageTooLarge:
883
info = _("Message too large");
886
case SIP_PDU::GlobalFailure_BusyEverywhere:
887
info = _("Busy everywhere");
890
case SIP_PDU::GlobalFailure_Decline:
894
case SIP_PDU::GlobalFailure_DoesNotExistAnywhere:
895
info = _("Does not exist anymore");
898
case SIP_PDU::GlobalFailure_NotAcceptable:
899
info = _("Globally not acceptable");
902
case SIP_PDU::Local_TransportError:
903
case SIP_PDU::Local_BadTransportAddress:
904
info = _("Transport error");
907
case SIP_PDU::Failure_TransactionDoesNotExist:
908
case SIP_PDU::Failure_Gone:
909
case SIP_PDU::MaxStatusCode:
913
case SIP_PDU::Information_Trying:
914
case SIP_PDU::Information_Ringing:
915
case SIP_PDU::Information_CallForwarded:
916
case SIP_PDU::Information_Queued:
917
case SIP_PDU::Information_Session_Progress:
918
case SIP_PDU::Successful_OK:
919
case SIP_PDU::Successful_Accepted:
923
/* Signal the SIP Endpoint */
924
SIPEndPoint::OnRegistrationFailed (strm.str ().c_str (), r, wasRegistering);
927
Ekiga::Account *account = account_core.find_account (strm.str ());
929
runtime.run_in_main (sigc::bind (account->registration_event.make_slot (),
930
wasRegistering ? Ekiga::AccountCore::RegistrationFailed : Ekiga::AccountCore::UnregistrationFailed,
935
void Opal::Sip::EndPoint::OnMWIReceived (const PString & party, OpalManager::MessageWaitingType /*type*/, const PString & info)
937
std::string mwi = info;
938
std::transform (mwi.begin(), mwi.end(), mwi.begin(), ::tolower);
943
Ekiga::Account *account = account_core.find_account (party);
945
runtime.run_in_main (sigc::bind (account->mwi_event.make_slot (), info));
949
bool Opal::Sip::EndPoint::OnIncomingConnection (OpalConnection &connection,
951
OpalConnection::StringOptions * stroptions)
953
PTRACE (3, "Opal::Sip::EndPoint\tIncoming connection");
955
if (!forward_uri.empty () && manager.get_unconditional_forward ())
956
connection.ForwardCall (forward_uri);
957
else if (manager.GetCallCount () > 1) {
959
if (!forward_uri.empty () && manager.get_forward_on_busy ())
960
connection.ForwardCall (forward_uri);
962
connection.ClearCall (OpalConnection::EndedByLocalBusy);
967
Opal::Call *call = dynamic_cast<Opal::Call *> (&connection.GetCall ());
970
if (!forward_uri.empty () && manager.get_forward_on_no_answer ())
971
call->set_no_answer_forward (manager.get_reject_delay (), forward_uri);
973
call->set_reject_delay (manager.get_reject_delay ());
976
return SIPEndPoint::OnIncomingConnection (connection, options, stroptions);
983
bool Opal::Sip::EndPoint::OnReceivedMESSAGE (OpalTransport & transport,
986
PString *last = NULL;
989
PString from = pdu.GetMIME().GetFrom();
990
PINDEX j = from.Find (';');
991
if (j != P_MAX_INDEX)
992
from = from.Left(j); // Remove all parameters
994
if (j != P_MAX_INDEX && from.Find ('>') == P_MAX_INDEX)
997
PWaitAndSignal m(msgDataMutex);
998
last = msgData.GetAt (SIPURL (from).AsString ());
999
if (!last || *last != pdu.GetMIME ().GetFrom ()) {
1001
val = new PString (pdu.GetMIME ().GetFrom ());
1002
msgData.SetAt (SIPURL (from).AsString (), val);
1005
uri.Sanitise (SIPURL::RequestURI);
1006
std::string display_name = (const char *) uri.GetDisplayName ();
1007
std::string message_uri = (const char *) uri.AsString ();
1008
std::string _message = (const char *) pdu.GetEntityBody ();
1010
runtime.run_in_main (sigc::bind (sigc::ptr_fun (push_message_in_main), dialect, message_uri, display_name, _message));
1013
return SIPEndPoint::OnReceivedMESSAGE (transport, pdu);
1017
void Opal::Sip::EndPoint::OnMessageFailed (const SIPURL & messageUrl,
1018
SIP_PDU::StatusCodes /*reason*/)
1020
SIPURL to = messageUrl;
1021
to.Sanitise (SIPURL::ToURI);
1022
std::string uri = (const char *) to.AsString ();
1023
std::string display_name = (const char *) to.GetDisplayName ();
1025
runtime.run_in_main (sigc::bind (sigc::ptr_fun (push_notice_in_main),
1026
dialect, uri, display_name,
1027
_("Could not send message")));
1031
SIPURL Opal::Sip::EndPoint::GetRegisteredPartyName (const SIPURL & host)
1033
PString local_address;
1034
PIPSocket::Address address;
1037
SIPURL registration_address;
1039
/* If we are registered to an account corresponding to host, use it.
1041
PSafePtr<SIPHandler> info = activeSIPHandlers.FindSIPHandlerByDomain(host.GetHostName (), SIP_PDU::Method_REGISTER, PSafeReadOnly);
1044
return SIPURL ("\"" + GetDefaultDisplayName () + "\" <" + info->GetTargetAddress ().AsString () + ">");
1048
/* If we are not registered to host,
1049
* then use the default account as outgoing identity.
1050
* If we are exchanging messages with a peer on our network,
1051
* then do not use the default account as outgoing identity.
1053
if (host.GetHostAddress ().GetIpAndPort (address, port) && !manager.IsLocalAddress (address)) {
1055
Ekiga::Account *account = account_core.find_account ("ekiga.net");
1058
return SIPURL ("\"" + GetDefaultDisplayName () + "\" <" + PString(account->get_aor ()) + ">");
1062
/* As a last resort, ie not registered to host, no default account or
1063
* dialog with a local peer, then use the local address
1065
local_address = GetListeners()[0].GetLocalAddress();
1067
PINDEX j = local_address.Find ('$');
1068
if (j != P_MAX_INDEX)
1069
local_address = local_address.Mid (j+1);
1071
SIPURL ("\"" + GetDefaultDisplayName () + "\" <" + PString ("sip:") + GetDefaultLocalPartyName() + "@" + local_address + ";transport=udp>");
1078
Opal::Sip::EndPoint::OnPresenceInfoReceived (const PString & user,
1079
const PString & basic,
1080
const PString & note)
1083
PCaselessString b = basic;
1084
PCaselessString s = note;
1087
std::string presence = "unknown";
1089
if (b.Find ("Open") != P_MAX_INDEX)
1090
presence = "online";
1092
presence = "offline";
1094
if (s.Find ("Away") != P_MAX_INDEX)
1096
else if (s.Find ("On the phone") != P_MAX_INDEX
1097
|| s.Find ("Ringing") != P_MAX_INDEX)
1098
presence = "inacall";
1099
else if (s.Find ("dnd") != P_MAX_INDEX
1100
|| s.Find ("Do Not Disturb") != P_MAX_INDEX)
1103
else if (s.Find ("Free For Chat") != P_MAX_INDEX)
1104
presence = "freeforchat";
1106
if ((j = s.Find (" - ")) != P_MAX_INDEX)
1107
status = (const char *) note.Mid (j + 3);
1109
SIPURL sip_uri = SIPURL (user);
1110
sip_uri.Sanitise (SIPURL::ExternalURI);
1111
std::string _uri = sip_uri.AsString ();
1115
* Wouldn't it be convenient to emit the signal and have the presence core listen to it ?
1117
runtime.run_in_main (sigc::bind (sigc::ptr_fun (presence_status_in_main), this, _uri, presence, status));
1121
void Opal::Sip::EndPoint::on_dial (std::string uri)
1127
void Opal::Sip::EndPoint::on_message (std::string uri,
1130
dialect->start_chat_with (uri, name);
1134
void Opal::Sip::EndPoint::on_transfer (std::string uri)
1136
/* FIXME : we don't handle several calls here */
1137
for (PSafePtr<OpalConnection> connection(connectionsActive, PSafeReference); connection != NULL; ++connection)
1138
if (!PIsDescendant(&(*connection), OpalPCSSConnection))
1139
connection->TransferConnection (uri);