c732d49e |
/**@file tdav_session_mcptt.h
* @brief The Media Burst Control Protocol (MCPTT) session.
* Used for OMA PoC control plane
*/
#if !defined(HAVE_TINYMCPTT) || HAVE_TINYMCPTT
#include "tinydav/mcptt/tdav_session_mcptt.h"
#include "tinymcptt/tmcptt_manager.h"
#include "tinyrtp/rtp/trtp_rtp_packet.h"
#include "tinyrtp/rtcp/trtp_rtcp_packet.h"
#include "tinyrtp/rtcp/trtp_rtcp_header.h"
#include "tinyrtp/rtcp/trtp_rtcp_report_app.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_taken.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_idle.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_granted.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_request.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_release.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_ack.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_deny.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_revoke.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_specific.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_queue_position_info.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_queue_position_request.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_preestablished.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_ack_preestablished.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_connect.h"
#include "tinymcptt/packet/tmcptt_mcptt_packet_disconnect.h"
#include "tinymcptt/tmcptt_event.h"
#include "tinymcptt/tmcptt_timers.h"
#include "tinymcptt/tmcptt_counters.h"
#include "tsk_memory.h" /* TSK_FREE */
#include "tsk_timer.h"
/**
This function is in all services tinyDAV
*/
int tdav_mcptt_event_proxy_cb(tmcptt_event_t* _event/*!Not the owner of the object*/)
{
tdav_session_mcptt_t* mcptt;
int ret = 0;
if(!_event || !_event->callback_data){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
mcptt = tsk_object_ref((void*)_event->callback_data);
if(TMEDIA_SESSION_MCPTT(mcptt)->callback.func){
_event->callback_data = TMEDIA_SESSION_MSRP(mcptt)->callback.data; // steal callback data
ret = TMEDIA_SESSION_MCPTT(mcptt)->callback.func(_event); // call callback function()
}
tsk_object_unref(mcptt);
return ret;
}
static int tdav_session_mcptt_alert_user(tdav_session_mcptt_t* self, tmcptt_event_type_t type, tmcptt_message_t* message)
{
int ret;
tdav_session_mcptt_t *session = (tdav_session_mcptt_t*)tsk_object_ref((void*)self);
tmcptt_event_t* _event = tmcptt_event_create(session, type, message);
ret = tdav_mcptt_event_proxy_cb(_event);
TSK_OBJECT_SAFE_FREE(_event);
tsk_object_unref(session);
return ret;
}
static int tdav_session_mcptt_timer_t100_expired_handler(const void* arg, tsk_timer_id_t timer_id)
{
//T100 (Floor release)
tdav_session_mcptt_t* mcptt = (tdav_session_mcptt_t*)arg;
va_list ap;
if (mcptt == tsk_null) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if (mcptt->timer_t100.id != timer_id) {
TSK_DEBUG_ERROR("Incorrect timer identity");
return -1;
}
switch (mcptt->mcptt_status)
{
case mcptt_status_pending_release:
{
if (mcptt->counter_c100.curr_value < mcptt->counter_c100.max_value)
{
va_start(ap, "token");
tdav_session_mcptt_send_release(TMEDIA_SESSION_MCPTT(mcptt), &ap);
va_end(ap);
mcptt->timer_t100.id = tsk_timer_manager_schedule(mcptt->h_timer, mcptt->timer_t100.timeout, tdav_session_mcptt_timer_t100_expired_handler, mcptt);
mcptt->counter_c100.curr_value++;
}
else
mcptt->mcptt_status = mcptt_status_no_permission;
break;
}
}
return 0;
}
static int tdav_session_mcptt_timer_t101_expired_handler(const void* arg, tsk_timer_id_t timer_id)
{
//T101 (Floor request)
tdav_session_mcptt_t* mcptt = (tdav_session_mcptt_t*)arg;
va_list ap;
if (mcptt == tsk_null) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if (mcptt->timer_t101.id != timer_id) {
TSK_DEBUG_ERROR("Incorrect timer identity");
return -1;
}
switch (mcptt->mcptt_status)
{
case mcptt_status_pending_request:
{
if (mcptt->counter_c101.curr_value < mcptt->counter_c101.max_value)
{
va_start(ap, "token");
tdav_session_mcptt_send_request(TMEDIA_SESSION_MCPTT(mcptt), &ap);
va_end(ap);
mcptt->timer_t101.id = tsk_timer_manager_schedule(mcptt->h_timer, mcptt->timer_t101.timeout, tdav_session_mcptt_timer_t101_expired_handler, mcptt);
mcptt->counter_c101.curr_value++;
}
else
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_token_denied, tsk_null);
mcptt->mcptt_status = mcptt_status_no_permission;
}
break;
}
}
return 0;
}
static int tdav_session_mcptt_timer_t103_expired_handler(const void* arg, tsk_timer_id_t timer_id)
{
//T103 (End of RTP media)
tdav_session_mcptt_t* mcptt = (tdav_session_mcptt_t*)arg;
if (mcptt == tsk_null) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if (mcptt->timer_t103.id != timer_id) {
TSK_DEBUG_ERROR("Incorrect timer identity");
return -1;
}
switch (mcptt->mcptt_status)
{
case mcptt_status_no_permission:
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_idle_channel, tsk_null);
break;
}
}
return 0;
}
static int tdav_session_mcptt_timer_t104_expired_handler(const void* arg, tsk_timer_id_t timer_id)
{
//T104 (Floor Queue Position Request)
tdav_session_mcptt_t* mcptt = (tdav_session_mcptt_t*)arg;
va_list ap;
if (mcptt == tsk_null) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if (mcptt->timer_t104.id != timer_id) {
TSK_DEBUG_ERROR("Incorrect timer identity");
return -1;
}
switch (mcptt->mcptt_status)
{
case mcptt_status_queued:
{
if (mcptt->counter_c104.curr_value < mcptt->counter_c104.max_value)
{
va_start(ap, "token");
tdav_session_mcptt_send_queue_position_request(TMEDIA_SESSION_MCPTT(mcptt), &ap);
va_end(ap);
mcptt->timer_t104.id = tsk_timer_manager_schedule(mcptt->h_timer, mcptt->timer_t104.timeout, tdav_session_mcptt_timer_t104_expired_handler, mcptt);
mcptt->counter_c104.curr_value++;
}
else
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_queued_timeout, tsk_null);
va_start(ap, "token");
tdav_session_mcptt_send_release(TMEDIA_SESSION_MCPTT(mcptt), &ap);
va_end(ap);
mcptt->mcptt_status = mcptt_status_pending_release;
}
break;
}
}
return 0;
}
static int tdav_session_mcptt_timer_t132_expired_handler(const void* arg, tsk_timer_id_t timer_id)
{
//T132 (Queued granted user action)
tdav_session_mcptt_t* mcptt = (tdav_session_mcptt_t*)arg;
va_list ap;
if (mcptt == tsk_null) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if (mcptt->timer_t132.id != timer_id) {
TSK_DEBUG_ERROR("Incorrect timer identity");
return -1;
}
switch (mcptt->mcptt_status)
{
case mcptt_status_queued:
{
va_start(ap, "token");
tdav_session_mcptt_send_release(TMEDIA_SESSION_MCPTT(mcptt), &ap);
va_end(ap);
mcptt->mcptt_status = mcptt_status_no_permission;
break;
}
}
return 0;
}
/**
In this function is state machine of mcptt
*/
static int tdav_session_mcptt_cb(const void* callback_data, const trtp_rtcp_packet_t* packet, ...)
{
/*
tdav_session_mcptt_t* mcptt = (tdav_session_mcptt_t*)callback_data;
const trtp_rtcp_report_app_t* rtcp_app = tsk_null;
TSK_DEBUG_INFO("tdav_session_mcptt_cb");
//#define TMCPTT_ALERT_USER(type) \
//{ \
// tdav_session_mcptt_t *session = (tdav_session_mcptt_t*)tsk_object_ref((void*)mcptt); \
// tmcptt_event_t* _event = tmcptt_event_create(session, tsk_false, type); \
// tdav_mcptt_event_proxy_cb(_event); \
// TSK_OBJECT_SAFE_FREE(_event); \
// tsk_object_unref(session); \
//}
if (!packet || !callback_data) {
TSK_DEBUG_ERROR("Invalid MCPTT packet");
return -1;
}
if(packet->header->type != trtp_rtcp_packet_type_app){
TSK_DEBUG_ERROR("Invalid RTCP packet.");
return -1;
}
rtcp_app = (const trtp_rtcp_report_app_t*)packet;
if(tsk_strnicmp(rtcp_app->name, MCPTT_PROTO_NAME, 4) != 0){
TSK_DEBUG_ERROR("Incorrect application");
return -1;
}
TSK_DEBUG_INFO("MCPTT message received from SSRC: %u", rtcp_app->ssrc);
switch(rtcp_app->subtype)
{
case MCPTT_TAKEN_ACK:
{
va_list ap;
va_start(ap, "token");
tdav_session_mcptt_send_ack(TMEDIA_SESSION_MCPTT(mcptt), MCPTT_TAKEN, &ap);
va_end(ap);
}
case MCPTT_TAKEN:
{
tmcptt_mcptt_packet_taken_t* taken_msg = tmcptt_mcptt_packet_taken_create_null();
TSK_DEBUG_INFO("MCPTT TAKEN received");
taken_msg = tmcptt_mcptt_packet_taken_deserialize(rtcp_app->payload, rtcp_app->payload_size);
if(taken_msg)
{
if (tdav_session_mcptt_process_taken(mcptt, taken_msg) != 0) {
TSK_DEBUG_ERROR("Error processing TAKEN message");
return -1;
}
}
break;
}
case MCPTT_IDLE_ACK:
{
va_list ap;
va_start(ap, "token");
tdav_session_mcptt_send_ack(TMEDIA_SESSION_MCPTT(mcptt), MCPTT_IDLE, &ap);
va_end(ap);
}
case MCPTT_IDLE:
{
tmcptt_mcptt_packet_idle_t* idle_msg = tmcptt_mcptt_packet_idle_create_null();
TSK_DEBUG_INFO("MCPTT IDLE received");
idle_msg = tmcptt_mcptt_packet_idle_deserialize(rtcp_app->payload, rtcp_app->payload_size);
if(idle_msg)
{
if (tdav_session_mcptt_process_idle(mcptt, idle_msg) != 0) {
TSK_DEBUG_ERROR("Error processing IDLE message");
return -1;
}
}
break;
}
case MCPTT_GRANTED_ACK:
{
va_list ap;
va_start(ap, "token");
tdav_session_mcptt_send_ack(TMEDIA_SESSION_MCPTT(mcptt), MCPTT_GRANTED, &ap);
va_end(ap);
}
case MCPTT_GRANTED:
{
tmcptt_mcptt_packet_granted_t* granted_msg = tmcptt_mcptt_packet_granted_create_null();
TSK_DEBUG_INFO("MCPTT GRANTED received");
granted_msg = tmcptt_mcptt_packet_granted_deserialize(rtcp_app->payload, rtcp_app->payload_size);
if(granted_msg)
{
if (tdav_session_mcptt_process_granted(mcptt, granted_msg) != 0) {
TSK_DEBUG_ERROR("Error processing GRANTED message");
return -1;
}
}
break;
}
case MCPTT_DENY_ACK:
{
va_list ap;
va_start(ap, "token");
tdav_session_mcptt_send_ack(TMEDIA_SESSION_MCPTT(mcptt), MCPTT_DENY, &ap);
va_end(ap);
}
case MCPTT_DENY:
{
tmcptt_mcptt_packet_deny_t* deny_msg = tmcptt_mcptt_packet_deny_create_null();
TSK_DEBUG_INFO("MCPTT DENY received");
deny_msg = tmcptt_mcptt_packet_deny_deserialize(rtcp_app->payload, rtcp_app->payload_size);
if(deny_msg)
{
if (tdav_session_mcptt_process_deny(mcptt, deny_msg) != 0) {
TSK_DEBUG_ERROR("Error processing DENY message");
return -1;
}
}
}
case MCPTT_QUEUE_POS_INFO_ACK:
{
va_list ap;
va_start(ap, "token");
tdav_session_mcptt_send_ack(TMEDIA_SESSION_MCPTT(mcptt), MCPTT_QUEUE_POS_INFO, &ap);
va_end(ap);
}
case MCPTT_QUEUE_POS_INFO:
{
tmcptt_mcptt_packet_queue_position_info_t* queue_pos_info_msg = tmcptt_mcptt_packet_queue_position_info_create_null();
TSK_DEBUG_INFO("MCPTT QUEUE POSITION INFO received");
queue_pos_info_msg = tmcptt_mcptt_packet_queue_position_info_deserialize(rtcp_app->payload, rtcp_app->payload_size);
if(queue_pos_info_msg)
{
if (tdav_session_mcptt_process_queue_position_info(mcptt, queue_pos_info_msg) != 0) {
TSK_DEBUG_ERROR("Error processing QUEUE POSITION INFO message");
return -1;
}
}
}
case MCPTT_REVOKE:
{
tmcptt_mcptt_packet_revoke_t* revoke_msg = tmcptt_mcptt_packet_revoke_create_null();
TSK_DEBUG_INFO("MCPTT REVOKE received");
revoke_msg = tmcptt_mcptt_packet_revoke_deserialize(rtcp_app->payload, rtcp_app->payload_size);
if(revoke_msg)
{
if (tdav_session_mcptt_process_revoke(mcptt, revoke_msg) != 0) {
TSK_DEBUG_ERROR("Error processing REVOKE message");
return -1;
}
}
}
}
*/
return 0;
}
/* ============ Plugin interface ================= */
int tdav_session_mcptt_set(tmedia_session_t* self, const tmedia_param_t* param)
{
int ret = 0;
tdav_session_mcptt_t* mcptt;
if(!self){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
TSK_DEBUG_INFO("tdav_session_mcptt_set");
mcptt = (tdav_session_mcptt_t*)self;
if(param->value_type == tmedia_pvt_int32)
{
if(tsk_striequals(param->key, "local_ssrc")){
mcptt->local_ssrc = TSK_TO_UINT32((uint8_t*)param->value);
}else if (tsk_striequals(param->key, "priority")){
mcptt->priority_local=TSK_TO_UINT32(((uint8_t*)param->value));
}else if (tsk_striequals(param->key, "implicit")){
mcptt->implicit_local=TSK_TO_UINT32(((uint8_t*)param->value));
}else if (tsk_striequals(param->key, "granted")){
mcptt->granted_local=TSK_TO_UINT32(((uint8_t*)param->value));
}else if (tsk_striequals(param->key, "type_session")){
mcptt->type_session=TSK_TO_UINT32(((uint8_t*)param->value));
}else if (tsk_striequals(param->key, "t100")){
mcptt->timer_t100.timeout = TSK_TO_UINT32(((uint8_t*)param->value));
}else if (tsk_striequals(param->key, "t101")){
mcptt->timer_t101.timeout = TSK_TO_UINT32(((uint8_t*)param->value));
}else if (tsk_striequals(param->key, "t103")){
mcptt->timer_t103.timeout = TSK_TO_UINT32(((uint8_t*)param->value));
}else if (tsk_striequals(param->key, "t104")){
mcptt->timer_t104.timeout = TSK_TO_UINT32(((uint8_t*)param->value));
}else if (tsk_striequals(param->key, "t132")){
mcptt->timer_t132.timeout = TSK_TO_UINT32(((uint8_t*)param->value));
}else if (tsk_striequals(param->key, "c100")){
mcptt->counter_c100.max_value = TSK_TO_UINT32(((uint8_t*)param->value));
}else if (tsk_striequals(param->key, "c101")){
mcptt->counter_c101.max_value = TSK_TO_UINT32(((uint8_t*)param->value));
}else if (tsk_striequals(param->key, "c104")){
mcptt->counter_c104.max_value = TSK_TO_UINT32(((uint8_t*)param->value));
}else if (tsk_striequals(param->key, "queueing_enabled")){
if(TSK_TO_UINT32(((uint8_t*)param->value)) > 0)
mcptt->queueing_enabled = tsk_true;
else
mcptt->queueing_enabled = tsk_false;
}
}
else if(param->value_type == tmedia_pvt_pobject)
{
if (tsk_striequals(param->key, "audio_session")) {
TSK_OBJECT_SAFE_FREE(mcptt->audio_session);
mcptt->audio_session = (tmedia_session_audio_t*)tsk_object_ref(param->value);
}
else if(tsk_striequals(param->key, "multicast_audio_session")) {
TSK_OBJECT_SAFE_FREE(mcptt->multicast_audio_session);
mcptt->multicast_audio_session = (tmedia_session_audio_t*)tsk_object_ref(param->value);
}else if(tsk_striequals(param->key, "mcptt_id_local")) {
TSK_OBJECT_SAFE_FREE(mcptt->mcptt_id_local);
mcptt->mcptt_id_local = (tsip_uri_t*)tsk_object_ref(param->value);
}else if(tsk_striequals(param->key, "mcptt_calling_user_id")) {
TSK_OBJECT_SAFE_FREE(mcptt->mcptt_calling_user_id);
mcptt->mcptt_calling_user_id = (tsip_uri_t*)tsk_object_ref(param->value);
}else if(tsk_striequals(param->key, "mcptt_called_party_id")) {
TSK_OBJECT_SAFE_FREE(mcptt->mcptt_called_party_id);
mcptt->mcptt_called_party_id = (tsip_uri_t*)tsk_object_ref(param->value);
}else if(tsk_striequals(param->key, "mcptt_calling_group_id")) {
TSK_OBJECT_SAFE_FREE(mcptt->mcptt_calling_group_id);
mcptt->mcptt_calling_group_id = (tsip_uri_t*)tsk_object_ref(param->value);
}
}
else if(param->value_type == tmedia_pvt_pchar){
if(tsk_striequals(param->key, "remote-ip")){
// only if no ip associated to the "m=" line
if(param->value && !mcptt->remote_ip){
mcptt->remote_ip = tsk_strdup((const char*)param->value);
}
}
else if(tsk_striequals(param->key, "local-ip")){
tsk_strupdate(&mcptt->local_ip, (const char*)param->value);
}
}
return ret;
}
int tdav_session_mcptt_get(tmedia_session_t* self, tmedia_param_t* param)
{
return -1;
}
int tdav_session_mcptt_prepare(tmedia_session_t* self)
{
tdav_session_mcptt_t* mcptt;
int ret = 0;
TSK_DEBUG_INFO("tdav_session_mcptt_prepare");
mcptt = (tdav_session_mcptt_t*)self;
mcptt->is_multimedia = tsk_true;
mcptt->floorid = 0; //TO-DO
mcptt->media_label = "AAA"; //TO-DO
if(!mcptt->mcptt_manager)
{
mcptt->mcptt_manager = tmcptt_manager_create(mcptt->local_ip);
if(mcptt->mcptt_manager)
{
if((ret = tmcptt_manager_set_port_range(mcptt->mcptt_manager, tmedia_defaults_get_rtp_port_range_start(), tmedia_defaults_get_rtp_port_range_stop()))){
return ret;
}
if((ret = tmcptt_manager_set_mcptt_callback(mcptt->mcptt_manager, tdav_session_mcptt_cb, mcptt))){
return ret;
}
if((ret = tmcptt_manager_prepare(mcptt->mcptt_manager))){
return ret;
}
}
}
if(mcptt->local_port == 0)
mcptt->local_port = mcptt->mcptt_manager->public_port;
if (mcptt->implicit) {
mcptt->mcptt_status = mcptt_status_pending_request;
/* Start timer T101 */
mcptt->timer_t101.id = tsk_timer_manager_schedule(mcptt->h_timer, mcptt->timer_t101.timeout, tdav_session_mcptt_timer_t101_expired_handler, mcptt);
mcptt->counter_c101.curr_value = 1;
}
return ret;
}
int tdav_session_mcptt_start(tmedia_session_t* self)
{
<<<<<<< HEAD
tdav_session_mcptt_t* mcptt;
tmcptt_message_t* msg;
int ret = 0;
va_list ap;
=======
//tdav_session_mcptt_t* mcptt;
int ret = 0;
/*
>>>>>>> 3786611ddac22a4cb96f1767a972e3ad4f4aa13a
TSK_DEBUG_INFO("tdav_session_mcptt_start");
if(!self){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
mcptt = (tdav_session_mcptt_t*)self;
if((ret = tmcptt_manager_set_mcptt_remote(mcptt->mcptt_manager, mcptt->remote_ip, mcptt->remote_port))){
TSK_DEBUG_ERROR("Error setting remote MCPTT parameters");
return -1;
}
if((ret = tmcptt_manager_start(mcptt->mcptt_manager))){
TSK_DEBUG_ERROR("Error starting MCPTT manager");
return -1;
}
<<<<<<< HEAD
if((ret = tsk_timer_manager_start(mcptt->h_timer)) != 0){
TSK_DEBUG_ERROR("Failed to start the timer");
return ret;
}
if (mcptt->implicit && mcptt->implicit_response)
{
if (mcptt->granted && mcptt->granted_response) {
msg = tmcptt_message_create_null();
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_token_granted, msg);
mcptt->mcptt_status = mcptt_status_permission; //No need to send REQUEST nor GRANTED
}
else
mcptt->mcptt_status = mcptt_status_pending_request; //Continue waiting for GRANTED request
} else { //Need to send REQUEST message
va_start(ap, "token");
tdav_session_mcptt_send_request(TMEDIA_SESSION_MCPTT(mcptt), &ap);
va_end(ap);
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t101.id)) {
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t101.id);
mcptt->timer_t101.id = TSK_INVALID_TIMER_ID;
}
/* Start timer T101 */
mcptt->timer_t101.id = tsk_timer_manager_schedule(mcptt->h_timer, mcptt->timer_t101.timeout, tdav_session_mcptt_timer_t101_expired_handler, mcptt);
mcptt->counter_c101.curr_value = 1;
mcptt->mcptt_status = mcptt_status_pending_request; //Wait for GRANTED
}
if(mcptt->audio_session && mcptt->mcptt_status != mcptt_status_permission)
TMEDIA_SESSION(mcptt->audio_session)->lo_held = tsk_true;
else if(mcptt->audio_session && mcptt->mcptt_status == mcptt_status_permission)
TMEDIA_SESSION(mcptt->audio_session)->lo_held = tsk_false;
if(mcptt->multicast_audio_session)
TMEDIA_SESSION(mcptt->multicast_audio_session)->lo_held = tsk_true;
=======
*/
>>>>>>> 3786611ddac22a4cb96f1767a972e3ad4f4aa13a
// /* start the transport */
// if((ret = tnet_transport_start(msrp->transport))){
// goto bail;
// }
//
// switch(msrp->setup){
// case msrp_setup_active:
// case msrp_setup_actpass:
// {
// //
// // ACTIVE
// //
// TSK_DEBUG_INFO("connectto(%s:%d)", msrp->remote_ip, msrp->remote_port);
// if((msrp->connectedFD = tnet_transport_connectto_2(msrp->transport, msrp->remote_ip, msrp->remote_port)) == TNET_INVALID_FD){
// TSK_DEBUG_ERROR("Failed to connect to the remote party");
// ret = -2;
// goto bail;
// }
// else{
// //TSK_DEBUG_INFO("Msrp connected FD=%d", msrp->connectedFD);
// //if((ret = tnet_sockfd_waitUntilWritable(msrp->connectedFD, TDAV_MSRP_CONNECT_TIMEOUT)) && msrp->offerer){
// // TSK_DEBUG_ERROR("%d milliseconds elapsed and the socket is still not connected to (%s:%d).", TDAV_MSRP_CONNECT_TIMEOUT, msrp->remote_ip, msrp->remote_port);
// // goto bail;
// //}
// /* draft-denis-simple-msrp-comedia-02 - 4.2.3. Setting up the connection
// Once the TCP session is established, and if the answerer was the
// active connection endpoint, it MUST send an MSRP request. In
// particular, if it has no pending data to send, it MUST send an empty
// MSRP SEND request. That is necessary for the other endpoint to
// authenticate this TCP session.
//
// ...RFC 4975 - 7.1
// */
// msrp->send_bodiless = tsk_true;
// }
// break;
// }
// default:
// {
// //
// // PASSIVE
// //
// break;
// }
// }
//
// // create and start the receiver
// if(!msrp->receiver){
// if((msrp->receiver = tmsrp_receiver_create(msrp->config, msrp->connectedFD))){
// tnet_transport_set_callback(msrp->transport, TNET_TRANSPORT_CB_F(tdav_transport_layer_stream_cb), msrp);
// if((ret = tmsrp_receiver_start(msrp->receiver, msrp, tdav_msrp_event_proxy_cb))){
// TSK_DEBUG_ERROR("Failed to start the MSRP receiver");
// goto bail;
// }
// }
// }
//
// // create and start the sender
// if(!msrp->sender){
// if((msrp->sender = tmsrp_sender_create(msrp->config, msrp->connectedFD))){
// msrp->sender->chunck_duration = msrp->chunck_duration;
// if((ret = tmsrp_sender_start(msrp->sender))){
// TSK_DEBUG_ERROR("Failed to start the MSRP sender");
// goto bail;
// }
// }
// }
//
//bail:
return ret;
}
int tdav_session_mcptt_pause(tmedia_session_t* self)
{
TSK_DEBUG_ERROR("Not Implemented");
return -1;
}
//BYE
int tdav_session_mcptt_stop(tmedia_session_t* self)
{
tdav_session_mcptt_t* mcptt;
int ret = 0;
if(!self){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
mcptt = (tdav_session_mcptt_t*)self;
tsk_object_unref(mcptt->audio_session);
tsk_object_unref(mcptt->multicast_audio_session);
//
// if(msrp->sender){
// if((ret = tmsrp_sender_stop(msrp->sender))){
// TSK_DEBUG_ERROR("Failed to stop the MSRP sender");
// }
// }
// if(msrp->receiver){
// if((ret = tmsrp_receiver_stop(msrp->receiver))){
// TSK_DEBUG_ERROR("Failed to stop the MSRP receiver");
// }
// }
//
// if(msrp->transport){
// if((ret = tnet_transport_shutdown(msrp->transport))){
// TSK_DEBUG_ERROR("Failed to stop the MSRP transport");
// }
// }
if((ret = tmcptt_manager_stop(mcptt->mcptt_manager))){
TSK_DEBUG_ERROR("Error stopping MCPTT manager");
return -1;
}
return 0;
}
const tsdp_header_M_t* tdav_session_mcptt_get_lo(tmedia_session_t* self)
{
tmedia_session_t* base = TMEDIA_SESSION(self);
tdav_session_mcptt_t* mcptt;
tsk_bool_t changed = tsk_false;
const char* proto_transport = "udp";
const char* proto = "MCPTT";
char* proto_attr;
size_t proto_attr_len = 0;
const char* multi = "multimedia";
const char* mstrm = "mstrm";
const char* priority = "mc_priority";
const char* implicit = "mc_implicit_request";
const char* granted = "mc_granted";
char* fmtp_attr;
char* fmtp_attr_int;
size_t fmtp_attr_len = 0;
tsk_istr_t floorid_str;
TSK_DEBUG_INFO("tdav_session_mcptt_get_lo");
if(!self || !self->plugin){
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
mcptt = (tdav_session_mcptt_t*)self;
if(!base->M.lo)
{
//Create INVITE SRC and recive INVITE
if((base->M.lo = tsdp_header_M_create(base->plugin->media, mcptt->local_port, proto_transport)))
{
fmtp_attr_int=(char*)tsk_calloc(fmtp_attr_len, 1);
tsdp_header_M_add_headers(base->M.lo,
TSDP_FMT_VA_ARGS(proto),
tsk_null);
proto_attr_len = tsk_strlen(proto) + 1;
if(mcptt->is_multimedia)
proto_attr_len += tsk_strlen(multi) + 2;
proto_attr = (char*)tsk_calloc(proto_attr_len, sizeof(char));
if(mcptt->is_multimedia)
tsk_sprintf(&proto_attr, "%s %s=1", proto, multi);
else
tsk_sprintf(&proto_attr, "%s", proto);
tsk_itoa(mcptt->floorid, &floorid_str);
if(base->M.ro){
fmtp_attr_len=tsk_strlen(proto)+tsk_strlen(priority)+3;
fmtp_attr = (char*)tsk_calloc(fmtp_attr_len, sizeof(char));
if(mcptt->priority_remote>mcptt->priority_local && mcptt->priority_local>0 && mcptt->priority_local<10){
tsk_sprintf(&fmtp_attr, "%s %s=%d", proto,priority,mcptt->priority_local);
}else if(mcptt->priority_remote<=mcptt->priority_local && mcptt->priority_remote>0 && mcptt->priority_remote<10){
tsk_sprintf(&fmtp_attr, "%s %s=%d", proto,priority,mcptt->priority_remote);
}else {
tsk_sprintf(&fmtp_attr, "%s %s=%d", proto,priority,0);
}
if(mcptt->granted_remote==tsk_true && mcptt->granted_local==tsk_true){
fmtp_attr_len+=1+tsk_strlen(granted);
fmtp_attr_int=(char*)tsk_calloc(fmtp_attr_len, sizeof(char));
tsk_sprintf(&fmtp_attr_int, "%s;%s",fmtp_attr, granted);
fmtp_attr=tsk_realloc(fmtp_attr, fmtp_attr_len*sizeof(char));
strcpy(fmtp_attr, fmtp_attr_int);
}
if(mcptt->implicit_remote==tsk_true && mcptt->implicit_local==tsk_true){
fmtp_attr_len+=1+tsk_strlen(implicit);
fmtp_attr_int=(char*)tsk_calloc(fmtp_attr_len, sizeof(char));
tsk_sprintf(&fmtp_attr_int, "%s;%s", fmtp_attr, implicit);
fmtp_attr=tsk_realloc(fmtp_attr, fmtp_attr_len*sizeof(char));
strcpy(fmtp_attr, fmtp_attr_int);
}
}else{
fmtp_attr_len=tsk_strlen(proto)+tsk_strlen(priority)+3;
fmtp_attr = (char*)tsk_calloc(fmtp_attr_len, sizeof(char));
if(mcptt->priority_local>0 && mcptt->priority_local<10){
tsk_sprintf(&fmtp_attr, "%s %s=%d", proto,priority,mcptt->priority_local);
}else{
tsk_sprintf(&fmtp_attr, "%s %s=%d", proto,priority,0);
}
if(mcptt->granted_local==tsk_true){
fmtp_attr_len+=1+tsk_strlen(granted);
fmtp_attr_int=(char*)tsk_calloc(fmtp_attr_len, sizeof(char));
tsk_sprintf(&fmtp_attr_int, "%s;%s",fmtp_attr, granted);
fmtp_attr=tsk_realloc(fmtp_attr, fmtp_attr_len*sizeof(char));
strcpy(fmtp_attr, fmtp_attr_int);
}
if(mcptt->implicit_local==tsk_true){
fmtp_attr_len+=1+tsk_strlen(implicit);
fmtp_attr_int=(char*)tsk_calloc(fmtp_attr_len, sizeof(char));
tsk_sprintf(&fmtp_attr_int, "%s;%s", fmtp_attr, implicit);
fmtp_attr=tsk_realloc(fmtp_attr, fmtp_attr_len*sizeof(char));
strcpy(fmtp_attr, fmtp_attr_int);
}
}
//strcpy(array2, array1);
//mc_priority=(0-7)
tsdp_header_M_add_headers(base->M.lo,
TSDP_HEADER_A_VA_ARGS("fmtp",fmtp_attr),
tsk_null);
tsk_free((void**)&fmtp_attr_int);
tsk_free((void**)&proto_attr);
fmtp_attr=tsk_realloc(fmtp_attr, fmtp_attr_len*sizeof(char));
tsk_free((void**)&fmtp_attr);
}
}else{//PROCESS INVITE DSC
}
return self->M.lo;
}
int tdav_session_mcptt_set_ro(tmedia_session_t* self, const tsdp_header_M_t* m)
{
tdav_session_mcptt_t* mcptt;
const tsdp_header_A_t* A_fmtp;
//tsk_bool_t answer;
TSK_DEBUG_INFO("tdav_session_mcptt_set_ro");
if(!self || !m){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
self->M.ro = tsk_object_ref((void*)m);
mcptt = (tdav_session_mcptt_t*)self;
mcptt->remote_port = m->port;
if((A_fmtp = tsdp_header_M_findA(m, "fmtp"))){
int index;
char num_char;
int num;
const char* priority = "mc_priority";
const char* implicit = "mc_implicit_request";
const char* granted = "mc_granted";
if((index=tsk_strindexOf(A_fmtp->value,tsk_strlen(A_fmtp->value),granted))>=0){
mcptt->granted_remote=tsk_true;
}
if((index=tsk_strindexOf(A_fmtp->value,tsk_strlen(A_fmtp->value),implicit))>=0){
mcptt->implicit_remote=tsk_true;
}
if((index=tsk_strindexOf(A_fmtp->value,tsk_strlen(A_fmtp->value),priority))>=0){
num_char=(A_fmtp->value)[1+index+tsk_strlen(priority)];
num=num_char-'0';
if(num>=0 && num<10){
mcptt->priority_remote=(uint32_t)num;
}else{
mcptt->priority_remote=(uint32_t)0;
}
}
}
//
return 0;
}
/* ============ Public functions ================= */
int tdav_session_mcptt_request_token (tmedia_session_mcptt_t* self, va_list *app)
{
<<<<<<< HEAD
tdav_session_mcptt_t* mcptt;
int ret = 0;
if(!(mcptt = (tdav_session_mcptt_t*)self)){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if (mcptt->mcptt_status != mcptt_status_no_permission) {
TSK_DEBUG_ERROR("Incorrect status");
return -1;
}
if (tdav_session_mcptt_send_request(self, app) < 0) {
TSK_DEBUG_ERROR("Error sending REQUEST");
return -1;
}
/* Start timer T101 */
mcptt->timer_t101.id = tsk_timer_manager_schedule(mcptt->h_timer, mcptt->timer_t101.timeout, tdav_session_mcptt_timer_t101_expired_handler, mcptt);
mcptt->counter_c101.curr_value = 1;
mcptt->mcptt_status = mcptt_status_pending_request;
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_request_sent, tsk_null);
return ret;
}
int tdav_session_mcptt_release_token (tmedia_session_mcptt_t* self, va_list *app)
{
tdav_session_mcptt_t* mcptt;
int ret = 0;
if(!(mcptt = (tdav_session_mcptt_t*)self)){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if(mcptt->audio_session) //Stop RTP
TMEDIA_SESSION(mcptt->audio_session)->lo_held = tsk_true;
if(mcptt->multicast_audio_session) //Multicast channel ON. In case someone transmits
TMEDIA_SESSION(mcptt->multicast_audio_session)->ro_held = tsk_false;
if (tdav_session_mcptt_send_release(self, app) < 0) {
TSK_DEBUG_ERROR("Error sending RELEASE");
return -1;
}
mcptt->timer_t100.id = tsk_timer_manager_schedule(mcptt->h_timer, mcptt->timer_t100.timeout, tdav_session_mcptt_timer_t100_expired_handler, mcptt);
mcptt->counter_c100.curr_value = 1;
if (mcptt->mcptt_status == mcptt_status_pending_request) {
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t101.id))
{
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t101.id);
mcptt->timer_t101.id = TSK_INVALID_TIMER_ID;
}
}
if (mcptt->mcptt_status == mcptt_status_queued) {
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t104.id))
{
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t104.id);
mcptt->timer_t104.id = TSK_INVALID_TIMER_ID;
}
}
mcptt->mcptt_status = mcptt_status_pending_release;
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_release_sent, tsk_null);
return ret;
}
int tdav_session_mcptt_request_queue_position (tmedia_session_mcptt_t* self, va_list *app)
{
tdav_session_mcptt_t* mcptt;
int ret = 0;
if(!(mcptt = (tdav_session_mcptt_t*)self)){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if(mcptt->audio_session) //Stop RTP
TMEDIA_SESSION(mcptt->audio_session)->lo_held = tsk_true;
if(mcptt->multicast_audio_session) //Multicast channel ON. In case someone transmits
TMEDIA_SESSION(mcptt->multicast_audio_session)->ro_held = tsk_false;
if (tdav_session_mcptt_send_queue_position_request(self, app) < 0) {
TSK_DEBUG_ERROR("Error sending QUEUE POSITION REQUEST");
return -1;
}
mcptt->timer_t104.id = tsk_timer_manager_schedule(mcptt->h_timer, mcptt->timer_t100.timeout, tdav_session_mcptt_timer_t100_expired_handler, mcptt);
mcptt->counter_c104.curr_value = 1;
mcptt->mcptt_status = mcptt_status_queued;
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_queue_pos_request_sent, tsk_null);
return ret;
}
int tdav_session_mcptt_send_request (tmedia_session_mcptt_t* self, va_list *app)
{
tdav_session_mcptt_t* mcptt;
=======
/*tdav_session_mcptt_t* mcptt;
>>>>>>> 3786611ddac22a4cb96f1767a972e3ad4f4aa13a
tmcptt_mcptt_packet_request_t* request_pkt;
tsk_size_t rtcp_payload_size = 0;
char* rtcp_payload = tsk_null;
trtp_rtcp_report_app_t* rtcp_pkt;
<<<<<<< HEAD
=======
uint64_t ntp_now;*/
>>>>>>> 3786611ddac22a4cb96f1767a972e3ad4f4aa13a
int ret = 0;
/*
if(!(mcptt = (tdav_session_mcptt_t*)self)){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
request_pkt = tmcptt_mcptt_packet_request_create_null();
request_pkt->floor_priority = tmcptt_mcptt_packet_specific_binary_create_null();
request_pkt->floor_priority->f_id = FID_FLOOR_PRIORITY;
request_pkt->floor_priority->f_length = 2;
request_pkt->floor_priority->f_h_value = (uint8_t)mcptt->priority_response;
request_pkt->floor_priority->f_l_value = 0;
request_pkt->floor_indicator = tmcptt_mcptt_packet_specific_binary_16_create_null();
request_pkt->floor_indicator->f_id = FID_FLOOR_INDICATOR;
request_pkt->floor_indicator->f_length = 2;
request_pkt->floor_indicator->f_value = tdav_session_mcptt_get_floor_indicator(self);
rtcp_payload_size = tmcptt_mcptt_packet_request_get_size(request_pkt);
rtcp_payload = (char*)tsk_malloc(rtcp_payload_size*sizeof(char));
if(!rtcp_payload)
return -1;
tmcptt_mcptt_packet_request_serialize_to(request_pkt, rtcp_payload, rtcp_payload_size);
rtcp_pkt = trtp_rtcp_report_app_create_2(MCPTT_PROTO_NAME, MCPTT_REQUEST, mcptt->local_ssrc, rtcp_payload, rtcp_payload_size);
ret = tmcptt_manager_send_mcptt_packet(mcptt->mcptt_manager, rtcp_pkt);
TSK_FREE(rtcp_payload);
<<<<<<< HEAD
=======
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_request_sent, tsk_null);
*/
>>>>>>> 3786611ddac22a4cb96f1767a972e3ad4f4aa13a
return ret;
}
int tdav_session_mcptt_send_release (tmedia_session_mcptt_t* self, va_list *app)
{
tdav_session_mcptt_t* mcptt;
tmcptt_mcptt_packet_release_t* release_pkt;
tsk_size_t rtcp_payload_size = 0;
char* rtcp_payload = tsk_null;
trtp_rtcp_report_app_t* rtcp_pkt;
uint32_t ssrc = 0;
int ret = 0;
if(!(mcptt = (tdav_session_mcptt_t*)self)){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if(mcptt->audio_session) //Stop RTP
TMEDIA_SESSION(mcptt->audio_session)->lo_held = tsk_true;
if(mcptt->multicast_audio_session) //Multicast channel ON. In case someone transmits
TMEDIA_SESSION(mcptt->multicast_audio_session)->ro_held = tsk_false;
release_pkt = tmcptt_mcptt_packet_release_create_null();
release_pkt->floor_indicator = tmcptt_mcptt_packet_specific_binary_16_create_null();
release_pkt->floor_indicator->f_id = FID_FLOOR_INDICATOR;
release_pkt->floor_indicator->f_length = 2;
release_pkt->floor_indicator->f_value = tdav_session_mcptt_get_floor_indicator(self);
rtcp_payload_size = tmcptt_mcptt_packet_release_get_size(release_pkt);
rtcp_payload = (char*)tsk_malloc(rtcp_payload_size*sizeof(char));
if(!rtcp_payload)
return -1;
tmcptt_mcptt_packet_release_serialize_to(release_pkt, rtcp_payload, rtcp_payload_size);
rtcp_pkt = trtp_rtcp_report_app_create_2(MCPTT_PROTO_NAME, MCPTT_RELEASE, mcptt->local_ssrc, rtcp_payload, rtcp_payload_size);
ret = tmcptt_manager_send_mcptt_packet(mcptt->mcptt_manager, rtcp_pkt);
TSK_FREE(rtcp_payload);
return ret;
}
int tdav_session_mcptt_send_ack (tmedia_session_mcptt_t* self, tmcptt_mcptt_packet_type_t type, va_list *app)
{
/*tdav_session_mcptt_t* mcptt;
tmcptt_mcptt_packet_ack_t* ack_pkt;
tsk_size_t rtcp_payload_size = 0;
char* rtcp_payload = tsk_null;
trtp_rtcp_report_app_t* rtcp_pkt;
uint32_t ssrc = 0; */
int ret = 0;
/*
if(!(mcptt = (tdav_session_mcptt_t*)self)){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
ack_pkt = tmcptt_mcptt_packet_ack_create(FLR_SOURCE_PARTICIPANT, type);
rtcp_payload_size = tmcptt_mcptt_packet_ack_get_size(ack_pkt);
rtcp_payload = (char*)tsk_malloc(rtcp_payload_size*sizeof(char));
if(!rtcp_payload)
return -1;
tmcptt_mcptt_packet_ack_serialize_to(ack_pkt, rtcp_payload, rtcp_payload_size);
rtcp_pkt = trtp_rtcp_report_app_create_2(MCPTT_PROTO_NAME, MCPTT_ACK, mcptt->local_ssrc, rtcp_payload, rtcp_payload_size);
ret = tmcptt_manager_send_mcptt_packet(mcptt->mcptt_manager, rtcp_pkt);
TSK_FREE(rtcp_payload);
<<<<<<< HEAD
return ret;
}
int tdav_session_mcptt_send_queue_position_request (tmedia_session_mcptt_t* self, va_list *app)
{
tdav_session_mcptt_t* mcptt;
tmcptt_mcptt_packet_queue_position_request_t* queue_pos_req_pkt;
tsk_size_t rtcp_payload_size = 0;
char* rtcp_payload = tsk_null;
trtp_rtcp_report_app_t* rtcp_pkt;
uint32_t ssrc = 0;
int ret = 0;
if(!(mcptt = (tdav_session_mcptt_t*)self)){
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
if (mcptt->mcptt_status != mcptt_status_queued)
{
TSK_DEBUG_ERROR("Invalid MCPTT status");
return -1;
}
queue_pos_req_pkt = tmcptt_mcptt_packet_queue_position_request_create_null();
rtcp_payload_size = tmcptt_mcptt_packet_queue_position_request_get_size(queue_pos_req_pkt);
rtcp_payload = (char*)tsk_malloc(rtcp_payload_size*sizeof(char));
if(!rtcp_payload)
return -1;
tmcptt_mcptt_packet_queue_position_request_serialize_to(queue_pos_req_pkt, rtcp_payload, rtcp_payload_size);
rtcp_pkt = trtp_rtcp_report_app_create_2(MCPTT_PROTO_NAME, MCPTT_QUEUE_POS_REQ, mcptt->local_ssrc, rtcp_payload, rtcp_payload_size);
ret = tmcptt_manager_send_mcptt_packet(mcptt->mcptt_manager, rtcp_pkt);
TSK_FREE(rtcp_payload);
=======
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_taken_acknowledged, tsk_null);
*/
>>>>>>> 3786611ddac22a4cb96f1767a972e3ad4f4aa13a
return ret;
}
uint16_t tdav_session_mcptt_get_floor_indicator(tmedia_session_mcptt_t* self)
{
//tdav_session_mcptt_t* mcptt;
uint16_t floor_indicator = 0;
/*
if(!(mcptt = (tdav_session_mcptt_t*)self)){
TSK_DEBUG_ERROR("Invalid parameter");
return 0;
}
if (mcptt->session_type == mcptt_session_type_private ||
mcptt->session_type == mcptt_session_type_group_prearranged ||
mcptt->session_type == mcptt_session_type_group_chat)
floor_indicator = FLR_IND_NORMAL_CALL;
if (mcptt->is_broadcast == tsk_true)
floor_indicator = FLR_IND_BROADCAST_GRP_CALL;
if (mcptt->is_emergency == tsk_true)
floor_indicator |= FLR_IND_EMERGENCY_CALL;
if (mcptt->is_imminent_peril == tsk_true)
floor_indicator |= FLR_IND_IMMINENT_PERIL_CALL;
if (mcptt->queueing_enabled == tsk_true)
floor_indicator |= FLR_IND_QUEUEING_SUPPORTED;
<<<<<<< HEAD
if (mcptt->is_dual_floor == tsk_true)
floor_indicator |= FLR_IND_DUAL_FLOOR;
=======
*/
>>>>>>> 3786611ddac22a4cb96f1767a972e3ad4f4aa13a
return floor_indicator;
}
int tdav_session_mcptt_process_taken(tdav_session_mcptt_t* mcptt, tmcptt_mcptt_packet_taken_t* taken_msg)
{
tmcptt_message_t* msg = tmcptt_message_create_null();
if (mcptt == tsk_null)
return -1;
if (taken_msg == tsk_null)
return -1;
if (taken_msg->granted_party_id)
{
TSK_DEBUG_INFO("MCPTT TAKEN client name: %.*s", taken_msg->granted_party_id->f_length, taken_msg->granted_party_id->f_value);
msg->user = (char*)tsk_malloc((taken_msg->granted_party_id->f_length + 1) * sizeof(char));
memcpy(msg->user, taken_msg->granted_party_id->f_value, taken_msg->granted_party_id->f_length * sizeof(char));
msg->user[taken_msg->granted_party_id->f_length] = '\0';
}
if ((taken_msg->floor_indicator->f_value & FLR_IND_BROADCAST_GRP_CALL) == FLR_IND_BROADCAST_GRP_CALL)
msg->is_broadcast_call = tsk_true;
switch (mcptt->mcptt_status)
{
case mcptt_status_no_permission:
{
if (msg->is_broadcast_call)
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_token_taken, msg);
/* Cannot start timer T103 (End of RTP media).
Cannot access RTP packet reception function */
// mcptt->timer_t103.id = tsk_timer_manager_schedule(mcptt->h_timer, mcptt->timer_t103.timeout, tdav_session_mcptt_timer_t103_expired_handler, mcptt);
break;
}
case mcptt_status_pending_request:
{
if (tsk_strcmp(taken_msg->granted_party_id->f_value, mcptt->local_mcptt_id) != 0) {
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_token_taken, msg);
if(mcptt->audio_session) //Stop RTP transmission
TMEDIA_SESSION(mcptt->audio_session)->lo_held = tsk_true;
if(mcptt->multicast_audio_session) //Multicast channel ON
{
TMEDIA_SESSION(mcptt->multicast_audio_session)->ro_held = tsk_false;
TMEDIA_SESSION(mcptt->multicast_audio_session)->lo_held = tsk_true;
}
if (mcptt->queueing_enabled == tsk_false)
{
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t101.id)) {
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t101.id);
mcptt->timer_t101.id = TSK_INVALID_TIMER_ID;
}
/* Cannot start timer T103 (End of RTP media) */
//mcptt->timer_t103.id = tsk_timer_manager_schedule(mcptt->h_timer, mcptt->timer_t103.timeout, tdav_session_mcptt_timer_t103_expired_handler, mcptt);
mcptt->mcptt_status = mcptt_status_no_permission;
}
}
break;
}
case mcptt_status_pending_release:
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_token_taken, msg);
//Start timer T103??
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t100.id))
{
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t100.id);
mcptt->timer_t100.id = TSK_INVALID_TIMER_ID;
}
mcptt->mcptt_status = mcptt_status_no_permission;
break;
}
case mcptt_status_queued:
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_token_taken, msg);
break;
}
}
return 0;
}
int tdav_session_mcptt_process_idle(tdav_session_mcptt_t* mcptt, tmcptt_mcptt_packet_idle_t* idle_msg)
{
tmcptt_message_t* msg = tmcptt_message_create_null();
if (mcptt == tsk_null)
return -1;
if (idle_msg == tsk_null)
return -1;
if(idle_msg->message_seq_num)
TSK_DEBUG_INFO("MCPTT IDLE seq num: %u", idle_msg->message_seq_num->f_value);
if ((idle_msg->floor_indicator->f_value & FLR_IND_BROADCAST_GRP_CALL) == FLR_IND_BROADCAST_GRP_CALL)
msg->is_broadcast_call = tsk_true;
switch (mcptt->mcptt_status)
{
case mcptt_status_no_permission:
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_idle_channel, msg);
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t103.id))
{
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t103.id);
mcptt->timer_t103.id = TSK_INVALID_TIMER_ID;
}
break;
}
case mcptt_status_pending_release:
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_idle_channel, msg);
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t100.id))
{
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t100.id);
mcptt->timer_t100.id = TSK_INVALID_TIMER_ID;
}
if (!msg->is_broadcast_call ||
(idle_msg->floor_indicator->f_value & FLR_IND_NORMAL_CALL) == FLR_IND_NORMAL_CALL)
mcptt->mcptt_status = mcptt_status_no_permission;
if (msg->is_broadcast_call)
mcptt->mcptt_status = mcptt_status_releasing;
break;
}
case mcptt_status_queued:
{
mcptt->mcptt_status = mcptt_status_no_permission;
break;
}
}
return 0;
}
int tdav_session_mcptt_process_granted(tdav_session_mcptt_t* mcptt, tmcptt_mcptt_packet_granted_t* granted_msg)
{
tmcptt_message_t* msg = tmcptt_message_create_null();
if (mcptt == tsk_null)
return -1;
if (granted_msg == tsk_null)
return -1;
if (granted_msg->duration) {
TSK_DEBUG_INFO("MCPTT GRANTED duration: %u", granted_msg->duration->f_value);
msg->time = granted_msg->duration->f_value;
}
if (granted_msg->floor_priority)
TSK_DEBUG_INFO("MCPTT GRANTED priority: %u", granted_msg->floor_priority->f_h_value);
if ((granted_msg->floor_indicator->f_value & FLR_IND_BROADCAST_GRP_CALL) == FLR_IND_BROADCAST_GRP_CALL)
msg->is_broadcast_call = tsk_true;
if ((granted_msg->floor_indicator->f_value & FLR_IND_DUAL_FLOOR) == FLR_IND_DUAL_FLOOR)
mcptt->is_dual_floor = tsk_true;
switch (mcptt->mcptt_status)
{
case mcptt_status_pending_request:
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_token_granted, msg);
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t103.id))
{
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t103.id);
mcptt->timer_t103.id = TSK_INVALID_TIMER_ID;
}
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t101.id))
{
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t101.id);
mcptt->timer_t101.id = TSK_INVALID_TIMER_ID;
}
mcptt->mcptt_status = mcptt_status_permission;
if(mcptt->audio_session) //Start RTP transmission
TMEDIA_SESSION(mcptt->audio_session)->lo_held = tsk_false;
if(mcptt->multicast_audio_session) //Multicast channel OFF. We should not hear ourselves
{
TMEDIA_SESSION(mcptt->multicast_audio_session)->ro_held = tsk_true;
TMEDIA_SESSION(mcptt->multicast_audio_session)->lo_held = tsk_true; //Just unicast uplink stream
}
break;
}
case mcptt_status_queued:
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_token_granted, msg);
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t104.id))
{
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t104.id);
mcptt->timer_t104.id = TSK_INVALID_TIMER_ID;
}
mcptt->timer_t132.id = tsk_timer_manager_schedule(mcptt->h_timer, mcptt->timer_t132.timeout, tdav_session_mcptt_timer_t132_expired_handler, mcptt);
mcptt->mcptt_status = mcptt_status_permission;
if(mcptt->audio_session) //Start RTP transmission
TMEDIA_SESSION(mcptt->audio_session)->lo_held = tsk_false;
if(mcptt->multicast_audio_session) //Multicast channel OFF. We should not hear ourselves
{
TMEDIA_SESSION(mcptt->multicast_audio_session)->ro_held = tsk_true;
TMEDIA_SESSION(mcptt->multicast_audio_session)->lo_held = tsk_true; //Just unicast uplink stream
}
break;
}
}
return 0;
}
int tdav_session_mcptt_process_deny(tdav_session_mcptt_t* mcptt, tmcptt_mcptt_packet_deny_t* deny_msg)
{
tmcptt_message_t* msg = tmcptt_message_create_null();
tsk_size_t size = 0;
if (mcptt == tsk_null)
return -1;
if (deny_msg == tsk_null)
return -1;
if (deny_msg->reject_cause)
TSK_DEBUG_INFO("MCPTT DENY reject cause: %u (%s)", deny_msg->reject_cause->f_bin_value, deny_msg->reject_cause->f_txt_value);
msg->reason_code = deny_msg->reject_cause->f_bin_value;
size = deny_msg->reject_cause->f_length - sizeof(uint16_t);
if (size > 0)
{
msg->reason_phrase = (char*)tsk_malloc((size + 1) * sizeof(char));
memcpy(msg->reason_phrase, deny_msg->reject_cause, size);
msg->reason_phrase[size] = '\0';
}
switch (mcptt->mcptt_status)
{
case mcptt_status_pending_request:
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_token_denied, msg);
/* Stop timer T101 (Floor request) */
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t101.id))
{
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t101.id);
mcptt->timer_t101.id = TSK_INVALID_TIMER_ID;
}
mcptt->mcptt_status = mcptt_status_no_permission;
if(mcptt->audio_session) //Stop RTP transmission
TMEDIA_SESSION(mcptt->audio_session)->lo_held = tsk_true;
if(mcptt->multicast_audio_session) //Multicast channel ON
{
TMEDIA_SESSION(mcptt->multicast_audio_session)->ro_held = tsk_false;
TMEDIA_SESSION(mcptt->multicast_audio_session)->lo_held = tsk_true;
}
break;
}
case mcptt_status_queued:
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_token_denied, msg);
/* Stop timer T104 (Floor queue position request) */
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t104.id))
{
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t104.id);
mcptt->timer_t104.id = TSK_INVALID_TIMER_ID;
}
mcptt->mcptt_status = mcptt_status_no_permission;
if(mcptt->audio_session) //Stop RTP transmission
TMEDIA_SESSION(mcptt->audio_session)->lo_held = tsk_true;
if(mcptt->multicast_audio_session) //Multicast channel ON
{
TMEDIA_SESSION(mcptt->multicast_audio_session)->ro_held = tsk_false;
TMEDIA_SESSION(mcptt->multicast_audio_session)->lo_held = tsk_true;
}
break;
}
}
return 0;
}
int tdav_session_mcptt_process_revoke(tdav_session_mcptt_t* mcptt, tmcptt_mcptt_packet_revoke_t* revoke_msg)
{
tmcptt_message_t* msg = tmcptt_message_create_null();
tsk_size_t size = 0;
va_list ap;
if (mcptt == tsk_null)
return -1;
if (revoke_msg == tsk_null)
return -1;
if (revoke_msg->reject_cause)
TSK_DEBUG_INFO("MCPTT REVOKE reject cause: %u (%s)", revoke_msg->reject_cause->f_bin_value, revoke_msg->reject_cause->f_txt_value);
msg->reason_code = revoke_msg->reject_cause->f_bin_value;
size = revoke_msg->reject_cause->f_length - sizeof(uint16_t);
if (size > 0)
{
msg->reason_phrase = (char*)tsk_malloc((size + 1) * sizeof(char));
memcpy(msg->reason_phrase, revoke_msg->reject_cause, size);
msg->reason_phrase[size] = '\0';
}
switch (mcptt->mcptt_status)
{
case mcptt_status_permission:
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_permission_revoked, msg);
va_start(ap, "token");
tdav_session_mcptt_send_release(TMEDIA_SESSION_MCPTT(mcptt), &ap);
va_end(ap);
mcptt->timer_t100.id = tsk_timer_manager_schedule(mcptt->h_timer, mcptt->timer_t100.timeout, tdav_session_mcptt_timer_t100_expired_handler, mcptt);
mcptt->counter_c100.curr_value = 1;
mcptt->mcptt_status = mcptt_status_pending_release;
if(mcptt->audio_session) //Stop RTP transmission
TMEDIA_SESSION(mcptt->audio_session)->lo_held = tsk_true;
if(mcptt->multicast_audio_session) //Multicast channel ON
{
TMEDIA_SESSION(mcptt->multicast_audio_session)->ro_held = tsk_false;
TMEDIA_SESSION(mcptt->multicast_audio_session)->lo_held = tsk_true;
}
break;
}
case mcptt_status_pending_release:
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_permission_revoked, msg);
break;
}
}
return 0;
}
int tdav_session_mcptt_process_queue_position_info(tdav_session_mcptt_t* mcptt, tmcptt_mcptt_packet_queue_position_info_t* queue_position_info_msg)
{
tmcptt_message_t* msg = tmcptt_message_create_null();
tsk_size_t size = 0;
if (mcptt == tsk_null)
return -1;
if (queue_position_info_msg == tsk_null)
return -1;
if (queue_position_info_msg->queue_info)
TSK_DEBUG_INFO("MCPTT QUEUE POSITION INFO : position: %u, priority: %u", queue_position_info_msg->queue_info->f_h_value, queue_position_info_msg->queue_info->f_l_value);
msg->queue_position = queue_position_info_msg->queue_info->f_h_value;
msg->queue_priority = queue_position_info_msg->queue_info->f_l_value;
switch (mcptt->mcptt_status)
{
case mcptt_status_pending_request:
{
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_queued, msg);
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t104.id))
{
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t104.id);
mcptt->timer_t104.id = TSK_INVALID_TIMER_ID;
}
mcptt->mcptt_status = mcptt_status_queued;
break;
}
case mcptt_status_queued:
{
/* If queue position info == 65534, MCPTT client is not queued
* If queue position info == 65535, MCPTT server unable to determine position */
if (!(msg->queue_position == 255 && msg->queue_priority == 254)) //If client is queued
tdav_session_mcptt_alert_user(mcptt, tmcptt_event_type_queued, msg);
if (TSK_TIMER_ID_IS_VALID(mcptt->timer_t104.id))
{
tsk_timer_manager_cancel(mcptt->h_timer, mcptt->timer_t104.id);
mcptt->timer_t104.id = TSK_INVALID_TIMER_ID;
}
break;
}
}
return 0;
}
/*Constructor*/
static tsk_object_t* tdav_session_mcptt_ctor(tsk_object_t * self, va_list * app)
{
tdav_session_mcptt_t *session = self;
if(session){
TMEDIA_SESSION_MCPTT(session)->request_token = tdav_session_mcptt_request_token;
TMEDIA_SESSION_MCPTT(session)->release_token = tdav_session_mcptt_release_token;
session->floorid = 0;
session->is_multimedia = tsk_true;
session->local_ip = tsk_null;
session->local_port = 0;
session->remote_ip = tsk_null;
session->remote_port = 0;
session->local_ssrc = 0;
session->mcptt_status = mcptt_status_start_stop;
session->is_broadcast = tsk_false;
session->is_emergency = tsk_false;
session->is_imminent_peril = tsk_false;
session->is_dual_floor = tsk_false;
session->queueing_enabled = tsk_false;
if(!(session->h_timer = tsk_timer_manager_create())){
TSK_DEBUG_ERROR("Failed to create timer manager");
return tsk_null;
}
session->timer_t100.id = TSK_INVALID_TIMER_ID;
session->timer_t100.timeout = MCPTT_TIMER_T100_DEFAULT_VALUE;
session->timer_t101.id = TSK_INVALID_TIMER_ID;
session->timer_t101.timeout = MCPTT_TIMER_T101_DEFAULT_VALUE;
session->timer_t103.id = TSK_INVALID_TIMER_ID;
session->timer_t103.timeout = MCPTT_TIMER_T103_DEFAULT_VALUE;
session->timer_t104.id = TSK_INVALID_TIMER_ID;
session->timer_t104.timeout = MCPTT_TIMER_T103_DEFAULT_VALUE;
session->timer_t132.id = TSK_INVALID_TIMER_ID;
session->timer_t132.timeout = MCPTT_TIMER_T132_DEFAULT_VALUE;
session->counter_c100.curr_value = 1;
session->counter_c100.max_value = MCPTT_COUNTER_C100_DEFAULT_VALUE;
session->counter_c101.curr_value = 1;
session->counter_c101.max_value = MCPTT_COUNTER_C101_DEFAULT_VALUE;
session->counter_c104.curr_value = 1;
session->counter_c104.max_value = MCPTT_COUNTER_C104_DEFAULT_VALUE;
}
return self;
}
/* destructor */
static tsk_object_t* tdav_session_mcptt_dtor(tsk_object_t * self)
{
tdav_session_mcptt_t *session = self;
if(session){
if(session->remote_ip)
TSK_FREE(session->remote_ip);
/* deinit base */
tmedia_session_deinit(self);
}
return self;
}
/* object definition */
static const tsk_object_def_t tdav_session_mcptt_def_s =
{
sizeof(tdav_session_mcptt_t),
tdav_session_mcptt_ctor,
tdav_session_mcptt_dtor,
tmedia_session_cmp,
};
/* plugin definition*/
static const tmedia_session_plugin_def_t tdav_session_mcptt_plugin_def_s =
{
&tdav_session_mcptt_def_s,
tmedia_mcptt,
"application",
tdav_session_mcptt_set,
tdav_session_mcptt_get,
tdav_session_mcptt_prepare,
tdav_session_mcptt_start,
tdav_session_mcptt_pause,
tdav_session_mcptt_stop,
/* Audio part */
{ tsk_null },
tdav_session_mcptt_get_lo,
tdav_session_mcptt_set_ro
};
const tmedia_session_plugin_def_t *tdav_session_mcptt_plugin_def_t = &tdav_session_mcptt_plugin_def_s;
#endif /* !defined(HAVE_TINYMSRP) || HAVE_TINYMSRP */ |