sdp_message_t *
eXosip_get_previous_local_sdp (int jid)
{
  eXosip_dialog_t *jd = NULL;
  eXosip_call_t *jc = NULL;
  osip_transaction_t *invite_tr = NULL;

  if (jid > 0)
    {
      eXosip_call_dialog_find (jid, &jc, &jd);
    }
  if (jc == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: No call here?\n"));
      return NULL;
    }
  invite_tr = eXosip_find_last_invite (jc, jd);
  if (invite_tr == NULL)
    return NULL;
  invite_tr = eXosip_find_previous_invite (jc, jd, invite_tr);
  if (invite_tr == NULL)
    return NULL;

  return _eXosip_get_local_sdp (invite_tr);
}
Example #2
0
int
eXosip_call_get_referto (int did, char *refer_to, size_t refer_to_len)
{
  eXosip_dialog_t *jd = NULL;
  eXosip_call_t *jc = NULL;
  osip_transaction_t *tr = NULL;
  osip_uri_t *referto_uri;
  char atmp[256];
  char *referto_tmp = NULL;
  int i;

  if (did <= 0)
    return OSIP_BADPARAMETER;

  eXosip_call_dialog_find (did, &jc, &jd);
  if (jc == NULL || jd == NULL || jd->d_dialog == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: No call here?\n"));
      return OSIP_NOTFOUND;
    }

  tr = eXosip_find_last_invite (jc, jd);

  if (tr == NULL || tr->orig_request == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: No transaction for call?\n"));
      return OSIP_NOTFOUND;
    }

  i = osip_uri_clone (jd->d_dialog->remote_uri->url, &referto_uri);
  if (i != 0)
    return i;

  snprintf (atmp, sizeof (atmp), "%s;to-tag=%s;from-tag=%s",
            jd->d_dialog->call_id,
            jd->d_dialog->remote_tag, jd->d_dialog->local_tag);

  osip_uri_uheader_add (referto_uri, osip_strdup ("Replaces"), osip_strdup (atmp));
  i = osip_uri_to_str (referto_uri, &referto_tmp);
  if (i != 0)
    {
      osip_uri_free (referto_uri);
      return i;
    }

  snprintf (refer_to, refer_to_len, "%s", referto_tmp);
  osip_uri_free (referto_uri);

  return OSIP_SUCCESS;
}
Example #3
0
int
eXosip_call_set_reference (int id, void *reference)
{
  eXosip_dialog_t *jd = NULL;
  eXosip_call_t *jc = NULL;

  if (id > 0)
    {
      eXosip_call_dialog_find (id, &jc, &jd);
      if (jc == NULL)
        {
          eXosip_call_find (id, &jc);
        }
    }
  if (jc == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: No call here?\n"));
      return OSIP_NOTFOUND;
    }
  jc->external_reference = reference;
  return OSIP_SUCCESS;
}
Example #4
0
int
eXosip_call_terminate (int cid, int did)
{
  int i;
  osip_transaction_t *tr;
  osip_message_t *request = NULL;
  eXosip_dialog_t *jd = NULL;
  eXosip_call_t *jc = NULL;

  if (did <= 0 && cid <= 0)
    return OSIP_BADPARAMETER;
  if (did > 0)
    {
      eXosip_call_dialog_find (did, &jc, &jd);
      if (jd == NULL)
        {
          OSIP_TRACE (osip_trace
                      (__FILE__, __LINE__, OSIP_ERROR, NULL,
                       "eXosip: No call here?\n"));
          return OSIP_NOTFOUND;
        }
  } else
    {
      eXosip_call_find (cid, &jc);
    }

  if (jc == NULL)
    {
      return OSIP_NOTFOUND;
    }

  tr = eXosip_find_last_out_invite (jc, jd);
  if (jd != NULL && jd->d_dialog != NULL
      && jd->d_dialog->state == DIALOG_CONFIRMED)
    {
      /* don't send CANCEL on re-INVITE: send BYE instead */
  } else if (tr != NULL && tr->last_response != NULL
             && MSG_IS_STATUS_1XX (tr->last_response))
    {
      i = generating_cancel (&request, tr->orig_request);
      if (i != 0)
        {
          OSIP_TRACE (osip_trace
                      (__FILE__, __LINE__, OSIP_ERROR, NULL,
                       "eXosip: cannot terminate this call!\n"));
          return i;
        }
      i = eXosip_create_cancel_transaction (jc, jd, request);
      if (i != 0)
        {
          OSIP_TRACE (osip_trace
                      (__FILE__, __LINE__, OSIP_ERROR, NULL,
                       "eXosip: cannot initiate SIP transaction!\n"));
          return i;
        }
      if (jd != NULL)
        {
          osip_dialog_free (jd->d_dialog);
          jd->d_dialog = NULL;
          eXosip_update ();     /* AMD 30/09/05 */
        }
      return OSIP_SUCCESS;
    }

  if (jd == NULL || jd->d_dialog == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: No established dialog!\n"));
      return OSIP_WRONG_STATE;
    }

  if (tr == NULL)
    {
      /*this may not be enough if it's a re-INVITE! */
      tr = eXosip_find_last_inc_invite (jc, jd);
      if (tr != NULL && tr->last_response != NULL &&
          MSG_IS_STATUS_1XX (tr->last_response))
        {                       /* answer with 603 */
          osip_generic_param_t *to_tag;
          osip_from_param_get_byname (tr->orig_request->to, "tag", &to_tag);

          i = eXosip_call_send_answer (tr->transactionid, 603, NULL);

          if (to_tag == NULL)
            return i;
        }
    }

  if (jd->d_dialog == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: cannot terminate this call!\n"));
      return OSIP_WRONG_STATE;
    }

  i = generating_bye (&request, jd->d_dialog, eXosip.transport);

  if (i != 0)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: cannot terminate this call!\n"));
      return i;
    }

  eXosip_add_authentication_information (request, NULL);

  i = eXosip_create_transaction (jc, jd, request);
  if (i != 0)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: cannot initiate SIP transaction!\n"));
      return i;
    }

  osip_dialog_free (jd->d_dialog);
  jd->d_dialog = NULL;
  eXosip_update ();             /* AMD 30/09/05 */
  return OSIP_SUCCESS;
}
Example #5
0
int
eXosip_call_send_request (int jid, osip_message_t * request)
{
  eXosip_dialog_t *jd = NULL;
  eXosip_call_t *jc = NULL;

  osip_transaction_t *transaction;
  osip_event_t *sipevent;

  int i;

  if (request == NULL)
    return OSIP_BADPARAMETER;
  if (jid <= 0)
    {
      osip_message_free (request);
      return OSIP_BADPARAMETER;
    }

  if (request->sip_method == NULL)
    {
      osip_message_free (request);
      return OSIP_BADPARAMETER;
    }

  if (jid > 0)
    {
      eXosip_call_dialog_find (jid, &jc, &jd);
    }
  if (jd == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: No call here?\n"));
      osip_message_free (request);
      return OSIP_NOTFOUND;
    }

  transaction = NULL;
  if (0 == osip_strcasecmp (request->sip_method, "INVITE"))
    {
      transaction = eXosip_find_last_invite (jc, jd);
  } else                        /* OPTIONS, UPDATE, INFO, REFER, ?... */
    {
      transaction = eXosip_find_last_transaction (jc, jd, request->sip_method);
    }

  if (transaction != NULL)
    {
      if (0 != osip_strcasecmp (request->sip_method, "INVITE"))
        {
          if (transaction->state != NICT_TERMINATED &&
              transaction->state != NIST_TERMINATED &&
              transaction->state != NICT_COMPLETED &&
              transaction->state != NIST_COMPLETED)
            {
              osip_message_free (request);
              return OSIP_WRONG_STATE;
            }
      } else
        {
          if (transaction->state != ICT_TERMINATED &&
              transaction->state != IST_TERMINATED &&
              transaction->state != IST_CONFIRMED &&
              transaction->state != ICT_COMPLETED)
            {
              osip_message_free (request);
              return OSIP_WRONG_STATE;
            }
        }
    }

  transaction = NULL;
  if (0 != osip_strcasecmp (request->sip_method, "INVITE"))
    {
      i = _eXosip_transaction_init (&transaction, NICT, eXosip.j_osip, request);
  } else
    {
      i = _eXosip_transaction_init (&transaction, ICT, eXosip.j_osip, request);
    }

  if (i != 0)
    {
      osip_message_free (request);
      return i;
    }

  osip_list_add (jd->d_out_trs, transaction, 0);

  sipevent = osip_new_outgoing_sipmessage (request);
  sipevent->transactionid = transaction->transactionid;

#ifndef MINISIZE
  osip_transaction_set_your_instance (transaction,
                                      __eXosip_new_jinfo (jc, jd, NULL, NULL));
#else
  osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, jd));
#endif
  osip_transaction_add_event (transaction, sipevent);
  __eXosip_wakeup ();
  return OSIP_SUCCESS;
}
Example #6
0
int
eXosip_call_build_request (int jid, const char *method, osip_message_t ** request)
{
  eXosip_dialog_t *jd = NULL;
  eXosip_call_t *jc = NULL;

  osip_transaction_t *transaction;
  int i;

  *request = NULL;
  if (jid <= 0)
    return OSIP_BADPARAMETER;
  if (method == NULL || method[0] == '\0')
    return OSIP_BADPARAMETER;

  if (jid > 0)
    {
      eXosip_call_dialog_find (jid, &jc, &jd);
    }
  if (jd == NULL || jd->d_dialog == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: No call here?\n"));
      return OSIP_NOTFOUND;
    }

  transaction = NULL;
  if (0 == osip_strcasecmp (method, "INVITE"))
    {
      transaction = eXosip_find_last_invite (jc, jd);
  } else                        /* OPTIONS, UPDATE, INFO, REFER, ?... */
    {
      transaction = eXosip_find_last_transaction (jc, jd, method);
    }

  if (transaction != NULL)
    {
      if (0 != osip_strcasecmp (method, "INVITE"))
        {
          if (transaction->state != NICT_TERMINATED &&
              transaction->state != NIST_TERMINATED &&
              transaction->state != NICT_COMPLETED &&
              transaction->state != NIST_COMPLETED)
            return OSIP_WRONG_STATE;
      } else
        {
          if (transaction->state != ICT_TERMINATED &&
              transaction->state != IST_TERMINATED &&
              transaction->state != IST_CONFIRMED &&
              transaction->state != ICT_COMPLETED)
            return OSIP_WRONG_STATE;
        }
    }

  i = _eXosip_build_request_within_dialog (request, method, jd->d_dialog,
                                           eXosip.transport);
  if (i != 0)
    return i;

  eXosip_add_authentication_information (*request, NULL);

  return OSIP_SUCCESS;
}
Example #7
0
int
eXosip_call_send_ack (int did, osip_message_t * ack)
{
  eXosip_dialog_t *jd = NULL;
  eXosip_call_t *jc = NULL;
  int i;

  osip_route_t *route;
  char *host;
  int port;

  if (did <= 0)
    return OSIP_BADPARAMETER;
  if (did > 0)
    {
      eXosip_call_dialog_find (did, &jc, &jd);
    }

  if (jc == NULL || jd == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: No call here?\n"));
      if (ack != NULL)
        osip_message_free (ack);
      return OSIP_NOTFOUND;
    }

  if (ack == NULL)
    {
      i = eXosip_call_build_ack (did, &ack);
      if (i != 0)
        {
          return i;
        }
    }

  osip_message_get_route (ack, 0, &route);
  if (route != NULL)
    {
      osip_uri_param_t *lr_param = NULL;

      osip_uri_uparam_get_byname (route->url, "lr", &lr_param);
      if (lr_param == NULL)
        route = NULL;
    }

  if (route != NULL)
    {
      port = 5060;
      if (route->url->port != NULL)
        port = osip_atoi (route->url->port);
      host = route->url->host;
  } else
    {
      /* search for maddr parameter */
      osip_uri_param_t *maddr_param = NULL;
      osip_uri_uparam_get_byname (ack->req_uri, "maddr", &maddr_param);
      host = NULL;
      if (maddr_param != NULL && maddr_param->gvalue != NULL)
        host = maddr_param->gvalue;

      port = 5060;
      if (ack->req_uri->port != NULL)
        port = osip_atoi (ack->req_uri->port);

      if (host == NULL)
        host = ack->req_uri->host;
    }

  i = cb_snd_message (NULL, ack, host, port, -1);

  if (jd->d_ack != NULL)
    osip_message_free (jd->d_ack);
  jd->d_ack = ack;
  if (i < 0)
    return i;

  /* TODO: could be 1 for icmp... */
  return OSIP_SUCCESS;
}
Example #8
0
int
eXosip_call_build_ack (int did, osip_message_t ** _ack)
{
  eXosip_dialog_t *jd = NULL;
  eXosip_call_t *jc = NULL;
  osip_transaction_t *tr = NULL;

  osip_message_t *ack;
  char *transport;
  int i;

  *_ack = NULL;

  if (did <= 0)
    return OSIP_BADPARAMETER;
  if (did > 0)
    {
      eXosip_call_dialog_find (did, &jc, &jd);
    }
  if (jc == NULL || jd == NULL || jd->d_dialog == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: No call here?\n"));
      return OSIP_NOTFOUND;
    }

  tr = eXosip_find_last_invite (jc, jd);

  if (tr == NULL || tr->orig_request == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: No transaction for call?\n"));
      return OSIP_NOTFOUND;
    }

  if (0 != osip_strcasecmp (tr->orig_request->sip_method, "INVITE"))
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: ACK are only sent for invite transactions\n"));
      return OSIP_BADPARAMETER;
    }

  transport = NULL;
  transport = _eXosip_transport_protocol (tr->orig_request);
  if (transport == NULL)
    i = _eXosip_build_request_within_dialog (&ack, "ACK", jd->d_dialog, "UDP");
  else
    i = _eXosip_build_request_within_dialog (&ack, "ACK", jd->d_dialog, transport);

  if (i != 0)
    {
      return i;
    }

  _eXosip_call_reuse_contact (tr->orig_request, ack);

  /* Fix CSeq Number when request has been exchanged during INVITE transactions */
  if (tr->orig_request->cseq != NULL && tr->orig_request->cseq->number != NULL)
    {
      if (ack != NULL && ack->cseq != NULL && ack->cseq->number != NULL)
        {
          osip_free (ack->cseq->number);
          ack->cseq->number = osip_strdup (tr->orig_request->cseq->number);
        }
    }

  /* copy all credentials from INVITE! */
  {
    int pos = 0;
    osip_proxy_authorization_t *pa = NULL;

    i = osip_message_get_proxy_authorization (tr->orig_request, pos, &pa);
    while (i >= 0 && pa != NULL)
      {
        osip_proxy_authorization_t *pa2;

        i = osip_proxy_authorization_clone (pa, &pa2);
        if (i != 0)
          {
            OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
                                    "Error in credential from INVITE\n"));
            break;
          }
        osip_list_add (&ack->proxy_authorizations, pa2, -1);
        pa = NULL;
        pos++;
        i = osip_message_get_proxy_authorization (tr->orig_request, pos, &pa);
      }
  }

  *_ack = ack;
  return OSIP_SUCCESS;
}