Commit a45d28a3 authored by Simon Morlat's avatar Simon Morlat
Browse files

implement receiving of in-dialog chat message

parent e022c576
......@@ -137,7 +137,7 @@ void sal_compute_sal_errors_from_code(int code ,SalError* sal_err,SalReason* sal
void sal_op_presence_fill_cbs(SalOp*op);
/*messaging*/
void sal_op_message_fill_cbs(SalOp*op);
void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *event);
void sal_op_subscribe_fill_cbs(SalOp*op);
/*call transfer*/
......
......@@ -322,7 +322,7 @@ static void call_terminated(SalOp* op,belle_sip_server_transaction_t* server_tra
static void unsupported_method(belle_sip_server_transaction_t* server_transaction,belle_sip_request_t* request) {
belle_sip_response_t* resp;
resp=belle_sip_response_create_from_request(request,500);
resp=belle_sip_response_create_from_request(request,501);
belle_sip_server_transaction_send_response(server_transaction,resp);
return;
}
......@@ -392,15 +392,16 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
belle_sip_dialog_state_t dialog_state;
belle_sip_response_t* resp;
belle_sip_header_t* call_info;
const char *method=belle_sip_request_get_method(req);
if (strcmp("ACK",belle_sip_request_get_method(req))!=0){ /*ACK does'nt create srv transaction*/
if (strcmp("ACK",method)!=0){ /*ACK does'nt create srv transaction*/
server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event));
belle_sip_object_ref(server_transaction);
belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(server_transaction),op);
sal_op_ref(op);
}
if (strcmp("INVITE",belle_sip_request_get_method(req))==0) {
if (strcmp("INVITE",method)==0) {
if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans);
/*updating pending invite transaction*/
op->pending_server_trans=server_transaction;
......@@ -414,7 +415,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
dialog_state=belle_sip_dialog_get_state(op->dialog);
switch(dialog_state) {
case BELLE_SIP_DIALOG_NULL: {
if (strcmp("INVITE",belle_sip_request_get_method(req))==0) {
if (strcmp("INVITE",method)==0) {
if (!op->replaces && (op->replaces=belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_replaces_t))) {
belle_sip_object_ref(op->replaces);
} else if(op->replaces) {
......@@ -429,15 +430,13 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
ms_message("The caller asked to automatically answer the call(Emergency?)\n");
}
}
op->base.root->callbacks.call_received(op);
break;
} /* else same behavior as for EARLY state*/
}
case BELLE_SIP_DIALOG_EARLY: {
//hmm probably a cancel
if (strcmp("CANCEL",belle_sip_request_get_method(req))==0) {
if (strcmp("CANCEL",method)==0) {
if(belle_sip_request_event_get_server_transaction(event)) {
/*first answer 200 ok to cancel*/
belle_sip_server_transaction_send_response(server_transaction
......@@ -453,7 +452,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
belle_sip_server_transaction_send_response(server_transaction
,sal_op_create_response_from_request(op,req,481));
}
} else if (strcmp("PRACK",belle_sip_request_get_method(req))==0) {
} else if (strcmp("PRACK",method)==0) {
resp=sal_op_create_response_from_request(op,req,200);
belle_sip_server_transaction_send_response(server_transaction,resp);
} else {
......@@ -464,7 +463,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
}
case BELLE_SIP_DIALOG_CONFIRMED:
/*great ACK received*/
if (strcmp("ACK",belle_sip_request_get_method(req))==0) {
if (strcmp("ACK",method)==0) {
if (op->sdp_offering){
SalReason reason;
if (extract_sdp(BELLE_SIP_MESSAGE(req),&sdp,&reason)==0){
......@@ -485,13 +484,13 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
op->reinvite=FALSE;
}*/
op->base.root->callbacks.call_ack(op);
} else if(strcmp("BYE",belle_sip_request_get_method(req))==0) {
} else if(strcmp("BYE",method)==0) {
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;
/*call end not notified by dialog deletion because transaction can end before dialog*/
} else if(strcmp("INVITE",belle_sip_request_get_method(req))==0) {
} else if(strcmp("INVITE",method)==0) {
/*re-invite*/
if (op->base.remote_media){
sal_media_description_unref(op->base.remote_media);
......@@ -503,7 +502,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
}
if (process_sdp_for_invite(op,req)==0)
op->base.root->callbacks.call_updating(op);
} else if (strcmp("INFO",belle_sip_request_get_method(req))==0){
} else if (strcmp("INFO",method)==0){
if (belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))
&& strstr(belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)),"picture_fast_update")) {
/*vfu request*/
......@@ -528,19 +527,19 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
}
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) {
}else if (strcmp("REFER",method)==0) {
sal_op_process_refer(op,event,server_transaction);
} else if (strcmp("NOTIFY",belle_sip_request_get_method(req))==0) {
} else if (strcmp("NOTIFY",method)==0) {
sal_op_call_process_notify(op,event,server_transaction);
} else if (strcmp("OPTIONS",belle_sip_request_get_method(req))==0) {
} else if (strcmp("OPTIONS",method)==0) {
resp=sal_op_create_response_from_request(op,req,200);
belle_sip_server_transaction_send_response(server_transaction,resp);
} else if (strcmp("CANCEL",belle_sip_request_get_method(req))==0) {
} else if (strcmp("CANCEL",method)==0) {
/*call leg does not exist because 200ok already sent*/
belle_sip_server_transaction_send_response( server_transaction
,sal_op_create_response_from_request(op,req,481));
} else{
belle_sip_server_transaction_send_response(server_transaction,sal_op_create_response_from_request(op,req,481));
} else if (strcmp("MESSAGE",method)==0){
sal_process_incoming_message(op,event);
}else{
ms_error("unexpected method [%s] for dialog [%p]",belle_sip_request_get_method(req),op->dialog);
unsupported_method(server_transaction,req);
}
......
......@@ -84,8 +84,11 @@ static bool_t is_im_iscomposing(belle_sip_header_content_type_t* content_type) {
&& strcmp("im-iscomposing+xml",belle_sip_header_content_type_get_subtype(content_type))==0;
}
static void process_request_event(void *op_base, const belle_sip_request_event_t *event) {
SalOp* op = (SalOp*)op_base;
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"));
}
void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *event){
belle_sip_request_t* req = belle_sip_request_event_get_request(event);
belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,req);
belle_sip_header_address_t* address;
......@@ -95,7 +98,6 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
belle_sip_header_call_id_t* call_id = belle_sip_message_get_header_by_type(req,belle_sip_header_call_id_t);
belle_sip_header_cseq_t* cseq = belle_sip_message_get_header_by_type(req,belle_sip_header_cseq_t);
belle_sip_header_date_t *date=belle_sip_message_get_header_by_type(req,belle_sip_header_date_t);
int response_code=501;
char* from;
bool_t plain_text=FALSE;
bool_t external_body=FALSE;
......@@ -126,7 +128,6 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
belle_sip_object_unref(address);
belle_sip_free(from);
if (salmsg.url) ms_free((char*)salmsg.url);
response_code=200;
} else if (content_type && is_im_iscomposing(content_type)) {
SalIsComposing saliscomposing;
address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header))
......@@ -137,14 +138,21 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
op->base.root->callbacks.is_composing_received(op,&saliscomposing);
belle_sip_object_unref(address);
belle_sip_free(from);
response_code=200;
} else {
ms_error("Unsupported MESSAGE with content type [%s/%s]",belle_sip_header_content_type_get_type(content_type)
,belle_sip_header_content_type_get_subtype(content_type));
response_code=501; /*not implemented sound appropriate*/
resp = belle_sip_response_create_from_request(req,415);
add_message_accept((belle_sip_message_t*)resp);
belle_sip_server_transaction_send_response(server_transaction,resp);
return;
}
resp = belle_sip_response_create_from_request(req,response_code);
resp = belle_sip_response_create_from_request(req,200);
belle_sip_server_transaction_send_response(server_transaction,resp);
}
static void process_request_event(void *op_base, const belle_sip_request_event_t *event) {
SalOp* op = (SalOp*)op_base;
sal_process_incoming_message(op,event);
sal_op_release(op);
}
......@@ -154,16 +162,21 @@ int sal_message_send(SalOp *op, const char *from, const char *to, const char* co
size_t content_length = msg?strlen(msg):0;
time_t curtime=time(NULL);
sal_op_message_fill_cbs(op);
if (from)
sal_op_set_from(op,from);
if (to)
sal_op_set_to(op,to);
op->dir=SalOpDirOutgoing;
req=sal_op_build_request(op,"MESSAGE");
if (sal_op_get_contact_address(op)){
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op)));
if (op->dialog){
/*for SIP MESSAGE that are sent in call's dialog*/
req=belle_sip_dialog_create_queued_request(op->dialog,"MESSAGE");
}else{
sal_op_message_fill_cbs(op);
if (from)
sal_op_set_from(op,from);
if (to)
sal_op_set_to(op,to);
op->dir=SalOpDirOutgoing;
req=sal_op_build_request(op,"MESSAGE");
if (sal_op_get_contact_address(op)){
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(sal_op_create_contact(op)));
}
}
snprintf(content_type_raw,sizeof(content_type_raw),BELLE_SIP_CONTENT_TYPE ": %s",content_type);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_type_parse(content_type_raw)));
......
......@@ -149,7 +149,6 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
call->state==LinphoneCallPausedByRemote){
ms_message("send SIP message through the existing call.");
op = call->op;
call->pending_message=msg;
identity=linphone_core_find_best_identity(cr->lc,linphone_call_get_remote_address(call));
}
}
......@@ -224,7 +223,6 @@ LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAd
}
void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessage *sal_msg){
LinphoneChatRoom *cr=NULL;
LinphoneAddress *addr;
char *cleanfrom;
......
......@@ -2845,8 +2845,6 @@ static LinphoneAddress *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call ,
}
}
return ret;
}
void linphone_call_set_contact_op(LinphoneCall* call) {
......
......@@ -199,7 +199,6 @@ struct _LinphoneCall
UpnpSession *upnp_session;
#endif //BUILD_UPNP
IceSession *ice_session;
LinphoneChatMessage* pending_message;
int ping_time;
unsigned int remote_session_id;
unsigned int remote_session_ver;
......
......@@ -94,6 +94,27 @@ static void text_message(void) {
linphone_core_manager_destroy(pauline);
}
static void text_message_within_dialog(void) {
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
lp_config_set_int(pauline->lc->config,"sip","chat_use_call_dialogs",1);
char* to = linphone_address_as_string(marie->identity);
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
ms_free(to);
CU_ASSERT_TRUE(call(marie,pauline));
linphone_chat_room_send_message(chat_room,"Bla bla bla bla");
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
CU_ASSERT_PTR_NOT_NULL(linphone_core_get_chat_room(marie->lc,pauline->identity));
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static LinphoneAuthInfo* text_message_with_credential_from_auth_cb_auth_info;
static void text_message_with_credential_from_auth_cb_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username, const char *domain) {
stats* counters;
......@@ -332,6 +353,7 @@ static void is_composing_notification(void) {
test_t message_tests[] = {
{ "Text message", text_message },
{ "Text message within call's dialog", text_message_within_dialog},
{ "Text message with credentials from auth info cb", text_message_with_credential_from_auth_cb},
{ "Text message with privacy", text_message_with_privacy },
{ "Text message compatibility mode", text_message_compatibility_mode },
......
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