mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-03 20:46:28 +00:00
add support of external-body for SIP message
This commit is contained in:
parent
cb0fe631e1
commit
8004607607
7 changed files with 179 additions and 24 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
/**
|
||||
* clone a chat message
|
||||
*@param message #LinphoneChatMessage obj
|
||||
*@return #LinphoneChatMessage
|
||||
*/
|
||||
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*);
|
||||
/**
|
||||
* user pointer get function
|
||||
*/
|
||||
void* linphone_chat_message_get_user_data(const LinphoneChatMessage* message);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue