Commit 510f3b72 authored by jehan's avatar jehan

implement presence

parent 6c323ddc
......@@ -59,7 +59,7 @@
<folderInfo id="0.2131511368.593515799." name="/" resourcePath="">
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1930099439" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
<targetPlatform binaryParser="org.eclipse.cdt.core.MachO64" id="org.eclipse.cdt.build.core.prefbase.toolchain.1930099439.714963030" name=""/>
<builder arguments="CFLAGS=&quot;-g -Wall -Werror -Wno-deprecated-declarations&quot; V=1" command="make" id="org.eclipse.cdt.build.core.settings.default.builder.896899734" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
<builder arguments="CFLAGS=&quot;-g -Wall -Werror -Wno-deprecated-declarations -Wno-unused-function&quot; V=1" command="make" id="org.eclipse.cdt.build.core.settings.default.builder.896899734" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.1682581923" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.730520342" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.552841386" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
......
......@@ -46,7 +46,8 @@ liblinphone_la_SOURCES+= bellesip_sal/sal_address_impl.c \
bellesip_sal/sal_op_call.c \
bellesip_sal/sal_op_registration.c \
bellesip_sal/sal_sdp.c \
bellesip_sal/sal_op_message.c
bellesip_sal/sal_op_message.c \
bellesip_sal/sal_op_presence.c
else
liblinphone_la_SOURCES+= sal_eXosip2.c sal_eXosip2.h\
sal_eXosip2_sdp.c \
......
......@@ -35,12 +35,28 @@ static void sal_add_pending_auth(Sal *sal, SalOp *op){
}
void sal_process_authentication(SalOp *op, belle_sip_response_t *response) {
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(op->request),BELLE_SIP_AUTHORIZATION);
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(op->request),BELLE_SIP_PROXY_AUTHORIZATION);
if (belle_sip_provider_add_authorization(op->base.root->prov,op->request,response)) {
sal_op_resend_request(op,op->request);
belle_sip_request_t* request;
bool_t is_within_dialog=FALSE;
if (op->dialog && belle_sip_dialog_get_state(op->dialog)==BELLE_SIP_DIALOG_CONFIRMED) {
request = belle_sip_dialog_create_request_from(op->dialog,(const belle_sip_request_t *)op->request);
is_within_dialog=TRUE;
} else {
request=op->request;
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_AUTHORIZATION);
belle_sip_message_remove_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_PROXY_AUTHORIZATION);
}
if (belle_sip_provider_add_authorization(op->base.root->prov,request,response)) {
if (is_within_dialog) {
sal_op_resend_request(op,request);
} else {
sal_op_send_request(op,request);
}
}else {
ms_message("No auth info found for [%s]",sal_op_get_from(op));
if (is_within_dialog) {
belle_sip_object_unref(request);
}
sal_add_pending_auth(op->base.root,op);
}
......@@ -76,6 +92,10 @@ static void process_request_event(void *sal, const belle_sip_request_event_t *ev
op=sal_op_new((Sal*)sal);
op->dir=SalOpDirIncoming;
sal_op_call_fill_cbs(op);
} else if (strcmp("SUBSCRIBE",belle_sip_request_get_method(req))==0) {
op=sal_op_new((Sal*)sal);
op->dir=SalOpDirIncoming;
sal_op_presence_fill_cbs(op);
} else if (strcmp("MESSAGE",belle_sip_request_get_method(req))==0) {
content_type=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_content_type_t);
if (content_type
......
......@@ -66,6 +66,7 @@ struct SalOp{
bool_t supports_session_timers;
SalOpSate_t state;
SalOpDir_t dir;
belle_sip_refresher_t* refresher;
};
belle_sdp_session_description_t * media_description_to_sdp(const SalMediaDescription *sal);
......@@ -80,4 +81,9 @@ int sal_op_send_request(SalOp* op, belle_sip_request_t* request);
void sal_op_resend_request(SalOp* op, belle_sip_request_t* request);
void sal_process_authentication(SalOp *op, belle_sip_response_t *response);
bool_t sal_compute_sal_errors(belle_sip_response_t* response,SalError* sal_err,SalReason* sal_reason,char* reason, size_t reason_size);
/*presence*/
void sal_op_presence_fill_cbs(SalOp*op);
#endif /* SAL_IMPL_H_ */
......@@ -88,40 +88,6 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) {
/*presence Subscribe/notify*/
int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
ms_fatal("sal_subscribe_presence not implemented yet");
return -1;
}
int sal_unsubscribe(SalOp *op){
ms_fatal("sal_unsubscribe not implemented yet");
return -1;
}
int sal_subscribe_accept(SalOp *op){
ms_fatal("sal_subscribe_accept not implemented yet");
return -1;
}
int sal_subscribe_decline(SalOp *op){
ms_fatal("sal_subscribe_decline not implemented yet");
return -1;
}
int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_message){
ms_fatal("sal_notify_presence not implemented yet");
return -1;
}
int sal_notify_close(SalOp *op){
ms_fatal("sal_notify_close not implemented yet");
return -1;
}
/*presence publish */
int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus status){
ms_fatal("sal_publish not implemented yet");
return -1;
}
/*ping: main purpose is to obtain its own contact address behind firewalls*/
int sal_ping(SalOp *op, const char *from, const char *to){
ms_fatal("sal_ping not implemented yet");
......@@ -141,6 +107,11 @@ void sal_op_resend_request(SalOp* op, belle_sip_request_t* request) {
belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1);
sal_op_send_request(op,request);
}
static bool_t is_request_creating_dialog(belle_sip_request_t* request) {
return strcmp("INVITE",belle_sip_request_get_method(request))==0
||
strcmp("SUBSCRIBE",belle_sip_request_get_method(request))==0;
}
int sal_op_send_request(SalOp* op, belle_sip_request_t* request) {
belle_sip_client_transaction_t* client_transaction;
belle_sip_provider_t* prov=op->base.root->prov;
......@@ -155,7 +126,7 @@ int sal_op_send_request(SalOp* op, belle_sip_request_t* request) {
client_transaction = belle_sip_provider_create_client_transaction(prov,request);
belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),op);
/*in case DIALOG is in state NULL create a new dialog*/
if (!op->dialog && strcmp("INVITE",belle_sip_request_get_method(request))==0) {
if (!op->dialog && is_request_creating_dialog(request)) {
op->dialog=belle_sip_provider_create_dialog(prov,BELLE_SIP_TRANSACTION(client_transaction));
op->pending_inv_client_trans=client_transaction; /*update pending inv for being able to cancel*/
belle_sip_dialog_set_application_data(op->dialog,op);
......@@ -167,3 +138,65 @@ int sal_op_send_request(SalOp* op, belle_sip_request_t* request) {
return belle_sip_client_transaction_send_request(client_transaction);
}
/*return TRUE if error code*/
bool_t sal_compute_sal_errors(belle_sip_response_t* response,SalError* sal_err,SalReason* sal_reason,char* reason, size_t reason_size) {
int code = belle_sip_response_get_status_code(response);
belle_sip_header_t* reason_header = belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Reason");
*sal_err=SalErrorUnknown;
*sal_reason = SalReasonUnknown;
if (reason_header){
snprintf(reason
,reason_size
,"%s %s"
,belle_sip_response_get_reason_phrase(response)
,belle_sip_header_extension_get_value(BELLE_SIP_HEADER_EXTENSION(reason_header)));
} else {
strncpy(reason,belle_sip_response_get_reason_phrase(response),reason_size);
}
if (code >=400) {
switch(code) {
case 400:
*sal_err=SalErrorUnknown;
break;
case 404:
*sal_err=SalErrorFailure;
*sal_reason=SalReasonNotFound;
break;
case 415:
*sal_err=SalErrorFailure;
*sal_reason=SalReasonMedia;
break;
case 422:
ms_error ("422 not implemented yet");;
break;
case 480:
*sal_err=SalErrorFailure;
*sal_reason=SalReasonTemporarilyUnavailable;
break;
case 486:
*sal_err=SalErrorFailure;
*sal_reason=SalReasonBusy;
break;
case 487:
break;
case 600:
*sal_err=SalErrorFailure;
*sal_reason=SalReasonDoNotDisturb;
break;
case 603:
*sal_err=SalErrorFailure;
*sal_reason=SalReasonDeclined;
break;
default:
if (code>0){
*sal_err=SalErrorFailure;
*sal_reason=SalReasonUnknown;
}else *sal_err=SalErrorNoResponse;
/* no break */
}
return TRUE;
} else {
return FALSE;
}
}
This diff is collapsed.
......@@ -30,11 +30,7 @@ static void register_refresh(SalOp* op) {
belle_sip_header_cseq_set_seq_number(cseq,belle_sip_header_cseq_get_seq_number(cseq)+1);
sal_op_send_request(op,op->request);
}
static bool_t is_contact_equal(belle_sip_header_contact_t* a,belle_sip_header_contact_t* b) {
if (!a | !b) return FALSE;
return !belle_sip_uri_equals(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(a))
,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(b)));
}
static void register_response_event(void *user_ctx, const belle_sip_response_event_t *event){
belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event);
SalOp* op = (SalOp*)belle_sip_transaction_get_application_data(BELLE_SIP_TRANSACTION(client_transaction));
......@@ -52,7 +48,7 @@ static void register_response_event(void *user_ctx, const belle_sip_response_eve
contact_header_list = belle_sip_message_get_headers(BELLE_SIP_MESSAGE(response),BELLE_SIP_CONTACT);
if (contact_header_list) {
contact_header_list = belle_sip_list_find_custom((belle_sip_list_t*)contact_header_list,(belle_sip_compare_func)is_contact_equal, (const void*)sal_op_get_contact_address(op));
contact_header_list = belle_sip_list_find_custom((belle_sip_list_t*)contact_header_list,(belle_sip_compare_func)belle_sip_header_contact_equals, (const void*)sal_op_get_contact_address(op));
if (!contact_header_list) {
ms_error("no matching contact for [%s]", sal_op_get_contact(op));
} else {
......
......@@ -338,8 +338,8 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
ms_warning("No sip url defined.");
return;
}
fr->lc=lc;
linphone_core_write_friends_config(lc);
if (fr->inc_subscribe_pending){
......@@ -390,6 +390,7 @@ void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf)
return ;
}
lc->friends=ms_list_append(lc->friends,lf);
lf->lc=lc;
if ( linphone_core_ready(lc)) linphone_friend_apply(lf,lc);
else lf->commit=TRUE;
return ;
......
......@@ -414,3 +414,18 @@ const char* sal_stream_dir_to_string(SalStreamDir type) {
}
}
const char* sal_reason_to_string(const SalReason reason) {
switch (reason) {
case SalReasonDeclined : return "SalReasonDeclined";
case SalReasonBusy: return "SalReasonBusy";
case SalReasonRedirect: return "SalReasonRedirect";
case SalReasonTemporarilyUnavailable: return "SalReasonTemporarilyUnavailable";
case SalReasonNotFound: return "SalReasonNotFound";
case SalReasonDoNotDisturb: return "SalReasonDoNotDisturb";
case SalReasonMedia: return "SalReasonMedia";
case SalReasonForbidden: return "SalReasonForbidden";
case SalReasonUnknown: return "SalReasonUnknown";
default: return "Unkown reason";
}
}
......@@ -201,6 +201,8 @@ typedef enum SalReason{
SalReasonUnknown
}SalReason;
const char* sal_reason_to_string(const SalReason reason);
typedef enum SalPresenceStatus{
SalPresenceOffline,
SalPresenceOnline,
......
......@@ -84,6 +84,9 @@ typedef struct _stats {
int number_of_LinphoneCallReleased;
int number_of_LinphoneMessageReceived;
int number_of_NewSubscriptionRequest;
int number_of_NotifyReceived;
}stats;
static stats global_stat;
......@@ -296,7 +299,6 @@ static void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCal
}
static void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from_address, const char *message) {
char* from=linphone_address_as_string(from_address);
ms_message("Message from [%s] is [%s]",from,message);
ms_free(from);
......@@ -304,6 +306,21 @@ static void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, cons
counters->number_of_LinphoneMessageReceived++;
}
void new_subscribtion_request(LinphoneCore *lc, LinphoneFriend *lf, const char *url){
char* from=linphone_address_as_string(linphone_friend_get_address(lf));
ms_message("New subscription request from [%s] url [%s]",from,url);
ms_free(from);
stats* counters = (stats*)linphone_core_get_user_data(lc);
counters->number_of_NewSubscriptionRequest++;
}
static void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf) {
char* from=linphone_address_as_string(linphone_friend_get_address(lf));
ms_message("New Notify request from [%s] ",from);
ms_free(from);
stats* counters = (stats*)linphone_core_get_user_data(lc);
counters->number_of_NotifyReceived++;
}
static bool_t wait_for(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value) {
int retry=0;
while (*counter<value && retry++ <20) {
......@@ -339,6 +356,8 @@ static LinphoneCoreManager* linphone_core_manager_new(const char* rc_file) {
mgr->v_table.registration_state_changed=registration_state_changed;
mgr->v_table.call_state_changed=call_state_changed;
mgr->v_table.text_received=text_message_received;
mgr->v_table.new_subscription_request=new_subscribtion_request;
mgr->v_table.notify_presence_recv=notify_presence_received;
mgr->lc=configure_lc_from(&mgr->v_table,rc_file,1);
enable_codec(mgr->lc,"PCMU",8000);
linphone_core_set_user_data(mgr->lc,&mgr->stat);
......@@ -551,6 +570,37 @@ static void text_message() {
linphone_core_manager_destroy(pauline);
}
static void simple_publish() {
LinphoneCoreManager* marie = linphone_core_manager_new("./tester/marie_rc");
LinphoneProxyConfig* proxy;
linphone_core_get_default_proxy(marie->lc,&proxy);
linphone_proxy_config_edit(proxy);
linphone_proxy_config_enable_publish(proxy,TRUE);
linphone_proxy_config_done(proxy);
linphone_core_iterate(marie->lc);
linphone_core_manager_destroy(marie);
}
static void simple_subscribe() {
LinphoneCoreManager* marie = linphone_core_manager_new("./tester/marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new("./tester/pauline_rc");
const MSList* marie_friends = linphone_core_get_friend_list(marie->lc);
CU_ASSERT_PTR_NOT_NULL_FATAL(marie_friends);
LinphoneFriend* friend = (LinphoneFriend*) marie_friends->data;
linphone_friend_edit(friend);
linphone_friend_enable_subscribes(friend,TRUE);
linphone_friend_done(friend);
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,1));
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_NotifyReceived,1));
linphone_core_manager_destroy(marie);
CU_ASSERT_TRUE(wait_for(NULL,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,2)); /*wait for unsubscribe*/
linphone_core_manager_destroy(pauline);
}
int init_test_suite () {
CU_pSuite pSuite = CU_add_suite("liblinphone", init, uninit);
......@@ -604,6 +654,12 @@ CU_pSuite pSuite = CU_add_suite("liblinphone", init, uninit);
if (NULL == CU_add_test(pSuite, "text_message", text_message)) {
return CU_get_error();
}
if (NULL == CU_add_test(pSuite, "simple_subscribe", simple_subscribe)) {
return CU_get_error();
}
if (NULL == CU_add_test(pSuite, "simple_publish", simple_publish)) {
return CU_get_error();
}
return 0;
}
int main (int argc, char *argv[]) {
......
......@@ -22,6 +22,11 @@ reg_sendregister=1
publish=0
dial_escape_plus=0
[friend_0]
url="Paupoche" <sip:pauline@sip.example.org>
pol=accept
subscribe=0
[rtp]
audio_rtp_port=8070
......
......@@ -22,6 +22,11 @@ reg_sendregister=1
publish=0
dial_escape_plus=0
#[friend_0]
#url="Mariette" <sip:marie@sip.example.org>
#pol=accept
#subscribe=0
[rtp]
audio_rtp_port=8090
video_rtp_port=8092
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment