Commit edd42fcf authored by Ghislain MARY's avatar Ghislain MARY

Rework sal to be able multipart LinphoneContent objects.

parent 96d249c6
......@@ -166,8 +166,7 @@ belle_sip_response_t *sal_create_response_from_request(Sal *sal, belle_sip_reque
void sal_op_assign_recv_headers(SalOp *op, belle_sip_message_t *incoming);
void sal_op_add_body(SalOp *op, belle_sip_message_t *req, const SalBody *body);
bool_t sal_op_get_body(SalOp *op, belle_sip_message_t *msg, SalBody *salbody);
SalBodyHandler * sal_op_get_body_handler(SalOp *op, belle_sip_message_t *msg);
SalReason sal_reason_to_sip_code(SalReason r);
......
......@@ -669,15 +669,19 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
}
}else{
SalBody salbody;
if (sal_op_get_body(op,(belle_sip_message_t*)req,&salbody)) {
if (sal_body_has_type(&salbody,"application","dtmf-relay")){
belle_sip_message_t *msg = BELLE_SIP_MESSAGE(req);
belle_sip_body_handler_t *body_handler = BELLE_SIP_BODY_HANDLER(sal_op_get_body_handler(op, msg));
if (body_handler) {
belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_type_t);
if (content_type
&& (strcmp(belle_sip_header_content_type_get_type(content_type), "application") == 0)
&& (strcmp(belle_sip_header_content_type_get_subtype(content_type), "dtmf-relay") == 0)) {
char tmp[10];
if (sal_lines_get_value(salbody.data, "Signal",tmp, sizeof(tmp))){
if (sal_lines_get_value(belle_sip_message_get_body(msg), "Signal",tmp, sizeof(tmp))){
op->base.root->callbacks.dtmf_received(op,tmp[0]);
}
}else
op->base.root->callbacks.info_received(op,&salbody);
op->base.root->callbacks.info_received(op, (SalBodyHandler *)body_handler);
} else {
op->base.root->callbacks.info_received(op,NULL);
}
......
......@@ -77,7 +77,7 @@ static void subscribe_process_timeout(void *user_ctx, const belle_sip_timeout_ev
static void subscribe_process_transaction_terminated(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) {
}
static void handle_notify(SalOp *op, belle_sip_request_t *req, const char *eventname, SalBody * body){
static void handle_notify(SalOp *op, belle_sip_request_t *req, const char *eventname, SalBodyHandler* body_handler){
SalSubscribeStatus sub_state;
belle_sip_header_subscription_state_t* subscription_state_header=belle_sip_message_get_header_by_type(req,belle_sip_header_subscription_state_t);
belle_sip_response_t* resp;
......@@ -89,7 +89,7 @@ static void handle_notify(SalOp *op, belle_sip_request_t *req, const char *event
} else
sub_state=SalSubscribeActive;
sal_op_ref(op);
op->base.root->callbacks.notify(op,sub_state,eventname,body);
op->base.root->callbacks.notify(op,sub_state,eventname,body_handler);
resp=sal_op_create_response_from_request(op,req,200);
belle_sip_server_transaction_send_response(server_transaction,resp);
sal_op_unref(op);
......@@ -102,7 +102,7 @@ static void subscribe_process_request_event(void *op_base, const belle_sip_reque
belle_sip_dialog_state_t dialog_state;
belle_sip_header_expires_t* expires = belle_sip_message_get_header_by_type(req,belle_sip_header_expires_t);
belle_sip_header_t *event_header;
SalBody body;
belle_sip_body_handler_t *body_handler;
belle_sip_response_t* resp;
const char *eventname=NULL;
const char *method=belle_sip_request_get_method(req);
......@@ -112,7 +112,7 @@ static void subscribe_process_request_event(void *op_base, const belle_sip_reque
op->pending_server_trans=server_transaction;
event_header=belle_sip_message_get_header((belle_sip_message_t*)req,"Event");
sal_op_get_body(op,(belle_sip_message_t*)req,&body);
body_handler = BELLE_SIP_BODY_HANDLER(sal_op_get_body_handler(op, BELLE_SIP_MESSAGE(req)));
if (event_header==NULL){
ms_warning("No event header in incoming SUBSCRIBE.");
......@@ -132,7 +132,7 @@ static void subscribe_process_request_event(void *op_base, const belle_sip_reque
belle_sip_dialog_set_application_data(op->dialog, sal_op_ref(op));
ms_message("new incoming subscription from [%s] to [%s]",sal_op_get_from(op),sal_op_get_to(op));
}else{ /*this is a NOTIFY*/
handle_notify(op,req,eventname,&body);
handle_notify(op, req, eventname, (SalBodyHandler *)body_handler);
return;
}
}
......@@ -140,7 +140,10 @@ static void subscribe_process_request_event(void *op_base, const belle_sip_reque
switch(dialog_state) {
case BELLE_SIP_DIALOG_NULL: {
op->base.root->callbacks.subscribe_received(op,eventname,body.type ? &body : NULL);
const char *type = NULL;
belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req), belle_sip_header_content_type_t);
if (content_type) type = belle_sip_header_content_type_get_type(content_type);
op->base.root->callbacks.subscribe_received(op, eventname, type ? (SalBodyHandler *)body_handler : NULL);
break;
}
case BELLE_SIP_DIALOG_EARLY:
......@@ -149,7 +152,7 @@ static void subscribe_process_request_event(void *op_base, const belle_sip_reque
case BELLE_SIP_DIALOG_CONFIRMED:
if (strcmp("NOTIFY",method)==0) {
handle_notify(op,req,eventname,&body);
handle_notify(op, req, eventname, (SalBodyHandler *)body_handler);
} else if (strcmp("SUBSCRIBE",method)==0) {
/*either a refresh of an unsubscribe*/
if (expires && belle_sip_header_expires_get_expires(expires)>0) {
......@@ -185,7 +188,7 @@ void sal_op_subscribe_fill_cbs(SalOp*op) {
}
int sal_subscribe(SalOp *op, const char *from, const char *to, const char *eventname, int expires, const SalBody *body){
int sal_subscribe(SalOp *op, const char *from, const char *to, const char *eventname, int expires, const SalBodyHandler *body_handler){
belle_sip_request_t *req=NULL;
if (from)
......@@ -207,13 +210,13 @@ int sal_subscribe(SalOp *op, const char *from, const char *to, const char *event
}
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->event);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires)));
sal_op_add_body(op,(belle_sip_message_t*)req,body);
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(body_handler));
return sal_op_send_and_create_refresher(op,req,expires,subscribe_refresher_listener);
}else 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);
/* modify last request to update body*/
sal_op_add_body(op,(belle_sip_message_t*)last_req,body);
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(last_req), BELLE_SIP_BODY_HANDLER(body_handler));
return belle_sip_refresher_refresh(op->refresher,expires);
}
ms_warning("sal_subscribe(): no dialog and no refresher ?");
......@@ -224,7 +227,7 @@ int sal_unsubscribe(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);
sal_op_add_body(op,(belle_sip_message_t*)last_req,NULL);
belle_sip_message_set_body(BELLE_SIP_MESSAGE(last_req), NULL, 0);
belle_sip_refresher_refresh(op->refresher,0);
return 0;
}
......@@ -247,7 +250,7 @@ int sal_subscribe_decline(SalOp *op, SalReason reason){
return 0;
}
int sal_notify(SalOp *op, const SalBody *body){
int sal_notify(SalOp *op, const SalBodyHandler *body_handler){
belle_sip_request_t* notify;
if (!op->dialog) return -1;
......@@ -258,8 +261,7 @@ int sal_notify(SalOp *op, const SalBody *body){
belle_sip_message_add_header(BELLE_SIP_MESSAGE(notify)
,BELLE_SIP_HEADER(belle_sip_header_subscription_state_create(BELLE_SIP_SUBSCRIPTION_STATE_ACTIVE,600)));
sal_op_add_body(op,(belle_sip_message_t*)notify, body);
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(notify), BELLE_SIP_BODY_HANDLER(body_handler));
return sal_op_send_request(op,notify);
}
......
......@@ -706,50 +706,17 @@ const char *sal_op_get_remote_contact(const SalOp *op){
return op->base.remote_contact;
}
void sal_op_add_body(SalOp *op, belle_sip_message_t *req, const SalBody *body){
belle_sip_message_remove_header((belle_sip_message_t*)req,"Content-type");
belle_sip_message_remove_header((belle_sip_message_t*)req,"Content-length");
belle_sip_message_remove_header((belle_sip_message_t*)req,"Content-encoding");
belle_sip_message_set_body((belle_sip_message_t*)req,NULL,0);
if (body && body->type && body->subtype && body->data){
belle_sip_message_add_header((belle_sip_message_t*)req,
(belle_sip_header_t*)belle_sip_header_content_type_create(body->type,body->subtype));
belle_sip_message_add_header((belle_sip_message_t*)req,
(belle_sip_header_t*)belle_sip_header_content_length_create(body->size));
belle_sip_message_set_body((belle_sip_message_t*)req,(const char*)body->data,body->size);
if (body->encoding){
belle_sip_message_add_header((belle_sip_message_t*)req,(belle_sip_header_t*)
belle_sip_header_create("Content-encoding",body->encoding));
}
}
}
bool_t sal_op_get_body(SalOp *op, belle_sip_message_t *msg, SalBody *salbody){
const char *body = NULL;
belle_sip_header_content_type_t *content_type;
belle_sip_header_content_length_t *clen=NULL;
belle_sip_header_t *content_encoding;
content_type=belle_sip_message_get_header_by_type(msg,belle_sip_header_content_type_t);
if (content_type){
body=belle_sip_message_get_body(msg);
clen=belle_sip_message_get_header_by_type(msg,belle_sip_header_content_length_t);
}
content_encoding=belle_sip_message_get_header(msg,"Content-encoding");
memset(salbody,0,sizeof(SalBody));
if (content_type && body && clen) {
salbody->type=belle_sip_header_content_type_get_type(content_type);
salbody->subtype=belle_sip_header_content_type_get_subtype(content_type);
salbody->data=body;
salbody->size=belle_sip_header_content_length_get_content_length(clen);
if (content_encoding)
salbody->encoding=belle_sip_header_get_unparsed_value(content_encoding);
return TRUE;
}
return FALSE;
SalBodyHandler * sal_op_get_body_handler(SalOp *op, belle_sip_message_t *msg) {
belle_sip_body_handler_t *body_handler = belle_sip_message_get_body_handler(msg);
if (body_handler != NULL) {
belle_sip_header_content_type_t *content_type = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_type_t);
belle_sip_header_content_length_t *content_length = belle_sip_message_get_header_by_type(msg, belle_sip_header_content_length_t);
belle_sip_header_t *content_encoding = belle_sip_message_get_header(msg, "Content-Encoding");
if (content_type != NULL) belle_sip_body_handler_add_header(body_handler, BELLE_SIP_HEADER(content_type));
if (content_length != NULL) belle_sip_body_handler_add_header(body_handler, BELLE_SIP_HEADER(content_length));
if (content_encoding != NULL) belle_sip_body_handler_add_header(body_handler, content_encoding);
}
return (SalBodyHandler *)body_handler;
}
void sal_op_set_privacy(SalOp* op,SalPrivacyMask privacy) {
......
......@@ -19,12 +19,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "sal_impl.h"
int sal_send_info(SalOp *op, const char *from, const char *to, const SalBody *body){
int sal_send_info(SalOp *op, const char *from, const char *to, const SalBodyHandler *body_handler){
if (op->dialog){
belle_sip_request_t *req;
belle_sip_dialog_enable_pending_trans_checking(op->dialog,op->base.root->pending_trans_checking);
req=belle_sip_dialog_create_queued_request(op->dialog,"INFO");
sal_op_add_body(op,(belle_sip_message_t*)req,body);
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(body_handler));
return sal_op_send_request(op,req);
}
return -1;
......
......@@ -96,7 +96,7 @@ int sal_publish_presence(SalOp *op, const char *from, const char *to, int expire
}
}
int sal_publish(SalOp *op, const char *from, const char *to, const char *eventname, int expires, const SalBody *body){
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;
if(!op->refresher || !belle_sip_refresher_get_transaction(op->refresher)) {
if (from)
......@@ -114,7 +114,7 @@ int sal_publish(SalOp *op, const char *from, const char *to, const char *eventna
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",eventname));
sal_op_add_body(op,BELLE_SIP_MESSAGE(req),body);
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(body_handler));
if (expires!=-1)
return sal_op_send_and_create_refresher(op,req,expires,publish_refresher_listener);
else return sal_op_send_request(op,req);
......@@ -123,7 +123,11 @@ int sal_publish(SalOp *op, const char *from, const char *to, const char *eventna
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));
/*update body*/
sal_op_add_body(op,BELLE_SIP_MESSAGE(last_publish),expires!=0 ? body : NULL);
if (expires == 0) {
belle_sip_message_set_body(BELLE_SIP_MESSAGE(last_publish), NULL, 0);
} else {
belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(last_publish), BELLE_SIP_BODY_HANDLER(body_handler));
}
return belle_sip_refresher_refresh(op->refresher,expires==-1 ? BELLE_SIP_REFRESHER_REUSE_EXPIRES : expires);
}
}
......@@ -1276,9 +1276,9 @@ static void text_delivery_update(SalOp *op, SalTextDeliveryStatus status){
}
}
static void info_received(SalOp *op, const SalBody *body){
static void info_received(SalOp *op, SalBodyHandler *body_handler){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
linphone_core_notify_info_message(lc,op,body);
linphone_core_notify_info_message(lc,op,body_handler);
}
static void subscribe_response(SalOp *op, SalSubscribeStatus status){
......@@ -1299,7 +1299,7 @@ static void subscribe_response(SalOp *op, SalSubscribeStatus status){
}
}
static void notify(SalOp *op, SalSubscribeStatus st, const char *eventname, const SalBody *body){
static void notify(SalOp *op, SalSubscribeStatus st, const char *eventname, SalBodyHandler *body_handler){
LinphoneEvent *lev=(LinphoneEvent*)sal_op_get_user_pointer(op);
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
......@@ -1308,7 +1308,7 @@ static void notify(SalOp *op, SalSubscribeStatus st, const char *eventname, cons
lev=linphone_event_new_with_out_of_dialog_op(lc,op,LinphoneSubscriptionOutgoing,eventname);
}
{
LinphoneContent *ct=linphone_content_from_sal_body(body);
LinphoneContent *ct=linphone_content_from_sal_body_handler(body_handler);
if (ct) linphone_core_notify_notify_received(lc,lev,eventname,ct);
}
if (st!=SalSubscribeNone){
......@@ -1316,7 +1316,7 @@ static void notify(SalOp *op, SalSubscribeStatus st, const char *eventname, cons
}
}
static void subscribe_received(SalOp *op, const char *eventname, const SalBody *body){
static void subscribe_received(SalOp *op, const char *eventname, const SalBodyHandler *body_handler){
LinphoneEvent *lev=(LinphoneEvent*)sal_op_get_user_pointer(op);
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
......
......@@ -215,8 +215,7 @@ static void linphone_chat_message_process_response_from_post_file(void *data,
linphone_content_get_subtype(msg->file_transfer_information)));
/* insert it in a multipart body handler which will manage the boundaries of multipart msg */
bh = belle_sip_multipart_body_handler_new(linphone_chat_message_file_transfer_on_progress, msg,
first_part_bh);
bh = belle_sip_multipart_body_handler_new(linphone_chat_message_file_transfer_on_progress, msg, first_part_bh, NULL);
linphone_chat_message_ref(msg);
_release_http_request(msg);
......
This diff is collapsed.
......@@ -40,51 +40,6 @@ struct _LinphoneContent;
**/
typedef struct _LinphoneContent LinphoneContent;
/**
* @deprecated Use LinphoneContent objects instead of this structure.
*/
struct _LinphoneContentPrivate{
char *type; /**<mime type for the data, for example "application"*/
char *subtype; /**<mime subtype for the data, for example "html"*/
void *data; /**<the actual data buffer, usually a string. Null when provided by callbacks #LinphoneCoreFileTransferSendCb or #LinphoneCoreFileTransferRecvCb*/
size_t size; /**<the size of the data buffer, excluding null character despite null character is always set for convenience.
When provided by callback #LinphoneCoreFileTransferSendCb or #LinphoneCoreFileTransferRecvCb, it states the total number of bytes of the transfered file*/
char *encoding; /**<The encoding of the data buffer, for example "gzip"*/
char *name; /**< used by RCS File transfer messages to store the original filename of the file to be downloaded from server */
char *key; /**< used by RCS File transfer messages to store the key to encrypt file if needed */
size_t keyLength; /**< Length of key in bytes */
void *cryptoContext; /**< crypto context used to encrypt file for RCS file transfer */
};
/**
* Alias to the LinphoneContentPrivate struct.
* @deprecated
**/
typedef struct _LinphoneContentPrivate LinphoneContentPrivate;
/**
* Convert a LinphoneContentPrivate structure to a LinphoneContent object.
* @deprecated Utility macro to ease porting existing code from LinphoneContentPrivate structure (old LinphoneContent structure) to new LinphoneContent object.
*/
#define LINPHONE_CONTENT(lcp) linphone_content_private_to_linphone_content(lcp)
/**
* Convert a LinphoneContentPrivate structure to a LinphoneContent object.
* @deprecated Utility function to ease porting existing code from LinphoneContentPrivate structure (old LinphoneContent structure) to new LinphoneContent object.
*/
LINPHONE_PUBLIC LinphoneContent * linphone_content_private_to_linphone_content(const LinphoneContentPrivate *lcp);
/**
* Convert a LinphoneContent object to a LinphoneContentPrivate structure.
* @deprecated Utility macro to ease porting existing code from LinphoneContentPrivate structure (old LinphoneContent structure) to new LinphoneContent object.
*/
#define LINPHONE_CONTENT_PRIVATE(lc) linphone_content_to_linphone_content_private(lc)
/**
* Convert a LinphoneContent object to a LinphoneContentPrivate structure.
* @deprecated Utility function to ease porting existing code from LinphoneContentPrivate structure (old LinphoneContent structure) to new LinphoneContent object.
*/
LINPHONE_PUBLIC LinphoneContentPrivate * linphone_content_to_linphone_content_private(const LinphoneContent *content);
/**
* Create a content with default values from Linphone core.
......@@ -219,6 +174,16 @@ LINPHONE_PUBLIC const char * linphone_content_get_name(const LinphoneContent *co
*/
LINPHONE_PUBLIC void linphone_content_set_name(LinphoneContent *content, const char *name);
LINPHONE_PUBLIC bool_t linphone_content_is_multipart(const LinphoneContent *content);
LINPHONE_PUBLIC LinphoneContent * linphone_content_get_part(const LinphoneContent *content);
LINPHONE_PUBLIC void linphone_content_add_part(LinphoneContent *content, LinphoneContent *part);
LINPHONE_PUBLIC const char * linphone_content_get_custom_header(const LinphoneContent *content, const char *header_name);
LINPHONE_PUBLIC void linphone_content_add_custom_header(LinphoneContent *content, const char *header_name, const char *header_value);
/**
* @}
*/
......
......@@ -151,7 +151,7 @@ LinphoneEvent *linphone_core_subscribe(LinphoneCore *lc, const LinphoneAddress *
int linphone_event_send_subscribe(LinphoneEvent *lev, const LinphoneContent *body){
SalBody salbody;
SalBodyHandler *body_handler;
int err;
if (lev->dir!=LinphoneSubscriptionOutgoing){
......@@ -179,7 +179,8 @@ int linphone_event_send_subscribe(LinphoneEvent *lev, const LinphoneContent *bod
lev->send_custom_headers=NULL;
}else sal_op_set_sent_custom_header(lev->op,NULL);
err=sal_subscribe(lev->op,NULL,NULL,lev->name,lev->expires,sal_body_from_content(&salbody,body));
body_handler = sal_body_handler_from_content(body);
err=sal_subscribe(lev->op,NULL,NULL,lev->name,lev->expires,body_handler);
if (err==0){
if (lev->subscription_state==LinphoneSubscriptionNone)
linphone_event_set_state(lev,LinphoneSubscriptionOutgoingInit);
......@@ -216,7 +217,7 @@ int linphone_event_deny_subscription(LinphoneEvent *lev, LinphoneReason reason){
}
int linphone_event_notify(LinphoneEvent *lev, const LinphoneContent *body){
SalBody salbody;
SalBodyHandler *body_handler;
if (lev->subscription_state!=LinphoneSubscriptionActive){
ms_error("linphone_event_notify(): cannot notify if subscription is not active.");
return -1;
......@@ -225,7 +226,8 @@ int linphone_event_notify(LinphoneEvent *lev, const LinphoneContent *body){
ms_error("linphone_event_notify(): cannot notify if not an incoming subscription.");
return -1;
}
return sal_notify(lev->op,sal_body_from_content(&salbody,body));
body_handler = sal_body_handler_from_content(body);
return sal_notify(lev->op, body_handler);
}
LinphoneEvent *linphone_core_create_publish(LinphoneCore *lc, const LinphoneAddress *resource, const char *event, int expires){
......@@ -236,7 +238,7 @@ LinphoneEvent *linphone_core_create_publish(LinphoneCore *lc, const LinphoneAddr
}
static int _linphone_event_send_publish(LinphoneEvent *lev, const LinphoneContent *body, bool_t notify_err){
SalBody salbody;
SalBodyHandler *body_handler;
int err;
if (lev->dir!=LinphoneSubscriptionInvalidDir){
......@@ -247,7 +249,8 @@ static int _linphone_event_send_publish(LinphoneEvent *lev, const LinphoneConten
sal_op_set_sent_custom_header(lev->op,lev->send_custom_headers);
lev->send_custom_headers=NULL;
}else sal_op_set_sent_custom_header(lev->op,NULL);
err=sal_publish(lev->op,NULL,NULL,lev->name,lev->expires,sal_body_from_content(&salbody,body));
body_handler = sal_body_handler_from_content(body);
err=sal_publish(lev->op,NULL,NULL,lev->name,lev->expires,body_handler);
if (err==0){
linphone_event_set_publish_state(lev,LinphonePublishProgress);
}else if (notify_err){
......
......@@ -69,10 +69,10 @@ LinphoneInfoMessage *linphone_core_create_info_message(LinphoneCore *lc){
* @param call the call
* @param info the info message
**/
int linphone_call_send_info_message(LinphoneCall *call, const LinphoneInfoMessage *info){
SalBody body;
sal_op_set_sent_custom_header(call->op,info->headers);
return sal_send_info(call->op,NULL, NULL, sal_body_from_content(&body,info->content));
int linphone_call_send_info_message(LinphoneCall *call, const LinphoneInfoMessage *info) {
SalBodyHandler *body_handler = sal_body_handler_from_content(info->content);
sal_op_set_sent_custom_header(call->op, info->headers);
return sal_send_info(call->op,NULL, NULL, body_handler);
}
/**
......@@ -112,12 +112,12 @@ const LinphoneContent * linphone_info_message_get_content(const LinphoneInfoMess
return (im->content && linphone_content_get_type(im->content)) ? im->content : NULL;
}
void linphone_core_notify_info_message(LinphoneCore* lc,SalOp *op, const SalBody *body){
void linphone_core_notify_info_message(LinphoneCore* lc,SalOp *op, SalBodyHandler *body_handler){
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
if (call){
LinphoneInfoMessage *info=ms_new0(LinphoneInfoMessage,1);
info->headers=sal_custom_header_clone(sal_op_get_recv_custom_header(op));
if (body) info->content=linphone_content_from_sal_body(body);
if (body_handler) info->content=linphone_content_from_sal_body_handler(body_handler);
linphone_core_notify_info_received(lc,call,info);
linphone_info_message_destroy(info);
}
......
......@@ -520,7 +520,7 @@ static void process_response_from_post_file_log_collection(void *data, const bel
(belle_sip_header_t *)belle_sip_header_content_type_create(linphone_content_get_type(core->log_collection_upload_information), linphone_content_get_subtype(core->log_collection_upload_information)));
/* Insert it in a multipart body handler which will manage the boundaries of multipart message */
bh = belle_sip_multipart_body_handler_new(log_collection_upload_on_progress, core, (belle_sip_body_handler_t *)first_part_bh);
bh = belle_sip_multipart_body_handler_new(log_collection_upload_on_progress, core, (belle_sip_body_handler_t *)first_part_bh, NULL);
ua = ms_strdup_printf("%s/%s", linphone_core_get_user_agent_name(), linphone_core_get_user_agent_version());
uri = belle_generic_uri_parse(linphone_core_get_log_collection_upload_server_url(core));
req = belle_http_request_create("POST", uri, belle_sip_header_create("User-Agent", ua), NULL);
......
......@@ -1071,10 +1071,10 @@ const char *linphone_core_create_uuid(LinphoneCore *lc);
void linphone_configure_op(LinphoneCore *lc, SalOp *op, const LinphoneAddress *dest, SalCustomHeader *headers, bool_t with_contact);
void linphone_call_create_op(LinphoneCall *call);
int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer);
void linphone_core_notify_info_message(LinphoneCore* lc,SalOp *op, const SalBody *body);
void linphone_core_notify_info_message(LinphoneCore* lc,SalOp *op, SalBodyHandler *body);
LinphoneContent * linphone_content_new(void);
LinphoneContent * linphone_content_copy(const LinphoneContent *ref);
SalBody *sal_body_from_content(SalBody *body, const LinphoneContent *content);
SalBodyHandler *sal_body_handler_from_content(const LinphoneContent *content);
SalReason linphone_reason_to_sal(LinphoneReason reason);
LinphoneReason linphone_reason_from_sal(SalReason reason);
LinphoneEvent *linphone_event_new(LinphoneCore *lc, LinphoneSubscriptionDir dir, const char *name, int expires);
......@@ -1086,14 +1086,18 @@ LinphoneEvent *linphone_event_new_with_out_of_dialog_op(LinphoneCore *lc, SalOp
void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state);
void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState state);
LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatus ss);
LinphoneContent *linphone_content_from_sal_body(const SalBody *ref);
LinphoneContent *linphone_content_from_sal_body_handler(SalBodyHandler *ref);
void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc);
struct _LinphoneContent {
belle_sip_object_t base;
void *user_data;
struct _LinphoneContentPrivate lcp;
SalBodyHandler *body_handler;
char *name; /**< used by RCS File transfer messages to store the original filename of the file to be downloaded from server */
char *key; /**< used by RCS File transfer messages to store the key to encrypt file if needed */
size_t keyLength; /**< Length of key in bytes */
void *cryptoContext; /**< crypto context used to encrypt file for RCS file transfer */
bool_t owned_fields;
};
......
......@@ -849,10 +849,101 @@ int sal_lines_get_value(const char *data, const char *key, char *value, size_t v
return FALSE;
}
int sal_body_has_type(const SalBody *body, const char *type, const char *subtype){
return body->type && body->subtype
&& strcmp(body->type,type)==0
&& strcmp(body->subtype,subtype)==0;
static belle_sip_header_t * sal_body_handler_find_header(const SalBodyHandler *body_handler, const char *header_name) {
belle_sip_body_handler_t *bsbh = BELLE_SIP_BODY_HANDLER(body_handler);
const belle_sip_list_t *l = belle_sip_body_handler_get_headers(bsbh);
for (; l != NULL; l = l->next) {
belle_sip_header_t *header = BELLE_SIP_HEADER(l->data);
if (strcmp(belle_sip_header_get_name(header), header_name) == 0) {
return header;
}
}
return NULL;
}
SalBodyHandler * sal_body_handler_new(void) {
belle_sip_memory_body_handler_t *body_handler = belle_sip_memory_body_handler_new(NULL, NULL);
return (SalBodyHandler *)BELLE_SIP_BODY_HANDLER(body_handler);
}
SalBodyHandler * sal_body_handler_ref(SalBodyHandler *body_handler) {
return (SalBodyHandler *)belle_sip_object_ref(BELLE_SIP_OBJECT(body_handler));
}
void sal_body_handler_unref(SalBodyHandler *body_handler) {
belle_sip_object_unref(BELLE_SIP_OBJECT(body_handler));
}
const char * sal_body_handler_get_type(const SalBodyHandler *body_handler) {
belle_sip_header_content_type_t *content_type = BELLE_SIP_HEADER_CONTENT_TYPE(sal_body_handler_find_header(body_handler, "Content-Type"));
if (content_type != NULL) {
return belle_sip_header_content_type_get_type(content_type);
}
return NULL;
}
void sal_body_handler_set_type(SalBodyHandler *body_handler, const char *type) {
belle_sip_header_content_type_t *content_type = BELLE_SIP_HEADER_CONTENT_TYPE(sal_body_handler_find_header(body_handler, "Content-Type"));
if (content_type == NULL) {
content_type = belle_sip_header_content_type_new();
belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(body_handler), BELLE_SIP_HEADER(content_type));
}
belle_sip_header_content_type_set_type(content_type, type);
}
const char * sal_body_handler_get_subtype(const SalBodyHandler *body_handler) {
belle_sip_header_content_type_t *content_type = BELLE_SIP_HEADER_CONTENT_TYPE(sal_body_handler_find_header(body_handler, "Content-Type"));
if (content_type != NULL) {
return belle_sip_header_content_type_get_subtype(content_type);
}
return NULL;
}
void sal_body_handler_set_subtype(SalBodyHandler *body_handler, const char *subtype) {
belle_sip_header_content_type_t *content_type = BELLE_SIP_HEADER_CONTENT_TYPE(sal_body_handler_find_header(body_handler, "Content-Type"));
if (content_type == NULL) {
content_type = belle_sip_header_content_type_new();
belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(body_handler), BELLE_SIP_HEADER(content_type));
}
belle_sip_header_content_type_set_subtype(content_type, subtype);
}
const char * sal_body_handler_get_encoding(const SalBodyHandler *body_handler) {
belle_sip_header_t *content_encoding = sal_body_handler_find_header(body_handler, "Content-Encoding");
if (content_encoding != NULL) {
return belle_sip_header_get_unparsed_value(content_encoding);
}
return NULL;
}
void sal_body_handler_set_encoding(SalBodyHandler *body_handler, const char *encoding) {
belle_sip_header_t *content_encoding = sal_body_handler_find_header(body_handler, "Content-Encoding");
if (content_encoding != NULL) {
belle_sip_body_handler_remove_header_from_ptr(BELLE_SIP_BODY_HANDLER(body_handler), content_encoding);
}
belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(body_handler), belle_sip_header_create("Content-Encoding", encoding));
}
void * sal_body_handler_get_data(const SalBodyHandler *body_handler) {
return belle_sip_memory_body_handler_get_buffer(BELLE_SIP_MEMORY_BODY_HANDLER(body_handler));
}
void sal_body_handler_set_data(SalBodyHandler *body_handler, void *data) {
belle_sip_memory_body_handler_set_buffer(BELLE_SIP_MEMORY_BODY_HANDLER(body_handler), data);
}
size_t sal_body_handler_get_size(const SalBodyHandler *body_handler) {
return belle_sip_body_handler_get_size(BELLE_SIP_BODY_HANDLER(body_handler));
}
void sal_body_handler_set_size(SalBodyHandler *body_handler, size_t size) {
belle_sip_header_content_length_t *content_length = BELLE_SIP_HEADER_CONTENT_LENGTH(sal_body_handler_find_header(body_handler, "Content-Length"));
if (content_length == NULL) {
content_length = belle_sip_header_content_length_new();
belle_sip_body_handler_add_header(BELLE_SIP_BODY_HANDLER(body_handler), BELLE_SIP_HEADER(content_length));
}
belle_sip_header_content_length_set_content_length(content_length, size);
belle_sip_body_handler_set_size(BELLE_SIP_BODY_HANDLER(body_handler), size);
}
belle_sip_stack_t *sal_get_belle_sip_stack(Sal *sal) {
......
......@@ -55,6 +55,10 @@ struct SalAddress;
typedef struct SalAddress SalAddress;
struct SalBodyHandler;
typedef struct SalBodyHandler SalBodyHandler;
struct SalCustomHeader;
typedef struct SalCustomHeader SalCustomHeader;
......@@ -453,14 +457,6 @@ typedef struct SalAuthInfo{
SalCertificatesChain *certificates;
}SalAuthInfo;
typedef struct SalBody{
const char *type;
const char *subtype;
const void *data;
size_t size;
const char *encoding;
}SalBody;
typedef void (*SalOnCallReceived)(SalOp *op);
typedef void (*SalOnCallRinging)(SalOp *op);
typedef void (*SalOnCallAccepted)(SalOp *op);
......@@ -482,8 +478,8 @@ typedef void (*SalOnTextDeliveryUpdate)(SalOp *op, SalTextDeliveryStatus);
typedef void (*SalOnIsComposingReceived)(SalOp *op, const SalIsComposing *is_composing);
typedef void (*SalOnNotifyRefer)(SalOp *op, SalReferStatus state);
typedef void (*SalOnSubscribeResponse)(SalOp *op, SalSubscribeStatus status);
typedef void (*SalOnNotify)(SalOp *op, SalSubscribeStatus status, const char *event, const SalBody *body);
typedef void (*SalOnSubscribeReceived)(SalOp *salop, const char *event, const SalBody *body);
typedef void (*SalOnNotify)(SalOp *op, SalSubscribeStatus status, const char *event, SalBodyHandler *body);
typedef void (*SalOnSubscribeReceived)(SalOp *salop, const char *event, const SalBodyHandler *body);
typedef void (*SalOnSubscribeClosed)(SalOp *salop);
typedef void (*SalOnParsePresenceRequested)(SalOp *salop, const char *content_type, const char *content_subtype, const char *content, SalPresenceModel **result);
typedef void (*SalOnConvertPresenceToXMLRequested)(SalOp *salop, SalPresenceModel *presence, const char *contact, char **content);
......@@ -491,7 +487,7 @@ typedef void (*SalOnNotifyPresence)(SalOp *op, SalSubscribeStatus ss, SalPresenc
typedef void (*SalOnSubscribePresenceReceived)(SalOp *salop, const char *from);
typedef void (*SalOnSubscribePresenceClosed)(SalOp *salop, const char *from);
typedef void (*SalOnPingReply)(SalOp *salop);
typedef void (*SalOnInfoReceived)(SalOp *salop, const SalBody *body);
typedef void (*SalOnInfoReceived)(SalOp *salop, SalBodyHandler *body);
typedef void (*SalOnPublishResponse)(SalOp *salop);
typedef void (*SalOnExpire)(SalOp *salop);
/*allows sal implementation to access auth info if available, return TRUE if found*/
......@@ -739,16 +735,16 @@ int sal_publish_presence(SalOp *op, const char *from, const char *to, int expire
int sal_ping(SalOp *op, const char *from, const char *to);
/*info messages*/
int sal_send_info(SalOp *op, const char *from, const char *to, const SalBody *body);
int sal_send_info(SalOp *op, const char *from, const char *to, const SalBodyHandler *body);
/*generic subscribe/notify/publish api*/
int sal_subscribe(SalOp *op, const char *from, const char *to, const char *eventname, int expires, const SalBody *body);
int sal_subscribe(SalOp *op, const char *from, const char *to, const char *eventname, int expires, const SalBodyHandler *body);
int sal_unsubscribe(SalOp *op);
int sal_subscribe_accept(SalOp *op);
int sal_subscribe_decline(SalOp *op, SalReason reason);
int sal_notify(SalOp *op, const SalBody *body);
int sal_notify(SalOp *op, const SalBodyHandler *body);
int sal_notify_close(SalOp *op);
int sal_publish(SalOp *op, const char *from, const char *to, const char*event_name, int expires, const SalBody *body);
int sal_publish(SalOp *op, const char *from, const char *to, const char*event_name, int expires, const SalBodyHandler *body);
/*privacy, must be in sync with LinphonePrivacyMask*/
typedef enum _SalPrivacy {
......@@ -844,7 +840,21 @@ unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size);
belle_sip_source_t * sal_create_timer(Sal *sal, belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms, const char* timer_name);
void sal_cancel_timer(Sal *sal, belle_sip_source_t *timer);
int sal_body_has_type(const SalBody *body, const char *type, const char *subtype);
//SalBodyHandler * sal_body_handler_new(const char *type, const char *subtype, void *data, size_t size, const char *encoding);
SalBodyHandler * sal_body_handler_new(void);
SalBodyHandler * sal_body_handler_ref(SalBodyHandler *body_handler);
void sal_body_handler_unref(SalBodyHandler *body_handler);
const char * sal_body_handler_get_type(const SalBodyHandler *body_handler);
void sal_body_handler_set_type(SalBodyHandler *body_handler, const char *type);
const char * sal_body_handler_get_subtype(const SalBodyHandler *body_handler);
void sal_body_handler_set_subtype(SalBodyHandler *body_handler, const char *subtype);
const char * sal_body_handler_get_encoding(const SalBodyHandler *body_handler);