- implement contact +sip.instance parameter, with random uuid generated and store in linphonerc

- add user-agent string in response
This commit is contained in:
Simon Morlat 2013-05-09 18:04:11 +02:00
parent 22f396386a
commit 9ac3d64c86
11 changed files with 110 additions and 42 deletions

View file

@ -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;
}

View file

@ -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_ */

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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("\"<urn:uuid:%s>\"",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)) {

View file

@ -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){

View file

@ -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);
}

View file

@ -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);
}

View file

@ -1151,26 +1151,7 @@ int linphone_core_get_local_ip_for(int type, const char *dest, char *result){
return 0;
}
#ifndef WIN32
#include <resolv.h>
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

View file

@ -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
}

View file

@ -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);