📄 excall_api.c
字号:
eXosip_update (); /* AMD 30/09/05 */ return OSIP_SUCCESS;}#ifndef MINISIZEinteXosip_call_build_prack (int tid, osip_message_t ** prack){ eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; osip_transaction_t *tr = NULL; osip_header_t *rseq; char *transport; int i; *prack = NULL; if (tid < 0) return OSIP_BADPARAMETER; if (tid > 0) { _eXosip_call_transaction_find (tid, &jc, &jd, &tr); } if (jc == NULL || jd == NULL || jd->d_dialog == 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")); return OSIP_NOTFOUND; } if (0 != osip_strcasecmp (tr->orig_request->sip_method, "INVITE")) return OSIP_BADPARAMETER; /* PRACK are only send in the PROCEEDING state */ if (tr->state != ICT_PROCEEDING) return OSIP_WRONG_STATE; if (tr->orig_request->cseq == NULL || tr->orig_request->cseq->number == NULL || tr->orig_request->cseq->method == NULL) return OSIP_SYNTAXERROR; transport = NULL; if (tr != NULL && tr->orig_request != NULL) transport = _eXosip_transport_protocol (tr->orig_request); if (transport == NULL) i = _eXosip_build_request_within_dialog (prack, "PRACK", jd->d_dialog, "UDP"); else i = _eXosip_build_request_within_dialog (prack, "PRACK", jd->d_dialog, transport); if (i != 0) return i; osip_message_header_get_byname (tr->last_response, "RSeq", 0, &rseq); if (rseq != NULL && rseq->hvalue != NULL) { char tmp[128]; memset (tmp, '\0', sizeof (tmp)); snprintf (tmp, 127, "%s %s %s", rseq->hvalue, tr->orig_request->cseq->number, tr->orig_request->cseq->method); osip_message_set_header (*prack, "RAck", tmp); } return OSIP_SUCCESS;}inteXosip_call_send_prack (int tid, osip_message_t * prack){ eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; osip_transaction_t *tr = NULL; osip_event_t *sipevent; int i; if (tid < 0) return OSIP_BADPARAMETER; if (prack == NULL) return OSIP_BADPARAMETER; if (tid > 0) { _eXosip_call_transaction_find (tid, &jc, &jd, &tr); } if (jc == NULL || jd == NULL || jd->d_dialog == 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 (prack); return OSIP_NOTFOUND; } if (0 != osip_strcasecmp (tr->orig_request->sip_method, "INVITE")) { osip_message_free (prack); return OSIP_BADPARAMETER; } /* PRACK are only send in the PROCEEDING state */ if (tr->state != ICT_PROCEEDING) { osip_message_free (prack); return OSIP_WRONG_STATE; } tr = NULL; i = _eXosip_transaction_init (&tr, NICT, eXosip.j_osip, prack); if (i != 0) { osip_message_free (prack); return i; } jd->d_mincseq++; osip_list_add (jd->d_out_trs, tr, 0); sipevent = osip_new_outgoing_sipmessage (prack); sipevent->transactionid = tr->transactionid;#ifndef MINISIZE osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd, NULL, NULL));#else osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd));#endif osip_transaction_add_event (tr, sipevent); __eXosip_wakeup (); return OSIP_SUCCESS;}#endifint_eXosip_call_retry_request (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * out_tr){ osip_transaction_t *tr = NULL; osip_message_t *msg = NULL; osip_event_t *sipevent; int cseq; osip_via_t *via; osip_contact_t *co; int pos; int i; int protocol = IPPROTO_UDP; if (jc == NULL) return OSIP_BADPARAMETER; if (jd != NULL) { if (jd->d_out_trs == NULL) return OSIP_BADPARAMETER; } if (out_tr == NULL || out_tr->orig_request == NULL || out_tr->last_response == NULL) return OSIP_BADPARAMETER; i = osip_message_clone (out_tr->orig_request, &msg); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: could not clone msg for authentication\n")); return i; } via = (osip_via_t *) osip_list_get (&msg->vias, 0); if (via == NULL || msg->cseq == NULL || msg->cseq->number == NULL) { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing via or cseq header\n")); return OSIP_SYNTAXERROR; } if (MSG_IS_STATUS_3XX (out_tr->last_response)) { co = NULL; pos = 0; while (!osip_list_eol (&out_tr->last_response->contacts, pos)) { co = (osip_contact_t *) osip_list_get (&out_tr->last_response->contacts, pos); if (co != NULL && co->url != NULL) { /* check tranport? Only allow UDP, right now */ osip_uri_param_t *u_param; int pos2; u_param = NULL; pos2 = 0; while (!osip_list_eol (&co->url->url_params, pos2)) { u_param = (osip_uri_param_t *) osip_list_get (&co->url->url_params, pos2); if (u_param == NULL || u_param->gname == NULL || u_param->gvalue == NULL) { u_param = NULL; /* skip */ } else if (0 == osip_strcasecmp (u_param->gname, "transport")) { if (0 == osip_strcasecmp (u_param->gvalue, "udp")) { u_param = NULL; protocol = IPPROTO_UDP; break; /* ok */ } else if (0 == osip_strcasecmp (u_param->gvalue, "tcp")) { protocol = IPPROTO_TCP; u_param = NULL; } break; } pos2++; } if (u_param == NULL || u_param->gname == NULL || u_param->gvalue == NULL) { break; /* default is udp! */ } } pos++; co = NULL; } if (co == NULL || co->url == NULL) { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: contact header\n")); return OSIP_SYNTAXERROR; } /* TODO: remove extra parameter from new request-uri check usual parameter like "transport" */ if (msg->req_uri != NULL && msg->req_uri->host != NULL && co->url->host != NULL && 0 == osip_strcasecmp (co->url->host, msg->req_uri->host)) { osip_uri_param_t *maddr_param = NULL; osip_uri_uparam_get_byname (co->url, "maddr", &maddr_param); if (maddr_param != NULL && maddr_param->gvalue != NULL) { /* This is a redirect server, the route should probably be removed? */ osip_route_t *route = NULL; osip_generic_param_t *tag = NULL; osip_message_get_route (msg, 0, &route); if (route != NULL) { osip_to_get_tag (msg->to, &tag); if (tag == NULL && route != NULL && route->url != NULL) { osip_list_remove (&msg->routes, 0); osip_route_free (route); } } } } /* replace request-uri with NEW contact address */ osip_uri_free (msg->req_uri); msg->req_uri = NULL; osip_uri_clone (co->url, &msg->req_uri); /* support for diversions headers/draft! */ { int count = 0; pos = 0; while (!osip_list_eol (&out_tr->last_response->headers, pos)) { osip_header_t *copy = NULL; osip_header_t *head = osip_list_get (&out_tr->last_response->headers, pos); if (head != NULL && 0 == osip_strcasecmp (head->hname, "diversion")) { i = osip_header_clone (head, ©); if (i == 0) { osip_list_add (&msg->headers, copy, count); count++; } } pos++; } } } /* remove all previous authentication headers */ osip_list_special_free (&msg->authorizations, (void *(*)(void *)) &osip_authorization_free); osip_list_special_free (&msg->proxy_authorizations, (void *(*)(void *)) &osip_proxy_authorization_free); /* increment cseq */ cseq = atoi (msg->cseq->number); osip_free (msg->cseq->number); msg->cseq->number = strdup_printf ("%i", cseq + 1); if (jd != NULL && jd->d_dialog != NULL) { jd->d_dialog->local_cseq++; } i = eXosip_update_top_via (msg); if (i != 0) { osip_message_free (msg); return i; } if (out_tr->last_response->status_code == 401 || out_tr->last_response->status_code == 407) eXosip_add_authentication_information (msg, out_tr->last_response); else eXosip_add_authentication_information (msg, NULL); osip_message_force_update (msg); if (0 != osip_strcasecmp (msg->sip_method, "INVITE")) { i = _eXosip_transaction_init (&tr, NICT, eXosip.j_osip, msg); } else { i = _eXosip_transaction_init (&tr, ICT, eXosip.j_osip, msg); } if (i != 0) { osip_message_free (msg); return i; } if (out_tr == jc->c_out_tr) { /* replace with the new tr */ osip_list_add (&eXosip.j_transactions, jc->c_out_tr, 0); jc->c_out_tr = tr; /* fix dialog issue */ if (jd != NULL) { REMOVE_ELEMENT (jc->c_dialogs, jd); eXosip_dialog_free (jd); jd = NULL; } } else { /* add the new tr for the current dialog */ osip_list_add (jd->d_out_trs, tr, 0); } sipevent = osip_new_outgoing_sipmessage (msg);#ifndef MINISIZE osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd, NULL, NULL));#else osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd));#endif osip_transaction_add_event (tr, sipevent); eXosip_update (); /* fixed? */ __eXosip_wakeup (); return OSIP_SUCCESS;}#ifndef MINISIZEinteXosip_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;}inteXosip_call_find_by_replaces (char *replaces_str){ eXosip_call_t *jc = NULL; eXosip_dialog_t *jd = NULL; char *call_id; char *to_tag; char *from_tag; char *early_flag; char *semicolon; char *totag_str = (char *) "to-tag="; char *fromtag_str = (char *) "from-tag="; char *earlyonly_str = (char *) "early-only"; /* copy replaces string */ if (replaces_str == NULL) return OSIP_SYNTAXERROR; call_id = osip_strdup (replaces_str); if (call_id == NULL) return OSIP_NOMEM; /* parse replaces string */ strcpy (call_id, replaces_str); to_tag = strstr (call_id, totag_str); from_tag = strstr (call_id, fromtag_str); early_flag = strstr (call_id, earlyonly_str); if ((to_tag == NULL) || (from_tag == NULL)) { osip_free (call_id); return OSIP_SYNTAXERROR; } to_tag += strlen (totag_str); from_tag += strlen (fromtag_str); while ((semicolon = strrchr (call_id, ';')) != NULL) { *semicolon = '\0'; } for (jc = eXosip.j_calls; jc != NULL; jc = jc->next) { for (jd = jc->c_dialogs; jd != NULL; jd = jd->next) { if (jd->d_dialog == NULL) { /* skip */ } else if (((0 == strcmp (jd->d_dialog->call_id, call_id)) && (0 == strcmp (jd->d_dialog->remote_tag, to_tag)) && (0 == strcmp (jd->d_dialog->local_tag, from_tag))) || ((0 == strcmp (jd->d_dialog->call_id, call_id)) && (0 == strcmp (jd->d_dialog->local_tag, to_tag)) && (0 == strcmp (jd->d_dialog->remote_tag, from_tag)))) { /* This dialog match! */ if (jd->d_dialog->state == DIALOG_CONFIRMED && early_flag != NULL) { osip_free (call_id); return OSIP_WRONG_STATE; /* confirmed dialog but already answered with 486 */ } if (jd->d_dialog->state == DIALOG_EARLY && jd->d_dialog->type == CALLEE) { osip_free (call_id); return OSIP_BADPARAMETER; /* confirmed dialog but already answered with 481 */ } osip_free (call_id); return jc->c_id; /* match anyway */ } } } osip_free (call_id); return OSIP_NOTFOUND; /* answer with 481 */}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -