int sal_call_notify_ringing(SalOp *op, bool_t early_media){ int status_code =early_media?183:180; belle_sip_request_t* req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans)); belle_sip_response_t* ringing_response = sal_op_create_response_from_request(op,req,status_code); belle_sip_header_t *require; const char *tags=NULL; if (early_media){ handle_offer_answer_response(op,ringing_response); } require=belle_sip_message_get_header((belle_sip_message_t*)req,"Require"); if (require) tags=belle_sip_header_get_unparsed_value(require); /* if client requires 100rel, then add necessary stuff*/ if (tags && strstr(tags,"100rel")!=0) { belle_sip_message_add_header((belle_sip_message_t*)ringing_response,belle_sip_header_create("Require","100rel")); belle_sip_message_add_header((belle_sip_message_t*)ringing_response,belle_sip_header_create("RSeq","1")); } #ifndef SAL_OP_CALL_FORCE_CONTACT_IN_RINGING if (tags && strstr(tags,"100rel")!=0) #endif { belle_sip_header_address_t* contact= (belle_sip_header_address_t*)sal_op_get_contact_address(op); belle_sip_header_contact_t* contact_header; if (contact && (contact_header=belle_sip_header_contact_create(contact))) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(ringing_response),BELLE_SIP_HEADER(contact_header)); } } belle_sip_server_transaction_send_response(op->pending_server_trans,ringing_response); return 0; }
static void sal_op_fill_invite(SalOp *op, belle_sip_request_t* invite) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),BELLE_SIP_HEADER(create_allow(op->base.root->enable_sip_update))); if (op->base.root->session_expires!=0){ belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),belle_sip_header_create( "Session-expires", "600;refresher=uas")); belle_sip_message_add_header(BELLE_SIP_MESSAGE(invite),belle_sip_header_create( "Supported", "timer")); } if (op->base.local_media){ op->sdp_offering=TRUE; set_sdp_from_desc(BELLE_SIP_MESSAGE(invite),op->base.local_media); }else op->sdp_offering=FALSE; return; }
int sal_publish(SalOp *op, const char *from, const char *to, const char *eventname, int expires, const SalBody *body){ belle_sip_request_t *req=NULL; if(!op->refresher || !belle_sip_refresher_get_transaction(op->refresher)) { if (from) sal_op_set_from(op,from); if (to) sal_op_set_to(op,to); sal_op_publish_fill_cbs(op); req=sal_op_build_request(op,"PUBLISH"); if (sal_op_get_contact(op)){ belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op))); } belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Event",eventname)); sal_op_add_body(op,BELLE_SIP_MESSAGE(req),body); return sal_op_send_and_create_refresher(op,req,expires,publish_refresher_listener); } else { /*update status*/ const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(op->refresher); belle_sip_request_t* last_publish=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(last_publish_trans)); /*update body*/ sal_op_add_body(op,BELLE_SIP_MESSAGE(last_publish),expires!=0 ? body : NULL); return belle_sip_refresher_refresh(op->refresher,expires==-1 ? BELLE_SIP_REFRESHER_REUSE_EXPIRES : expires); } }
/*presence Subscribe/notify*/ int sal_subscribe_presence(SalOp *op, const char *from, const char *to, int expires){ belle_sip_request_t *req=NULL; if (from) sal_op_set_from(op,from); if (to) sal_op_set_to(op,to); sal_op_presence_fill_cbs(op); if (expires==-1){ if (op->refresher){ expires=belle_sip_refresher_get_expires(op->refresher); belle_sip_object_unref(op->refresher); op->refresher=NULL; }else{ ms_error("sal_subscribe_presence(): cannot guess expires from previous refresher."); return -1; } } if (!op->event){ op->event=belle_sip_header_create("Event","presence"); belle_sip_object_ref(op->event); } belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(op->base.from_address),"tag"); belle_sip_parameters_remove_parameter(BELLE_SIP_PARAMETERS(op->base.to_address),"tag"); req=sal_op_build_request(op,"SUBSCRIBE"); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->event); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires))); return sal_op_send_request(op,req); }
/*accept an incoming call or, during a call accept a reINVITE*/ int sal_call_accept(SalOp*h){ belle_sip_response_t *response; belle_sip_header_contact_t* contact_header; if (!h->pending_server_trans) { ms_error("No transaction to accept for op [%p]",h); return -1; } /* sends a 200 OK */ response = sal_op_create_response_from_request(h,belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(h->pending_server_trans)),200); if (response==NULL){ ms_error("Fail to build answer for call"); return -1; } belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(create_allow())); if (h->base.root->session_expires!=0){ if (h->supports_session_timers) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),belle_sip_header_create( "Supported", "timer")); } } if ((contact_header=sal_op_create_contact(h))) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(contact_header)); } handle_offer_answer_response(h,response); belle_sip_server_transaction_send_response(h->pending_server_trans,response); return 0; }
static belle_sip_request_t *create_presence_notify(SalOp *op){ belle_sip_request_t* notify=belle_sip_dialog_create_queued_request(op->dialog,"NOTIFY"); if (!notify) return NULL; belle_sip_message_add_header((belle_sip_message_t*)notify,belle_sip_header_create("Event","presence")); return notify; }
void sal_body_handler_set_encoding(SalBodyHandler *body_handler, const char *encoding) { belle_sip_header_t *content_encoding = sal_body_handler_find_header(body_handler, "Content-Encoding"); if (content_encoding != NULL) { belle_sip_body_handler_remove_header_from_ptr(BELLE_SIP_BODY_HANDLER(body_handler), content_encoding); } belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(body_handler), belle_sip_header_create("Content-Encoding", encoding)); }
int sal_subscribe(SalOp *op, const char *from, const char *to, const char *eventname, int expires, const SalBody *body){ belle_sip_request_t *req=NULL; if (from) sal_op_set_from(op,from); if (to) sal_op_set_to(op,to); if (!op->dialog){ sal_op_subscribe_fill_cbs(op); /*???sal_exosip_fix_route(op); make sure to ha ;lr*/ req=sal_op_build_request(op,"SUBSCRIBE"); if (eventname){ if (op->event) belle_sip_object_unref(op->event); op->event=belle_sip_header_create("Event",eventname); belle_sip_object_ref(op->event); } belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->event); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires))); sal_op_add_body(op,(belle_sip_message_t*)req,body); return sal_op_send_and_create_refresher(op,req,expires,subscribe_refresher_listener); }else if (op->refresher){ const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(op->refresher); belle_sip_request_t *last_req=belle_sip_transaction_get_request(tr); /* modify last request to update body*/ sal_op_add_body(op,(belle_sip_message_t*)last_req,body); return belle_sip_refresher_refresh(op->refresher,expires); } ms_warning("sal_subscribe(): no dialog and no refresher ?"); return -1; }
/*accept an incoming call or, during a call accept a reINVITE*/ int sal_call_accept(SalOp*h){ belle_sip_response_t *response; belle_sip_header_contact_t* contact_header; belle_sip_server_transaction_t* transaction; /*first check if an UPDATE transaction need to be accepted*/ if (h->pending_update_server_trans) { transaction=h->pending_update_server_trans; } else if (h->pending_server_trans) { /*so it must be an invite/re-invite*/ transaction=h->pending_server_trans; } else { ms_error("No transaction to accept for op [%p]",h); return -1; } ms_message("Accepting server transaction [%p] on op [%p]", transaction, h); /* sends a 200 OK */ response = sal_op_create_response_from_request(h,belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(transaction)),200); if (response==NULL){ ms_error("Fail to build answer for call"); return -1; } belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(create_allow(h->base.root->enable_sip_update))); if (h->base.root->session_expires!=0){ /* if (h->supports_session_timers) {*/ belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),belle_sip_header_create("Supported", "timer")); belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),belle_sip_header_create( "Session-expires", "600;refresher=uac")); /*}*/ } if ((contact_header=sal_op_create_contact(h))) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(contact_header)); } _sal_op_add_custom_headers(h, BELLE_SIP_MESSAGE(response)); handle_offer_answer_response(h,response); belle_sip_server_transaction_send_response(transaction,response); if (h->pending_update_server_trans) { belle_sip_object_unref(h->pending_update_server_trans); h->pending_update_server_trans=NULL; } return 0; }
int sal_call_update(SalOp *op, const char *subject){ belle_sip_request_t *reinvite=belle_sip_dialog_create_request(op->dialog,"INVITE"); if (reinvite){ belle_sip_message_add_header(BELLE_SIP_MESSAGE(reinvite),belle_sip_header_create( "Subject", subject)); sal_op_fill_invite(op, reinvite); return sal_op_send_request(op,reinvite); } return -1; }
static int send_notify_for_refer(SalOp* op, int code, const char *reason){ belle_sip_request_t* notify=belle_sip_dialog_create_queued_request(op->dialog,"NOTIFY"); char *sipfrag=belle_sip_strdup_printf("SIP/2.0 %i %s\r\n",code,reason); size_t content_length=strlen(sipfrag); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify) ,BELLE_SIP_HEADER(belle_sip_header_subscription_state_create(BELLE_SIP_SUBSCRIPTION_STATE_ACTIVE,-1))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),belle_sip_header_create("Event","refer")); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_HEADER(belle_sip_header_content_type_create("message","sipfrag"))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify),BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_length))); belle_sip_message_assign_body(BELLE_SIP_MESSAGE(notify),sipfrag,content_length); return sal_op_send_request(op,notify); }
SalCustomHeader *sal_custom_header_append(SalCustomHeader *ch, const char *name, const char *value){ belle_sip_message_t *msg=(belle_sip_message_t*)ch; belle_sip_header_t *h; if (msg==NULL){ msg=(belle_sip_message_t*)belle_sip_request_new(); belle_sip_object_ref(msg); } h=belle_sip_header_create(name,value); if (h==NULL){ belle_sip_error("Fail to parse custom header."); return (SalCustomHeader*)msg; } belle_sip_message_add_header(msg,h); return (SalCustomHeader*)msg; }
void sal_op_add_body(SalOp *op, belle_sip_message_t *req, const SalBody *body){ belle_sip_message_remove_header((belle_sip_message_t*)req,"Content-type"); belle_sip_message_remove_header((belle_sip_message_t*)req,"Content-length"); belle_sip_message_remove_header((belle_sip_message_t*)req,"Content-encoding"); belle_sip_message_set_body((belle_sip_message_t*)req,NULL,0); if (body && body->type && body->subtype && body->data){ belle_sip_message_add_header((belle_sip_message_t*)req, (belle_sip_header_t*)belle_sip_header_content_type_create(body->type,body->subtype)); belle_sip_message_add_header((belle_sip_message_t*)req, (belle_sip_header_t*)belle_sip_header_content_length_create(body->size)); belle_sip_message_set_body((belle_sip_message_t*)req,(const char*)body->data,body->size); if (body->encoding){ belle_sip_message_add_header((belle_sip_message_t*)req,(belle_sip_header_t*) belle_sip_header_create("Content-encoding",body->encoding)); } } }
/*presence publish */ int sal_publish_presence(SalOp *op, const char *from, const char *to, int expires, SalPresenceModel *presence){ belle_sip_request_t *req=NULL; if(!op->refresher || !belle_sip_refresher_get_transaction(op->refresher)) { if (from) sal_op_set_from(op,from); if (to) sal_op_set_to(op,to); op->type=SalOpPublish; req=sal_op_build_request(op,"PUBLISH"); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Event","presence")); sal_add_presence_info(op,BELLE_SIP_MESSAGE(req),presence); return sal_op_send_and_create_refresher(op,req,expires,publish_refresher_listener); } else { /*update presence status*/ const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(op->refresher); belle_sip_request_t* last_publish=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(last_publish_trans)); sal_add_presence_info(op,BELLE_SIP_MESSAGE(last_publish),presence); return belle_sip_refresher_refresh(op->refresher,expires); } }
static void one_get(const char *url,http_counters_t* counters, int *counter){ belle_http_request_listener_callbacks_t cbs={0}; belle_http_request_listener_t *l; belle_generic_uri_t *uri; belle_http_request_t *req; uri=belle_generic_uri_parse(url); req=belle_http_request_create("GET", uri, belle_sip_header_create("User-Agent","belle-sip/"PACKAGE_VERSION), NULL); cbs.process_response=process_response; cbs.process_io_error=process_io_error; cbs.process_auth_requested=process_auth_requested; l=belle_http_request_listener_create_from_callbacks(&cbs,counters); belle_http_provider_send_request(prov,req,l); wait_for(stack,counter,1,3000); belle_sip_object_unref(l); }
int sal_register(SalOp *op, const char *proxy, const char *from, int expires,SalAddress* old_contact){ belle_sip_request_t *req; belle_sip_uri_t* req_uri; belle_sip_header_t* accept_header; if (op->refresher){ belle_sip_refresher_stop(op->refresher); belle_sip_object_unref(op->refresher); op->refresher=NULL; } op->type=SalOpRegister; sal_op_set_from(op,from); sal_op_set_to(op,from); sal_op_set_route(op,proxy); req = sal_op_build_request(op,"REGISTER"); req_uri = belle_sip_request_get_uri(req); belle_sip_uri_set_user(req_uri,NULL); /*remove userinfo if any*/ if (op->base.root->use_dates){ time_t curtime=time(NULL); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_date_create_from_time(&curtime))); } accept_header = belle_sip_header_create("Accept", "application/sdp, text/plain, application/vnd.gsma.rcs-ft-http+xml"); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req), accept_header); belle_sip_message_set_header(BELLE_SIP_MESSAGE(req),(belle_sip_header_t*)sal_op_create_contact(op)); if (old_contact) { belle_sip_header_contact_t *contact=belle_sip_header_contact_create((const belle_sip_header_address_t *)old_contact); if (contact) { char * tmp; belle_sip_header_contact_set_expires(contact,0); /*remove old aor*/ belle_sip_message_add_header(BELLE_SIP_MESSAGE(req), BELLE_SIP_HEADER(contact)); tmp = belle_sip_object_to_string(contact); ms_message("Clearing contact [%s] for op [%p]",tmp,op); ms_free(tmp); } else { ms_error("Cannot add old contact header to op [%p]",op); } } return sal_op_send_and_create_refresher(op,req,expires,register_refresher_listener); }
int sal_call_update(SalOp *op, const char *subject, bool_t no_user_consent){ belle_sip_request_t *update; belle_sip_dialog_state_t state=belle_sip_dialog_get_state(op->dialog); /*check for dialog state*/ if ( state == BELLE_SIP_DIALOG_CONFIRMED) { if (no_user_consent) update=belle_sip_dialog_create_request(op->dialog,"UPDATE"); else update=belle_sip_dialog_create_request(op->dialog,"INVITE"); } else if (state == BELLE_SIP_DIALOG_EARLY) { update=belle_sip_dialog_create_request(op->dialog,"UPDATE"); } else { ms_error("Cannot update op [%p] with dialog [%p] in state [%s]",op, op->dialog,belle_sip_dialog_state_to_string(state)); return -1; } if (update){ belle_sip_message_add_header(BELLE_SIP_MESSAGE(update),belle_sip_header_create( "Subject", subject)); sal_op_fill_invite(op, update); return sal_op_send_request(op,update); } return -1; }
static void split_request_url(belle_http_request_t *req){ belle_generic_uri_t *uri=belle_http_request_get_uri(req); belle_generic_uri_t *new_uri; char *host_value; const char *path; if (belle_generic_uri_get_host(uri)==NULL && req->orig_uri!=NULL) return;/*already processed request uri*/ path=belle_generic_uri_get_path(uri); if (path==NULL) path="/"; new_uri=belle_generic_uri_new(); belle_generic_uri_set_path(new_uri,path); belle_generic_uri_set_query(new_uri, belle_generic_uri_get_query(uri)); if (belle_generic_uri_get_port(uri)>0) host_value=belle_sip_strdup_printf("%s:%i",belle_generic_uri_get_host(uri),belle_generic_uri_get_port(uri)); else host_value=belle_sip_strdup(belle_generic_uri_get_host(uri)); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Host",host_value)); belle_sip_free(host_value); SET_OBJECT_PROPERTY(req,orig_uri,uri); belle_http_request_set_uri(req,new_uri); }
static void make_supported_header(Sal *sal){ bctbx_list_t *it; char *alltags=NULL; size_t buflen=64; size_t written=0; if (sal->supported){ belle_sip_object_unref(sal->supported); sal->supported=NULL; } for(it=sal->supported_tags;it!=NULL;it=it->next){ const char *tag=(const char*)it->data; size_t taglen=strlen(tag); if (alltags==NULL || (written+taglen+1>=buflen)) alltags=ms_realloc(alltags,(buflen=buflen*2)); written+=snprintf(alltags+written,buflen-written,it->next ? "%s, " : "%s",tag); } if (alltags){ sal->supported=belle_sip_header_create("Supported",alltags); if (sal->supported){ belle_sip_object_ref(sal->supported); } ms_free(alltags); } }
static void add_message_accept(belle_sip_message_t *msg){ belle_sip_message_add_header(msg,belle_sip_header_create("Accept","text/plain, message/external-body, application/im-iscomposing+xml")); }
belle_sip_header_t * sal_make_supported_header(Sal *sal){ return belle_sip_header_create("Supported","replaces, outbound"); }
static void add_message_accept(belle_sip_message_t *msg){ belle_sip_message_add_header(msg,belle_sip_header_create("Accept","text/plain, message/external-body, application/im-iscomposing+xml, xml/cipher, application/vnd.gsma.rcs-ft-http+xml, application/cipher.vnd.gsma.rcs-ft-http+xml")); }
static void process_request_event(void *ud, const belle_sip_request_event_t *event) { Sal *sal=(Sal*)ud; SalOp* op=NULL; belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_dialog_t* dialog=belle_sip_request_event_get_dialog(event); belle_sip_header_address_t* origin_address; belle_sip_header_address_t* address; belle_sip_header_from_t* from_header; belle_sip_header_to_t* to; belle_sip_response_t* resp; belle_sip_header_t *evh; const char *method=belle_sip_request_get_method(req); from_header=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_from_t); if (dialog) { op=(SalOp*)belle_sip_dialog_get_application_data(dialog); if (op==NULL || op->state==SalOpStateTerminated){ ms_warning("Receiving request for null or terminated op [%p], ignored",op); return; } }else if (strcmp("INVITE",method)==0) { op=sal_op_new(sal); op->dir=SalOpDirIncoming; sal_op_call_fill_cbs(op); }else if ((strcmp("SUBSCRIBE",method)==0 || strcmp("NOTIFY",method)==0) && (evh=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Event"))!=NULL) { op=sal_op_new(sal); op->dir=SalOpDirIncoming; if (strncmp(belle_sip_header_get_unparsed_value(evh),"presence",strlen("presence"))==0){ sal_op_presence_fill_cbs(op); }else sal_op_subscribe_fill_cbs(op); }else if (strcmp("MESSAGE",method)==0) { op=sal_op_new(sal); op->dir=SalOpDirIncoming; sal_op_message_fill_cbs(op); }else if (strcmp("OPTIONS",method)==0) { resp=belle_sip_response_create_from_request(req,200); belle_sip_provider_send_response(sal->prov,resp); return; }else if (strcmp("INFO",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*INFO out of call dialogs are not allowed*/ belle_sip_provider_send_response(sal->prov,resp); return; }else if (strcmp("BYE",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*out of dialog BYE */ belle_sip_provider_send_response(sal->prov,resp); return; }else if (strcmp("CANCEL",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*out of dialog CANCEL */ belle_sip_provider_send_response(sal->prov,resp); return; }else if (sal->enable_test_features && strcmp("PUBLISH",method)==0) { resp=belle_sip_response_create_from_request(req,200);/*out of dialog BYE */ belle_sip_message_add_header((belle_sip_message_t*)resp,belle_sip_header_create("SIP-Etag","4441929FFFZQOA")); belle_sip_provider_send_response(sal->prov,resp); return; }else { ms_error("sal process_request_event not implemented yet for method [%s]",belle_sip_request_get_method(req)); resp=belle_sip_response_create_from_request(req,501); belle_sip_provider_send_response(sal->prov,resp); return; } if (!op->base.from_address) { address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header)) ,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header))); sal_op_set_from_address(op,(SalAddress*)address); belle_sip_object_unref(address); } if (!op->base.to_address) { to=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_to_t); address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(to)) ,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(to))); sal_op_set_to_address(op,(SalAddress*)address); belle_sip_object_unref(address); } if (!op->base.origin) { /*set origin uri*/ origin_address=belle_sip_header_address_create(NULL,belle_sip_request_extract_origin(req)); __sal_op_set_network_origin_address(op,(SalAddress*)origin_address); belle_sip_object_unref(origin_address); } if (!op->base.remote_ua) { sal_op_set_remote_ua(op,BELLE_SIP_MESSAGE(req)); } if (!op->base.call_id) { op->base.call_id=ms_strdup(belle_sip_header_call_id_get_call_id(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req), belle_sip_header_call_id_t)))); } /*It is worth noting that proxies can (and will) remove this header field*/ sal_op_set_privacy_from_message(op,(belle_sip_message_t*)req); sal_op_assign_recv_headers(op,(belle_sip_message_t*)req); if (op->callbacks.process_request_event) { op->callbacks.process_request_event(op,event); } else { ms_error("sal process_request_event not implemented yet"); } }
static void process_response_event(belle_sip_listener_t *user_ctx, const belle_sip_response_event_t *event){ belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event); belle_sip_response_t* response = belle_sip_response_event_get_response(event); belle_sip_request_t* request=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction)); int response_code = belle_sip_response_get_status_code(response); belle_sip_refresher_t* refresher=(belle_sip_refresher_t*)user_ctx; belle_sip_header_contact_t *contact; if (refresher && (client_transaction !=refresher->transaction)) return; /*not for me*/ set_or_update_dialog(refresher,belle_sip_response_event_get_dialog(event)); /*success case:*/ if (response_code>=200 && response_code<300){ refresher->auth_failures=0; refresher->number_of_retry=0; /*great, success*/ if (strcmp(belle_sip_request_get_method(request),"PUBLISH")==0) { /*search for etag*/ belle_sip_header_t* etag=belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"SIP-ETag"); if (etag) { belle_sip_header_t* sip_if_match = belle_sip_header_create("SIP-If-Match",belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(etag))); /*update request for next refresh*/ belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),"SIP-If-Match"); belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),sip_if_match); } else if (refresher->target_expires > 0){ belle_sip_warning("Refresher [%p] received 200ok to a publish without etag",refresher); } } /*update expire if needed*/ set_expires_from_trans(refresher); if (refresher->target_expires<=0) { belle_sip_refresher_stop(refresher); /*doesn't not make sense to refresh if expire =0;*/ } else { /*remove all contact with expire = 0 from request if any, because no need to refresh them*/ const belle_sip_list_t * contact_list= belle_sip_message_get_headers(BELLE_SIP_MESSAGE(request),BELLE_SIP_CONTACT); belle_sip_list_t *iterator, *head; if (contact_list) { for (iterator=head=belle_sip_list_copy(contact_list);iterator!=NULL;iterator=iterator->next) { belle_sip_header_contact_t *contact_for_expire = (belle_sip_header_contact_t *)(iterator->data); if (belle_sip_header_contact_get_expires(contact_for_expire) == 0) { belle_sip_message_remove_header_from_ptr(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(contact_for_expire)); } } belle_sip_list_free(head); } } if (refresher->state==started) { if (!refresher->first_acknoleged_request) belle_sip_object_ref(refresher->first_acknoleged_request = request); if (is_contact_address_acurate(refresher,request)) { schedule_timer(refresher); /*re-arm timer*/ } else { belle_sip_message("belle_sip_refresher_start(): refresher [%p] is resubmitting request because contact sent was not correct in original request.",refresher); belle_sip_refresher_refresh(refresher,refresher->target_expires); return; } } else belle_sip_message("Refresher [%p] not scheduling next refresh, because it was stopped",refresher); }else{/*special error cases*/ switch (response_code) { case 301: case 302: contact=belle_sip_message_get_header_by_type(response,belle_sip_header_contact_t); if (contact){ belle_sip_uri_t *uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact)); if (uri && belle_sip_refresher_refresh_internal(refresher,refresher->target_expires,TRUE,&refresher->auth_events,uri)==0) return; } break; case 401: case 407: refresher->auth_failures++; if (refresher->auth_failures>1){ /*avoid looping with 407 or 401 */ belle_sip_warning("Authentication is failing constantly, %s",(refresher->target_expires>0)? "will retry later":"giving up."); if (refresher->target_expires>0) retry_later(refresher); refresher->auth_failures=0; /*reset auth failure*/ break; } if (refresher->auth_events) { refresher->auth_events=belle_sip_list_free_with_data(refresher->auth_events,(void (*)(void*))belle_sip_auth_event_destroy); } if (belle_sip_refresher_refresh_internal(refresher,refresher->target_expires,TRUE,&refresher->auth_events,NULL)==0) return; /*ok, keep 401 internal*/ break; /*Else notify user of registration failure*/ case 403: /*In case of 403, we will retry later, just in case*/ if (refresher->target_expires>0) retry_later(refresher); break; case 412: if (strcmp(belle_sip_request_get_method(request),"PUBLISH")==0) { belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),"SIP-If-Match"); if (refresher->target_expires>0) { retry_later_on_io_error(refresher); return; /*do not notify this kind of error*/ } } else { if (refresher->target_expires>0) retry_later(refresher); } break; case 423:{ belle_sip_header_extension_t *min_expires=BELLE_SIP_HEADER_EXTENSION(belle_sip_message_get_header((belle_sip_message_t*)response,"Min-Expires")); if (min_expires){ const char *value=belle_sip_header_extension_get_value(min_expires); if (value){ int new_expires=atoi(value); if (new_expires>0 && refresher->state==started){ refresher->target_expires=new_expires; belle_sip_refresher_refresh(refresher,refresher->target_expires); return; } } }else belle_sip_warning("Receiving 423 but no min-expires header."); break; } case 491: { if (refresher->target_expires>0) { retry_later_on_io_error(refresher); return; /*do not notify this kind of error*/ } } case 505: case 501: /*irrecoverable errors, probably no need to retry later*/ break; default: /*for all other errors, retry later*/ if (refresher->target_expires>0) retry_later(refresher); break; } } if (refresher->listener) refresher->listener(refresher,refresher->user_data,response_code, belle_sip_response_get_reason_phrase(response)); }
static void prepare_query(CardDavRequest *request) { belle_http_request_listener_callbacks_t cbs = { 0 }; belle_http_request_listener_t *l = NULL; belle_generic_uri_t *uri = NULL; belle_http_request_t *req = NULL; belle_sip_memory_body_handler_t *bh = NULL; belle_sip_stack_t *stack = NULL; belle_http_provider_t *http_provider = NULL; belle_sip_set_log_level(BELLE_SIP_LOG_MESSAGE); uri = belle_generic_uri_parse(request->url); if (!uri) { belle_sip_error("Could not send request, URL %s is invalid", request->url); return; } req = belle_http_request_create(request->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), belle_sip_header_create("Depth", request->depth), NULL); if (!req) { belle_sip_object_unref(uri); belle_sip_error("Could not create request"); return; } bh = belle_sip_memory_body_handler_new_copy_from_buffer(request->body, strlen(request->body), NULL, NULL); belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(bh)); cbs.process_response = process_response_from_post_xml_rpc_request; cbs.process_io_error = process_io_error_from_post_xml_rpc_request; cbs.process_auth_requested = process_auth_requested_from_post_xml_rpc_request; l = belle_http_request_listener_create_from_callbacks(&cbs, request); stack = belle_sip_stack_new(NULL); http_provider = belle_sip_stack_create_http_provider(stack, "0.0.0.0"); request->request_in_progress = 1; belle_http_provider_send_request(http_provider, req, l); while (request->request_in_progress) { belle_sip_stack_sleep(stack, 0); } }
static void subscribe_test(void) { belle_sip_listener_callbacks_t client_callbacks; belle_sip_listener_callbacks_t server_callbacks; belle_sip_request_t* req; belle_sip_client_transaction_t* trans; belle_sip_header_route_t* destination_route; const char* identity = "sip:" USERNAME "@" SIPDOMAIN ; const char* domain="sip:" SIPDOMAIN ; endpoint_t* client,*server; belle_sip_uri_t *dest_uri; belle_sip_refresher_t* refresher; belle_sip_header_contact_t* contact=belle_sip_header_contact_new(); uint64_t begin; uint64_t end; memset(&client_callbacks,0,sizeof(belle_sip_listener_callbacks_t)); memset(&server_callbacks,0,sizeof(belle_sip_listener_callbacks_t)); client_callbacks.process_response_event=client_process_response_event; client_callbacks.process_auth_requested=client_process_auth_requested; server_callbacks.process_request_event=server_process_request_event; client = create_udp_endpoint(3452,&client_callbacks); server = create_udp_endpoint(6788,&server_callbacks); server->expire_in_contact=0; server->auth=digest_auth; dest_uri=(belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)belle_sip_listening_point_get_uri(server->lp)); belle_sip_uri_set_host(dest_uri,"127.0.0.1"); destination_route=belle_sip_header_route_create(belle_sip_header_address_create(NULL,dest_uri)); req=belle_sip_request_create( belle_sip_uri_parse(domain), "SUBSCRIBE", belle_sip_provider_create_call_id(client->provider), belle_sip_header_cseq_create(20,"SUBSCRIBE"), belle_sip_header_from_create2(identity,BELLE_SIP_RANDOM_TAG), belle_sip_header_to_create2(identity,NULL), belle_sip_header_via_new(), 70); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(contact)); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(1))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_create("Event","Presence"))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(destination_route)); trans=belle_sip_provider_create_client_transaction(client->provider,req); belle_sip_object_ref(trans);/*to avoid trans from being deleted before refresher can use it*/ belle_sip_client_transaction_send_request(trans); CU_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.fourHundredOne,1,1000)); req=belle_sip_client_transaction_create_authenticated_request(trans,NULL,NULL); belle_sip_object_unref(trans); trans=belle_sip_provider_create_client_transaction(client->provider,req); belle_sip_object_ref(trans); belle_sip_client_transaction_send_request(trans); CU_ASSERT_TRUE_FATAL(wait_for(server->stack,client->stack,&client->stat.twoHundredOk,1,1000)); /*maybe dialog should be automatically created*/ CU_ASSERT_PTR_NOT_NULL_FATAL(belle_sip_transaction_get_dialog(BELLE_SIP_TRANSACTION(trans))) refresher = belle_sip_client_transaction_create_refresher(trans); belle_sip_object_unref(trans); belle_sip_refresher_set_listener(refresher,belle_sip_refresher_listener,client); begin = belle_sip_time_ms(); CU_ASSERT_TRUE(wait_for(server->stack,client->stack,&client->stat.refreshOk,3,4000)); end = belle_sip_time_ms(); CU_ASSERT_TRUE(end-begin>=3000); CU_ASSERT_TRUE(end-begin<5000); /*unsubscribe twice to make sure refresh operation can be safely cascaded*/ belle_sip_refresher_refresh(refresher,0); belle_sip_refresher_refresh(refresher,0); belle_sip_refresher_stop(refresher); belle_sip_object_unref(refresher); destroy_endpoint(client); destroy_endpoint(server); }
static void server_process_request_event(void *obj, const belle_sip_request_event_t *event){ endpoint_t* endpoint = (endpoint_t*)obj; belle_sip_server_transaction_t* server_transaction =belle_sip_provider_create_server_transaction(endpoint->provider,belle_sip_request_event_get_request(event)); belle_sip_request_t* req = belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(server_transaction)); belle_sip_response_t* resp; belle_sip_header_contact_t* contact; belle_sip_header_expires_t* expires; belle_sip_header_authorization_t* authorization; belle_sip_header_via_t* via; const char* raw_authenticate_digest = "WWW-Authenticate: Digest " "algorithm=MD5, realm=\"" SIPDOMAIN "\", opaque=\"1bc7f9097684320\""; belle_sip_header_www_authenticate_t* www_authenticate=NULL; const char* auth_uri; const char* qop; unsigned char auth_ok=0; char local_resp[33]; belle_sip_message("caller_process_request_event received [%s] message",belle_sip_request_get_method(belle_sip_request_event_get_request(event))); switch (endpoint->auth) { case none: { auth_ok=1; break; } case digest_auth: case digest: { if ((authorization=belle_sip_message_get_header_by_type(req,belle_sip_header_authorization_t)) != NULL){ qop=belle_sip_header_authorization_get_qop(authorization); if (qop && strcmp(qop,"auth")==0) { compute_response_auth_qop( belle_sip_header_authorization_get_username(authorization) ,belle_sip_header_authorization_get_realm(authorization) ,PASSWD ,endpoint->nonce ,endpoint->nonce_count ,belle_sip_header_authorization_get_cnonce(authorization) ,belle_sip_header_authorization_get_qop(authorization) ,belle_sip_request_get_method(req) ,auth_uri=belle_sip_uri_to_string(belle_sip_header_authorization_get_uri(authorization)) ,local_resp); } else { /*digest*/ compute_response(belle_sip_header_authorization_get_username(authorization) ,belle_sip_header_authorization_get_realm(authorization) ,PASSWD ,endpoint->nonce ,belle_sip_request_get_method(req) ,auth_uri=belle_sip_uri_to_string(belle_sip_header_authorization_get_uri(authorization)) ,local_resp); } belle_sip_free((void*)auth_uri); auth_ok=strcmp(belle_sip_header_authorization_get_response(authorization),local_resp)==0; } if (auth_ok && endpoint->nonce_count<MAX_NC_COUNT ) {/*revoke nonce after MAX_NC_COUNT uses*/ if (endpoint->auth == digest ) { sprintf(endpoint->nonce,"%p",authorization); //*change the nonce for next auth*/ } else { endpoint->nonce_count++; } } else { auth_ok=0; www_authenticate=belle_sip_header_www_authenticate_parse(raw_authenticate_digest); sprintf(endpoint->nonce,"%p",authorization); //*change the nonce for next auth*/ belle_sip_header_www_authenticate_set_nonce(www_authenticate,endpoint->nonce); if (endpoint->auth == digest_auth) { belle_sip_header_www_authenticate_add_qop(www_authenticate,"auth"); if (endpoint->nonce_count>=MAX_NC_COUNT) { belle_sip_header_www_authenticate_set_stale(www_authenticate,1); endpoint->nonce_count=1; } } } } break; default: break; } if (auth_ok) { resp=belle_sip_response_create_from_request(belle_sip_request_event_get_request(event),200); if (!endpoint->expire_in_contact) { belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(expires=belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t))); } if (strcmp(belle_sip_request_get_method(req),"REGISTER")==0) { contact=belle_sip_message_get_header_by_type(req,belle_sip_header_contact_t); } else { contact=belle_sip_header_contact_new(); } if(endpoint->unreconizable_contact) { /*put an unexpected address*/ belle_sip_uri_set_host(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact)),"nimportequoi.com"); } belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(contact)); if (strcmp(belle_sip_request_get_method(req),"PUBLISH")==0) { belle_sip_header_t* sip_if_match=belle_sip_message_get_header(BELLE_SIP_MESSAGE(resp),"SIP-If-Match"); if (sip_if_match) { CU_ASSERT_STRING_EQUAL(belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(sip_if_match)),"blablietag"); } /*check for body*/ CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))); if (belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))) { CU_ASSERT_STRING_EQUAL(belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)),publish_body); } CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header_by_type(req,belle_sip_header_content_type_t)); CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header_by_type(req,belle_sip_header_content_length_t)); belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),belle_sip_header_create("SIP-ETag","blablietag")); } } else { resp=belle_sip_response_create_from_request(belle_sip_request_event_get_request(event),401); if (www_authenticate) belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(www_authenticate)); } if (endpoint->received) { via=belle_sip_message_get_header_by_type(req,belle_sip_header_via_t); belle_sip_header_via_set_received(via,endpoint->received); } belle_sip_server_transaction_send_response(server_transaction,resp); }
static void process_request_event(void *ud, const belle_sip_request_event_t *event) { Sal *sal=(Sal*)ud; SalOp* op=NULL; belle_sip_request_t* req = belle_sip_request_event_get_request(event); belle_sip_dialog_t* dialog=belle_sip_request_event_get_dialog(event); belle_sip_header_address_t* origin_address; belle_sip_header_address_t* address=NULL; belle_sip_header_from_t* from_header; belle_sip_header_to_t* to; belle_sip_response_t* resp; belle_sip_header_t *evh; const char *method=belle_sip_request_get_method(req); belle_sip_header_contact_t* remote_contact = belle_sip_message_get_header_by_type(req, belle_sip_header_contact_t); from_header=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_from_t); if (dialog) { op=(SalOp*)belle_sip_dialog_get_application_data(dialog); if (op == NULL && strcmp("NOTIFY",method) == 0) { /*special case for Dialog created by notify mathing subscribe*/ belle_sip_transaction_t * sub_trans = belle_sip_dialog_get_last_transaction(dialog); op = (SalOp*)belle_sip_transaction_get_application_data(sub_trans); } if (op==NULL || op->state==SalOpStateTerminated){ ms_warning("Receiving request for null or terminated op [%p], ignored",op); return; } }else{ /*handle the case where we are receiving a request with to tag but it is not belonging to any dialog*/ belle_sip_header_to_t *to = belle_sip_message_get_header_by_type(req, belle_sip_header_to_t); if ((strcmp("INVITE",method)==0 || strcmp("NOTIFY",method)==0) && (belle_sip_header_to_get_tag(to) != NULL)) { ms_warning("Receiving %s with to-tag but no know dialog here. Rejecting.", method); resp=belle_sip_response_create_from_request(req,481); belle_sip_provider_send_response(sal->prov,resp); return; /* by default (eg. when a to-tag is present), out of dialog ACK are automatically handled in lower layers (belle-sip) but in case it misses, it will be forwarded to us */ } else if (strcmp("ACK",method)==0 && (belle_sip_header_to_get_tag(to) == NULL)) { ms_warning("Receiving ACK without to-tag but no know dialog here. Ignoring"); return; } if (strcmp("INVITE",method)==0) { op=sal_op_new(sal); op->dir=SalOpDirIncoming; sal_op_call_fill_cbs(op); }else if ((strcmp("SUBSCRIBE",method)==0 || strcmp("NOTIFY",method)==0) && (evh=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Event"))!=NULL) { op=sal_op_new(sal); op->dir=SalOpDirIncoming; if (strncmp(belle_sip_header_get_unparsed_value(evh),"presence",strlen("presence"))==0){ sal_op_presence_fill_cbs(op); }else sal_op_subscribe_fill_cbs(op); }else if (strcmp("MESSAGE",method)==0) { op=sal_op_new(sal); op->dir=SalOpDirIncoming; sal_op_message_fill_cbs(op); }else if (strcmp("OPTIONS",method)==0) { resp=belle_sip_response_create_from_request(req,200); belle_sip_provider_send_response(sal->prov,resp); return; }else if (strcmp("INFO",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*INFO out of call dialogs are not allowed*/ belle_sip_provider_send_response(sal->prov,resp); return; }else if (strcmp("BYE",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*out of dialog BYE */ belle_sip_provider_send_response(sal->prov,resp); return; }else if (strcmp("CANCEL",method)==0) { resp=belle_sip_response_create_from_request(req,481);/*out of dialog CANCEL */ belle_sip_provider_send_response(sal->prov,resp); return; }else if (sal->enable_test_features && strcmp("PUBLISH",method)==0) { resp=belle_sip_response_create_from_request(req,200);/*out of dialog PUBLISH */ belle_sip_message_add_header((belle_sip_message_t*)resp,belle_sip_header_create("SIP-Etag","4441929FFFZQOA")); belle_sip_provider_send_response(sal->prov,resp); return; }else { ms_error("sal process_request_event not implemented yet for method [%s]",belle_sip_request_get_method(req)); resp=belle_sip_response_create_from_request(req,405); belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp) ,BELLE_SIP_HEADER(belle_sip_header_allow_create("INVITE, CANCEL, ACK, BYE, SUBSCRIBE, NOTIFY, MESSAGE, OPTIONS, INFO"))); belle_sip_provider_send_response(sal->prov,resp); return; } } if (!op->base.from_address) { if (belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header))) address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header)) ,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header))); else if ((belle_sip_header_address_get_absolute_uri(BELLE_SIP_HEADER_ADDRESS(from_header)))) address=belle_sip_header_address_create2(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header)) ,belle_sip_header_address_get_absolute_uri(BELLE_SIP_HEADER_ADDRESS(from_header))); else ms_error("Cannot not find from uri from request [%p]",req); sal_op_set_from_address(op,(SalAddress*)address); belle_sip_object_unref(address); } if( remote_contact ){ __sal_op_set_remote_contact(op, belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(remote_contact))); } if (!op->base.to_address) { to=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_to_t); if (belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(to))) address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(to)) ,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(to))); else if ((belle_sip_header_address_get_absolute_uri(BELLE_SIP_HEADER_ADDRESS(to)))) address=belle_sip_header_address_create2(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(to)) ,belle_sip_header_address_get_absolute_uri(BELLE_SIP_HEADER_ADDRESS(to))); else ms_error("Cannot not find to uri from request [%p]",req); sal_op_set_to_address(op,(SalAddress*)address); belle_sip_object_unref(address); } if (!op->base.origin) { /*set origin uri*/ origin_address=belle_sip_header_address_create(NULL,belle_sip_request_extract_origin(req)); __sal_op_set_network_origin_address(op,(SalAddress*)origin_address); belle_sip_object_unref(origin_address); } if (!op->base.remote_ua) { sal_op_set_remote_ua(op,BELLE_SIP_MESSAGE(req)); } if (!op->base.call_id) { op->base.call_id=ms_strdup(belle_sip_header_call_id_get_call_id(BELLE_SIP_HEADER_CALL_ID(belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req), belle_sip_header_call_id_t)))); } /*It is worth noting that proxies can (and will) remove this header field*/ sal_op_set_privacy_from_message(op,(belle_sip_message_t*)req); sal_op_assign_recv_headers(op,(belle_sip_message_t*)req); if (op->callbacks && op->callbacks->process_request_event) { op->callbacks->process_request_event(op,event); } else { ms_error("sal process_request_event not implemented yet"); } }