コード例 #1
0
ファイル: jpublish.c プロジェクト: HunterChen/exosip
int
_eXosip_pub_update (struct eXosip_t *excontext, eXosip_pub_t ** pub, osip_transaction_t * tr, osip_message_t * answer)
{
  eXosip_pub_t *jpub;

  *pub = NULL;

  for (jpub = excontext->j_pub; jpub != NULL; jpub = jpub->next) {
    if (jpub->p_last_tr == NULL) {      /*bug? */
    }
    else if (tr == jpub->p_last_tr) {
      /* update the sip_etag parameter */
      if (answer == NULL) {     /* bug? */
      }
      else if (MSG_IS_STATUS_2XX (answer)) {
        osip_header_t *sip_etag = NULL;

        osip_message_header_get_byname (answer, "SIP-ETag", 0, &sip_etag);
        if (sip_etag != NULL && sip_etag->hvalue != NULL)
          snprintf (jpub->p_sip_etag, 64, "%s", sip_etag->hvalue);
      }
      *pub = jpub;
      return OSIP_SUCCESS;
    }
  }
  return OSIP_NOTFOUND;
}
コード例 #2
0
ファイル: osip_dialog.c プロジェクト: gabrieldelsaint/UIM
int
osip_dialog_update_route_set_as_uac (osip_dialog_t * dialog,
                                     osip_message_t * response)
{
  /* only the remote target URI is updated here... */
  osip_contact_t *contact;
  int i;

  if (dialog == NULL)
    return -1;
  if (response == NULL)
    return -1;

  if (osip_list_eol (&response->contacts, 0))
    {                           /* no contact header in response? */
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_WARNING, NULL,
                   "missing a contact in response!\n"));
  } else
    {
      /* I personally think it's a bad idea to keep the old
         value in case the new one is broken... */
      if (dialog->remote_contact_uri != NULL)
        {
          osip_contact_free (dialog->remote_contact_uri);
        }
      dialog->remote_contact_uri = NULL;
      contact = osip_list_get (&response->contacts, 0);
      i = osip_contact_clone (contact, &(dialog->remote_contact_uri));
      if (i != 0)
        return -1;
    }

  if (dialog->state == DIALOG_EARLY && osip_list_size (&dialog->route_set) == 0)
    {                           /* update the route set */
      int pos = 0;

      while (!osip_list_eol (&response->record_routes, pos))
        {
          osip_record_route_t *rr;
          osip_record_route_t *rr2;

          rr =
            (osip_record_route_t *) osip_list_get (&response->record_routes, pos);
          i = osip_record_route_clone (rr, &rr2);
          if (i != 0)
            return -1;
          osip_list_add (&dialog->route_set, rr2, 0);
          pos++;
        }
    }

  if (MSG_IS_STATUS_2XX (response))
    dialog->state = DIALOG_CONFIRMED;
  return 0;
}
コード例 #3
0
ファイル: osip_event.c プロジェクト: Nymphetaminer/dsl-n55u
type_t
evt_set_type_incoming_sipmessage (osip_message_t * sip)
{
  if (MSG_IS_REQUEST (sip))
    {
      if (MSG_IS_INVITE (sip))
	return RCV_REQINVITE;
      else if (MSG_IS_ACK (sip))
	return RCV_REQACK;
      return RCV_REQUEST;
    }
  else
    {
      if (MSG_IS_STATUS_1XX (sip))
	return RCV_STATUS_1XX;
      else if (MSG_IS_STATUS_2XX (sip))
	return RCV_STATUS_2XX;
      return RCV_STATUS_3456XX;
    }
}
void
ist_rcv_invite (osip_transaction_t * ist, osip_event_t * evt)
{
  int i;

  if (ist->state == IST_PRE_PROCEEDING) {       /* announce new INVITE */
    /* Here we have ist->orig_request == NULL */
    ist->orig_request = evt->sip;

    __osip_message_callback (OSIP_IST_INVITE_RECEIVED, ist, evt->sip);
  }
  else {                        /* IST_PROCEEDING or IST_COMPLETED */

    /* delete retransmission */
    osip_message_free (evt->sip);

    __osip_message_callback (OSIP_IST_INVITE_RECEIVED_AGAIN, ist, ist->orig_request);
    if (ist->last_response != NULL) {   /* retransmit last response */
      i = __osip_transaction_snd_xxx (ist, ist->last_response);
      if (i != 0) {
        ist_handle_transport_error (ist, i);
        return;
      }
      else {
        if (MSG_IS_STATUS_1XX (ist->last_response))
          __osip_message_callback (OSIP_IST_STATUS_1XX_SENT, ist, ist->last_response);
        else if (MSG_IS_STATUS_2XX (ist->last_response))
          __osip_message_callback (OSIP_IST_STATUS_2XX_SENT_AGAIN, ist, ist->last_response);
        else
          __osip_message_callback (OSIP_IST_STATUS_3456XX_SENT_AGAIN, ist, ist->last_response);
      }
    }
    return;
  }

  /* we come here only if it was the first INVITE received */
  __osip_transaction_set_state (ist, IST_PROCEEDING);
}
コード例 #5
0
ファイル: nist_fsm.c プロジェクト: tws67/bayonne-base-windows
void
nist_rcv_request (osip_transaction_t * nist, osip_event_t * evt)
{
  int i;

  if (nist->state == NIST_PRE_TRYING)   /* announce new REQUEST */
    {
      /* Here we have ist->orig_request == NULL */
      nist->orig_request = evt->sip;

      if (MSG_IS_REGISTER (evt->sip))
        __osip_message_callback (OSIP_NIST_REGISTER_RECEIVED, nist,
                                 nist->orig_request);
      else if (MSG_IS_BYE (evt->sip))
        __osip_message_callback (OSIP_NIST_BYE_RECEIVED, nist, nist->orig_request);
      else if (MSG_IS_OPTIONS (evt->sip))
        __osip_message_callback (OSIP_NIST_OPTIONS_RECEIVED, nist,
                                 nist->orig_request);
      else if (MSG_IS_INFO (evt->sip))
        __osip_message_callback (OSIP_NIST_INFO_RECEIVED, nist,
                                 nist->orig_request);
      else if (MSG_IS_CANCEL (evt->sip))
        __osip_message_callback (OSIP_NIST_CANCEL_RECEIVED, nist,
                                 nist->orig_request);
      else if (MSG_IS_NOTIFY (evt->sip))
        __osip_message_callback (OSIP_NIST_NOTIFY_RECEIVED, nist,
                                 nist->orig_request);
      else if (MSG_IS_SUBSCRIBE (evt->sip))
        __osip_message_callback (OSIP_NIST_SUBSCRIBE_RECEIVED, nist,
                                 nist->orig_request);
      else
        __osip_message_callback (OSIP_NIST_UNKNOWN_REQUEST_RECEIVED, nist,
                                 nist->orig_request);
  } else                        /* NIST_PROCEEDING or NIST_COMPLETED */
    {
      /* delete retransmission */
      osip_message_free (evt->sip);

      __osip_message_callback (OSIP_NIST_REQUEST_RECEIVED_AGAIN, nist,
                               nist->orig_request);
      if (nist->last_response != NULL)  /* retransmit last response */
        {
	  i = __osip_transaction_snd_xxx(nist, nist->last_response);
          if (i != 0)
            {
              nist_handle_transport_error (nist, i);
              return;
          } else
            {
              if (MSG_IS_STATUS_1XX (nist->last_response))
                __osip_message_callback (OSIP_NIST_STATUS_1XX_SENT, nist,
                                         nist->last_response);
              else if (MSG_IS_STATUS_2XX (nist->last_response))
                __osip_message_callback (OSIP_NIST_STATUS_2XX_SENT_AGAIN,
                                         nist, nist->last_response);
              else
                __osip_message_callback (OSIP_NIST_STATUS_3456XX_SENT_AGAIN,
                                         nist, nist->last_response);
              return;
            }
        }
      /* we are already in the proper state */
      return;
    }

  /* we come here only if it was the first REQUEST received */
  __osip_transaction_set_state (nist, NIST_TRYING);
}
コード例 #6
0
void
eXosip_automatic_action (void)
{
  eXosip_call_t *jc;
  eXosip_dialog_t *jd;
#ifndef MINISIZE
  eXosip_subscribe_t *js;
  eXosip_notify_t *jn;
#endif

  eXosip_reg_t *jr;
  time_t now;

  now = time (NULL);

  for (jc = eXosip.j_calls; jc != NULL; jc = jc->next)
    {
      if (jc->c_id < 1)
        {
      } else if (jc->c_dialogs == NULL || jc->c_dialogs->d_dialog == NULL)
        {
          /* an EARLY dialog may have failed with 401,407 or 3Xx */

          osip_transaction_t *out_tr = NULL;

          out_tr = jc->c_out_tr;

          if (out_tr != NULL
              && (out_tr->state == ICT_TERMINATED
                  || out_tr->state == NICT_TERMINATED
                  || out_tr->state == ICT_COMPLETED
                  || out_tr->state == NICT_COMPLETED) &&
              now - out_tr->birth_time < 120 &&
              out_tr->orig_request != NULL &&
              out_tr->last_response != NULL &&
              (out_tr->last_response->status_code == 401
               || out_tr->last_response->status_code == 407))
            {
              /* retry with credential */
              if (jc->c_retry < 3)
                {
                  int i;

                  i = _eXosip_call_retry_request (jc, NULL, out_tr);
                  if (i != 0)
                    {
                      OSIP_TRACE (osip_trace
                                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                                   "eXosip: could not clone msg for authentication\n"));
                    }
                  jc->c_retry++;
                }
          } else if (out_tr != NULL
                     && (out_tr->state == ICT_TERMINATED
                         || out_tr->state == NICT_TERMINATED
                         || out_tr->state == ICT_COMPLETED
                         || out_tr->state == NICT_COMPLETED) &&
                     now - out_tr->birth_time < 120 &&
                     out_tr->orig_request != NULL &&
                     out_tr->last_response != NULL &&
                     (out_tr->last_response->status_code >= 300
                      && out_tr->last_response->status_code <= 399))
            {
              /* retry with credential */
              int i;

              i = _eXosip_call_retry_request (jc, NULL, out_tr);
              if (i != 0)
                {
                  OSIP_TRACE (osip_trace
                              (__FILE__, __LINE__, OSIP_ERROR, NULL,
                               "eXosip: could not clone msg for redirection\n"));
                }
            }
        }

      for (jd = jc->c_dialogs; jd != NULL; jd = jd->next)
        {
          if (jd->d_dialog == NULL)     /* finished call */
            {
          } else
            {
              osip_transaction_t *out_tr = NULL;

              out_tr = osip_list_get (jd->d_out_trs, 0);
              if (out_tr == NULL)
                out_tr = jc->c_out_tr;

              if (out_tr != NULL
                  && (out_tr->state == ICT_TERMINATED
                      || out_tr->state == NICT_TERMINATED
                      || out_tr->state == ICT_COMPLETED
                      || out_tr->state == NICT_COMPLETED) &&
                  now - out_tr->birth_time < 120 &&
                  out_tr->orig_request != NULL &&
                  out_tr->last_response != NULL &&
                  (out_tr->last_response->status_code == 401
                   || out_tr->last_response->status_code == 407))
                {
                  /* retry with credential */
                  if (jd->d_retry < 3)
                    {
                      int i;

                      i =
                        _eXosip_call_retry_request (jc, jd, out_tr);
                      if (i != 0)
                        {
                          OSIP_TRACE (osip_trace
                                      (__FILE__, __LINE__, OSIP_ERROR, NULL,
                                       "eXosip: could not clone msg for authentication\n"));
                        }
                      jd->d_retry++;
                    }
              } else if (out_tr != NULL
                         && (out_tr->state == ICT_TERMINATED
                             || out_tr->state == NICT_TERMINATED
                             || out_tr->state == ICT_COMPLETED
                             || out_tr->state == NICT_COMPLETED) &&
                         now - out_tr->birth_time < 120 &&
                         out_tr->orig_request != NULL &&
                         out_tr->last_response != NULL &&
                         (out_tr->last_response->status_code >= 300
                          && out_tr->last_response->status_code <= 399))
                {
                  /* retry with credential */
                  int i;

                  i = _eXosip_call_retry_request (jc, jd, out_tr);
                  if (i != 0)
                    {
                      OSIP_TRACE (osip_trace
                                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                                   "eXosip: could not clone msg for redirection\n"));
                    }
                }
            }
        }
    }

#ifndef MINISIZE

  for (js = eXosip.j_subscribes; js != NULL; js = js->next)
    {
      if (js->s_id < 1)
        {
      } else if (js->s_dialogs == NULL)
        {
          osip_transaction_t *out_tr = NULL;

          out_tr = js->s_out_tr;

          if (out_tr != NULL
              && (out_tr->state == NICT_TERMINATED
                  || out_tr->state == NICT_COMPLETED) &&
              now - out_tr->birth_time < 120 &&
              out_tr->orig_request != NULL &&
              out_tr->last_response != NULL &&
              (out_tr->last_response->status_code == 401
               || out_tr->last_response->status_code == 407))
            {
              /* retry with credential */
              if (js->s_retry < 3)
                {
                  int i;

                  i =
                    _eXosip_subscribe_send_request_with_credential (js, NULL,
                                                                    out_tr);
                  if (i != 0)
                    {
                      OSIP_TRACE (osip_trace
                                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                                   "eXosip: could not clone msg for authentication\n"));
                    }
                  js->s_retry++;
                }
            }
        }

      for (jd = js->s_dialogs; jd != NULL; jd = jd->next)
        {
          if (jd->d_dialog != NULL)     /* finished call */
            {
              if (jd->d_id >= 1)
                {
                  osip_transaction_t *out_tr = NULL;

                  out_tr = osip_list_get (jd->d_out_trs, 0);
                  if (out_tr == NULL)
                    out_tr = js->s_out_tr;

                  if (out_tr != NULL
                      && (out_tr->state == NICT_TERMINATED
                          || out_tr->state == NICT_COMPLETED) &&
                      now - out_tr->birth_time < 120 &&
                      out_tr->orig_request != NULL &&
                      out_tr->last_response != NULL &&
                      (out_tr->last_response->status_code == 401
                       || out_tr->last_response->status_code == 407))
                    {
                      /* retry with credential */
                      if (jd->d_retry < 3)
                        {
                          int i;
						  i =
							_eXosip_subscribe_send_request_with_credential (js, jd,
																			out_tr);
                          if (i != 0)
                            {
                              OSIP_TRACE (osip_trace
                                          (__FILE__, __LINE__, OSIP_ERROR,
                                           NULL,
                                           "eXosip: could not clone suscbribe for authentication\n"));
                            }
                          jd->d_retry++;
                        }
                  } else if (js->s_reg_period == 0 || out_tr == NULL)
                    {
                  } else if (now - out_tr->birth_time > js->s_reg_period - 60)
                    {           /* will expires in 60 sec: send refresh! */
                      int i;

					  i = _eXosip_subscribe_automatic_refresh(js, jd, out_tr);
                      if (i != 0)
                        {
                          OSIP_TRACE (osip_trace
                                      (__FILE__, __LINE__, OSIP_ERROR, NULL,
                                       "eXosip: could not clone subscribe for refresh\n"));
                        }
                    }
                }
            }
        }
    }


  for (jn = eXosip.j_notifies; jn != NULL; jn = jn->next)
    {
      for (jd = jn->n_dialogs; jd != NULL; jd = jd->next)
        {
          if (jd->d_dialog != NULL)     /* finished call */
            {
              if (jd->d_id >= 1)
                {
                  osip_transaction_t *out_tr = NULL;

                  out_tr = osip_list_get (jd->d_out_trs, 0);

                  if (out_tr != NULL
                      && (out_tr->state == NICT_TERMINATED
                          || out_tr->state == NICT_COMPLETED) &&
                      now - out_tr->birth_time < 120 &&
                      out_tr->orig_request != NULL &&
                      out_tr->last_response != NULL &&
                      (out_tr->last_response->status_code == 401
                       || out_tr->last_response->status_code == 407))
                    {
                      /* retry with credential */
                      if (jd->d_retry < 3)
                        {
                          int i;

                          i =
                            _eXosip_insubscription_send_request_with_credential
                            (jn, jd, out_tr);
                          if (i != 0)
                            {
                              OSIP_TRACE (osip_trace
                                          (__FILE__, __LINE__, OSIP_ERROR,
                                           NULL,
                                           "eXosip: could not clone notify for authentication\n"));
                            }
                          jd->d_retry++;
                        }
                    }
                }
            }
        }
    }

#endif

  for (jr = eXosip.j_reg; jr != NULL; jr = jr->next)
    {
      if (jr->r_id >= 1 && jr->r_last_tr != NULL)
        {
          if (jr->r_reg_period != 0 && now - jr->r_last_tr->birth_time > 900)
            {
              /* automatic refresh */
              eXosip_register_send_register (jr->r_id, NULL);
          } else if (jr->r_reg_period != 0
                     && now - jr->r_last_tr->birth_time > jr->r_reg_period - 60)
            {
              /* automatic refresh */
              eXosip_register_send_register (jr->r_id, NULL);
          } else if (jr->r_reg_period != 0
                     && now - jr->r_last_tr->birth_time > 120
                     && (jr->r_last_tr->last_response == NULL
                         || (!MSG_IS_STATUS_2XX (jr->r_last_tr->last_response))))
            {
              /* automatic refresh */
              eXosip_register_send_register (jr->r_id, NULL);
          } else if (now - jr->r_last_tr->birth_time < 120 &&
                     jr->r_last_tr->orig_request != NULL &&
                     (jr->r_last_tr->last_response != NULL
                      && (jr->r_last_tr->last_response->status_code == 401
                          || jr->r_last_tr->last_response->status_code == 407)))
            {
              if (jr->r_retry < 3)
                {
                  /* TODO: improve support for several retries when
                     several credentials are needed */
                  eXosip_register_send_register (jr->r_id, NULL);
                  jr->r_retry++;
                }
            }
        }
    }
}
コード例 #7
0
void
eXosip_automatic_refresh (void)
{
  eXosip_subscribe_t *js;
  eXosip_dialog_t *jd;

  eXosip_reg_t *jr;
  time_t now;

  now = time (NULL);

  for (js = eXosip.j_subscribes; js != NULL; js = js->next)
    {
      for (jd = js->s_dialogs; jd != NULL; jd = jd->next)
        {
          if (jd->d_dialog != NULL && (jd->d_id >= 1))  /* finished call */
            {
              osip_transaction_t *out_tr = NULL;

              out_tr = osip_list_get (jd->d_out_trs, 0);
              if (out_tr == NULL)
                out_tr = js->s_out_tr;

              if (js->s_reg_period == 0 || out_tr == NULL)
                {
              } else if (now - out_tr->birth_time > js->s_reg_period - 60)
                {               /* will expires in 60 sec: send refresh! */
                  int i;

				  i = _eXosip_subscribe_automatic_refresh(js, jd, out_tr);
				  if (i != 0)
                    {
                      OSIP_TRACE (osip_trace
                                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                                   "eXosip: could not send subscribe for refresh\n"));
                    }
                }
            }
        }
    }

  for (jr = eXosip.j_reg; jr != NULL; jr = jr->next)
    {
      if (jr->r_id >= 1 && jr->r_last_tr != NULL)
        {
          if (jr->r_reg_period == 0)
            {
              /* skip refresh! */
          } else if (now - jr->r_last_tr->birth_time > 900)
            {
              /* automatic refresh */
              eXosip_register_send_register (jr->r_id, NULL);
          } else if (now - jr->r_last_tr->birth_time > jr->r_reg_period - 60)
            {
              /* automatic refresh */
              eXosip_register_send_register (jr->r_id, NULL);
          } else if (now - jr->r_last_tr->birth_time > 120 &&
                     (jr->r_last_tr->last_response == NULL
                      || (!MSG_IS_STATUS_2XX (jr->r_last_tr->last_response))))
            {
              /* automatic refresh */
              eXosip_register_send_register (jr->r_id, NULL);
            }
        }
    }
}
コード例 #8
0
ファイル: proxy.c プロジェクト: OPSF/uClinux
/*
 * PROXY_RESPONSE
 *
 * RETURNS
 *	STS_SUCCESS on success
 *	STS_FAILURE on error
 * RFC3261
 *    Section 16.7: Proxy Behavior - Response Processing
 *    1.  Find the appropriate response context
 *    2.  Update timer C for provisional responses
 *    3.  Remove the topmost Via
 *    4.  Add the response to the response context
 *    5.  Check to see if this response should be forwarded immediately
 *    6.  When necessary, choose the best final response from the
 *        response context
 *    7.  Aggregate authorization header field values if necessary
 *    8.  Optionally rewrite Record-Route header field values
 *    9.  Forward the response
 *    10. Generate any necessary CANCEL requests 
 *
 */
int proxy_response (sip_ticket_t *ticket) {
   int i;
   int sts;
   int type;
   struct in_addr sendto_addr;
   osip_via_t *via;
   int port;
   char *buffer;
   int buflen;
   osip_message_t *response;
   struct sockaddr_in *from;

   DEBUGC(DBCLASS_PROXY,"proxy_response");

   if (ticket==NULL) {
      ERROR("proxy_response: called with NULL ticket");
      return STS_FAILURE;
   }

   response=ticket->sipmsg;
   from=&ticket->from;

   /*
    * RFC 3261, Section 16.7 step 3
    * Proxy Behavior - Response Processing - Remove my Via header field value
    */
   /* remove my Via header line */
   sts = sip_del_myvia(ticket);
   if (sts == STS_FAILURE) {
      DEBUGC(DBCLASS_PROXY,"not addressed to my VIA, ignoring response");
      return STS_FAILURE;
   }

   /*
    * figure out if this is an request coming from the outside
    * world to one of our registered clients
    */

   /* Ahhrghh...... a response seems to have NO contact information... 
    * so let's take FROM instead...
    * the TO and FROM headers are EQUAL to the request - that means 
    * they are swapped in their meaning for a response...
    */

#if _OLD_DIRECTION_EVALUATION
   type = 0;
   for (i=0; i<URLMAP_SIZE; i++) {
      if (urlmap[i].active == 0) continue;

      /* incoming response ('from' == 'masq') || ('from' == 'reg') */
      if ((compare_url(response->from->url, urlmap[i].reg_url)==STS_SUCCESS) ||
          (compare_url(response->from->url, urlmap[i].masq_url)==STS_SUCCESS)) {
         type=RESTYP_INCOMING;
         DEBUGC(DBCLASS_PROXY,"incoming response for %s@%s from outbound",
	   response->from->url->username? response->from->url->username:"******",
	   response->from->url->host? response->from->url->host : "*NULL*");
	 break;
      }

      /* outgoing response ('to' == 'reg') || ('to' == 'masq' ) */
      if ((compare_url(response->to->url, urlmap[i].masq_url)==STS_SUCCESS) ||
          (compare_url(response->to->url, urlmap[i].reg_url)==STS_SUCCESS)){
         type=RESTYP_OUTGOING;
         DEBUGC(DBCLASS_PROXY,"outgoing response for %s@%s from inbound",
	        response->from->url->username ?
                   response->from->url->username : "******",
	        response->from->url->host ? 
                   response->from->url->host : "*NULL*");
	 break;
      }
   }
#else
   type = 0;
   /*
    * did I receive the telegram from a REGISTERED host?
    * -> it must be an OUTGOING response
    */
   for (i=0; i<URLMAP_SIZE; i++) {
      struct in_addr tmp_addr;
      if (urlmap[i].active == 0) continue;

      if (get_ip_by_host(urlmap[i].true_url->host, &tmp_addr) == STS_FAILURE) {
         DEBUGC(DBCLASS_PROXY, "proxy_response: cannot resolve host [%s]",
             urlmap[i].true_url);
      } else {
         DEBUGC(DBCLASS_PROXY, "proxy_response: reghost:%s ip:%s",
                urlmap[i].true_url->host, utils_inet_ntoa(from->sin_addr));
         if (memcmp(&tmp_addr, &from->sin_addr, sizeof(tmp_addr)) == 0) {
            type=RESTYP_OUTGOING;
	    break;
         }
      }
   }
   /*
    * is the telegram directed to an internal registered host?
    * -> it must be an INCOMING response
    */
   if (type == 0) {
      for (i=0; i<URLMAP_SIZE; i++) {
         if (urlmap[i].active == 0) continue;
         /* incoming response ('from' == 'masq') || ('from' == 'reg') */
         if ((compare_url(response->from->url, urlmap[i].reg_url)==STS_SUCCESS) ||
             (compare_url(response->from->url, urlmap[i].masq_url)==STS_SUCCESS)) {
            type=RESTYP_INCOMING;
	    break;
         }
      }
   }
/* &&&& Open Issue &&&&
   it has been seen with cross-provider calls that the FROM may be 'garbled'
   (e.g [email protected] for calls made sipphone -> FWD)
   How can we deal with this? Should I take into consideration the 'Via'
   headers? This is the only clue I have, pointing to the *real* UA.
   Maybe I should put in a 'siproxd' ftag value to recognize it as a header
   inserted by myself
*/
   if ((type == 0) && (!osip_list_eol(response->vias, 0))) {
      osip_via_t *via;
      struct in_addr addr_via, addr_myself;
      int port_via, port_ua;

      /* get the via address */
      via = (osip_via_t *) osip_list_get (response->vias, 0);
      DEBUGC(DBCLASS_PROXY, "proxy_response: check via [%s] for "
             "registered UA",via->host);
      sts=get_ip_by_host(via->host, &addr_via);
      if (sts == STS_FAILURE) {
         DEBUGC(DBCLASS_DNS, "proxy_response: cannot resolve VIA [%s]",
                via->host);
      } else {

         for (i=0; i<URLMAP_SIZE; i++) {
            if (urlmap[i].active == 0) continue;
            /* incoming response (1st via in list points to a registered UA) */
            sts=get_ip_by_host(urlmap[i].true_url->host, &addr_myself);
            if (sts == STS_FAILURE) {
               DEBUGC(DBCLASS_DNS, "proxy_response: cannot resolve "
                      "true_url [%s]", via->host);
               continue;
            }

            port_via=0;
            if (via->port) port_via=atoi(via->port);
            if (port_via <= 0) port_via=SIP_PORT;

            port_ua=0;
            if (urlmap[i].true_url->port)
               port_ua=atoi(urlmap[i].true_url->port);
            if (port_ua <= 0) port_ua=SIP_PORT;

            DEBUGC(DBCLASS_BABBLE, "proxy_response: checking for registered "
                   "host [%s:%i] <-> [%s:%i]",
                   urlmap[i].true_url->host, port_ua,
                   via->host, port_via);

            if ((memcmp(&addr_myself, &addr_via, sizeof(addr_myself))==0) &&
                (port_via == port_ua)) {
               type=RESTYP_INCOMING;
	       break;
            }
         }
      }
   }
    
#endif
   ticket->direction=type;

/*
 * ok, we got a response that we are allowed to process.
 */
   switch (type) {
  /*
   * from an external host to the internal masqueraded host
   */
   case RESTYP_INCOMING:
      DEBUGC(DBCLASS_PROXY,"incoming response for %s@%s from outbound",
	response->from->url->username? response->from->url->username:"******",
	response->from->url->host? response->from->url->host : "*NULL*");

      /*
       * Response for INVITE - deal with RTP data in body and
       *                       start RTP proxy stream(s). In case
       *                       of a negative answer, stop RTP stream
       */
      if (MSG_IS_RESPONSE_FOR(response,"INVITE")) {
         /* positive response, start RTP stream */
         if ((MSG_IS_STATUS_1XX(response)) || 
              (MSG_IS_STATUS_2XX(response))) {
            if (configuration.rtp_proxy_enable == 1) {
               sts = proxy_rewrite_invitation_body(response, DIR_INCOMING);
            }
         /* negative - stop a possibly started RTP stream */
         } else if ((MSG_IS_STATUS_4XX(response))  ||
                     (MSG_IS_STATUS_5XX(response)) ||
                     (MSG_IS_STATUS_6XX(response))) {
            rtp_stop_fwd(osip_message_get_call_id(response), DIR_INCOMING);
            rtp_stop_fwd(osip_message_get_call_id(response), DIR_OUTGOING);
         }
      } /* if INVITE */

      /*
       * Response for REGISTER - special handling of Contact header
       */
      if (MSG_IS_RESPONSE_FOR(response,"REGISTER")) {
         /*
          * REGISTER returns *my* Contact header information.
          * Rewrite Contact header back to represent the true address.
          * Other responses do return the Contact header of the sender.
          */
         sip_rewrite_contact(ticket, DIR_INCOMING);
      }

      /* 
       * Response for SUBSCRIBE
       *
       * HACK for Grandstream SIP phones (with newer firmware like 1.0.4.40):
       *   They send a SUBSCRIBE request to the registration server. In
       *   case of beeing registering directly to siproxd, this request of
       *   course will eventually be forwarded back to the same UA.
       *   Grandstream then does reply with an '202' response (A 202
       *   response merely indicates that the subscription has been
       *   understood, and that authorization may or may not have been
       *   granted), which then of course is forwarded back to the phone.
       *   Ans it seems that the Grandstream can *not* *handle* this
       *   response, as it immediately sends another SUBSCRIBE request.
       *   And this games goes on and on and on...
       *
       *   As a workaround we will transform any 202 response to a
       *   '404 unknown destination'
       *   
       */
{
      osip_header_t *ua_hdr=NULL;
      osip_message_get_user_agent(response, 0, &ua_hdr);
      if (ua_hdr && ua_hdr->hvalue &&
          (osip_strncasecmp(ua_hdr->hvalue,"grandstream", 11)==0) &&
          (MSG_IS_RESPONSE_FOR(response,"SUBSCRIBE")) &&
          (MSG_TEST_CODE(response, 202))) {
         DEBUGC(DBCLASS_PROXY, "proxy_response: Grandstream hack 202->404");
         response->status_code=404;
      }
}
      break;
   
  /*
   * from the internal masqueraded host to an external host
   */
   case RESTYP_OUTGOING:
      DEBUGC(DBCLASS_PROXY,"outgoing response for %s@%s from inbound",
	     response->from->url->username ?
                response->from->url->username : "******",
	     response->from->url->host ? 
                response->from->url->host : "*NULL*");

      /* rewrite Contact header to represent the masqued address */
      sip_rewrite_contact(ticket, DIR_OUTGOING);

      /*
       * If an 2xx OK or 1xx response, answer to an INVITE request,
       * rewrite body
       *
       * In case of a negative answer, stop RTP stream
       */
      if (MSG_IS_RESPONSE_FOR(response,"INVITE")) {
         /* positive response, start RTP stream */
         if ((MSG_IS_STATUS_1XX(response)) || 
              (MSG_IS_STATUS_2XX(response))) {
            /* This is an outgoing response, therefore an outgoing stream */
            sts = proxy_rewrite_invitation_body(response, DIR_OUTGOING);
         /* megative - stop a possibly started RTP stream */
         } else if ((MSG_IS_STATUS_4XX(response))  ||
                     (MSG_IS_STATUS_5XX(response)) ||
                     (MSG_IS_STATUS_6XX(response))) {
            rtp_stop_fwd(osip_message_get_call_id(response), DIR_INCOMING);
            rtp_stop_fwd(osip_message_get_call_id(response), DIR_OUTGOING);
         }
      } /* if INVITE */

      break;
   
   default:
      DEBUGC(DBCLASS_PROXY, "response from/to unregistered UA (%s@%s)",
	   response->from->url->username? response->from->url->username:"******",
	   response->from->url->host? response->from->url->host : "*NULL*");
      return STS_FAILURE;
   }

   /*
    * for ALL incoming response include my Record-Route header.
    * The local UA will probably send its answer to the topmost 
    * Route Header (8.1.2 of RFC3261)
    */
    if (type == RESTYP_INCOMING) {
       DEBUGC(DBCLASS_PROXY,"Adding my Record-Route");
       route_add_recordroute(ticket);
    } else {
       /*
        * outgoing packets must not have my record route header, as
        * this likely will contain a private IP address (my inbound).
        */
       DEBUGC(DBCLASS_PROXY,"Purging Record-Routes (outgoing packet)");
       route_purge_recordroute(ticket);
    }

   /*
    * Determine Next-Hop Address
    */
/*&&&& priority probably should be:
 * 1) Route header
 * 2) fixed outbound proxy
 * 3) SIP URI
 */
   /*
    * check if we need to send to an outbound proxy
    */
   if ((type == RESTYP_OUTGOING) &&
       (sip_find_outbound_proxy(ticket, &sendto_addr, &port) == STS_SUCCESS)) {
      DEBUGC(DBCLASS_PROXY, "proxy_response: have outbound proxy %s:%i",
             utils_inet_ntoa(sendto_addr), port);
   /*
    * Route present?
    * If so, fetch address from topmost Route: header and remove it.
    */
   } else if ((type == RESTYP_OUTGOING) && 
              (response->routes && !osip_list_eol(response->routes, 0))) {
      sts=route_determine_nexthop(ticket, &sendto_addr, &port);
      if (sts == STS_FAILURE) {
         DEBUGC(DBCLASS_PROXY, "proxy_response: route_determine_nexthop failed");
         return STS_FAILURE;
      }
      DEBUGC(DBCLASS_PROXY, "proxy_response: have Route header to %s:%i",
             utils_inet_ntoa(sendto_addr), port);
   } else {
      /* get target address and port from VIA header */
      via = (osip_via_t *) osip_list_get (response->vias, 0);
      if (via == NULL) {
         ERROR("proxy_response: list_get via failed");
         return STS_FAILURE;
      }

      sts = get_ip_by_host(via->host, &sendto_addr);
      if (sts == STS_FAILURE) {
         DEBUGC(DBCLASS_PROXY, "proxy_response: cannot resolve VIA [%s]",
                via->host);
         return STS_FAILURE;
      }

      if (via->port) {
         port=atoi(via->port);
      } else {
         port=SIP_PORT;
      }
   }

   sts = sip_message_to_str(response, &buffer, &buflen);
   if (sts != 0) {
      ERROR("proxy_response: sip_message_to_str failed");
      return STS_FAILURE;
   }

   sipsock_send(sendto_addr, port, ticket->protocol,
                buffer, buflen); 
   osip_free (buffer);
   return STS_SUCCESS;
}
コード例 #9
0
ファイル: Node.cpp プロジェクト: inuyasha1027/SI2P
NS_EVENT Node::ReportRCVEvent(osip_message_t *M) 
{
	osip_generic_param_t *param ;
	osip_uri_param_get_byname(M->from->gen_params,"user",&param) ;

	//
	if(!strcmp(param->gvalue,"multicast"))
	{
		if(MSG_IS_REQUEST(M))
		{
			return MULTICAST_REQ_RCV ;
		}
		else
		{
			if(MSG_IS_STATUS_2XX(M))
				return MULTICAST_RESP_2XX ;
			else 
				return EVT_OTHER ;
		}
	}

	//
	else if(!strcmp(param->gvalue,"join"))
	{
		if(MSG_IS_REQUEST(M))
		{
			return JOIN_REQ_RCV ;
		}
		else
		{
			if(MSG_IS_STATUS_2XX(M))
				return JOIN_RESP_2XX ;
			else if(MSG_IS_STATUS_3XX(M))
				return JOIN_RESP_3XX ;
			else 
				return EVT_OTHER ;
		}
	}
	
	//
	else if(!strcmp(param->gvalue,"findsucc"))
	{
		if(MSG_IS_REQUEST(M))
		{
			return FINDSUCC_REQ_RCV ;
		}
		else
		{
			if(MSG_IS_STATUS_2XX(M))
				return FINDSUCC_RESP_2XX ;
			else if(MSG_IS_STATUS_3XX(M))
				return FINDSUCC_RESP_3XX ;
			else 
				return EVT_OTHER ;
		}
	}
	
	//
	else if(!strcmp(param->gvalue,"stabilize"))
	{
		if(MSG_IS_REQUEST(M))
		{
			return STABILIZE_REQ_RCV ;
		}
		else
		{
			if(MSG_IS_STATUS_2XX(M))
				return STABILIZE_RESP_2XX ;
			else 
				return EVT_OTHER ;
		}
	}
	
	//
	else if(!strcmp(param->gvalue,"leave"))
	{
		if(MSG_IS_REQUEST(M))
		{
			return LEAVE_REQ_RCV ;
		}
		else 
			return EVT_OTHER ;
	}
	
	//
	else if(!strcmp(param->gvalue,"user_registration"))
	{
		if(MSG_IS_REQUEST(M))
		{
			return USER_REG_RCV ;
		}
		else if(MSG_IS_STATUS_2XX(M))
		
			return USER_REG_RESP_2XX;

		else if(MSG_IS_STATUS_3XX(M))

			return USER_REG_RESP_3XX;
		
		else return EVT_OTHER ;

	}
	else if(!strcmp(param->gvalue,"red_register"))
	{
		if(MSG_IS_REQUEST(M))
			return RED_REGISTER_RCV;
		else if(MSG_IS_STATUS_2XX(M))
			return RED_REGISTER_RESP_2XX;
		else return EVT_OTHER;
	}
	//
		else if(!strcmp(param->gvalue,"user_query"))
	{
		if(MSG_IS_REQUEST(M))
		{
			return USER_QUERY_RCV ;
		}
		else if(MSG_IS_STATUS_2XX(M))
		
			return USER_QUERY_RESP_2XX;

		else if(MSG_IS_STATUS_3XX(M))

			return USER_QUERY_RESP_3XX;
		
		else return EVT_OTHER ;

	}
	//
	else
	{
		return EVT_OTHER ;
	}	
}
static int
__osip_dialog_init (osip_dialog_t ** dialog, osip_message_t * invite, osip_message_t * response, osip_from_t * local, osip_to_t * remote, osip_message_t * remote_msg)
{
  int i;
  int pos;
  osip_generic_param_t *tag;

  *dialog = NULL;
  if (response == NULL)
    return OSIP_BADPARAMETER;
  if (response->cseq == NULL || local == NULL || remote == NULL)
    return OSIP_SYNTAXERROR;

  (*dialog) = (osip_dialog_t *) osip_malloc (sizeof (osip_dialog_t));
  if (*dialog == NULL)
    return OSIP_NOMEM;

  memset (*dialog, 0, sizeof (osip_dialog_t));
  (*dialog)->your_instance = NULL;

  if (MSG_IS_STATUS_2XX (response))
    (*dialog)->state = DIALOG_CONFIRMED;
  else                          /* 1XX */
    (*dialog)->state = DIALOG_EARLY;

  i = osip_call_id_to_str (response->call_id, &((*dialog)->call_id));
  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not establish dialog!\n"));
    osip_dialog_free (*dialog);
    *dialog = NULL;
    return i;
  }

  i = osip_to_get_tag (local, &tag);
  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not establish dialog!\n"));
    osip_dialog_free (*dialog);
    *dialog = NULL;
    return i;
  }

  (*dialog)->local_tag = osip_strdup (tag->gvalue);

  i = osip_from_get_tag (remote, &tag);
  if (i == 0)
    (*dialog)->remote_tag = osip_strdup (tag->gvalue);

  /* VR-2785: remember line value */
  if (invite) {
    osip_uri_param_t *line_param;

    i = osip_uri_param_get_byname (&invite->req_uri->url_params, "line", &line_param);
    if (i == 0 && line_param != NULL && line_param->gvalue != NULL)
      (*dialog)->line_param = osip_strdup (line_param->gvalue);
  }

  osip_list_init (&(*dialog)->route_set);

  pos = 0;
  while (!osip_list_eol (&response->record_routes, pos)) {
    osip_record_route_t *rr;
    osip_record_route_t *rr2;

    rr = (osip_record_route_t *) osip_list_get (&response->record_routes, pos);
    i = osip_record_route_clone (rr, &rr2);
    if (i != 0) {
      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not establish dialog!\n"));
      osip_dialog_free (*dialog);
      *dialog = NULL;
      return i;
    }
    if (invite == NULL)
      osip_list_add (&(*dialog)->route_set, rr2, 0);
    else
      osip_list_add (&(*dialog)->route_set, rr2, -1);

    pos++;
  }

  /* local_cseq is set to response->cseq->number for better
     handling of bad UA */
  (*dialog)->local_cseq = osip_atoi (response->cseq->number);

  i = osip_from_clone (remote, &((*dialog)->remote_uri));
  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not establish dialog!\n"));
    osip_dialog_free (*dialog);
    *dialog = NULL;
    return i;
  }

  i = osip_to_clone (local, &((*dialog)->local_uri));
  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not establish dialog!\n"));
    osip_dialog_free (*dialog);
    *dialog = NULL;
    return i;
  }

  {
    osip_contact_t *contact;

    if (!osip_list_eol (&remote_msg->contacts, 0)) {
      contact = osip_list_get (&remote_msg->contacts, 0);
      i = osip_contact_clone (contact, &((*dialog)->remote_contact_uri));
      if (i != 0) {
        OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not establish dialog!\n"));
        osip_dialog_free (*dialog);
        *dialog = NULL;
        return i;
      }
    }
    else {
      (*dialog)->remote_contact_uri = NULL;
      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "Remote UA is not compliant: missing a contact in remote message!\n"));
    }
  }
  (*dialog)->secure = -1;       /* non secure */

  return OSIP_SUCCESS;
}
コード例 #11
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;
}
コード例 #12
0
ファイル: nist_fsm.c プロジェクト: Nymphetaminer/dsl-n55u
void
nist_rcv_request (osip_transaction_t * nist, osip_event_t * evt)
{
  int i;
  osip_t *osip = (osip_t *) nist->config;

  if (nist->state == NIST_PRE_TRYING)	/* announce new REQUEST */
    {
      /* Here we have ist->orig_request == NULL */
      nist->orig_request = evt->sip;

      if (MSG_IS_REGISTER (evt->sip))
	__osip_message_callback (OSIP_NIST_REGISTER_RECEIVED, nist,
			   nist->orig_request);
      else if (MSG_IS_BYE (evt->sip))
	__osip_message_callback (OSIP_NIST_BYE_RECEIVED, nist,
			   nist->orig_request);
      else if (MSG_IS_OPTIONS (evt->sip))
	__osip_message_callback (OSIP_NIST_OPTIONS_RECEIVED, nist,
			   nist->orig_request);
      else if (MSG_IS_INFO (evt->sip))
	__osip_message_callback (OSIP_NIST_INFO_RECEIVED, nist,
			   nist->orig_request);
      else if (MSG_IS_CANCEL (evt->sip))
	__osip_message_callback (OSIP_NIST_CANCEL_RECEIVED, nist,
			   nist->orig_request);
      else if (MSG_IS_NOTIFY (evt->sip))
	__osip_message_callback (OSIP_NIST_NOTIFY_RECEIVED, nist,
			   nist->orig_request);
      else if (MSG_IS_SUBSCRIBE (evt->sip))
	__osip_message_callback (OSIP_NIST_SUBSCRIBE_RECEIVED, nist,
			   nist->orig_request);
      else
	__osip_message_callback (OSIP_NIST_UNKNOWN_REQUEST_RECEIVED, nist,
			   nist->orig_request);
    }
  else				/* NIST_PROCEEDING or NIST_COMPLETED */
    {
      /* delete retransmission */
      osip_message_free (evt->sip);

      __osip_message_callback (OSIP_NIST_REQUEST_RECEIVED_AGAIN, nist,
			 nist->orig_request);
      if (nist->last_response != NULL)	/* retransmit last response */
	{
	  osip_via_t *via;

	  via = (osip_via_t *) osip_list_get (nist->last_response->vias, 0);
	  if (via)
	    {
	      char *host;
	      int port;
	      osip_generic_param_t *maddr;
	      osip_generic_param_t *received;
	      osip_generic_param_t *rport;
	      osip_via_param_get_byname (via, "maddr", &maddr);
	      osip_via_param_get_byname (via, "received", &received);
	      osip_via_param_get_byname (via, "rport", &rport);
	      /* 1: user should not use the provided information
	         (host and port) if they are using a reliable
	         transport. Instead, they should use the already
	         open socket attached to this transaction. */
	      /* 2: check maddr and multicast usage */
	      if (maddr != NULL)
		host = maddr->gvalue;
	      /* we should check if this is a multicast address and use
	         set the "ttl" in this case. (this must be done in the
	         UDP message (not at the SIP layer) */
	      else if (received != NULL)
		host = received->gvalue;
	      else
		host = via->host;

	      if (rport == NULL || rport->gvalue == NULL)
		{
		  if (via->port != NULL)
		    port = osip_atoi (via->port);
		  else
		    port = 5060;
		}
	      else
		port = osip_atoi (rport->gvalue);

	      i = osip->cb_send_message (nist, nist->last_response, host,
					 port, nist->out_socket);
	    }
	  else
	    i = -1;
	  if (i != 0)
	    {
              nist_handle_transport_error (nist, i);
	      return;
	    }
	  else
	    {
	      if (MSG_IS_STATUS_1XX (nist->last_response))
		__osip_message_callback (OSIP_NIST_STATUS_1XX_SENT, nist,
				   nist->last_response);
	      else if (MSG_IS_STATUS_2XX (nist->last_response))
		__osip_message_callback (OSIP_NIST_STATUS_2XX_SENT_AGAIN, nist,
				   nist->last_response);
	      else
		__osip_message_callback (OSIP_NIST_STATUS_3456XX_SENT_AGAIN, nist,
				   nist->last_response);
	      return;
	    }
	}
      /* we are already in the proper state */
      return;
    }

  /* we come here only if it was the first REQUEST received */
  __osip_transaction_set_state (nist, NIST_TRYING);
}
コード例 #13
0
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;
}
コード例 #14
0
ファイル: osip_dialog.c プロジェクト: smx-smx/dsl-n55u
int
osip_dialog_init_as_uas (osip_dialog_t ** dialog, osip_message_t * invite, osip_message_t * response)
{
    int i;
    int pos;
    osip_generic_param_t *tag;

    (*dialog) = (osip_dialog_t *) osip_malloc (sizeof (osip_dialog_t));
    if (*dialog == NULL)
        return -1;

    (*dialog)->type = CALLEE;
    if (MSG_IS_STATUS_2XX (response))
        (*dialog)->state = DIALOG_CONFIRMED;
    else				/* 1XX */
        (*dialog)->state = DIALOG_EARLY;

    i = osip_call_id_to_str (response->call_id, &((*dialog)->call_id));
    if (i != 0)
        goto diau_error_0;

    i = osip_to_get_tag (response->to, &tag);
    if (i != 0)
        goto diau_error_1;
    (*dialog)->local_tag = osip_strdup (tag->gvalue);

    i = osip_from_get_tag (response->from, &tag);
    if (i != 0)
    {
        OSIP_TRACE (osip_trace
                    (__FILE__, __LINE__, OSIP_WARNING, NULL,
                     "Remote UA is not compliant: missing a tag in response!\n"));
        (*dialog)->remote_tag = NULL;
    }
    else
        (*dialog)->remote_tag = osip_strdup (tag->gvalue);

    (*dialog)->route_set = (osip_list_t *) osip_malloc (sizeof (osip_list_t));
    osip_list_init ((*dialog)->route_set);

    pos = 0;
    while (!osip_list_eol (response->record_routes, pos))
    {
        osip_record_route_t *rr;
        osip_record_route_t *rr2;

        rr = (osip_record_route_t *) osip_list_get (response->record_routes, pos);
        i = osip_record_route_clone (rr, &rr2);
        if (i != 0)
            goto diau_error_2;
        osip_list_add ((*dialog)->route_set, rr2, -1);
        pos++;
    }

    /* local_cseq is set to response->cseq->number for better
       handling of bad UA */
    (*dialog)->local_cseq = osip_atoi (response->cseq->number);
    (*dialog)->remote_cseq = osip_atoi (response->cseq->number);


    i = osip_from_clone (response->from, &((*dialog)->remote_uri));
    if (i != 0)
        goto diau_error_3;

    i = osip_to_clone (response->to, &((*dialog)->local_uri));
    if (i != 0)
        goto diau_error_4;

    {
        osip_contact_t *contact;

        if (!osip_list_eol (invite->contacts, 0))
        {
            contact = osip_list_get (invite->contacts, 0);
            i = osip_contact_clone (contact, &((*dialog)->remote_contact_uri));
            if (i != 0)
                goto diau_error_5;
        }
        else
        {
            (*dialog)->remote_contact_uri = NULL;
            OSIP_TRACE (osip_trace
                        (__FILE__, __LINE__, OSIP_WARNING, NULL,
                         "Remote UA is not compliant: missing a contact in response!\n"));
        }
    }
    (*dialog)->secure = -1;	/* non secure */

    return 0;

diau_error_5:
    osip_from_free ((*dialog)->local_uri);
diau_error_4:
    osip_from_free ((*dialog)->remote_uri);
diau_error_3:
diau_error_2:
    osip_list_special_free ((*dialog)->route_set,
                            (void *(*)(void *)) &osip_record_route_free);
    osip_free ((*dialog)->remote_tag);
    osip_free ((*dialog)->local_tag);
diau_error_1:
    osip_free ((*dialog)->call_id);
diau_error_0:
    OSIP_TRACE (osip_trace
                (__FILE__, __LINE__, OSIP_ERROR, NULL,
                 "Could not establish dialog!\n"));
    osip_free (*dialog);
    *dialog = NULL;
    return -1;
}