bool Opal::Sip::EndPoint::OnReceivedMESSAGE (OpalTransport & transport,
                                             SIP_PDU & pdu)
{
  PString *last = NULL;
  PString *val = NULL;

  PString from = pdu.GetMIME().GetFrom();   
  PINDEX j = from.Find (';');
  if (j != P_MAX_INDEX)
    from = from.Left(j); // Remove all parameters
  j = from.Find ('<');
  if (j != P_MAX_INDEX && from.Find ('>') == P_MAX_INDEX)
    from += '>';

  PWaitAndSignal m(msgDataMutex);
  last = msgData.GetAt (SIPURL (from).AsString ());
  if (!last || *last != pdu.GetMIME ().GetFrom ()) {

    val = new PString (pdu.GetMIME ().GetFrom ());
    msgData.SetAt (SIPURL (from).AsString (), val);

    SIPURL uri = from;
    uri.Sanitise (SIPURL::RequestURI);
    std::string display_name = (const char *) uri.GetDisplayName ();
    std::string message_uri = (const char *) uri.AsString ();
    std::string _message = (const char *) pdu.GetEntityBody ();

    runtime.run_in_main (sigc::bind (sigc::ptr_fun (push_message_in_main), dialect, message_uri, display_name, _message));
  }

  return SIPEndPoint::OnReceivedMESSAGE (transport, pdu);
}
Example #2
0
void
Opal::Sip::EndPoint::set_outbound_proxy (const std::string & uri)
{
  if (!uri.empty ()) {
    outbound_proxy = uri;
    PTRACE (4, "Opal::Sip::EndPoint\tSet outbound proxy to " << uri);
    SetProxy (SIPURL (outbound_proxy));
  }
}
void 
Opal::Sip::EndPoint::OnPresenceInfoReceived (const PString & user,
                                             const PString & basic,
                                             const PString & note)
{
  PINDEX j;
  PCaselessString b = basic;
  PCaselessString s = note;

  std::string presence = "unknown";
  std::string status;

  if (!basic.IsEmpty () && !note.IsEmpty ()) {

    if (b.Find ("Open") != P_MAX_INDEX)
      presence = "online";
    else
      presence = "offline";
  
    if (s.Find ("Away") != P_MAX_INDEX)
      presence = "away";
    else if (s.Find ("On the phone") != P_MAX_INDEX
             || s.Find ("Ringing") != P_MAX_INDEX) 
      presence = "inacall";
    else if (s.Find ("dnd") != P_MAX_INDEX
             || s.Find ("Do Not Disturb") != P_MAX_INDEX) 
      presence = "dnd";
  
    else if (s.Find ("Free For Chat") != P_MAX_INDEX) 
      presence = "freeforchat";
  
    if ((j = s.Find (" - ")) != P_MAX_INDEX)
      status = (const char *) note.Mid (j + 3);
  }

  SIPURL sip_uri = SIPURL (user);
  sip_uri.Sanitise (SIPURL::ExternalURI);
  std::string _uri = sip_uri.AsString ();
  std::string old_presence = uri_presences[_uri].first;
  std::string old_status = uri_presences[_uri].second;
  
  // If first notification, and no information, then we are offline
  if (presence == "unknown" && old_presence.empty ())
    presence = "offline";

  // If presence change, then signal it to the various components
  // If presence is unknown (notification with empty body), and it is not the 
  // first notification, and we can conclude it is a ping back from the server 
  // to indicate the presence status did not change, hence we do nothing.
  if (presence != "unknown" && (old_presence != presence || old_status != status)) {
    uri_presences[_uri] = std::pair<std::string, std::string> (presence, status);
    runtime.run_in_main (sigc::bind (sigc::ptr_fun (presence_status_in_main), this, _uri, presence, status));
  }
}
Example #4
0
bool
Opal::Sip::EndPoint::SetUpCall (const std::string & uri)
{
  PString token;
  boost::shared_ptr<Opal::Bank> bank = core.get<Opal::Bank> ("opal-account-store");
  if (bank) {
    Opal::AccountPtr account = bank->find_account (SIPURL (uri).GetHostPort ());
    if (account)
      return GetManager ().SetUpCall ("pc:*", account->get_full_uri (uri), token, (void*) uri.c_str ());
  }

  return GetManager ().SetUpCall ("pc:*", uri, token, (void*) uri.c_str ());
}
SIPURL Opal::Sip::EndPoint::GetRegisteredPartyName (const SIPURL & host)
{
  PString local_address;
  PIPSocket::Address address;
  WORD port;
  PString url;
  SIPURL registration_address;

  /* If we are registered to an account corresponding to host, use it.
  */
  PSafePtr<SIPHandler> info = activeSIPHandlers.FindSIPHandlerByDomain(host.GetHostName (), SIP_PDU::Method_REGISTER, PSafeReadOnly);
  if (info != NULL) {

    return SIPURL ("\"" + GetDefaultDisplayName () + "\" <" + info->GetTargetAddress ().AsString () + ">");
  }
  else {

    /* If we are not registered to host, 
     * then use the default account as outgoing identity.
     * If we are exchanging messages with a peer on our network,
     * then do not use the default account as outgoing identity.
     */
    if (host.GetHostAddress ().GetIpAndPort (address, port) && !manager.IsLocalAddress (address)) {

      Ekiga::Account *account = account_core.find_account ("ekiga.net");

      if (account)
        return SIPURL ("\"" + GetDefaultDisplayName () + "\" <" + PString(account->get_aor ()) + ">");
    }
  }

  /* As a last resort, ie not registered to host, no default account or
   * dialog with a local peer, then use the local address 
   */
  return GetDefaultRegisteredPartyName ();
}
Example #6
0
void
Opal::Sip::EndPoint::set_outbound_proxy (const std::string & uri)
{
  outbound_proxy = uri;
  SetProxy (SIPURL (outbound_proxy));
}
Example #7
0
void
Opal::Sip::EndPoint::OnRegistrationStatus (const RegistrationStatus & status)
{
  std::string info;

  boost::shared_ptr<Opal::Bank> bank = core.get<Opal::Bank> ("opal-account-store");
  if (!bank)
    return;

  Opal::AccountPtr account = bank->find_account (status.m_addressofRecord);
  if (!account)
    return;

  if (status.m_reason == SIP_PDU::Information_Trying)
    return;

  SIPEndPoint::OnRegistrationStatus (status);
  /* Only handle registration state transitions we are interested in.
   *
   * For example, if we were registering, we are interested in knowing if
   * the registration was successful or not. If the registration was not
   * successful and OPAL cleanly unregisters the account (as a consequence),
   * we are not interested in knowing the unregistration worked.
   */
  if (status.m_wasRegistering != account->is_enabled ())
    return;

  /* Successful registration or unregistration */
  if (status.m_reason == SIP_PDU::Successful_OK) {
    Ekiga::Runtime::run_in_main (boost::bind (&Opal::Account::handle_registration_event, account,
                                              status.m_wasRegistering?Account::Registered:Account::Unregistered,
                                              std::string (),
                                              status.m_addressofRecord));
  }
  /* Registration or unregistration failure */
  else {
    SIPURL m_addressOfRecord = SIPURL (status.m_addressofRecord);
    /* Try again in UDP mode */
    if (m_addressOfRecord.GetTransportProto () == "TCP") {
      SIPRegister::Params params;
      PString _aor;
      m_addressOfRecord.SetParamVar ("transport", "udp");
      if (m_addressOfRecord.GetParamVars ().Contains ("OPAL-proxy")) {
        PString proxy = m_addressOfRecord.GetParamVars().Get ("OPAL-proxy");
        PINDEX p = proxy.Find (";");
        if (p != P_MAX_INDEX)
          proxy = proxy.Left (p);
        m_addressOfRecord.SetParamVar ("OPAL-proxy", proxy);
      }
      params.m_addressOfRecord = m_addressOfRecord;
      params.m_instanceId = GetInstanceID ();
      params.m_compatibility = SIPRegister::e_RFC5626;
      params.m_authID = status.m_handler->GetAuthID ();
      params.m_password = status.m_handler->GetPassword ();
      params.m_expire = status.m_handler->GetExpire ();
      params.m_minRetryTime = PMaxTimeInterval;  // use default value
      params.m_maxRetryTime = PMaxTimeInterval;  // use default value
      if (status.m_handler->ShutDown ())
        activeSIPHandlers.Remove (status.m_handler); // Make sure the TCP handler is deleted
                                                     // or it will be retried indefinitely.
      SIPEndPoint::Register (params, _aor);
      return;
    }

    /* all these codes are defined in opal, file include/sip/sippdu.h */
    switch (status.m_reason) {
    case SIP_PDU::IllegalStatusCode:
      info = _("Illegal status code");
      break;

    case SIP_PDU::Local_TransportError:
      info = _("Transport error");
      break;

    case SIP_PDU::Local_BadTransportAddress:
      info = _("Invalid address");
      break;

    case SIP_PDU::Local_Timeout:
      /* Translators: Host of the remote party is offline, this should
       * appear when the remote host does not reply in an acceptable time */
      info = _("Remote party host is offline");
      break;

    case SIP_PDU::Information_Trying:
    case SIP_PDU::Information_Ringing:
    case SIP_PDU::Information_CallForwarded:
    case SIP_PDU::Information_Queued:
    case SIP_PDU::Information_Session_Progress:
    case SIP_PDU::Successful_OK:
    case SIP_PDU::Successful_Accepted:
      break;

    case SIP_PDU::Redirection_MultipleChoices:
      /* Translators: the following strings are answers from the SIP server
       * when the packet it receives has an error, see
       * http://www.ietf.org/rfc/rfc3261.txt, chapter 21 for more information */
      info = _("Multiple choices");
      break;

    case SIP_PDU::Redirection_MovedPermanently:
      info = _("Moved permanently");
      break;

    case SIP_PDU::Redirection_MovedTemporarily:
      info = _("Moved temporarily");
      break;

    case SIP_PDU::Redirection_UseProxy:
      info = _("Use proxy");
      break;

    case SIP_PDU::Redirection_AlternativeService:
      info = _("Alternative service");
      break;

    case SIP_PDU::Failure_BadRequest:
      info = _("Bad request");
      break;

    case SIP_PDU::Failure_UnAuthorised:
      info = _("Unauthorized");
      break;

    case SIP_PDU::Failure_PaymentRequired:
      info = _("Payment required");
      break;

    case SIP_PDU::Failure_Forbidden:
      info = _("Forbidden, please check that username and password are correct");
      break;

    case SIP_PDU::Failure_NotFound:
      info = _("Not found");
      break;

    case SIP_PDU::Failure_MethodNotAllowed:
      info = _("Method not allowed");
      break;

    case SIP_PDU::Failure_NotAcceptable:
      info = _("Not acceptable");
      break;

    case SIP_PDU::Failure_ProxyAuthenticationRequired:
      info = _("Proxy authentication required");
      break;

    case SIP_PDU::Failure_RequestTimeout:
      info = _("Timeout");
      break;

    case SIP_PDU::Failure_Conflict:
      info = _("Conflict");
      break;

    case SIP_PDU::Failure_LengthRequired:
      info = _("Length required");
      break;

    case SIP_PDU::Failure_RequestEntityTooLarge:
      info = _("Request entity too big");
      break;

    case SIP_PDU::Failure_RequestURITooLong:
      info = _("Request URI too long");
      break;

    case SIP_PDU::Failure_UnsupportedMediaType:
      info = _("Unsupported media type");
      break;

    case SIP_PDU::Failure_UnsupportedURIScheme:
      info = _("Unsupported URI scheme");
      break;

    case SIP_PDU::Failure_BadExtension:
      /* Translators:  The extension we are trying to register does not exist.
       * Here extension is a specific "phone number", see
       * http://en.wikipedia.org/wiki/Extension_(telephone)
       * for more information */
      info = _("Bad extension");
      break;

    case SIP_PDU::Failure_ExtensionRequired:
      info = _("Extension required");
      break;

    case SIP_PDU::Failure_IntervalTooBrief:
      info = _("Interval too brief");
      break;

    case SIP_PDU::Failure_TemporarilyUnavailable:
      info = _("Temporarily unavailable");
      break;

    case SIP_PDU::Failure_LoopDetected:
      info = _("Loop detected");
      break;

    case SIP_PDU::Failure_TooManyHops:
      info = _("Too many hops");
      break;

    case SIP_PDU::Failure_AddressIncomplete:
      info = _("Address incomplete");
      break;

    case SIP_PDU::Failure_Ambiguous:
      info = _("Ambiguous");
      break;

    case SIP_PDU::Failure_BusyHere:
      info = _("Busy Here");
      break;

    case SIP_PDU::Failure_RequestTerminated:
      info = _("Request terminated");
      break;

    case SIP_PDU::Failure_NotAcceptableHere:
      info = _("Not acceptable here");
      break;

    case SIP_PDU::Failure_BadEvent:
      info = _("Bad event");
      break;

    case SIP_PDU::Failure_RequestPending:
      info = _("Request pending");
      break;

    case SIP_PDU::Failure_Undecipherable:
      info = _("Undecipherable");
      break;

    case SIP_PDU::Failure_InternalServerError:
      info = _("Internal server error");
      break;

    case SIP_PDU::Failure_NotImplemented:
      info = _("Not implemented");
      break;

    case SIP_PDU::Failure_BadGateway:
      info = _("Bad gateway");
      break;

    case SIP_PDU::Failure_ServiceUnavailable:
      info = _("Service unavailable");
      break;

    case SIP_PDU::Failure_ServerTimeout:
      info = _("Server timeout");
      break;

    case SIP_PDU::Failure_SIPVersionNotSupported:
      info = _("SIP version not supported");
      break;

    case SIP_PDU::Failure_MessageTooLarge:
      info = _("Message too large");
      break;

    case SIP_PDU::GlobalFailure_BusyEverywhere:
      info = _("Busy everywhere");
      break;

    case SIP_PDU::GlobalFailure_Decline:
      info = _("Decline");
      break;

    case SIP_PDU::GlobalFailure_DoesNotExistAnywhere:
      info = _("Does not exist anymore");
      break;

    case SIP_PDU::GlobalFailure_NotAcceptable:
      info = _("Globally not acceptable");
      break;

    case SIP_PDU::Local_NotAuthenticated:
      info = _("Invalid certificates");
      break;

    case SIP_PDU::Failure_TransactionDoesNotExist:
    case SIP_PDU::Failure_Gone:
    case SIP_PDU::MaxStatusCode:
    case SIP_PDU::Local_NoCompatibleListener:
    case SIP_PDU::Local_CannotMapScheme:
    case SIP_PDU::Local_KeepAlive:
    case SIP_PDU::Local_TransportLost:
    case SIP_PDU::Failure_UnresolvableDestination:
    default:
      info = _("Failed");
    }

    /* Opal adds a RequestTerminated, and this should not be shown to user,
     * as a sip code has already been scheduled to be shown
     */
    if (status.m_reason != SIP_PDU::Failure_RequestTerminated) {
      Ekiga::Runtime::run_in_main (boost::bind (&Opal::Account::handle_registration_event, account,
                                                status.m_wasRegistering?Account::RegistrationFailed:Account::UnregistrationFailed,
                                                info, std::string ()));
    }
  }
}