linphone-iphone/coreapi/sal/message_op.cpp
2017-09-29 17:19:52 +02:00

88 lines
3.5 KiB
C++

#include "message_op.h"
using namespace std;
LINPHONE_BEGIN_NAMESPACE
void SalMessageOp::process_error() {
if (this->dir == Dir::Outgoing) {
this->root->callbacks.message_delivery_update(this, SalMessageDeliveryFailed);
} else {
ms_warning("unexpected io error for incoming message on op [%p]", this);
}
this->state=State::Terminated;
}
void SalMessageOp::process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event) {
SalMessageOp * op = (SalMessageOp *)user_ctx;
sal_error_info_set(&op->error_info,SalReasonIOError, "SIP", 503,"IO Error",NULL);
op->process_error();
}
void SalMessageOp::process_response_event_cb(void *op_base, const belle_sip_response_event_t *event) {
SalMessageOp * op = (SalMessageOp *)op_base;
int code = belle_sip_response_get_status_code(belle_sip_response_event_get_response(event));
SalMessageDeliveryStatus status;
op->set_error_info_from_response(belle_sip_response_event_get_response(event));
if (code>=100 && code <200)
status=SalMessageDeliveryInProgress;
else if (code>=200 && code <300)
status=SalMessageDeliveryDone;
else
status=SalMessageDeliveryFailed;
op->root->callbacks.message_delivery_update(op,status);
}
void SalMessageOp::process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event) {
SalMessageOp * op=(SalMessageOp *)user_ctx;
sal_error_info_set(&op->error_info,SalReasonRequestTimeout, "SIP", 408,"Request timeout",NULL);
op->process_error();
}
void SalMessageOp::process_request_event_cb(void *op_base, const belle_sip_request_event_t *event) {
SalMessageOp * op = (SalMessageOp *)op_base;
op->process_incoming_message(event);
}
void SalMessageOp::fill_cbs() {
static belle_sip_listener_callbacks_t op_message_callbacks = {0};
if (op_message_callbacks.process_io_error==NULL) {
op_message_callbacks.process_io_error=process_io_error_cb;
op_message_callbacks.process_response_event=process_response_event_cb;
op_message_callbacks.process_timeout=process_timeout_cb;
op_message_callbacks.process_request_event=process_request_event_cb;
}
this->callbacks=&op_message_callbacks;
this->type=Type::Message;
}
void SalMessageOpInterface::prepare_message_request(belle_sip_request_t *req, const char* content_type, const char *msg, const char *peer_uri) {
char content_type_raw[256];
size_t content_length = msg?strlen(msg):0;
time_t curtime = ms_time(NULL);
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)));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_content_length_create(content_length)));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_date_create_from_time(&curtime)));
if (msg){
/*don't call set_body() with null argument because it resets content type and content length*/
belle_sip_message_set_body(BELLE_SIP_MESSAGE(req), msg, content_length);
}
}
int SalMessageOp::send_message(const char *from, const char *to, const char* content_type, const char *msg, const char *peer_uri) {
fill_cbs();
if (from) set_from(from);
if (to) set_to(to);
this->dir=Dir::Outgoing;
belle_sip_request_t* req=build_request("MESSAGE");
if (req == NULL ) return -1;
if (get_contact_address()) belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(create_contact()));
prepare_message_request(req, content_type, msg, peer_uri);
return send_request(req);
}
LINPHONE_END_NAMESPACE