int
_eXosip_insubscription_answer_2xx (eXosip_notify_t * jn, eXosip_dialog_t * jd,
                                   int code)
{
  osip_event_t *evt_answer;
  osip_message_t *response;
  int i;
  osip_transaction_t *tr;

  tr = eXosip_find_last_inc_subscribe (jn, jd);

  if (tr == NULL || tr->orig_request == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: cannot find transaction to answer\n"));
      return -1;
    }

  if (jd != NULL && jd->d_dialog == NULL)
    {                           /* element previously removed, this is a no hop! */
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: cannot answer this closed transaction\n"));
      return -1;
    }

  if (jd == NULL)
    i = _eXosip_build_response_default (&response, NULL, code, tr->orig_request);
  else
    i =
      _eXosip_build_response_default (&response, jd->d_dialog, code,
                                      tr->orig_request);

  if (i != 0)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_INFO1, NULL,
                   "ERROR: Could not create response for subscribe\n"));
      code = 500;               /* ? which code to use? */
      return -1;
    }

  /* request that estabish a dialog: */
  /* 12.1.1 UAS Behavior */
  {
    i = complete_answer_that_establish_a_dialog (response, tr->orig_request);
    if (i != 0)
      goto g2atii_error_1;;     /* ?? */
  }

  /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */
  /* this response must be stored at the upper layer!!! (it will be destroyed */
  /* right after being sent! */

  if (jd == NULL)
    {
      i = eXosip_dialog_init_as_uas (&jd, tr->orig_request, response);
      if (i != 0)
        {
          OSIP_TRACE (osip_trace
                      (__FILE__, __LINE__, OSIP_ERROR, NULL,
                       "eXosip: cannot create dialog!\n"));
          return -1;
        }
      ADD_ELEMENT (jn->n_dialogs, jd);
    }

  eXosip_dialog_set_200ok (jd, response);
  evt_answer = osip_new_outgoing_sipmessage (response);
  evt_answer->transactionid = tr->transactionid;

  osip_transaction_add_event (tr, evt_answer);
  __eXosip_wakeup ();

  osip_dialog_set_state (jd->d_dialog, DIALOG_CONFIRMED);
  return 0;

g2atii_error_1:
  osip_message_free (response);
  return -1;
}
Exemple #2
0
int
eXosip_call_send_answer (int tid, int status, osip_message_t * answer)
{
  eXosip_dialog_t *jd = NULL;
  eXosip_call_t *jc = NULL;
  osip_transaction_t *tr = NULL;
  osip_event_t *evt_answer;

  if (tid < 0)
    {
      osip_message_free (answer);
      return OSIP_BADPARAMETER;
    }
  if (status <= 100)
    {
      osip_message_free (answer);
      return OSIP_BADPARAMETER;
    }
  if (status > 699)
    {
      osip_message_free (answer);
      return OSIP_BADPARAMETER;
    }

  if (tid > 0)
    {
      _eXosip_call_transaction_find (tid, &jc, &jd, &tr);
    }
  if (jd == NULL || tr == NULL || tr->orig_request == NULL
      || tr->orig_request->sip_method == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: No call here or no transaction for call\n"));
      osip_message_free (answer);
      return OSIP_NOTFOUND;
    }

  if (answer == NULL)
    {
      if (0 == osip_strcasecmp (tr->orig_request->sip_method, "INVITE"))
        {
          if (status >= 200 && status <= 299)
            {
              OSIP_TRACE (osip_trace
                          (__FILE__, __LINE__, OSIP_ERROR, NULL,
                           "eXosip: Wrong parameter?\n"));
              osip_message_free (answer);
              return OSIP_BADPARAMETER;
            }
        }
    }

  /* is the transaction already answered? */
  if (tr->state == IST_COMPLETED
      || tr->state == IST_CONFIRMED
      || tr->state == IST_TERMINATED
      || tr->state == NIST_COMPLETED || tr->state == NIST_TERMINATED)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: transaction already answered\n"));
      osip_message_free (answer);
      return OSIP_WRONG_STATE;
    }

  if (answer == NULL)
    {
      if (0 == osip_strcasecmp (tr->orig_request->sip_method, "INVITE"))
        {
          osip_message_t *response;
          return _eXosip_answer_invite_123456xx (jc, jd, status, &response, 1);
        }
      osip_message_free (answer);
      return OSIP_BADPARAMETER;
    }

  if (0 == osip_strcasecmp (tr->orig_request->sip_method, "INVITE"))
    {
      if (MSG_IS_STATUS_2XX (answer) && jd != NULL)
        {
          if (status >= 200 && status < 300 && jd != NULL)
            {
              eXosip_dialog_set_200ok (jd, answer);
              /* wait for a ACK */
              osip_dialog_set_state (jd->d_dialog, DIALOG_CONFIRMED);
            }
        }
    }

  evt_answer = osip_new_outgoing_sipmessage (answer);
  evt_answer->transactionid = tr->transactionid;

  osip_transaction_add_event (tr, evt_answer);
  eXosip_update ();
  __eXosip_wakeup ();
  return OSIP_SUCCESS;
}
int
eXosip_insubscription_send_answer (int tid, int status, osip_message_t * answer)
{
    int i = -1;
    eXosip_dialog_t *jd = NULL;
    eXosip_notify_t *jn = NULL;
    osip_transaction_t *tr = NULL;
    osip_event_t *evt_answer;

    if (tid > 0)
    {
        _eXosip_insubscription_transaction_find (tid, &jn, &jd, &tr);
    }
    if (jd == NULL || tr == NULL || tr->orig_request == NULL
            || tr->orig_request->sip_method == NULL)
    {
        OSIP_TRACE (osip_trace
                    (__FILE__, __LINE__, OSIP_ERROR, NULL,
                     "eXosip: No incoming subscription here?\n"));
        osip_message_free (answer);
        return -1;
    }

    if (answer == NULL)
    {
        if (0 == osip_strcasecmp (tr->orig_request->sip_method, "SUBSCRIBE"))
        {
            if (status >= 101 && status <= 199)
            {
            } else if (status >= 300 && status <= 699)
            {
            } else
            {
                OSIP_TRACE (osip_trace
                            (__FILE__, __LINE__, OSIP_ERROR, NULL,
                             "eXosip: Wrong parameter?\n"));
                return -1;
            }
        }
    }

    /* is the transaction already answered? */
    if (tr->state == NIST_COMPLETED || tr->state == NIST_TERMINATED)
    {
        OSIP_TRACE (osip_trace
                    (__FILE__, __LINE__, OSIP_ERROR, NULL,
                     "eXosip: transaction already answered\n"));
        osip_message_free (answer);
        return -1;
    }

    if (answer == NULL)
    {
        if (0 == osip_strcasecmp (tr->orig_request->sip_method, "SUBSCRIBE"))
        {
            if (status < 200)
                i = _eXosip_insubscription_answer_1xx (jn, jd, status);
            else
                i = _eXosip_insubscription_answer_3456xx (jn, jd, status);
            if (i != 0)
            {
                OSIP_TRACE (osip_trace
                            (__FILE__, __LINE__, OSIP_ERROR, NULL,
                             "eXosip: cannot send response!\n"));
                return -1;
            }
        } else
        {
            /* TODO */
            OSIP_TRACE (osip_trace
                        (__FILE__, __LINE__, OSIP_ERROR, NULL,
                         "eXosip: a response must be given!\n"));
            return -1;
        }
        return 0;
    } else
    {
        i = 0;
    }

    if (0 == osip_strcasecmp (tr->orig_request->sip_method, "SUBSCRIBE"))
    {
        if (MSG_IS_STATUS_1XX (answer))
        {
        } else if (MSG_IS_STATUS_2XX (answer))
        {
            eXosip_dialog_set_200ok (jd, answer);
            osip_dialog_set_state (jd->d_dialog, DIALOG_CONFIRMED);
        } else if (answer->status_code >= 300 && answer->status_code <= 699)
        {
            i = 0;
        } else
        {
            OSIP_TRACE (osip_trace
                        (__FILE__, __LINE__, OSIP_ERROR, NULL,
                         "eXosip: wrong status code (101<status<699)\n"));
            osip_message_free (answer);
            return -1;
        }
        if (i != 0)
        {
            osip_message_free (answer);
            return -1;
        }
    }

    evt_answer = osip_new_outgoing_sipmessage (answer);
    evt_answer->transactionid = tr->transactionid;

    osip_transaction_add_event (tr, evt_answer);
    eXosip_update ();
    __eXosip_wakeup ();
    return 0;
}
Exemple #4
0
int
_eXosip_answer_invite_123456xx (struct eXosip_t *excontext, eXosip_call_t * jc, eXosip_dialog_t * jd, int code, osip_message_t ** answer, int send)
{
  int i;
  osip_transaction_t *tr;

  *answer = NULL;
  tr = _eXosip_find_last_inc_invite (jc, jd);

  if (tr == NULL || tr->orig_request == NULL) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer\n"));
    return OSIP_NOTFOUND;
  }

  if (code >= 200 && code < 300 && jd != NULL && jd->d_dialog == NULL) {        /* element previously removed */
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot answer this closed transaction\n"));
    return OSIP_WRONG_STATE;
  }

  /* is the transaction already answered? */
  if (tr->state == IST_COMPLETED || tr->state == IST_CONFIRMED || tr->state == IST_TERMINATED) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n"));
    return OSIP_WRONG_STATE;
  }

  if (jd == NULL)
    i = _eXosip_build_response_default (excontext, answer, NULL, code, tr->orig_request);
  else
    i = _eXosip_build_response_default (excontext, answer, jd->d_dialog, code, tr->orig_request);

  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "ERROR: Could not create response for invite\n"));
    *answer = NULL;
    return i;
  }

  /* request that estabish a dialog: */
  /* 12.1.1 UAS Behavior */
  if (code > 100 && code < 300) {
    i = _eXosip_complete_answer_that_establish_a_dialog (excontext, *answer, tr->orig_request);
    if (i != 0) {
      osip_message_free (*answer);
      *answer = NULL;
      return i;
    }
  }


  if (send == 1) {
    osip_event_t *evt_answer;

    if (code >= 200 && code < 300 && jd != NULL) {
      _eXosip_dialog_set_200ok (jd, *answer);
      /* wait for a ACK */
      osip_dialog_set_state (jd->d_dialog, DIALOG_CONFIRMED);
    }

    evt_answer = osip_new_outgoing_sipmessage (*answer);
    evt_answer->transactionid = tr->transactionid;

    osip_transaction_add_event (tr, evt_answer);
    _eXosip_wakeup (excontext);
    *answer = NULL;
  }

  return OSIP_SUCCESS;
}
Exemple #5
0
int
eXosip_answer_invite_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, char *local_sdp_port, char *ctct, char *local_video_port,
			 char *public_sdp_port,  char *public_video_port)
{
  osip_event_t *evt_answer;
  osip_message_t *response;
  int i;
  char *size;
  char *body = NULL;
  osip_transaction_t *tr;
  tr = eXosip_find_last_inc_invite(jc, jd);

  if (tr==NULL || tr->orig_request==NULL)
    {
      OSIP_TRACE (osip_trace
		  (__FILE__, __LINE__, OSIP_ERROR, NULL,
         "eXosip: cannot find transaction to answer\n"));
      return -1;
    }

  if (jd!=NULL && jd->d_dialog==NULL)
    {  /* element previously removed */
      OSIP_TRACE (osip_trace
		  (__FILE__, __LINE__, OSIP_ERROR, NULL,
         "eXosip: cannot answer this closed transaction\n"));
      return -1;
    }

  /* is the transaction already answered? */
  if (tr->state==IST_COMPLETED
      || tr->state==IST_CONFIRMED
      || tr->state==IST_TERMINATED)
    {
      OSIP_TRACE (osip_trace
		  (__FILE__, __LINE__, OSIP_ERROR, NULL,
         "eXosip: transaction already answered\n"));
      return -1;
    }

  /* WE SHOULD LOOK FOR A SDP PACKET!! */
  if(NULL != osip_list_get(&tr->orig_request->bodies,0))
    {
      body = generating_sdp_answer(tr->orig_request, jc->c_ctx);
      if (body==NULL)
	code = 488; /* bad sdp */
    }
  else
    {
      if(local_sdp_port==NULL && local_video_port == NULL)
	code = 488; /* session description in the request is not acceptable. */
      else
	/* body is NULL (contains no SDP), generate a response to INVITE w/ no SDP */
	body = generating_no_sdp_answer(jc, jd, tr->orig_request, public_sdp_port ? public_sdp_port : local_sdp_port
					, public_video_port ? public_video_port : local_video_port);
    }
  
  if (jd==NULL)
    i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
  else
    i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);

  if (i!=0)
    {
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n"));
      code = 500; /* ? which code to use? */
      osip_free(body); /* not used */
      return -1;
    }

  if (code==488)
    {
      osip_message_set_content_length(response, "0");
      /*  TODO: send message to transaction layer */
      osip_free(body);
      evt_answer = osip_new_outgoing_sipmessage(response);
      evt_answer->transactionid = tr->transactionid;
      osip_transaction_add_event(tr, evt_answer);
	  __eXosip_wakeup();
      return 0;
    }

  if ( ! body ) {
    fprintf(stderr, "%s,%d: body is NULL\n", __FILE__, __LINE__);
    return -1;
  }

  i = osip_message_set_body(response, body, strlen(body));
  if (i!=0) {
    goto g2atii_error_1;
  }
  size = (char *) osip_malloc(6*sizeof(char));
#ifdef __APPLE_CC__
  sprintf(size,"%li",strlen(body));
#else
  sprintf(size,"%i",strlen(body));
#endif
  i = osip_message_set_content_length(response, size);
  osip_free(size);
  if (i!=0) goto g2atii_error_1;
  i = osip_message_set_content_type(response, "application/sdp");
  if (i!=0) goto g2atii_error_1;

  /* request that estabish a dialog: */
  /* 12.1.1 UAS Behavior */
  {
    i = complete_answer_that_establish_a_dialog2(response, tr->orig_request, ctct);
    if (i!=0) goto g2atii_error_1;; /* ?? */
  }

  osip_free(body);
  /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */
  /* this response must be stored at the upper layer!!! (it will be destroyed*/
  /* right after being sent! */

  if (jd==NULL)
    {
      i = eXosip_dialog_init_as_uas(&jd, owsip_transaction_account_get (tr), tr->orig_request, response);
      if (i!=0)
	{
     OSIP_TRACE (osip_trace
		 (__FILE__, __LINE__, OSIP_ERROR, NULL,
	     "eXosip: cannot create dialog!\n"));
	  return -1;
	}
      ADD_ELEMENT(jc->c_dialogs, jd);
    }

  eXosip_dialog_set_200ok(jd, response);
  evt_answer = osip_new_outgoing_sipmessage(response);
  evt_answer->transactionid = tr->transactionid;

  osip_transaction_add_event(tr, evt_answer);

  osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED);
  __eXosip_wakeup();
  return 0;

 g2atii_error_1:
  osip_free(body);
  osip_message_free(response);
  return -1;
}
Exemple #6
0
int
eXosip_answer_invite_2xx_with_body(eXosip_call_t *jc, eXosip_dialog_t *jd, int code,const char*bodytype, const char*body)
{
  osip_event_t *evt_answer;
  osip_message_t *response;
  int i;
  char *size;
  osip_transaction_t *tr;
  tr = eXosip_find_last_inc_invite(jc, jd);

  if (tr==NULL || tr->orig_request==NULL)
    {
      OSIP_TRACE (osip_trace
		  (__FILE__, __LINE__, OSIP_ERROR, NULL,
         "eXosip: cannot find transaction to answer\n"));
      return -1;
    }

  if (jd!=NULL && jd->d_dialog==NULL)
    {  /* element previously removed */
      OSIP_TRACE (osip_trace
		  (__FILE__, __LINE__, OSIP_ERROR, NULL,
         "eXosip: cannot answer this closed transaction\n"));
      return -1;
    }

  /* is the transaction already answered? */
  if (tr->state==IST_COMPLETED
      || tr->state==IST_CONFIRMED
      || tr->state==IST_TERMINATED)
    {
      OSIP_TRACE (osip_trace
		  (__FILE__, __LINE__, OSIP_ERROR, NULL,
         "eXosip: transaction already answered\n"));
      return -1;
    }
  
  if (jd==NULL)
    i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request);
  else
    i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request);

  if (i!=0)
    {
      OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n"));
      code = 500; /* ? which code to use? */
      return -1;
    }

  if (code==488)
    {
      osip_message_set_content_length(response, "0");
      /*  TODO: send message to transaction layer */
      evt_answer = osip_new_outgoing_sipmessage(response);
      evt_answer->transactionid = tr->transactionid;
      osip_transaction_add_event(tr, evt_answer);
  __eXosip_wakeup();
      return 0;
    }

  if ( ! body ) {
    fprintf(stderr, "%s,%d: body is NULL\n", __FILE__, __LINE__);
    return -1;
  }


  i = osip_message_set_body(response, body, strlen(body));
  if (i!=0) {
    goto g2atii_error_1;
  }
  size = (char *) osip_malloc(6*sizeof(char));
  sprintf(size,"%i",strlen(body));
  i = osip_message_set_content_length(response, size);
  osip_free(size);
  if (i!=0) goto g2atii_error_1;
  i = owsip_message_set_header(response, "content-type", bodytype);
  if (i!=0) goto g2atii_error_1;

  /* request that estabish a dialog: */
  /* 12.1.1 UAS Behavior */
    i = complete_answer_that_establish_a_dialog(response, tr->orig_request);
    if (i!=0) goto g2atii_error_1; /* ?? */
  /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */
  /* this response must be stored at the upper layer!!! (it will be destroyed*/
  /* right after being sent! */

  if (jd==NULL)
    {
      i = eXosip_dialog_init_as_uas(&jd, owsip_transaction_account_get (tr), tr->orig_request, response);
      if (i!=0)
	{
     OSIP_TRACE (osip_trace
		 (__FILE__, __LINE__, OSIP_ERROR, NULL,
	     "eXosip: cannot create dialog!\n"));
	  return -1;
	}
      ADD_ELEMENT(jc->c_dialogs, jd);
    }

  eXosip_dialog_set_200ok(jd, response);
  evt_answer = osip_new_outgoing_sipmessage(response);
  evt_answer->transactionid = tr->transactionid;

  osip_transaction_add_event(tr, evt_answer);

  osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED);
  __eXosip_wakeup();
  return 0;

 g2atii_error_1:
  osip_message_free(response);
  return -1;
}