From 9ac3d64c8611a46c226b16eeac5b730c8d686fb8 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Thu, 9 May 2013 18:04:11 +0200 Subject: [PATCH] - implement contact +sip.instance parameter, with random uuid generated and store in linphonerc - add user-agent string in response --- coreapi/bellesip_sal/sal_impl.c | 48 +++++++++++++++++++++ coreapi/bellesip_sal/sal_impl.h | 4 ++ coreapi/bellesip_sal/sal_op_call.c | 20 ++++----- coreapi/bellesip_sal/sal_op_call_transfer.c | 8 ++-- coreapi/bellesip_sal/sal_op_impl.c | 30 ++++++++++--- coreapi/bellesip_sal/sal_op_presence.c | 8 ++-- coreapi/bellesip_sal/sal_op_registration.c | 1 + coreapi/linphonecore.c | 11 +++++ coreapi/misc.c | 19 -------- coreapi/private.h | 1 + include/sal/sal.h | 2 + 11 files changed, 110 insertions(+), 42 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index 367551c81..9bce7aee6 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -744,6 +744,54 @@ const SalCustomHeader *sal_op_get_recv_custom_header(SalOp *op){ return b->recv_custom_headers; } +void sal_set_uuid(Sal *sal, const char *uuid){ + if (sal->uuid){ + belle_sip_free(sal->uuid); + sal->uuid=NULL; + } + if (uuid) + sal->uuid=belle_sip_strdup(uuid); +} + +typedef struct { + unsigned int time_low; + unsigned short time_mid; + unsigned short time_hi_and_version; + unsigned char clock_seq_hi_and_reserved; + unsigned char clock_seq_low; + unsigned char node[6]; +} sal_uuid_t; +int sal_create_uuid(Sal*ctx, char *uuid, size_t len){ + sal_uuid_t uuid_struct; + int i; + int written; + + if (len==0) return -1; + /*create an UUID as described in RFC4122, 4.4 */ + belle_sip_random_bytes((unsigned char*)&uuid_struct, sizeof(sal_uuid_t)); + uuid_struct.clock_seq_hi_and_reserved&=~(1<<6); + uuid_struct.clock_seq_hi_and_reserved|=1<<7; + uuid_struct.time_hi_and_version&=~(0xf<<12); + uuid_struct.time_hi_and_version|=4<<12; + + written=snprintf(uuid,len,"%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", uuid_struct.time_low, uuid_struct.time_mid, + uuid_struct.time_hi_and_version, uuid_struct.clock_seq_hi_and_reserved, + uuid_struct.clock_seq_low); + if (written>len+13){ + ms_error("sal_create_uuid(): buffer is too short !"); + return -1; + } + for (i = 0; i < 6; i++) + written+=snprintf(uuid+written,len-written,"%2.2x", uuid_struct.node[i]); + uuid[len-1]='\0'; + sal_set_uuid(ctx,uuid); + return 0; +} +belle_sip_response_t* sal_create_response_from_request ( Sal* sal, belle_sip_request_t* req, int code ) { + belle_sip_response_t *resp=belle_sip_response_create_from_request(req,code); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(sal->user_agent)); + return resp; +} diff --git a/coreapi/bellesip_sal/sal_impl.h b/coreapi/bellesip_sal/sal_impl.h index 7e2eab0ef..12f071740 100644 --- a/coreapi/bellesip_sal/sal_impl.h +++ b/coreapi/bellesip_sal/sal_impl.h @@ -37,6 +37,7 @@ struct Sal{ int session_expires; unsigned int keep_alive; char *root_ca; + char *uuid; bool_t one_matching_codec; bool_t use_tcp_tls_keep_alive; bool_t nat_helper_enabled; @@ -109,6 +110,7 @@ int sal_op_send_request(SalOp* op, belle_sip_request_t* request); int sal_op_send_request_with_expires(SalOp* op, belle_sip_request_t* request,int expires); void sal_op_resend_request(SalOp* op, belle_sip_request_t* request); int sal_op_send_and_create_refresher(SalOp* op,belle_sip_request_t* req, int expires,belle_sip_refresher_listener_t listener ); +belle_sip_response_t *sal_op_create_response_from_request(SalOp *op, belle_sip_request_t *req, int code); void sal_process_authentication(SalOp *op); belle_sip_header_contact_t* sal_op_create_contact(SalOp *op,belle_sip_header_from_t* from_header) ; @@ -128,6 +130,8 @@ void sal_add_pending_auth(Sal *sal, SalOp *op); void sal_add_presence_info(belle_sip_message_t *notify, SalPresenceStatus online_status); +belle_sip_response_t *sal_create_response_from_request(Sal *sal, belle_sip_request_t *req, int code); + void sal_op_assign_recv_headers(SalOp *op, belle_sip_message_t *incoming); #endif /* SAL_IMPL_H_ */ diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index ae237acfa..7dd98f2ce 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -339,7 +339,7 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_ static void call_terminated(SalOp* op,belle_sip_server_transaction_t* server_transaction, belle_sip_request_t* request,int status_code) { belle_sip_response_t* resp; op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op)); - resp=belle_sip_response_create_from_request(request,status_code); + resp=sal_op_create_response_from_request(op,request,status_code); belle_sip_server_transaction_send_response(server_transaction,resp); return; @@ -419,7 +419,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t if(belle_sip_request_event_get_server_transaction(event)) { /*first answer 200 ok to cancel*/ belle_sip_server_transaction_send_response(server_transaction - ,belle_sip_response_create_from_request(req,200)); + ,sal_op_create_response_from_request(op,req,200)); /*terminate invite transaction*/ call_terminated(op ,op->pending_server_trans @@ -429,10 +429,10 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t } else { /*call leg does not exist*/ belle_sip_server_transaction_send_response(server_transaction - ,belle_sip_response_create_from_request(req,481)); + ,sal_op_create_response_from_request(op,req,481)); } } else if (strcmp("PRACK",belle_sip_request_get_method(req))==0) { - resp=belle_sip_response_create_from_request(req,200); + resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } else { belle_sip_error("Unexpected method [%s] for dialog state BELLE_SIP_DIALOG_EARLY"); @@ -459,7 +459,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t }*/ op->base.root->callbacks.call_ack(op); } else if(strcmp("BYE",belle_sip_request_get_method(req))==0) { - resp=belle_sip_response_create_from_request(req,200); + resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op)); op->state=SalOpStateTerminating; @@ -486,14 +486,14 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t op->base.root->callbacks.vfu_request(op); } - resp=belle_sip_response_create_from_request(req,200); + resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); }else if (strcmp("REFER",belle_sip_request_get_method(req))==0) { sal_op_process_refer(op,event); } else if (strcmp("NOTIFY",belle_sip_request_get_method(req))==0) { sal_op_call_process_notify(op,event); } else if (strcmp("OPTIONS",belle_sip_request_get_method(req))==0) { - resp=belle_sip_response_create_from_request(req,200); + resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } else{ ms_error("unexpected method [%s] for dialog [%p]",belle_sip_request_get_method(req),op->dialog); @@ -587,7 +587,7 @@ static void handle_offer_answer_response(SalOp* op, belle_sip_response_t* respon 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 = belle_sip_response_create_from_request(req,status_code); + belle_sip_response_t* ringing_response = sal_op_create_response_from_request(op,req,status_code); if (early_media){ handle_offer_answer_response(op,ringing_response); } @@ -618,7 +618,7 @@ int sal_call_accept(SalOp*h){ } /* sends a 200 OK */ - response = belle_sip_response_create_from_request(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(h->pending_server_trans)),200); + 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"); @@ -676,7 +676,7 @@ int sal_call_decline(SalOp *op, SalReason reason, const char *redirection /*opti ms_error("Unexpected decline reason [%i]",reason); /* no break */ } - response = belle_sip_response_create_from_request(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans)),status); + response = sal_op_create_response_from_request(op,belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans)),status); if (contact) belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(contact)); belle_sip_server_transaction_send_response(op->pending_server_trans,response); return 0; diff --git a/coreapi/bellesip_sal/sal_op_call_transfer.c b/coreapi/bellesip_sal/sal_op_call_transfer.c index 4062bb30a..16f7500f3 100644 --- a/coreapi/bellesip_sal/sal_op_call_transfer.c +++ b/coreapi/bellesip_sal/sal_op_call_transfer.c @@ -179,13 +179,13 @@ void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event){ sal_op_set_referred_by(op,referred_by); } refer_to_uri_str=belle_sip_uri_to_string(refer_to_uri); - resp = belle_sip_response_create_from_request(req,202); + resp = sal_op_create_response_from_request(op,req,202); belle_sip_server_transaction_send_response(server_transaction,resp); op->base.root->callbacks.refer_received(op->base.root,op,refer_to_uri_str); belle_sip_free(refer_to_uri_str); } else { ms_warning("cannot do anything with the refer without destination\n"); - resp = belle_sip_response_create_from_request(req,501); + resp = sal_op_create_response_from_request(op,req,501); belle_sip_server_transaction_send_response(server_transaction,resp); } @@ -219,13 +219,13 @@ void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *even status=SalReferFailed; } belle_sip_object_unref(sipfrag); - resp = belle_sip_response_create_from_request(req,200); + resp = sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); op->base.root->callbacks.notify_refer(op,status); } }else{ ms_error("Notify without sipfrag, trashing"); - resp = belle_sip_response_create_from_request(req,501); + resp = sal_op_create_response_from_request(op,req,501); belle_sip_server_transaction_send_response(server_transaction,resp); } } diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 981eed9b2..0aa6ce1b1 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -76,7 +76,9 @@ int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **userna *username=op->auth_info?op->auth_info->username:NULL; return 0; } -belle_sip_header_contact_t* sal_op_create_contact(SalOp *op,belle_sip_header_from_t* from_header) { + +/* +belle_sip_header_contact_t* sal_op_create_contact(SalOp *op, belle_sip_header_from_t* from_header) { belle_sip_uri_t* req_uri = (belle_sip_uri_t*)belle_sip_object_clone((belle_sip_object_t*)belle_sip_header_address_get_uri((belle_sip_header_address_t*)from_header)); belle_sip_header_contact_t* contact_header; if (sal_op_get_contact_address(op)) { @@ -89,6 +91,24 @@ belle_sip_header_contact_t* sal_op_create_contact(SalOp *op,belle_sip_header_fro belle_sip_object_unref(req_uri); return contact_header; } +*/ + +belle_sip_header_contact_t* sal_op_create_contact(SalOp *op, belle_sip_header_from_t* from_header){ + belle_sip_header_contact_t* contact_header; + if (sal_op_get_contact_address(op)) { + contact_header = belle_sip_header_contact_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_contact_address(op))); + } else { + contact_header= belle_sip_header_contact_new(); + } + if (op->base.root->uuid){ + if (belle_sip_parameters_has_parameter(BELLE_SIP_PARAMETERS(contact_header),"+sip.instance")==0){ + char *instance_id=belle_sip_strdup_printf("\"\"",op->base.root->uuid); + belle_sip_parameters_set_parameter(BELLE_SIP_PARAMETERS(contact_header),"+sip.instance",instance_id); + belle_sip_free(instance_id); + } + } + return contact_header; +} belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) { belle_sip_header_from_t* from_header; @@ -116,7 +136,9 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) { return req; } - +belle_sip_response_t *sal_op_create_response_from_request(SalOp *op, belle_sip_request_t *req, int code){ + return sal_create_response_from_request(op->base.root,req,code); +} /*ping: main purpose is to obtain its own contact address behind firewalls*/ int sal_ping(SalOp *op, const char *from, const char *to){ @@ -133,7 +155,6 @@ void sal_op_set_remote_ua(SalOp*op,belle_sip_message_t* message) { } } - int sal_op_send_request_with_expires(SalOp* op, belle_sip_request_t* request,int expires) { belle_sip_header_expires_t* expires_header=(belle_sip_header_expires_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_EXPIRES); @@ -213,8 +234,7 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req if (add_contact) { contact = sal_op_create_contact(op,belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request),belle_sip_header_from_t)); - belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_CONTACT); - belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(contact)); + belle_sip_message_set_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(contact)); } if (!belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_AUTHORIZATION) && !belle_sip_message_get_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_PROXY_AUTHORIZATION)) { diff --git a/coreapi/bellesip_sal/sal_op_presence.c b/coreapi/bellesip_sal/sal_op_presence.c index 5268c063a..b325db9d7 100644 --- a/coreapi/bellesip_sal/sal_op_presence.c +++ b/coreapi/bellesip_sal/sal_op_presence.c @@ -548,7 +548,7 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques sub_state=SalSubscribeActive; op->base.root->callbacks.notify_presence(op,sub_state, estatus,NULL); - resp=belle_sip_response_create_from_request(req,200); + resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } else if (strcmp("SUBSCRIBE",belle_sip_request_get_method(req))==0) { /*either a refresh of an unsubscribe*/ @@ -556,7 +556,7 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques op->base.root->callbacks.subscribe_received(op,sal_op_get_from(op)); } else if(expires) { ms_message("Unsubscribe received from [%s]",sal_op_get_from(op)); - resp=belle_sip_response_create_from_request(req,200); + resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } } @@ -610,7 +610,7 @@ int sal_unsubscribe(SalOp *op){ int sal_subscribe_accept(SalOp *op){ belle_sip_request_t* req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans)); belle_sip_header_expires_t* expires = belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t); - belle_sip_response_t* resp = belle_sip_response_create_from_request(req,200); + belle_sip_response_t* resp = sal_op_create_response_from_request(op,req,200); belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(expires)); belle_sip_server_transaction_send_response(op->pending_server_trans,resp); return 0; @@ -624,7 +624,7 @@ int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_ belle_sip_request_t* notify=belle_sip_dialog_create_request(op->dialog,"NOTIFY"); sal_add_presence_info(BELLE_SIP_MESSAGE(notify),status); /*FIXME, what about expires ??*/ belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify) - ,BELLE_SIP_HEADER(belle_sip_header_subscription_state_create(BELLE_SIP_SUBSCRIPTION_STATE_ACTIVE,600))); + ,BELLE_SIP_HEADER(belle_sip_header_subscription_state_create(BELLE_SIP_SUBSCRIPTION_STATE_ACTIVE,600))); return sal_op_send_request(op,notify); } int sal_notify_close(SalOp *op){ diff --git a/coreapi/bellesip_sal/sal_op_registration.c b/coreapi/bellesip_sal/sal_op_registration.c index 2bda3266c..f40444e99 100644 --- a/coreapi/bellesip_sal/sal_op_registration.c +++ b/coreapi/bellesip_sal/sal_op_registration.c @@ -85,6 +85,7 @@ int sal_register(SalOp *op, const char *proxy, const char *from, int expires){ 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))); } + belle_sip_message_set_header(BELLE_SIP_MESSAGE(req),(belle_sip_header_t*)sal_op_create_contact(op,NULL)); return sal_op_send_and_create_refresher(op,req,expires,register_refresher_listener); } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 3a866a364..6a687726e 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1216,10 +1216,21 @@ void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const lc->vtable.global_state_changed(lc,gstate,message); } } + static void misc_config_read (LinphoneCore *lc) { LpConfig *config=lc->config; + const char *uuid; + lc->max_call_logs=lp_config_get_int(config,"misc","history_max_size",15); lc->max_calls=lp_config_get_int(config,"misc","max_calls",NB_MAX_CALLS); + + uuid=lp_config_get_string(config,"misc","uuid",NULL); + if (!uuid){ + char tmp[64]; + sal_create_uuid(lc->sal,tmp,sizeof(tmp)); + lp_config_set_string(config,"misc","uuid",tmp); + }else + sal_set_uuid(lc->sal, uuid); } diff --git a/coreapi/misc.c b/coreapi/misc.c index cd62a522f..c5177cae9 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -1151,26 +1151,7 @@ int linphone_core_get_local_ip_for(int type, const char *dest, char *result){ return 0; } -#ifndef WIN32 -#include - - - -void _linphone_core_configure_resolver(){ -/*bionic declares _res but does not define nor export it !!*/ -#ifdef ANDROID - /*timeout and attempts are the same as retrans and retry, but are android specific names.*/ - setenv("RES_OPTIONS","timeout:2 attempts:2 retrans:2 retry:2",1); -#else - res_init(); - _res.retrans=2; /*retransmit every two seconds*/ - _res.retry=2; /*only two times per DNS server*/ -#endif -} - -#else void _linphone_core_configure_resolver(){ } -#endif diff --git a/coreapi/private.h b/coreapi/private.h index 838ee69b0..611436f0b 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -738,6 +738,7 @@ typedef enum _LinphoneToneID{ }LinphoneToneID; void linphone_core_play_named_tone(LinphoneCore *lc, LinphoneToneID id); bool_t linphone_core_tone_indications_enabled(LinphoneCore*lc); +const char *linphone_core_create_uuid(LinphoneCore *lc); #ifdef __cplusplus } diff --git a/include/sal/sal.h b/include/sal/sal.h index 5274e02f9..719e42d44 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -407,6 +407,8 @@ void sal_set_root_ca(Sal* ctx, const char* rootCa); const char *sal_get_root_ca(Sal* ctx); void sal_verify_server_certificates(Sal *ctx, bool_t verify); void sal_verify_server_cn(Sal *ctx, bool_t verify); +void sal_set_uuid(Sal*ctx, const char *uuid); +int sal_create_uuid(Sal*ctx, char *uuid, size_t len); int sal_iterate(Sal *sal); MSList * sal_get_pending_auths(Sal *sal);