Commit 32b524a5 authored by Eloi Bail's avatar Eloi Bail
Browse files

Presence : missing files

Some files were not added in the previous commit
parent 0c2b5a41
This diff is collapsed.
/*
* Copyright (C) 2012, 2013 LOTES TM LLC
* Author : Andrey Loukhnov <aol.nnov@gmail.com>
*
* This file is a part of pult5-voip
*
* pult5-voip is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* pult5-voip is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this programm. If not, see <http://www.gnu.org/licenses/>.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify pult5-voip, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, LOTES-TM LLC
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#ifndef SIPBUDDY_H
#define SIPBUDDY_H
//#define THIS_FILE sipbuddy.cpp
#include <pjsip-simple/presence.h>
#include <pj/timer.h>
#include <pj/pool.h>
#include <string>
// ELOI #include "misc/noncopyable.h"
#include <pjsip-simple/evsub.h>
#include <pjsip-simple/evsub_msg.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_transport.h>
class SIPAccount;
static void sflphoned_evsub_on_state(pjsip_evsub *sub, pjsip_event *event);
static void sflphoned_evsub_on_tsx_state(pjsip_evsub *sub,
pjsip_transaction *tsx,
pjsip_event *event);
static void sflphoned_evsub_on_rx_notify(pjsip_evsub *sub,
pjsip_rx_data *rdata,
int *p_st_code,
pj_str_t **p_st_text,
pjsip_hdr *res_hdr,
pjsip_msg_body **p_body);
static void buddy_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry);
class SIPBuddy {
public:
SIPBuddy(const std::string &uri, SIPAccount *acc);
~SIPBuddy();
void subscribe();
void unsubscribe();
bool isSubscribed();
std::string getURI();
friend void sflphoned_evsub_on_state( pjsip_evsub *sub, pjsip_event *event);
friend void sflphoned_evsub_on_tsx_state(pjsip_evsub *sub,
pjsip_transaction *tsx,
pjsip_event *event);
friend void sflphoned_evsub_on_rx_notify(pjsip_evsub *sub,
pjsip_rx_data *rdata,
int *p_st_code,
pj_str_t **p_st_text,
pjsip_hdr *res_hdr,
pjsip_msg_body **p_body);
friend void buddy_timer_cb(pj_timer_heap_t *th, pj_timer_entry *entry);
void incLock() {
lock_count++;
}
void decLock() {
lock_count--;
}
private:
//ELOI FIXME NON_COPYABLE(SIPBuddy);
void rescheduleTimer(bool reschedule, unsigned msec);
pj_status_t updatePresence();
bool isTermReason(std::string);
unsigned getTermCode();
SIPAccount *acc;
pj_str_t uri; /**< Buddy URI. */
// unsigned buddy_id; /**< Buddy index. */
pj_str_t contact; /**< Contact learned from subscrp. */
pj_str_t display; /**< Buddy display name. */
pjsip_dialog *dlg; /**< The underlying dialog. */
// pj_str_t host; /**< Buddy host. */
pj_bool_t monitor; /**< Should we monitor? */
pj_str_t name; /**< Buddy name. */
pj_caching_pool cp_;
pj_pool_t *pool; /**< Pool for this buddy. */
// unsigned port; /**< Buddy port. */
pjsip_pres_status status; /**< Buddy presence status. */
pjsip_evsub *sub; /**< Buddy presence subscription */
unsigned term_code; /**< Subscription termination code */
pj_str_t term_reason;/**< Subscription termination reason */
pj_timer_entry timer; /**< Resubscription timer */
void *user_data; /**< Application data. */
int lock_count;
};
#endif /* SIPBUDDY_H */
/*
* Copyright (C) 2012б 2013 LOTES TM LLC
* Author : Andrey Loukhnov <aol.nnov@gmail.com>
*
* This file is a part of pult5-voip
*
* pult5-voip is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* pult5-voip is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this programm. If not, see <http://www.gnu.org/licenses/>.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify pult5-voip, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, LOTES-TM LLC
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string>
#include <bits/stringfwd.h>
#include <bits/basic_string.h>
#define THIS_FILE "sipvoip_pres.cpp"
#include "pjsip/sip_dialog.h"
#include "pjsip/sip_msg.h"
#include "pjsip/sip_ua_layer.h"
#include "pjsip/sip_transaction.h"
#include"pjsip-simple/evsub.h"
#include"pjsip-simple/presence.h"
#include <pj/log.h>
#include <pj/pool.h>
#include <pj/string.h>
#include <pj/compat/string.h>
#include "sipvoip_pres.h"
#include "logger.h"
#include "sipaccount.h"
#include "sipcall.h"
#include "sipvoiplink.h"
#include "manager.h"
/* Callback called when *server* subscription state has changed. */
void pres_evsub_on_srv_state(pjsip_evsub *sub, pjsip_event *event) {
/*****************/
#if 0 // ELOI : useless code ?
pjsip_rx_data *rdata = event->body.rx_msg.rdata;
if(!rdata) {
PJ_LOG(4, (THIS_FILE, "no rdata in presence"));
ERROR("no rdata in presence");
return;
}
// std::string name(rdata->msg_info.to->name.ptr, rdata->msg_info.to->name.slen);
// std::string servername(rdata->msg_info.from->name.ptr, rdata->msg_info.from->name.slen);
#if 0 //ELOI modify account management
std::string accountId = "IP2IP"; //Manager::instance().getAccountIdFromNameAndServer(name, servername);
SIPAccount *acc = (SIPAccount *) Phone::instance().getAccountById(accountId);
#else
std::string accountId = "IP2IP";//ELOI TODO is it proper accountId ?
SIPAccount *acc = Manager::instance().getSipAccount(accountId);
#endif
/******************/
PJ_UNUSED_ARG(event);
//#if 0
ServerPresenceSub *server;
// PJSUA_LOCK();
server = (ServerPresenceSub *) pjsip_evsub_get_mod_data(sub,
((SIPVoIPLink*) (acc->getVoIPLink()))->getModId() /*my_mod_pres.id*/);
PJ_LOG(4, (THIS_FILE, "Server subscription to %s is %s", server->remote, pjsip_evsub_get_state_name(sub)));
if (server) {
pjsip_evsub_state state;
PJ_LOG(4, (THIS_FILE, "Server subscription to %s is %s", server->remote, pjsip_evsub_get_state_name(sub)));
state = pjsip_evsub_get_state(sub);
#if 0
if (false pjsua_var.ua_cfg.cb.on_srv_subscribe_state) {
pj_str_t from;
from = server->dlg->remote.info_str;
(*pjsua_var.ua_cfg.cb.on_srv_subscribe_state)(uapres->acc_id,
uapres, &from,
state, event);
}
#endif
if (state == PJSIP_EVSUB_STATE_TERMINATED) {
pjsip_evsub_set_mod_data(sub, ((SIPVoIPLink*) (acc->getVoIPLink()))->getModId(), NULL);
// pj_list_erase(uapres);
#if 0 //ELOI modify account management
((SIPAccount*) (Phone::instance().getAccountById(server->accId)))->removerServerSubscription(server);
#else
// ELOI ((SIPAccount*) (Manager::instance().getSipAccount(server->accId)))->removerServerSubscription(server);
#endif
}
}
// PJSUA_UNLOCK();
#endif
}
pj_bool_t my_pres_on_rx_request(pjsip_rx_data *rdata) {
return PJ_FALSE;
#if 0 // ELOI useless code ?
pjsip_method *method = &rdata->msg_info.msg->line.req.method;
pj_str_t *str = &method->name;
std::string request(str->ptr, str->slen);
DEBUG("MY PRESENCE: %s ", request.c_str());
DEBUG("\n----------------------BUFFER--------------- \n %s \n ------------------------------------- ",rdata->msg_info.msg_buf);
PJ_LOG(1, (THIS_FILE, "> my_pres_on_rx_request" ));
pj_str_t contact;
pj_status_t status;
pjsip_dialog *dlg;
pjsip_evsub *sub;
pjsip_evsub_user pres_cb;
pjsip_pres_status pres_status;
pjsip_tx_data *tdata;
pjsip_expires_hdr *expires_hdr;
// int expires;
pjsip_status_code st_code;
pj_str_t reason;
pjsua_msg_data msg_data;
pjsip_evsub_state ev_state;
if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, pjsip_get_subscribe_method()) != 0){
ERROR("pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, pjsip_get_subscribe_method()) != 0)" );
ERROR("Method id = %d",rdata->msg_info.msg->line.req.method.id);
ERROR("Method name = %s",rdata->msg_info.msg->line.req.method.name);
return PJ_FALSE;
}
std::string name(rdata->msg_info.to->name.ptr, rdata->msg_info.to->name.slen);
std::string server(rdata->msg_info.from->name.ptr, rdata->msg_info.from->name.slen);
//std::string accountId = "IP2IP"; //Manager::instance().getAccountIdFromNameAndServer(name, server);
std::string accountId = "Account:1371589892"; //Manager::instance().getAccountIdFromNameAndServer(name, server);
#if 0 //ELOI modify account management
SIPAccount *acc = (SIPAccount *) Phone::instance().getAccountById(accountId);
#else
SIPAccount *acc = (SIPAccount *) Manager::instance().getSipAccount(accountId);
#endif
pjsip_endpoint *endpt = ((SIPVoIPLink*) acc->getVoIPLink())->getEndpoint();
contact = pj_str(strdup(acc->getContactHeader().c_str()));
/* Create UAS dialog: */
status = pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, &contact, &dlg);
if (status != PJ_SUCCESS) {
char errmsg[PJ_ERR_MSG_SIZE];
pj_strerror(status, errmsg, sizeof(errmsg));
PJ_LOG(1, (THIS_FILE, "Unable to create UAS dialog for subscription: %s [status=%d]", errmsg, status));
// PJSUA_UNLOCK();
pjsip_endpt_respond_stateless(endpt, rdata, 400, NULL, NULL, NULL);
return PJ_TRUE;
}
/* Init callback: */
pj_bzero(&pres_cb, sizeof(pres_cb));
pres_cb.on_evsub_state = &pres_evsub_on_srv_state;
/* Create server presence subscription: */
status = pjsip_pres_create_uas(dlg, &pres_cb, rdata, &sub);
if (status != PJ_SUCCESS) {
int code = PJSIP_ERRNO_TO_SIP_STATUS(status);
pjsip_tx_data *tdata;
PJ_LOG(1, (THIS_FILE, "Unable to create server subscription %d", status));
if (code == 599 || code > 699 || code < 300) {
code = 400;
}
status = pjsip_dlg_create_response(dlg, rdata, code, NULL, &tdata);
if (status == PJ_SUCCESS) {
status = pjsip_dlg_send_response(dlg, pjsip_rdata_get_tsx(rdata), tdata);
}
// PJSUA_UNLOCK();
return PJ_TRUE;
}
/* Attach our data to the subscription: */
// uapres = PJ_POOL_ALLOC_T(dlg->pool, pjsua_srv_pres);
// uapres->sub = sub;
// uapres->
char* remote = (char*) pj_pool_alloc(dlg->pool, PJSIP_MAX_URL_SIZE);
// uapres->acc_id = acc_id;
// uapres->dlg = dlg;
status = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, dlg->remote.info->uri, remote, PJSIP_MAX_URL_SIZE);
//ACHTUNG !!
pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, dlg->local.info->uri, contact.ptr, PJSIP_MAX_URL_SIZE);
ServerPresenceSub *serverSub = new ServerPresenceSub(sub, remote, accountId, dlg);
if (status < 1)
pj_ansi_strcpy(remote, "<-- url is too long-->");
else
remote[status] = '\0';
// pjsip_evsub_add_header(sub, &acc->cfg.sub_hdr_list);
int modId = ((SIPVoIPLink*) (acc->getVoIPLink()))->getModId();
pjsip_evsub_set_mod_data(sub, modId/*my_mod_pres.id*/, serverSub);
PJ_LOG(1, (THIS_FILE, "addServerSubscription" ));
// ELOI acc->addServerSubscription(serverSub);
/* Add server subscription to the list: */
// pj_list_push_back(&pjsua_var.acc[acc_id].pres_srv_list, uapres);
/* Capture the value of Expires header. */
expires_hdr = (pjsip_expires_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL);
if (expires_hdr)
serverSub->setExpires(expires_hdr->ivalue);
else
serverSub->setExpires(-1);
st_code = (pjsip_status_code) 200;
reason = pj_str("OK");
// pjsua_msg_data_init(&msg_data);
pj_bzero(&msg_data, sizeof(msg_data));
pj_list_init(&msg_data.hdr_list);
pjsip_media_type_init(&msg_data.multipart_ctype, NULL, NULL);
pj_list_init(&msg_data.multipart_parts);
/* Create and send 2xx response to the SUBSCRIBE request: */
status = pjsip_pres_accept(sub, rdata, st_code, &msg_data.hdr_list);
if (status != PJ_SUCCESS) {
PJ_LOG(1, (THIS_FILE, "Unable to accept presence subscription %d", status));
// pj_list_erase(uapres);
pjsip_pres_terminate(sub, PJ_FALSE);
// PJSUA_UNLOCK();
return PJ_FALSE;
}
//TODO: handle rejection case pjsua_pers.c:956
/* If code is 200, send NOTIFY now */
#if 0
if (st_code == 200) {
pjsua_pres_notify(acc_id, uapres, PJSIP_EVSUB_STATE_ACTIVE,
NULL, NULL, PJ_TRUE, &msg_data);
}
#endif
pj_bzero(&pres_status, sizeof(pres_status));
pres_status.info_cnt = 1;
pres_status.info[0].basic_open = true;
/*std::string currState = ((SIPVoIPLink*) acc->getVoIPLink())->getChannelState();
pres_status.info[0].chanState = pj_str(strdup(currState.c_str()));*/
std::string contactWithAngles = acc->getFromUri();
contactWithAngles.erase(contactWithAngles.find('>'));
int semicolon = contactWithAngles.find_first_of(":");
std::string contactWithoutAngles = contactWithAngles.substr(semicolon + 1);
pj_str_t contt = pj_str(strdup(contactWithoutAngles.c_str()));
// acc->get
pj_memcpy(&pres_status.info[0].contact, &contt, sizeof(pj_str_t));
// pres_status.info[0].id = pj_str("000005"); //TODO: tuple id
pjsip_pres_set_status(sub, &pres_status);
ev_state = PJSIP_EVSUB_STATE_ACTIVE;
if (serverSub->expires == 0)
ev_state = PJSIP_EVSUB_STATE_TERMINATED;
/* Create and send the NOTIFY to active subscription: */
pj_str_t stateStr = pj_str("");
tdata = NULL;
status = pjsip_pres_notify(sub, ev_state, &stateStr, &reason, &tdata);
if (status == PJ_SUCCESS) {
/* Force removal of message body if msg_body==FALSE */
//pjsua_process_msg_data(tdata, msg_data);
if (tdata->msg->type == PJSIP_REQUEST_MSG) {
const pj_str_t STR_USER_AGENT = {
"User-Agent",
10 };
pjsip_hdr *h;
pj_str_t ua = pj_str("SFLPhone");
h = (pjsip_hdr*) pjsip_generic_string_hdr_create(tdata->pool, &STR_USER_AGENT, &ua);
pjsip_msg_add_hdr(tdata->msg, h);
}
const pjsip_hdr *hdr;
hdr = msg_data.hdr_list.next;
while (hdr && hdr != &msg_data.hdr_list) {
pjsip_hdr *new_hdr;
new_hdr = (pjsip_hdr*) pjsip_hdr_clone(tdata->pool, hdr);
PJ_LOG(1, ("adding header", new_hdr->name.ptr));
pjsip_msg_add_hdr(tdata->msg, new_hdr);
hdr = hdr->next;
}
if (msg_data.content_type.slen && msg_data.msg_body.slen) {
// pjsip_media_type ctype;
pjsip_msg_body *body;
pj_str_t type = pj_str("application");
pj_str_t subtype = pj_str("pidf+xml");
// pjsua_parse_media_type(tdata->pool, &msg_data->content_type, &ctype);
body = pjsip_msg_body_create(tdata->pool, &type, &subtype, &msg_data.msg_body);
tdata->msg->body = body;
}
// process_msg_data
status = pjsip_pres_send_request(sub, tdata);
}
if (status != PJ_SUCCESS) {
PJ_LOG(1, (THIS_FILE, "Unable to create/send NOTIFY %d", status));
// pj_list_erase(srv_pres);
pjsip_pres_terminate(sub, PJ_FALSE);
// PJSUA_UNLOCK();
return status;
}
return PJ_TRUE;
#endif
}
/*
* Copyright (C) 2012б 2013 LOTES TM LLC
* Author : Andrey Loukhnov <aol.nnov@gmail.com>
*
* This file is a part of pult5-voip
*
* pult5-voip is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* pult5-voip is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this programm. If not, see <http://www.gnu.org/licenses/>.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify pult5-voip, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, LOTES-TM LLC
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#ifndef SIPVOIP_PRES_H
#define SIPVOIP_PRES_H
#include "pjsip/sip_types.h"
#include "pjsip/sip_module.h"
#include "pjsip/sip_msg.h"
#include "pjsip/sip_multipart.h"
//PJ_BEGIN_DECL
extern pj_bool_t my_pres_on_rx_request(pjsip_rx_data *rdata);
static pjsip_module my_mod_pres = {
NULL, NULL, /* prev, next. */
{ "mod-lotes-presence", 18}, /* Name. */
-1, /* Id */
// PJSIP_MOD_PRIORITY_APPLICATION, /* Priority */
PJSIP_MOD_PRIORITY_DIALOG_USAGE,
NULL, /* load() */
NULL, /* start() */
NULL, /* stop() */
NULL, /* unload() */
&my_pres_on_rx_request, /* on_rx_request() */
NULL, /* on_rx_response() */
NULL, /* on_tx_request. */
NULL, /* on_tx_response() */
NULL, /* on_tsx_state() */
};
struct pjsua_msg_data
{
/**
* Additional message headers as linked list. Application can add
* headers to the list by creating the header, either from the heap/pool
* or from temporary local variable, and add the header using
* linked list operation. See pjsip_apps.c for some sample codes.
*/
pjsip_hdr hdr_list;
/**
* MIME type of optional message body.
*/
pj_str_t content_type;
/**
* Optional message body to be added to the message, only when the
* message doesn't have a body.
*/
pj_str_t msg_body;
/**
* Content type of the multipart body. If application wants to send
* multipart message bodies, it puts the parts in \a parts and set
* the content type in \a multipart_ctype. If the message already
* contains a body, the body will be added to the multipart bodies.
*/
pjsip_media_type multipart_ctype;
/**
* List of multipart parts. If application wants to send multipart
* message bodies, it puts the parts in \a parts and set the content
* type in \a multipart_ctype. If the message already contains a body,
* the body will be added to the multipart bodies.
*/
pjsip_multipart_part multipart_parts;
};
//PJ_END_DECL
#endif /* SIPVOIP_PRES_H */
Supports Markdown
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