Commit 80046076 authored by jehan's avatar jehan

add support of external-body for SIP message

parent cb0fe631
......@@ -732,9 +732,12 @@ static void refer_received(Sal *sal, SalOp *op, const char *referto){
static void text_received(Sal *sal, const char *from, const char *msg){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal);
linphone_core_text_received(lc,from,msg);
linphone_core_message_received(lc,from,msg,NULL);
}
void message_external_body_received(Sal *sal, const char *from, const char *url) {
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal);
linphone_core_message_received(lc,from,NULL,url);
}
static void notify(SalOp *op, const char *from, const char *msg){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer (op);
......@@ -840,6 +843,7 @@ SalCallbacks linphone_sal_callbacks={
dtmf_received,
refer_received,
text_received,
message_external_body_received,
text_delivery_update,
notify,
notify_presence,
......
......@@ -55,6 +55,7 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
const char *identity=linphone_core_find_best_identity(cr->lc,cr->peer_url,&route);
SalOp *op=NULL;
LinphoneCall *call;
char* content_type;
if((call = linphone_core_get_call_by_remote_address(cr->lc,cr->peer))!=NULL){
if (call->state==LinphoneCallConnected ||
call->state==LinphoneCallStreamsRunning ||
......@@ -77,7 +78,15 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
cr->op=op;
sal_op_set_user_pointer(op, msg); /*if out of call, directly store msg*/
}
sal_text_send(op,identity,cr->peer,msg->message);
if (msg->external_body_url) {
content_type=ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"",msg->external_body_url);
sal_message_send(op,identity,cr->peer,content_type,NULL);
ms_free(content_type);
} else {
sal_text_send(op, identity, cr->peer, msg->message);
}
}
void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg) {
......@@ -89,16 +98,20 @@ bool_t linphone_chat_room_matches(LinphoneChatRoom *cr, const LinphoneAddress *f
return FALSE;
}
void linphone_chat_room_text_received(LinphoneChatRoom *cr, LinphoneCore *lc, const LinphoneAddress *from, const char *msg){
if (lc->vtable.text_received!=NULL) lc->vtable.text_received(lc, cr, from, msg);
void linphone_chat_room_message_received(LinphoneChatRoom *cr, LinphoneCore *lc, LinphoneChatMessage *msg){
if (msg->message)
//legacy API
if (lc->vtable.text_received!=NULL) lc->vtable.text_received(lc, cr, msg->from, msg->message);
if (lc->vtable.message_received!=NULL) lc->vtable.message_received(lc, cr,msg);
}
void linphone_core_text_received(LinphoneCore *lc, const char *from, const char *msg){
void linphone_core_message_received(LinphoneCore *lc, const char *from, const char *raw_msg,const char* external_url){
MSList *elem;
LinphoneChatRoom *cr=NULL;
LinphoneAddress *addr;
char *cleanfrom;
LinphoneChatMessage* msg;
addr=linphone_address_new(from);
linphone_address_clean(addr);
for(elem=lc->chatrooms;elem!=NULL;elem=ms_list_next(elem)){
......@@ -113,9 +126,13 @@ void linphone_core_text_received(LinphoneCore *lc, const char *from, const char
/* create a new chat room */
cr=linphone_core_create_chat_room(lc,cleanfrom);
}
msg = linphone_chat_room_create_message(cr, raw_msg);
linphone_chat_message_set_from(msg, cr->peer_url);
if (external_url) {
linphone_chat_message_set_external_body_url(msg, external_url);
}
linphone_address_destroy(addr);
linphone_chat_room_text_received(cr,lc,cr->peer_url,msg);
linphone_chat_room_message_received(cr,lc,msg);
ms_free(cleanfrom);
}
......@@ -140,12 +157,14 @@ const LinphoneAddress* linphone_chat_room_get_peer_address(LinphoneChatRoom *cr)
LinphoneChatMessage* linphone_chat_room_create_message(const LinphoneChatRoom *cr,const char* message) {
LinphoneChatMessage* msg = ms_new0(LinphoneChatMessage,1);
msg->chat_room=(LinphoneChatRoom*)cr;
msg->message=ms_strdup(message);
msg->message=message?ms_strdup(message):NULL;
return msg;
}
void linphone_chat_message_destroy(LinphoneChatMessage* msg) {
if (msg->message) ms_free(msg->message);
if (msg->external_body_url) ms_free(msg->external_body_url);
if (msg->from) linphone_address_destroy(msg->from);
ms_free(msg);
}
......@@ -186,3 +205,44 @@ void linphone_chat_message_set_user_data(LinphoneChatMessage* message,void* ud)
void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message) {
return message->message_userdata;
}
const char* linphone_chat_message_get_external_body_url(const LinphoneChatMessage* message) {
return message->external_body_url;
}
void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,const char* url) {
if (message->external_body_url) {
ms_free(message->external_body_url);
}
message->external_body_url=url?ms_strdup(url):NULL;
}
void linphone_chat_message_set_from(LinphoneChatMessage* message, const LinphoneAddress* from) {
if(message->from) linphone_address_destroy(message->from);
message->from=linphone_address_clone(from);
}
LinphoneAddress* linphone_chat_message_get_from(const LinphoneChatMessage* message) {
return message->from;
}
const char * linphone_chat_message_get_text(const LinphoneChatMessage* message) {
return message->message;
}
LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* msg) {
/*struct _LinphoneChatMessage {
char* message;
LinphoneChatRoom* chat_room;
LinphoneChatMessageStateChangeCb cb;
void* cb_ud;
void* message_userdata;
char* external_body_url;
LinphoneAddress* from;
};*/
LinphoneChatMessage* new_message = linphone_chat_room_create_message(msg->chat_room,msg->message);
if (msg->external_body_url) new_message->external_body_url=ms_strdup(msg->external_body_url);
new_message->cb=msg->cb;
new_message->cb_ud=msg->cb_ud;
new_message->message_userdata=msg->message_userdata;
new_message->cb=msg->cb;
if (msg->from) new_message->from=linphone_address_clone(msg->from);
return new_message;
}
\ No newline at end of file
......@@ -617,7 +617,6 @@ void linphone_chat_room_destroy(LinphoneChatRoom *cr);
*/
LinphoneChatMessage* linphone_chat_room_create_message(const LinphoneChatRoom *cr,const char* message);
/**
* get peer address \link linphone_core_create_chat_room() associated to \endlink this #LinphoneChatRoom
......@@ -641,18 +640,61 @@ typedef enum _LinphoneChatMessageStates {
LinphoneChatMessageStateNotDelivered /** message was not delivered*/
}LinphoneChatMessageState;
/**
* to string function
*/
const char* linphone_chat_message_state_to_string(const LinphoneChatMessageState state);
/**
* user pointer set function
* clone a chat message
*@param message #LinphoneChatMessage obj
*@return #LinphoneChatMessage
*/
void linphone_chat_message_set_user_data(LinphoneChatMessage* message,void*);
LinphoneChatMessage* linphone_chat_message_clone(const LinphoneChatMessage* message);
/**
* set origine of the message
*@param message #LinphoneChatMessage obj
*@param from #LinphoneAddress origin of this message (copied)
*/
void linphone_chat_message_set_from(LinphoneChatMessage* message, const LinphoneAddress* from);
/**
* get origine of the message
*@param message #LinphoneChatMessage obj
*@return #LinphoneAddress
*/
LinphoneAddress* linphone_chat_message_get_from(const LinphoneChatMessage* message);
/**
* Linphone message can carry external body as defined by rfc2017
* @param message #LinphoneChatMessage
* @return return external body url null if not present.
*/
const char* linphone_chat_message_get_external_body_url(const LinphoneChatMessage* message);
/**
* Linphone message can carry external body as defined by rfc2017
*
* @param #LinphoneChatMessage
* @param url ex: access-type=URL; URL="http://www.foo.com/file"
*/
void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,const char* url);
/**
* get text part of this message
*@return text or NULL if no text.
*/
const char * linphone_chat_message_get_text(const LinphoneChatMessage* message);
/**
* user pointer get function
*/
void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message);
/**
* user pointer set function
*/
void linphone_chat_message_set_user_data(LinphoneChatMessage* message,void*);
/**
* Call back used to notify message delivery status
......@@ -744,6 +786,7 @@ typedef void (*AuthInfoRequested)(struct _LinphoneCore *lc, const char *realm, c
typedef void (*CallLogUpdated)(struct _LinphoneCore *lc, struct _LinphoneCallLog *newcl);
/**
* Callback prototype
* @deprecated use #MessageReceived instead.
*
* @param lc #LinphoneCore object
* @param room #LinphoneChatRoom involved in this conversation. Can be be created by the framework in case \link #LinphoneAddress the from \endlink is not present in any chat room.
......@@ -751,6 +794,15 @@ typedef void (*CallLogUpdated)(struct _LinphoneCore *lc, struct _LinphoneCallLog
* @param message incoming message
* */
typedef void (*TextMessageReceived)(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message);
/**
* Chat message callback prototype
*
* @param lc #LinphoneCore object
* @param room #LinphoneChatRoom involved in this conversation. Can be be created by the framework in case \link #LinphoneAddress the from \endlink is not present in any chat room.
* @param LinphoneChatMessage incoming message
* */
typedef void (*MessageReceived)(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message);
/** Callback prototype */
typedef void (*DtmfReceived)(struct _LinphoneCore* lc, LinphoneCall *call, int dtmf);
/** Callback prototype */
......@@ -774,7 +826,8 @@ typedef struct _LinphoneVTable{
NewSubscribtionRequestCb new_subscription_request; /**< Notify about pending subscription request */
AuthInfoRequested auth_info_requested; /**< Ask the application some authentication information */
CallLogUpdated call_log_updated; /**< Notifies that call log list has been updated */
TextMessageReceived text_received; /**< A text message has been received */
TextMessageReceived text_received; /** @deprecated, use #message_received instead <br> A text message has been received */
MessageReceived message_received; /** a message is received, can be text or external body*/
DtmfReceived dtmf_received; /**< A dtmf has been received received */
ReferReceived refer_received; /**< An out of call refer was received */
CallEncryptionChangedCb call_encryption_changed; /**<Notifies on change in the encryption of call streams */
......
......@@ -96,6 +96,8 @@ struct _LinphoneChatMessage {
LinphoneChatMessageStateChangeCb cb;
void* cb_ud;
void* message_userdata;
char* external_body_url;
LinphoneAddress* from;
};
struct _LinphoneCall
......@@ -259,7 +261,7 @@ void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,Linphon
int linphone_proxy_config_normalize_number(LinphoneProxyConfig *cfg, const char *username, char *result, size_t result_len);
void linphone_core_text_received(LinphoneCore *lc, const char *from, const char *msg);
void linphone_core_message_received(LinphoneCore *lc, const char *from, const char *raw_msg,const char* external_url);
void linphone_core_play_tone(LinphoneCore *lc);
......
......@@ -275,6 +275,7 @@ typedef void (*SalOnVfuRequest)(SalOp *op);
typedef void (*SalOnDtmfReceived)(SalOp *op, char dtmf);
typedef void (*SalOnRefer)(Sal *sal, SalOp *op, const char *referto);
typedef void (*SalOnTextReceived)(Sal *sal, const char *from, const char *msg);
typedef void (*SalOnMessageExternalBodyReceived)(Sal *sal, const char *from, const char *url);
typedef void (*SalOnTextDeliveryUpdate)(SalOp *op, SalTextDeliveryStatus status);
typedef void (*SalOnNotify)(SalOp *op, const char *from, const char *event);
typedef void (*SalOnNotifyRefer)(SalOp *op, SalReferStatus state);
......@@ -300,6 +301,7 @@ typedef struct SalCallbacks{
SalOnDtmfReceived dtmf_received;
SalOnRefer refer_received;
SalOnTextReceived text_received;
SalOnMessageExternalBodyReceived message_external_body;
SalOnTextDeliveryUpdate text_delivery_update;
SalOnNotify notify;
SalOnNotifyPresence notify_presence;
......@@ -402,6 +404,7 @@ int sal_unregister(SalOp *h);
/*Messaging */
int sal_text_send(SalOp *op, const char *from, const char *to, const char *text);
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg);
/*presence Subscribe/notify*/
int sal_subscribe_presence(SalOp *op, const char *from, const char *to);
......
......@@ -341,6 +341,8 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
if (ctx->callbacks.ping_reply==NULL)
ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
if (ctx->callbacks.message_external_body==NULL)
ctx->callbacks.message_external_body=(SalOnMessageExternalBodyReceived)unimplemented_stub;
}
int sal_unlisten_ports(Sal *ctx){
......@@ -1701,15 +1703,44 @@ static bool_t comes_from_local_if(osip_message_t *msg){
static void text_received(Sal *sal, eXosip_event_t *ev){
osip_body_t *body=NULL;
char *from=NULL,*msg;
osip_content_type_t* content_type;
osip_uri_param_t* external_body_url;
char unquoted_external_body_url [256];
int external_body_size=0;
content_type= osip_message_get_content_type(ev->request);
if (!content_type) {
ms_error("Could not get message because no content type");
return;
}
osip_from_to_str(ev->request->from,&from);
if (content_type->type
&& strcmp(content_type->type, "text")==0
&& content_type->subtype
&& strcmp(content_type->subtype, "plain")==0 ) {
osip_message_get_body(ev->request,0,&body);
if (body==NULL){
ms_error("Could not get text message from SIP body");
return;
}
msg=body->body;
osip_from_to_str(ev->request->from,&from);
sal->callbacks.text_received(sal,from,msg);
} if (content_type->type
&& strcmp(content_type->type, "message")==0
&& content_type->subtype
&& strcmp(content_type->subtype, "external-body")==0 ) {
osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
/*remove both first and last character*/
strncpy(unquoted_external_body_url
,&external_body_url->gvalue[1]
,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
unquoted_external_body_url[external_body_size-1]='\0';
sal->callbacks.message_external_body(sal,from,unquoted_external_body_url);
} else {
ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
}
osip_free(from);
}
......
......@@ -81,7 +81,7 @@ void sal_remove_in_subscribe(Sal *sal, SalOp *op){
sal->in_subscribes=ms_list_remove(sal->in_subscribes,op);
}
int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg){
osip_message_t *sip=NULL;
if(op->cid == -1)
......@@ -97,8 +97,8 @@ int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){
eXosip_message_build_request(&sip,"MESSAGE",sal_op_get_to(op),
sal_op_get_from(op),sal_op_get_route(op));
if (sip!=NULL){
osip_message_set_content_type(sip,"text/plain");
osip_message_set_body(sip,msg,strlen(msg));
osip_message_set_content_type(sip,content_type);
if (msg) osip_message_set_body(sip,msg,strlen(msg));
sal_add_other(op->base.root,op,sip);
eXosip_message_send_request(sip);
}else{
......@@ -118,14 +118,16 @@ int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){
eXosip_unlock();
return -1;
}
osip_message_set_content_type(sip,"text/plain");
osip_message_set_body(sip,msg,strlen(msg));
osip_message_set_content_type(sip,content_type);
if (msg) osip_message_set_body(sip,msg,strlen(msg));
eXosip_call_send_request(op->did,sip);
eXosip_unlock();
}
return 0;
}
int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg) {
return sal_message_send(op,from,to,"text/plain",msg);
}
/*presence Subscribe/notify*/
int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
osip_message_t *msg=NULL;
......
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