Commit 29e0109c authored by jehan's avatar jehan
Browse files

-Publish are now implemented using LinphoneEvent API.

parent 2ebbc1aa
...@@ -236,15 +236,6 @@ int sal_subscribe(SalOp *op, const char *from, const char *to, const char *event ...@@ -236,15 +236,6 @@ int sal_subscribe(SalOp *op, const char *from, const char *to, const char *event
return -1; return -1;
} }
int sal_subscribe_refresh(SalOp *op) {
if (op->refresher) {
belle_sip_refresher_refresh(op->refresher,belle_sip_refresher_get_expires(op->refresher));
return 0;
}
ms_warning("sal_refresh_subscribe(): no refresher");
return -1;
}
int sal_unsubscribe(SalOp *op){ int sal_unsubscribe(SalOp *op){
if (op->refresher){ if (op->refresher){
const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(op->refresher); const belle_sip_transaction_t *tr=(const belle_sip_transaction_t*) belle_sip_refresher_get_transaction(op->refresher);
......
...@@ -789,3 +789,11 @@ bool_t sal_op_cnx_ip_to_0000_if_sendonly_enabled(SalOp *op) { ...@@ -789,3 +789,11 @@ bool_t sal_op_cnx_ip_to_0000_if_sendonly_enabled(SalOp *op) {
bool_t sal_op_is_forked_of(const SalOp *op1, const SalOp *op2){ bool_t sal_op_is_forked_of(const SalOp *op1, const SalOp *op2){
return op1->base.call_id && op2->base.call_id && strcmp(op1->base.call_id, op2->base.call_id) == 0; return op1->base.call_id && op2->base.call_id && strcmp(op1->base.call_id, op2->base.call_id) == 0;
} }
int sal_op_refresh(SalOp *op) {
if (op->refresher) {
belle_sip_refresher_refresh(op->refresher,belle_sip_refresher_get_expires(op->refresher));
return 0;
}
ms_warning("sal_refresh on op [%p] of type [%s] no refresher",op,sal_op_type_to_string(op));
return -1;
}
...@@ -25,17 +25,17 @@ static void publish_refresher_listener (belle_sip_refresher_t* refresher ...@@ -25,17 +25,17 @@ static void publish_refresher_listener (belle_sip_refresher_t* refresher
,const char* reason_phrase) { ,const char* reason_phrase) {
SalOp* op = (SalOp*)user_pointer; SalOp* op = (SalOp*)user_pointer;
const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(op->refresher); 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));
belle_sip_response_t *response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(last_publish_trans)); belle_sip_response_t *response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(last_publish_trans));
/*belle_sip_response_t* response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher)));*/
ms_message("Publish refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase?reason_phrase:"none",sal_op_get_proxy(op)); ms_message("Publish refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase?reason_phrase:"none",sal_op_get_proxy(op));
if (status_code==412){ if (status_code==0){
/*resubmit the request after removing the SIP-If-Match*/
belle_sip_message_remove_header((belle_sip_message_t*)last_publish,"SIP-If-Match");
belle_sip_refresher_refresh(op->refresher,BELLE_SIP_REFRESHER_REUSE_EXPIRES);
}else if (status_code==0){
op->base.root->callbacks.on_expire(op); op->base.root->callbacks.on_expire(op);
}else if (status_code>=200){ }else if (status_code>=200){
belle_sip_header_t *sip_etag;
const char *sip_etag_string = NULL;
if ((sip_etag = belle_sip_message_get_header(BELLE_SIP_MESSAGE(response), "SIP-ETag"))) {
sip_etag_string = belle_sip_header_get_unparsed_value(sip_etag);
}
sal_op_set_entity_tag(op, sip_etag_string);
sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL); sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL);
sal_op_assign_recv_headers(op,(belle_sip_message_t*)response); sal_op_assign_recv_headers(op,(belle_sip_message_t*)response);
op->base.root->callbacks.on_publish_response(op); op->base.root->callbacks.on_publish_response(op);
...@@ -60,42 +60,6 @@ void sal_op_publish_fill_cbs(SalOp *op) { ...@@ -60,42 +60,6 @@ void sal_op_publish_fill_cbs(SalOp *op) {
op->type=SalOpPublish; op->type=SalOpPublish;
} }
/*
* Sending a publish with 0 expires removes the event state and such request shall not contain a body.
* See RFC3903, section 4.5
*/
/*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");
if( req == NULL ){
return -1;
}
if (sal_op_get_contact_address(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","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),expires!=0 ? presence : NULL);
return belle_sip_refresher_refresh(op->refresher,expires);
}
}
int sal_publish(SalOp *op, const char *from, const char *to, const char *eventname, int expires, const SalBodyHandler *body_handler){ int sal_publish(SalOp *op, const char *from, const char *to, const char *eventname, int expires, const SalBodyHandler *body_handler){
belle_sip_request_t *req=NULL; belle_sip_request_t *req=NULL;
if(!op->refresher || !belle_sip_refresher_get_transaction(op->refresher)) { if(!op->refresher || !belle_sip_refresher_get_transaction(op->refresher)) {
...@@ -109,7 +73,11 @@ int sal_publish(SalOp *op, const char *from, const char *to, const char *eventna ...@@ -109,7 +73,11 @@ int sal_publish(SalOp *op, const char *from, const char *to, const char *eventna
if( req == NULL ){ if( req == NULL ){
return -1; return -1;
} }
if (sal_op_get_entity_tag(op)) {
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("SIP-If-Match", sal_op_get_entity_tag(op)));
}
if (sal_op_get_contact_address(op)){ if (sal_op_get_contact_address(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(sal_op_create_contact(op)));
} }
...@@ -131,3 +99,14 @@ int sal_publish(SalOp *op, const char *from, const char *to, const char *eventna ...@@ -131,3 +99,14 @@ int sal_publish(SalOp *op, const char *from, const char *to, const char *eventna
return belle_sip_refresher_refresh(op->refresher,expires==-1 ? BELLE_SIP_REFRESHER_REUSE_EXPIRES : expires); return belle_sip_refresher_refresh(op->refresher,expires==-1 ? BELLE_SIP_REFRESHER_REUSE_EXPIRES : expires);
} }
} }
int sal_op_unpublish(SalOp *op){
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);
belle_sip_message_set_body(BELLE_SIP_MESSAGE(last_req), NULL, 0);
belle_sip_refresher_refresh(op->refresher,0);
return 0;
}
return -1;
}
...@@ -1038,10 +1038,11 @@ static void register_failure(SalOp *op){ ...@@ -1038,10 +1038,11 @@ static void register_failure(SalOp *op){
} else { } else {
linphone_proxy_config_set_state(cfg,LinphoneRegistrationFailed,details); linphone_proxy_config_set_state(cfg,LinphoneRegistrationFailed,details);
} }
if (cfg->publish_op){ if (cfg->long_term_event){
/*prevent publish to be sent now until registration gets successful*/ /*prevent publish to be sent now until registration gets successful*/
sal_op_release(cfg->publish_op); linphone_event_terminate(cfg->long_term_event);
cfg->publish_op=NULL; linphone_event_unref(cfg->long_term_event);
cfg->long_term_event=NULL;
cfg->send_publish=cfg->publish; cfg->send_publish=cfg->publish;
} }
} }
...@@ -1137,7 +1138,13 @@ static void parse_presence_requested(SalOp *op, const char *content_type, const ...@@ -1137,7 +1138,13 @@ static void parse_presence_requested(SalOp *op, const char *content_type, const
} }
static void convert_presence_to_xml_requested(SalOp *op, SalPresenceModel *presence, const char *contact, char **content) { static void convert_presence_to_xml_requested(SalOp *op, SalPresenceModel *presence, const char *contact, char **content) {
linphone_notify_convert_presence_to_xml(op, presence, contact, content); /*for backward compatibility because still used by notify. No loguer used for publish*/
if(linphone_presence_model_get_presentity((LinphonePresenceModel*)presence) == NULL) {
LinphoneAddress * presentity = linphone_address_new(contact);
linphone_presence_model_set_presentity((LinphonePresenceModel*)presence, presentity);
}
*content = linphone_presence_model_to_xml((LinphonePresenceModel*)presence);
} }
static void notify_presence(SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model, const char *msg){ static void notify_presence(SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model, const char *msg){
......
...@@ -201,7 +201,7 @@ int linphone_event_update_subscribe(LinphoneEvent *lev, const LinphoneContent *b ...@@ -201,7 +201,7 @@ int linphone_event_update_subscribe(LinphoneEvent *lev, const LinphoneContent *b
} }
int linphone_event_refresh_subscribe(LinphoneEvent *lev) { int linphone_event_refresh_subscribe(LinphoneEvent *lev) {
return sal_subscribe_refresh(lev->op); return sal_op_refresh(lev->op);
} }
int linphone_event_accept_subscription(LinphoneEvent *lev){ int linphone_event_accept_subscription(LinphoneEvent *lev){
...@@ -291,6 +291,16 @@ int linphone_event_update_publish(LinphoneEvent* lev, const LinphoneContent* bod ...@@ -291,6 +291,16 @@ int linphone_event_update_publish(LinphoneEvent* lev, const LinphoneContent* bod
return linphone_event_send_publish(lev,body); return linphone_event_send_publish(lev,body);
} }
int linphone_event_refresh_publish(LinphoneEvent *lev) {
return sal_op_refresh(lev->op);
}
void linphone_event_pause_publish(LinphoneEvent *lev) {
if (lev->op) sal_op_stop_refreshing(lev->op);
}
void linphone_event_unpublish(LinphoneEvent *lev) {
lev->terminating = TRUE; /* needed to get clear event*/
if (lev->op) sal_op_unpublish(lev->op);
}
void linphone_event_set_user_data(LinphoneEvent *ev, void *up){ void linphone_event_set_user_data(LinphoneEvent *ev, void *up){
ev->userdata=up; ev->userdata=up;
} }
...@@ -320,7 +330,7 @@ void linphone_event_terminate(LinphoneEvent *lev){ ...@@ -320,7 +330,7 @@ void linphone_event_terminate(LinphoneEvent *lev){
if (lev->publish_state!=LinphonePublishNone){ if (lev->publish_state!=LinphonePublishNone){
if (lev->publish_state==LinphonePublishOk && lev->expires!=-1){ if (lev->publish_state==LinphonePublishOk && lev->expires!=-1){
sal_publish(lev->op,NULL,NULL,NULL,0,NULL); sal_publish(lev->op,NULL,NULL,NULL,0,NULL);
}else sal_op_stop_refreshing(lev->op); }else sal_op_unpublish(lev->op);
linphone_event_set_publish_state(lev,LinphonePublishCleared); linphone_event_set_publish_state(lev,LinphonePublishCleared);
return; return;
} }
......
...@@ -208,6 +208,21 @@ LINPHONE_PUBLIC int linphone_event_send_publish(LinphoneEvent *lev, const Linpho ...@@ -208,6 +208,21 @@ LINPHONE_PUBLIC int linphone_event_send_publish(LinphoneEvent *lev, const Linpho
**/ **/
LINPHONE_PUBLIC int linphone_event_update_publish(LinphoneEvent *lev, const LinphoneContent *body); LINPHONE_PUBLIC int linphone_event_update_publish(LinphoneEvent *lev, const LinphoneContent *body);
/**
* Refresh an outgoing publish keeping the same body.
* @param lev LinphoneEvent object.
* @return 0 if successful, -1 otherwise.
*/
LINPHONE_PUBLIC int linphone_event_refresh_publish(LinphoneEvent *lev);
/**
* Prevent an event from refreshing its publish.
* This is useful to let registrations to expire naturally (or) when the application wants to keep control on when
* refreshes are sent.
* The refreshing operations can be resumed with linphone_proxy_config_refresh_register().
* @param[in] cfg #LinphoneEvent object.
**/
LINPHONE_PUBLIC void linphone_event_pause_publish(LinphoneEvent *lev);
/** /**
* Return reason code (in case of error state reached). * Return reason code (in case of error state reached).
......
...@@ -6184,6 +6184,7 @@ void sip_config_uninit(LinphoneCore *lc) ...@@ -6184,6 +6184,7 @@ void sip_config_uninit(LinphoneCore *lc)
if (lc->sip_network_reachable) { if (lc->sip_network_reachable) {
for(elem=config->proxies;elem!=NULL;elem=ms_list_next(elem)){ for(elem=config->proxies;elem!=NULL;elem=ms_list_next(elem)){
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)(elem->data); LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)(elem->data);
_linphone_proxy_config_unpublish(cfg); /* to unpublish without changing the stored flag enable_publish */
_linphone_proxy_config_unregister(cfg); /* to unregister without changing the stored flag enable_register */ _linphone_proxy_config_unregister(cfg); /* to unregister without changing the stored flag enable_register */
} }
......
...@@ -261,6 +261,21 @@ LINPHONE_PUBLIC char * linphone_presence_model_get_contact(const LinphonePresenc ...@@ -261,6 +261,21 @@ LINPHONE_PUBLIC char * linphone_presence_model_get_contact(const LinphonePresenc
*/ */
LINPHONE_PUBLIC int linphone_presence_model_set_contact(LinphonePresenceModel *model, const char *contact); LINPHONE_PUBLIC int linphone_presence_model_set_contact(LinphonePresenceModel *model, const char *contact);
/**
* Sets the presentity of a presence model.
* @param[in] model The #LinphonePresenceModel object for which to set the contact.
* @param[in] presentity The presentity address to set (presentity is copied).
* @return 0 if successful, a value < 0 in case of error.
*/
LINPHONE_PUBLIC int linphone_presence_model_set_presentity(LinphonePresenceModel *model, const LinphoneAddress *presentity);
/**
* Gets the presentity of a presence model.
* @param[in] model The #LinphonePresenceModel object to get the contact from.
* @return A pointer to a const LinphoneAddress, or NULL if no contact is found.
*
*/
LINPHONE_PUBLIC const LinphoneAddress * linphone_presence_model_get_presentity(const LinphonePresenceModel *model);
/** /**
* Gets the first activity of a presence model (there is usually only one). * Gets the first activity of a presence model (there is usually only one).
* @param[in] model The #LinphonePresenceModel object to get the activity from. * @param[in] model The #LinphonePresenceModel object to get the activity from.
......
...@@ -67,6 +67,7 @@ struct _LinphonePresencePerson { ...@@ -67,6 +67,7 @@ struct _LinphonePresencePerson {
* This model is not complete. For example, it does not handle devices. * This model is not complete. For example, it does not handle devices.
*/ */
struct _LinphonePresenceModel { struct _LinphonePresenceModel {
LinphoneAddress *presentity; /* "The model seeks to describe the presentity, identified by a presentity URI.*/
void *user_data; void *user_data;
int refcnt; int refcnt;
MSList *services; /**< A list of _LinphonePresenceService structures. Also named tuples in the RFC. */ MSList *services; /**< A list of _LinphonePresenceService structures. Also named tuples in the RFC. */
...@@ -246,7 +247,8 @@ static void presence_model_find_open_basic_status(LinphonePresenceService *servi ...@@ -246,7 +247,8 @@ static void presence_model_find_open_basic_status(LinphonePresenceService *servi
static void presence_model_delete(LinphonePresenceModel *model) { static void presence_model_delete(LinphonePresenceModel *model) {
if (model == NULL) return; if (model == NULL) return;
if (model->presentity)
linphone_address_unref(model->presentity);
ms_list_for_each(model->services, (MSIterateFunc)linphone_presence_service_unref); ms_list_for_each(model->services, (MSIterateFunc)linphone_presence_service_unref);
ms_list_free(model->services); ms_list_free(model->services);
ms_list_for_each(model->persons, (MSIterateFunc)linphone_presence_person_unref); ms_list_for_each(model->persons, (MSIterateFunc)linphone_presence_person_unref);
...@@ -671,7 +673,22 @@ int linphone_presence_model_clear_persons(LinphonePresenceModel *model) { ...@@ -671,7 +673,22 @@ int linphone_presence_model_clear_persons(LinphonePresenceModel *model) {
return 0; return 0;
} }
int linphone_presence_model_set_presentity(LinphonePresenceModel *model, const LinphoneAddress *presentity) {
if (model->presentity) {
linphone_address_unref(model->presentity);
model->presentity = NULL;
}
if (presentity) {
model->presentity=linphone_address_clone(presentity);
linphone_address_clean(model->presentity);
}
return 0;
}
const LinphoneAddress * linphone_presence_model_get_presentity(const LinphonePresenceModel *model) {
return model->presentity;
}
/***************************************************************************** /*****************************************************************************
* PRESENCE SERVICE FUNCTIONS TO GET ACCESS TO ALL FUNCTIONALITIES * * PRESENCE SERVICE FUNCTIONS TO GET ACCESS TO ALL FUNCTIONALITIES *
...@@ -1772,24 +1789,28 @@ static void write_xml_presence_person_obj(LinphonePresencePerson *person, struct ...@@ -1772,24 +1789,28 @@ static void write_xml_presence_person_obj(LinphonePresencePerson *person, struct
if (err < 0) *st->err = err; if (err < 0) *st->err = err;
} }
void linphone_notify_convert_presence_to_xml(SalOp *op, SalPresenceModel *presence, const char *contact, char **content) { char *linphone_presence_model_to_xml(LinphonePresenceModel *model) {
LinphonePresenceModel *model; xmlBufferPtr buf = NULL;
xmlBufferPtr buf; xmlTextWriterPtr writer = NULL;
xmlTextWriterPtr writer;
int err; int err;
char *contact = NULL;
if ((contact == NULL) || (content == NULL)) return; char * content = NULL;
model = (LinphonePresenceModel *)presence; if (model->presentity) {
contact = linphone_address_as_string_uri_only(model->presentity);
} else {
ms_error("Cannot convert presence model [%p] to xml because no presentity set", model);
goto end;
}
buf = xmlBufferCreate(); buf = xmlBufferCreate();
if (buf == NULL) { if (buf == NULL) {
ms_error("Error creating the XML buffer"); ms_error("Error creating the XML buffer");
return; goto end;
} }
writer = xmlNewTextWriterMemory(buf, 0); writer = xmlNewTextWriterMemory(buf, 0);
if (writer == NULL) { if (writer == NULL) {
ms_error("Error creating the XML writer"); ms_error("Error creating the XML writer");
return; goto end;
} }
xmlTextWriterSetIndent(writer,1); xmlTextWriterSetIndent(writer,1);
...@@ -1815,7 +1836,7 @@ void linphone_notify_convert_presence_to_xml(SalOp *op, SalPresenceModel *presen ...@@ -1815,7 +1836,7 @@ void linphone_notify_convert_presence_to_xml(SalOp *op, SalPresenceModel *presen
} else { } else {
struct _presence_service_obj_st st={0}; struct _presence_service_obj_st st={0};
st.writer = writer; st.writer = writer;
st.contact = contact; st.contact = contact; /*default value*/
st.err = &err; st.err = &err;
ms_list_for_each2(model->services, (MSIterate2Func)write_xml_presence_service_obj, &st); ms_list_for_each2(model->services, (MSIterate2Func)write_xml_presence_service_obj, &st);
} }
...@@ -1842,10 +1863,14 @@ void linphone_notify_convert_presence_to_xml(SalOp *op, SalPresenceModel *presen ...@@ -1842,10 +1863,14 @@ void linphone_notify_convert_presence_to_xml(SalOp *op, SalPresenceModel *presen
} }
if (err > 0) { if (err > 0) {
/* xmlTextWriterEndDocument returns the size of the content. */ /* xmlTextWriterEndDocument returns the size of the content. */
*content = ms_strdup((char *)buf->content); content = ms_strdup((char *)buf->content);
} }
xmlFreeTextWriter(writer);
xmlBufferFree(buf); end:
if (contact) ms_free(contact);
if (writer) xmlFreeTextWriter(writer);
if (buf) xmlBufferFree(buf);
return content;
} }
void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model){ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model){
......
...@@ -398,6 +398,8 @@ void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrat ...@@ -398,6 +398,8 @@ void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrat
void linphone_proxy_config_stop_refreshing(LinphoneProxyConfig *obj); void linphone_proxy_config_stop_refreshing(LinphoneProxyConfig *obj);
void linphone_proxy_config_write_all_to_config_file(LinphoneCore *lc); void linphone_proxy_config_write_all_to_config_file(LinphoneCore *lc);
void _linphone_proxy_config_release(LinphoneProxyConfig *cfg); void _linphone_proxy_config_release(LinphoneProxyConfig *cfg);
void _linphone_proxy_config_unpublish(LinphoneProxyConfig *obj);
/* /*
* returns service route as defined in as defined by rfc3608, might be a list instead of just one. * returns service route as defined in as defined by rfc3608, might be a list instead of just one.
* Can be NULL * Can be NULL
...@@ -595,7 +597,6 @@ struct _LinphoneProxyConfig ...@@ -595,7 +597,6 @@ struct _LinphoneProxyConfig
int auth_failures; int auth_failures;
char *dial_prefix; char *dial_prefix;
LinphoneRegistrationState state; LinphoneRegistrationState state;
SalOp *publish_op;
LinphoneAVPFMode avpf_mode; LinphoneAVPFMode avpf_mode;
bool_t commit; bool_t commit;
...@@ -615,6 +616,8 @@ struct _LinphoneProxyConfig ...@@ -615,6 +616,8 @@ struct _LinphoneProxyConfig
LinphoneAddress *saved_identity; LinphoneAddress *saved_identity;
/*---*/ /*---*/
LinphoneAddress *pending_contact; /*use to store previous contact in case of network failure*/ LinphoneAddress *pending_contact; /*use to store previous contact in case of network failure*/
LinphoneEvent *long_term_event;
unsigned long long previous_publish_config_hash[2];
}; };
...@@ -1108,6 +1111,7 @@ SalReason linphone_reason_to_sal(LinphoneReason reason); ...@@ -1108,6 +1111,7 @@ SalReason linphone_reason_to_sal(LinphoneReason reason);
LinphoneReason linphone_reason_from_sal(SalReason reason); LinphoneReason linphone_reason_from_sal(SalReason reason);
LinphoneEvent *linphone_event_new(LinphoneCore *lc, LinphoneSubscriptionDir dir, const char *name, int expires); LinphoneEvent *linphone_event_new(LinphoneCore *lc, LinphoneSubscriptionDir dir, const char *name, int expires);
LinphoneEvent *linphone_event_new_with_op(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name); LinphoneEvent *linphone_event_new_with_op(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name);
void linphone_event_unpublish(LinphoneEvent *lev);
/** /**
* Useful for out of dialog notify * Useful for out of dialog notify
* */ * */
...@@ -1438,6 +1442,8 @@ BELLE_SIP_DECLARE_VPTR(LinphoneTunnelConfig); ...@@ -1438,6 +1442,8 @@ BELLE_SIP_DECLARE_VPTR(LinphoneTunnelConfig);
int linphone_core_get_default_proxy_config_index(LinphoneCore *lc); int linphone_core_get_default_proxy_config_index(LinphoneCore *lc);
char *linphone_presence_model_to_xml(LinphonePresenceModel *model) ;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -130,6 +130,50 @@ LinphoneProxyConfig *linphone_proxy_config_new() { ...@@ -130,6 +130,50 @@ LinphoneProxyConfig *linphone_proxy_config_new() {
return linphone_core_create_proxy_config(NULL); return linphone_core_create_proxy_config(NULL);
} }
static char * append_linphone_address(LinphoneAddress *addr,char *out) {
char *res = out;
if (addr) {
char *tmp;
tmp = linphone_address_as_string(addr);
res = ms_strcat_printf(out, "%s",tmp);
ms_free(tmp);
}
return res;
};
static char * append_string(const char * string,char *out) {
char *res = out;
if (string) {
res = ms_strcat_printf(out, "%s",string);
}
return res;
}
/*
* return true if computed value has changed
*/
bool_t linphone_proxy_config_compute_publish_params_hash(LinphoneProxyConfig * cfg) {
char * source = NULL;
char hash[33];
char saved;
unsigned long long previous_hash[2];
previous_hash[0] = cfg->previous_publish_config_hash[0];
previous_hash[1] = cfg->previous_publish_config_hash[1];
source = ms_strcat_printf(source, "%i",cfg->privacy);
source=append_linphone_address(cfg->identity_address, source);
source=append_string(cfg->reg_proxy,source);
source=append_string(cfg->reg_route,source);
source=append_string(cfg->realm,source);
source = ms_strcat_printf(source, "%i",cfg->publish_expires);
source = ms_strcat_printf(source, "%i",cfg->publish);
belle_sip_auth_helper_compute_ha1(source, "dummy", "dummy", hash);
ms_free(source);
saved = hash[16];
hash[16] = '\0';
cfg->previous_publish_config_hash[0] = strtoull(hash, (char **)NULL, 16);
hash[16] = saved;
cfg->previous_publish_config_hash[1] = strtoull(&hash[16], (char **)NULL, 16);
return previous_hash[0] != cfg->previous_publish_config_hash[0] || previous_hash[1] != cfg->previous_publish_config_hash[1];
}
static void _linphone_proxy_config_destroy(LinphoneProxyConfig *cfg); static void _linphone_proxy_config_destroy(LinphoneProxyConfig *cfg);
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneProxyConfig); BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneProxyConfig);
...@@ -152,9 +196,9 @@ void _linphone_proxy_config_release_ops(LinphoneProxyConfig *cfg){ ...@@ -152,9 +196,9 @@ void _linphone_proxy_config_release_ops(LinphoneProxyConfig *cfg){
sal_op_release(cfg->op); sal_op_release(cfg->op);
cfg->op=NULL; cfg->op=NULL;
} }
if (cfg->publish_op){ if (cfg->long_term_event){
sal_op_release(cfg->publish_op); linphone_event_unref(cfg->long_term_event);
cfg->publish_op=NULL; cfg->long_term_event=NULL;
} }
} }
...@@ -320,15 +364,13 @@ void linphone_proxy_config_pause_register(LinphoneProxyConfig *cfg){ ...@@ -320,15 +364,13 @@ void linphone_proxy_config_pause_register(LinphoneProxyConfig *cfg){
} }
void linphone_proxy_config_edit(LinphoneProxyConfig *cfg){ void linphone_proxy_config_edit(LinphoneProxyConfig *cfg){
if (cfg->publish && cfg->publish_op){
/*unpublish*/
sal_publish_presence(cfg->publish_op,NULL,NULL,0,(SalPresenceModel *)NULL);
sal_op_release(cfg->publish_op);
cfg->publish_op=NULL;
}
/*store current config related to server location*/ /*store current config related to server location*/
linphone_proxy_config_store_server_config(cfg); linphone_proxy_config_store_server_config(cfg);