int osip_content_type_clone (const osip_content_type_t * ctt, osip_content_type_t ** dest) { int i; osip_content_type_t *ct; *dest = NULL; if (ctt == NULL) return OSIP_BADPARAMETER; i = osip_content_type_init (&ct); if (i != 0) /* allocation failed */ return i; if (ctt->type != NULL) ct->type = osip_strdup (ctt->type); if (ctt->subtype != NULL) ct->subtype = osip_strdup (ctt->subtype); { osip_generic_param_t *dest_param; osip_list_iterator_t it; osip_generic_param_t *u_param = (osip_generic_param_t*) osip_list_get_first(&ctt->gen_params, &it); while (u_param != OSIP_SUCCESS) { i = osip_generic_param_clone (u_param, &dest_param); if (i != 0) { osip_content_type_free (ct); return i; } osip_list_add (&ct->gen_params, dest_param, -1); u_param = (osip_generic_param_t *) osip_list_get_next(&it); } } *dest = ct; return OSIP_SUCCESS; }
/* returns null on error. */ int osip_content_type_to_str (const osip_content_type_t * content_type, char **dest) { char *buf; char *tmp; size_t len; *dest = NULL; if ((content_type == NULL) || (content_type->type == NULL) || (content_type->subtype == NULL)) return OSIP_BADPARAMETER; /* try to guess a long enough length */ len = strlen (content_type->type) + strlen (content_type->subtype) + 4 /* for '/', ' ', ';' and '\0' */ + 10 * osip_list_size (&content_type->gen_params); buf = (char *) osip_malloc (len); if (buf == NULL) return OSIP_NOMEM; tmp = buf; sprintf (tmp, "%s/%s", content_type->type, content_type->subtype); tmp = tmp + strlen (tmp); { osip_list_iterator_t it; osip_generic_param_t *u_param = (osip_generic_param_t*) osip_list_get_first(&content_type->gen_params, &it); while (u_param != OSIP_SUCCESS) { size_t tmp_len; if (u_param->gvalue == NULL) { osip_free (buf); return OSIP_SYNTAXERROR; } tmp_len = strlen (buf) + 4 + strlen (u_param->gname) + strlen (u_param->gvalue) + 1; if (len < tmp_len) { buf = osip_realloc (buf, tmp_len); len = tmp_len; tmp = buf + strlen (buf); } snprintf (tmp, len - (tmp - buf), "; %s=%s", u_param->gname, u_param->gvalue); tmp = tmp + strlen (tmp); u_param = (osip_generic_param_t *) osip_list_get_next(&it); } } *dest = buf; return OSIP_SUCCESS; }
int osip_list_clone(const osip_list_t * src, osip_list_t * dst, int (*clone_func) (void *, void **)) { void *data; void *data2; int i; osip_list_iterator_t iterator; for (data = osip_list_get_first((osip_list_t *) src, &iterator); osip_list_iterator_has_elem(iterator); data = osip_list_get_next(&iterator)) { i = clone_func(data, &data2); if (i != 0) return i; osip_list_add(dst, data2, -1); } return OSIP_SUCCESS; }
/* returns null on error. */ int osip_accept_encoding_to_str (const osip_accept_encoding_t * accept_encoding, char **dest) { char *buf; char *tmp; size_t len; *dest = NULL; if ((accept_encoding == NULL) || (accept_encoding->element == NULL)) return OSIP_BADPARAMETER; len = strlen (accept_encoding->element) + 2; buf = (char *) osip_malloc (len); if (buf == NULL) return OSIP_NOMEM; sprintf (buf, "%s", accept_encoding->element); { size_t plen; osip_list_iterator_t it; osip_generic_param_t *u_param = (osip_generic_param_t*) osip_list_get_first(&accept_encoding->gen_params, &it); while (u_param != OSIP_SUCCESS) { if (u_param->gvalue == NULL) plen = strlen (u_param->gname) + 2; else plen = strlen (u_param->gname) + strlen (u_param->gvalue) + 3; len = len + plen; buf = (char *) osip_realloc (buf, len); tmp = buf; tmp = tmp + strlen (tmp); if (u_param->gvalue == NULL) snprintf (tmp, len - (tmp - buf), ";%s", u_param->gname); else snprintf (tmp, len - (tmp - buf), ";%s=%s", u_param->gname, u_param->gvalue); u_param = (osip_generic_param_t *) osip_list_get_next(&it); } } *dest = buf; return OSIP_SUCCESS; }
int osip_accept_encoding_clone (const osip_accept_encoding_t * ctt, osip_accept_encoding_t ** dest) { int i; osip_accept_encoding_t *ct; *dest = NULL; if (ctt == NULL) return OSIP_BADPARAMETER; if (ctt->element == NULL) return OSIP_BADPARAMETER; i = osip_accept_encoding_init (&ct); if (i != 0) /* allocation failed */ return i; ct->element = osip_strdup (ctt->element); if (ct->element == NULL) { osip_accept_encoding_free (ct); return OSIP_NOMEM; } { osip_generic_param_t *dest_param; osip_list_iterator_t it; osip_generic_param_t *u_param = (osip_generic_param_t*) osip_list_get_first(&ctt->gen_params, &it); while (u_param != OSIP_SUCCESS) { i = osip_generic_param_clone (u_param, &dest_param); if (i != 0) { osip_accept_encoding_free (ct); return i; } osip_list_add (&ct->gen_params, dest_param, -1); u_param = (osip_generic_param_t *) osip_list_get_next(&it); } } *dest = ct; return OSIP_SUCCESS; }
int _eXosip_build_response_default (struct eXosip_t *excontext, osip_message_t ** dest, osip_dialog_t * dialog, int status, osip_message_t * request) { osip_generic_param_t *tag; osip_message_t *response; int i; *dest = NULL; if (request == NULL) return OSIP_BADPARAMETER; i = osip_message_init (&response); if (i != 0) return i; /* initialise osip_message_t structure */ /* yet done... */ response->sip_version = (char *) osip_malloc (8 * sizeof (char)); if (response->sip_version == NULL) { osip_message_free (response); return OSIP_NOMEM; } sprintf (response->sip_version, "SIP/2.0"); osip_message_set_status_code (response, status); #ifndef MINISIZE /* handle some internal reason definitions. */ if (MSG_IS_NOTIFY (request) && status == 481) { response->reason_phrase = osip_strdup ("Subscription Does Not Exist"); } else if (MSG_IS_SUBSCRIBE (request) && status == 202) { response->reason_phrase = osip_strdup ("Accepted subscription"); } else { response->reason_phrase = osip_strdup (osip_message_get_reason (status)); if (response->reason_phrase == NULL) { if (response->status_code == 101) response->reason_phrase = osip_strdup ("Dialog Establishement"); else response->reason_phrase = osip_strdup ("Unknown code"); } response->req_uri = NULL; response->sip_method = NULL; } #else response->reason_phrase = osip_strdup (osip_message_get_reason (status)); if (response->reason_phrase == NULL) { if (response->status_code == 101) response->reason_phrase = osip_strdup ("Dialog Establishement"); else response->reason_phrase = osip_strdup ("Unknown code"); } response->req_uri = NULL; response->sip_method = NULL; #endif if (response->reason_phrase == NULL) { osip_message_free (response); return OSIP_NOMEM; } i = osip_to_clone (request->to, &(response->to)); if (i != 0) { osip_message_free (response); return i; } i = osip_to_get_tag (response->to, &tag); if (i != 0) { /* we only add a tag if it does not already contains one! */ if ((dialog != NULL) && (dialog->local_tag != NULL)) /* it should contain the local TAG we created */ { osip_to_set_tag (response->to, osip_strdup (dialog->local_tag)); } else { if (status != 100) osip_to_set_tag (response->to, _eXosip_malloc_new_random ()); } } i = osip_from_clone (request->from, &(response->from)); if (i != 0) { osip_message_free (response); return i; } { osip_list_iterator_t it; osip_via_t *via = (osip_via_t*)osip_list_get_first(&request->vias, &it); while (via != NULL) { osip_via_t *via2; i = osip_via_clone (via, &via2); if (i != 0) { osip_message_free (response); return i; } osip_list_add (&response->vias, via2, -1); via = (osip_via_t *)osip_list_get_next(&it); } } i = osip_call_id_clone (request->call_id, &(response->call_id)); if (i != 0) { osip_message_free (response); return i; } i = osip_cseq_clone (request->cseq, &(response->cseq)); if (i != 0) { osip_message_free (response); return i; } #ifndef MINISIZE if (MSG_IS_SUBSCRIBE (request)) { osip_header_t *exp; osip_header_t *evt_hdr; osip_message_header_get_byname (request, "event", 0, &evt_hdr); if (evt_hdr != NULL && evt_hdr->hvalue != NULL) osip_message_set_header (response, "Event", evt_hdr->hvalue); else osip_message_set_header (response, "Event", "presence"); i = osip_message_get_expires (request, 0, &exp); if (exp == NULL) { osip_header_t *cp; i = osip_header_clone (exp, &cp); if (cp != NULL) osip_list_add (&response->headers, cp, 0); } } #endif osip_message_set_user_agent (response, excontext->user_agent); *dest = response; return OSIP_SUCCESS; }
int _eXosip_complete_answer_that_establish_a_dialog (struct eXosip_t *excontext, osip_message_t * response, osip_message_t * request) { int i; int route_found = 0; char contact[1024]; char scheme[10]; osip_list_iterator_t it; osip_record_route_t *rr; snprintf(scheme, sizeof(scheme), "sip"); /* 12.1.1: copy all record-route in response add a contact with global scope */ rr = (osip_record_route_t *)osip_list_get_first(&request->record_routes, &it); while (rr != NULL) { osip_record_route_t *rr2; i = osip_record_route_clone (rr, &rr2); if (i != 0) return i; osip_list_add (&response->record_routes, rr2, -1); /* rfc3261: 12.1.1 UAS behavior (check sips in top most Record-Route) */ if (it.pos==0 && rr2!=NULL && rr2->url!=NULL && rr2->url->scheme!=NULL && osip_strcasecmp(rr2->url->scheme, "sips")==0) snprintf(scheme, sizeof(scheme), "sips"); rr = (osip_record_route_t *)osip_list_get_next(&it); route_found=1; } if (MSG_IS_BYE (request)) { return OSIP_SUCCESS; } if (route_found==0) { /* rfc3261: 12.1.1 UAS behavior (check sips in Contact if no Record-Route) */ osip_contact_t *co = (osip_contact_t *) osip_list_get(&request->contacts, 0); if (co!=NULL && co->url!=NULL && co->url->scheme!=NULL && osip_strcasecmp(co->url->scheme, "sips")==0) snprintf(scheme, sizeof(scheme), "sips"); } /* rfc3261: 12.1.1 UAS behavior (check sips in Request-URI) */ if (request->req_uri->scheme!=NULL && osip_strcasecmp(request->req_uri->scheme, "sips")==0) snprintf(scheme, sizeof(scheme), "sips"); /* special values to be replaced in transport layer (eXtl_*.c files) */ if (request->to->url->username == NULL) snprintf (contact, 1000, "<%s:999.999.999.999:99999>", scheme); else { char *tmp2 = __osip_uri_escape_userinfo (request->to->url->username); snprintf (contact, 1000, "<%s:%[email protected]:99999>", scheme, tmp2); osip_free (tmp2); } { osip_via_t *via; via = (osip_via_t *) osip_list_get (&response->vias, 0); if (via == NULL || via->protocol == NULL) return OSIP_SYNTAXERROR; if (excontext->enable_outbound==1) { contact[strlen (contact) - 1] = '\0'; strcat (contact, ";ob"); strcat (contact, ">"); } if (strlen (contact) + strlen (via->protocol) + strlen (";transport=>") < 1024 && 0 != osip_strcasecmp (via->protocol, "UDP")) { contact[strlen (contact) - 1] = '\0'; strcat (contact, ";transport="); strcat (contact, via->protocol); strcat (contact, ">"); } if (excontext->sip_instance[0] != 0 && strlen (contact) + 64 < 1024) { strcat(contact, ";+sip.instance=\"<urn:uuid:"); strcat(contact, excontext->sip_instance); strcat(contact, ">\""); } } osip_message_set_contact (response, contact); if (excontext->default_contact_displayname[0]!='\0') { osip_contact_t *new_contact; osip_message_get_contact(response, 0, &new_contact); if (new_contact!=NULL) { new_contact->displayname = osip_strdup (excontext->default_contact_displayname); } } if (excontext->eXtl_transport._tl_update_contact!=NULL) excontext->eXtl_transport._tl_update_contact(excontext, response); return OSIP_SUCCESS; }