Started unification of CLI and AMI code. Fixed numerous bugs in AMI and CLI commands. Add AMI CapichatMute, CapichatUnmute and CapiCommand commands
This commit is contained in:
parent
9c3cceccda
commit
487fb33bb9
2
Makefile
2
Makefile
|
@ -131,7 +131,7 @@ SHAREDOS=chan_capi.so
|
|||
OBJECTS=chan_capi.o chan_capi_utils.o chan_capi_rtp.o chan_capi_command.o xlaw.o dlist.o \
|
||||
chan_capi_qsig_core.o chan_capi_qsig_ecma.o chan_capi_qsig_asn197ade.o \
|
||||
chan_capi_qsig_asn197no.o chan_capi_supplementary.o chan_capi_chat.o \
|
||||
chan_capi_mwi.o chan_capi_cli.o chan_capi_ami.o
|
||||
chan_capi_mwi.o chan_capi_cli.o chan_capi_ami.o chan_capi_management_common.o
|
||||
|
||||
ifeq (${USE_OWN_LIBCAPI},yes)
|
||||
OBJECTS += libcapi20/convert.o libcapi20/capi20.o libcapi20/capifunc.o
|
||||
|
|
156
chan_capi_ami.c
156
chan_capi_ami.c
|
@ -25,23 +25,34 @@
|
|||
* Based on apps/app_meetme.c
|
||||
*
|
||||
*/
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
#include "chan_capi_platform.h"
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
#include "chan_capi_qsig.h"
|
||||
#include "chan_capi_utils.h"
|
||||
#include "chan_capi_chat.h"
|
||||
#include "chan_capi_management_common.h"
|
||||
#include "asterisk/manager.h"
|
||||
|
||||
|
||||
#define CC_AMI_ACTION_NAME_CHATLIST "CapichatList"
|
||||
#define CC_AMI_ACTION_NAME_CHATLIST "CapichatList"
|
||||
#define CC_AMI_ACTION_NAME_CHATMUTE "CapichatMute"
|
||||
#define CC_AMI_ACTION_NAME_CHATUNMUTE "CapichatUnmute"
|
||||
#define CC_AMI_ACTION_NAME_CAPICOMMAND "CapiCommand"
|
||||
|
||||
/*
|
||||
LOCALS
|
||||
*/
|
||||
static int pbx_capi_ami_capichat_list(struct mansession *s, const struct message *m);
|
||||
static int pbx_capi_ami_capichat_mute(struct mansession *s, const struct message *m);
|
||||
static int pbx_capi_ami_capichat_unmute(struct mansession *s, const struct message *m);
|
||||
static int pbx_capi_ami_capichat_control(struct mansession *s, const struct message *m, int chatMute);
|
||||
static int pbx_capi_ami_capicommand(struct mansession *s, const struct message *m);
|
||||
static int capiChatListRegistered;
|
||||
static int capiChatMuteRegistered;
|
||||
static int capiChatUnmuteRegistered;
|
||||
static int capiCommandRegistered;
|
||||
|
||||
static char mandescr_capichatlist[] =
|
||||
"Description: Lists all users in a particular CapiChat conference.\n"
|
||||
|
@ -51,6 +62,28 @@ static char mandescr_capichatlist[] =
|
|||
" *ActionId: <id>\n"
|
||||
" *Conference: <confname>\n";
|
||||
|
||||
static char mandescr_capichatmute[] =
|
||||
"Description: Mutes user in a particular CapiChat conference.\n"
|
||||
"Variables:\n"
|
||||
" *ActionId: <id>\n"
|
||||
" *Conference: <confname>\n"
|
||||
" *Member: <membername>\n"
|
||||
" *Path: <Rx or Tx>\n";
|
||||
|
||||
static char mandescr_capichatunmute[] =
|
||||
"Description: Unmutes user in a particular CapiChat conference.\n"
|
||||
"Variables:\n"
|
||||
" *ActionId: <id>\n"
|
||||
" *Conference: <confname>\n"
|
||||
" *Member: <membername>\n"
|
||||
" *Path: <Rx or Tx>\n";
|
||||
|
||||
static char mandescr_capicommand[] =
|
||||
"Description: Exec capicommand.\n"
|
||||
"Variables:\n"
|
||||
" *ActionId: <id>\n"
|
||||
" *Channel: <channame>\n"
|
||||
" *Capicommand: <capicommand>\n";
|
||||
|
||||
void pbx_capi_ami_register(void)
|
||||
{
|
||||
|
@ -59,12 +92,39 @@ void pbx_capi_ami_register(void)
|
|||
pbx_capi_ami_capichat_list,
|
||||
"List participants in a conference",
|
||||
mandescr_capichatlist) == 0;
|
||||
|
||||
capiChatMuteRegistered = ast_manager_register2(CC_AMI_ACTION_NAME_CHATMUTE,
|
||||
EVENT_FLAG_CALL,
|
||||
pbx_capi_ami_capichat_mute,
|
||||
"Mute a conference user",
|
||||
mandescr_capichatmute) == 0;
|
||||
|
||||
capiChatUnmuteRegistered = ast_manager_register2(CC_AMI_ACTION_NAME_CHATUNMUTE,
|
||||
EVENT_FLAG_CALL,
|
||||
pbx_capi_ami_capichat_unmute,
|
||||
"Unmute a conference user",
|
||||
mandescr_capichatunmute) == 0;
|
||||
|
||||
capiCommandRegistered = ast_manager_register2(CC_AMI_ACTION_NAME_CAPICOMMAND,
|
||||
EVENT_FLAG_CALL,
|
||||
pbx_capi_ami_capicommand,
|
||||
"Exec capicommand",
|
||||
mandescr_capicommand) == 0;
|
||||
}
|
||||
|
||||
void pbx_capi_ami_unregister(void)
|
||||
{
|
||||
if (capiChatListRegistered != 0)
|
||||
ast_manager_unregister(CC_AMI_ACTION_NAME_CHATLIST);
|
||||
|
||||
if (capiChatMuteRegistered != 0)
|
||||
ast_manager_unregister(CC_AMI_ACTION_NAME_CHATMUTE);
|
||||
|
||||
if (capiChatUnmuteRegistered != 0)
|
||||
ast_manager_unregister(CC_AMI_ACTION_NAME_CHATUNMUTE);
|
||||
|
||||
if (capiCommandRegistered != 0)
|
||||
ast_manager_unregister(CC_AMI_ACTION_NAME_CAPICOMMAND);
|
||||
}
|
||||
|
||||
static int pbx_capi_ami_capichat_list(struct mansession *s, const struct message *m) {
|
||||
|
@ -165,6 +225,98 @@ static int pbx_capi_ami_capichat_list(struct mansession *s, const struct message
|
|||
"\r\n", total, idText);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pbx_capi_ami_capichat_mute(struct mansession *s, const struct message *m)
|
||||
{
|
||||
return pbx_capi_ami_capichat_control(s, m, 1);
|
||||
}
|
||||
|
||||
static int pbx_capi_ami_capichat_unmute(struct mansession *s, const struct message *m)
|
||||
{
|
||||
return pbx_capi_ami_capichat_control(s, m, 0);
|
||||
}
|
||||
|
||||
static int pbx_capi_ami_capichat_control(struct mansession *s, const struct message *m, int chatMute)
|
||||
{
|
||||
const char *roomName = astman_get_header(m, "Conference");
|
||||
const char *userName = astman_get_header(m, "Member");
|
||||
const char *voicePath = astman_get_header(m, "Path");
|
||||
const char* capiCommand;
|
||||
int ret;
|
||||
|
||||
if (ast_strlen_zero(roomName)) {
|
||||
astman_send_error(s, m, "Capi Chat conference not specified");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ast_strlen_zero(userName)) {
|
||||
char* param = ast_strdupa((chatMute != 0) ? "yes" : "no");
|
||||
int ret = pbx_capi_chat_mute(NULL, param);
|
||||
if (ret == 0) {
|
||||
astman_send_ack(s, m, (chatMute != 0) ? "Conference muted" : "Conference unmuted");
|
||||
} else {
|
||||
astman_send_error(s, m, "Failed to change mode of Capi Chat conference");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((voicePath != NULL) && (strcmp(voicePath, "Rx") == 0)) {
|
||||
capiCommand = (chatMute != 0) ? "rxdgain,-128" : "rxdgain,0";
|
||||
} else {
|
||||
capiCommand = (chatMute != 0) ? "txdgain,-128" : "txdgain,0";
|
||||
}
|
||||
|
||||
ret = pbx_capi_management_capicommand(userName, capiCommand);
|
||||
|
||||
switch (ret) {
|
||||
case 0:
|
||||
astman_send_ack(s, m, (chatMute != 0) ? "User muted" : "User unmuted");
|
||||
break;
|
||||
|
||||
case -4:
|
||||
astman_send_error(s, m, "User not found");
|
||||
break;
|
||||
|
||||
default:
|
||||
astman_send_error(s, m, "Command error");
|
||||
break;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int pbx_capi_ami_capicommand(struct mansession *s, const struct message *m)
|
||||
{
|
||||
const char *requiredChannelName = astman_get_header(m, "Channel");
|
||||
const char *chancapiCommand = astman_get_header(m, "Command");
|
||||
int ret = pbx_capi_management_capicommand(requiredChannelName, chancapiCommand);
|
||||
|
||||
switch (ret) {
|
||||
case 0:
|
||||
astman_send_ack(s, m, "OK");
|
||||
break;
|
||||
|
||||
case -2:
|
||||
astman_send_error(s, m, "Channel name not specified");
|
||||
break;
|
||||
|
||||
case -3:
|
||||
astman_send_error(s, m, "Capi command name not specified");
|
||||
break;
|
||||
|
||||
case -4:
|
||||
astman_send_error(s, m, "Channel not found");
|
||||
break;
|
||||
|
||||
case -1:
|
||||
default:
|
||||
astman_send_error(s, m, "Command error");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
void pbx_capi_ami_register(void)
|
||||
{
|
||||
|
|
|
@ -916,13 +916,16 @@ int pbx_capi_chat_command(struct ast_channel *c, char *param)
|
|||
struct capi_pvt* pbx_check_resource_plci(struct ast_channel *c)
|
||||
{
|
||||
struct capi_pvt *i = NULL;
|
||||
const char* id = pbx_builtin_getvar_helper(c, "RESOURCEPLCI");
|
||||
|
||||
if (id != 0) {
|
||||
i = (struct capi_pvt*)strtoul(id, NULL, 0);
|
||||
if (i != 0 && capi_verify_resource_plci(i) != 0) {
|
||||
cc_log(LOG_ERROR, "resource PLCI lost\n");
|
||||
i = 0;
|
||||
if (c != NULL) {
|
||||
const char* id = pbx_builtin_getvar_helper(c, "RESOURCEPLCI");
|
||||
|
||||
if (id != 0) {
|
||||
i = (struct capi_pvt*)strtoul(id, NULL, 0);
|
||||
if (i != 0 && capi_verify_resource_plci(i) != 0) {
|
||||
cc_log(LOG_ERROR, "resource PLCI lost\n");
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
101
chan_capi_cli.c
101
chan_capi_cli.c
|
@ -21,15 +21,11 @@
|
|||
#include "chan_capi_utils.h"
|
||||
#include "chan_capi_chat.h"
|
||||
#include "chan_capi_cli.h"
|
||||
#include "chan_capi_management_common.h"
|
||||
#ifdef DIVA_STATUS
|
||||
#include "divastatus_ifc.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
LOCALS
|
||||
*/
|
||||
static int pbx_capi_cli_get_locks(struct capi_pvt *i);
|
||||
|
||||
/*
|
||||
* usages
|
||||
*/
|
||||
|
@ -542,25 +538,11 @@ static char *pbxcli_capi_exec_capicommand(struct ast_cli_entry *e, int cmd, stru
|
|||
static int pbxcli_capi_exec_capicommand(int fd, int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
int ifc_type, found, retry_search, search_loops = 10;
|
||||
struct capi_pvt *i;
|
||||
int required_args = 4;
|
||||
int provided_args;
|
||||
const char* requiredChannelName = NULL;
|
||||
const char* chancapiCommand = NULL;
|
||||
int ret = -1;
|
||||
struct {
|
||||
struct capi_pvt *head;
|
||||
void (*lock_proc)(void);
|
||||
void (*unlock_proc)(void);
|
||||
} data[2];
|
||||
|
||||
data[0].head = capi_iflist;
|
||||
data[0].lock_proc = pbx_capi_lock_interfaces;
|
||||
data[0].unlock_proc = pbx_capi_unlock_interfaces;
|
||||
data[1].head = (struct capi_pvt*)pbx_capi_get_nulliflist();
|
||||
data[1].lock_proc = pbx_capi_nulliflist_lock;
|
||||
data[1].unlock_proc = pbx_capi_nulliflist_unlock;
|
||||
int ret;
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
if (cmd == CLI_INIT) {
|
||||
|
@ -585,57 +567,7 @@ static int pbxcli_capi_exec_capicommand(int fd, int argc, char *argv[])
|
|||
chancapiCommand = argv[3];
|
||||
#endif
|
||||
|
||||
do {
|
||||
retry_search = 0;
|
||||
|
||||
for (ifc_type = 0, found = 0; (found == 0) && (ifc_type < sizeof(data)/sizeof(data[0])); ifc_type++) {
|
||||
data[ifc_type].lock_proc();
|
||||
for (i = data[ifc_type].head; (i != 0); i = i->next) {
|
||||
char* name;
|
||||
|
||||
if ((i->used == 0) || ((i->channeltype != CAPI_CHANNELTYPE_B) &&
|
||||
(i->channeltype != CAPI_CHANNELTYPE_NULL)))
|
||||
continue;
|
||||
if (i->data_plci != 0)
|
||||
continue;
|
||||
|
||||
name = ast_strdup(i->vname);
|
||||
if ((i->channeltype == CAPI_CHANNELTYPE_NULL) && (name != NULL)) {
|
||||
char* p = strstr(name, "-DATAPLCI");
|
||||
if (p != NULL)
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
if (strcmp(requiredChannelName, (name == 0) ? i->vname : name) == 0) {
|
||||
found = 1;
|
||||
ast_free(name);
|
||||
retry_search = pbx_capi_cli_get_locks(i);
|
||||
break;
|
||||
}
|
||||
|
||||
ast_free(name);
|
||||
}
|
||||
data[ifc_type].unlock_proc();
|
||||
}
|
||||
|
||||
if (retry_search != 0) {
|
||||
usleep (100);
|
||||
i = 0;
|
||||
}
|
||||
} while ((retry_search != 0) && (search_loops-- > 0));
|
||||
|
||||
if (i != NULL) {
|
||||
if (i->channeltype != CAPI_CHANNELTYPE_NULL) {
|
||||
struct ast_channel* c = i->owner;
|
||||
ret = pbx_capi_cli_exec_capicommand(c, chancapiCommand);
|
||||
cc_mutex_unlock(&i->lock);
|
||||
if (c)
|
||||
ast_channel_unlock (c);
|
||||
} else {
|
||||
ret = pbx_capi_cli_exec_capicommand(i->used, chancapiCommand);
|
||||
cc_mutex_unlock(&i->lock);
|
||||
}
|
||||
}
|
||||
ret = pbx_capi_management_capicommand(requiredChannelName, chancapiCommand);
|
||||
|
||||
#ifdef CC_AST_HAS_VERSION_1_6
|
||||
return ((ret == 0) ? CLI_SUCCESS : CLI_FAILURE);
|
||||
|
@ -796,30 +728,3 @@ void pbx_capi_cli_unregister(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int pbx_capi_cli_get_locks(struct capi_pvt *i)
|
||||
{
|
||||
if (i->channeltype != CAPI_CHANNELTYPE_NULL) {
|
||||
struct ast_channel* c = i->owner;
|
||||
if (c != 0) {
|
||||
if (ast_channel_trylock(c) == 0) {
|
||||
if (ast_mutex_trylock(&i->lock) == 0) {
|
||||
if (i->owner == c) {
|
||||
return (0);
|
||||
} else {
|
||||
ast_mutex_unlock(&i->lock);
|
||||
ast_channel_unlock (c);
|
||||
}
|
||||
} else {
|
||||
ast_channel_unlock (c);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ast_mutex_trylock(&i->lock) == 0) {
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
*
|
||||
Copyright (c) Dialogic (R) 2009 - 2010
|
||||
*
|
||||
This source file is supplied for the use with
|
||||
Eicon Networks range of DIVA Server Adapters.
|
||||
*
|
||||
Dialogic (R) File Revision : 1.9
|
||||
*
|
||||
This program 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 2, or (at your option)
|
||||
any later version.
|
||||
*
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
|
||||
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 program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*
|
||||
* Based on apps/app_meetme.c
|
||||
*
|
||||
*/
|
||||
#include "chan_capi_platform.h"
|
||||
#include "chan_capi20.h"
|
||||
#include "chan_capi.h"
|
||||
#include "chan_capi_qsig.h"
|
||||
#include "chan_capi_utils.h"
|
||||
#include "chan_capi_chat.h"
|
||||
|
||||
/*
|
||||
LOCALS
|
||||
*/
|
||||
static int pbx_capi_get_all_locks (struct capi_pvt *i, struct ast_channel** usedChannel);
|
||||
|
||||
/*!
|
||||
\brief Execute any capicommand
|
||||
|
||||
\note Called from CLI or from AMI context
|
||||
*/
|
||||
int pbx_capi_management_capicommand(const char *requiredChannelName, const char *chancapiCommand) {
|
||||
int ifc_type, retry_search, search_loops;
|
||||
struct capi_pvt *i;
|
||||
struct {
|
||||
struct capi_pvt *head;
|
||||
void (*lock_proc)(void);
|
||||
void (*unlock_proc)(void);
|
||||
} data[2];
|
||||
|
||||
data[0].head = capi_iflist;
|
||||
data[0].lock_proc = pbx_capi_lock_interfaces;
|
||||
data[0].unlock_proc = pbx_capi_unlock_interfaces;
|
||||
data[1].head = (struct capi_pvt*)pbx_capi_get_nulliflist();
|
||||
data[1].lock_proc = pbx_capi_nulliflist_lock;
|
||||
data[1].unlock_proc = pbx_capi_nulliflist_unlock;
|
||||
|
||||
if (ast_strlen_zero(requiredChannelName)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (ast_strlen_zero(chancapiCommand)) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
for (ifc_type = 0; ifc_type < sizeof(data)/sizeof(data[0]); ifc_type++) {
|
||||
search_loops = 10;
|
||||
do {
|
||||
data[ifc_type].lock_proc();
|
||||
for (i = data[ifc_type].head, retry_search = 0; i != 0; i = i->next) {
|
||||
struct ast_channel* c = NULL;
|
||||
|
||||
if ((i->used == 0) || ((i->channeltype != CAPI_CHANNELTYPE_B) &&
|
||||
(i->channeltype != CAPI_CHANNELTYPE_NULL)))
|
||||
continue;
|
||||
if (i->data_plci != 0)
|
||||
continue;
|
||||
|
||||
if (pbx_capi_get_all_locks (i, &c) != 0) {
|
||||
retry_search = 1;
|
||||
break;
|
||||
}
|
||||
if ((!ast_strlen_zero(c->name) && (strcmp(requiredChannelName, c->name) == 0)) ||
|
||||
strcmp(requiredChannelName, i->vname) == 0) {
|
||||
struct ast_channel* usedChannel = c;
|
||||
int ret;
|
||||
|
||||
data[ifc_type].unlock_proc();
|
||||
|
||||
if (i->channeltype != CAPI_CHANNELTYPE_NULL) {
|
||||
ret = (pbx_capi_cli_exec_capicommand(usedChannel, chancapiCommand) == 0) ? 0 : -1;
|
||||
cc_mutex_unlock(&i->lock);
|
||||
ast_channel_unlock(c);
|
||||
} else {
|
||||
ast_channel_unlock(c);
|
||||
ret = (pbx_capi_cli_exec_capicommand(usedChannel, chancapiCommand) == 0) ? 0 : -1;
|
||||
cc_mutex_unlock(&i->lock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
cc_mutex_unlock(&i->lock);
|
||||
ast_channel_unlock(c);
|
||||
}
|
||||
data[ifc_type].unlock_proc();
|
||||
if (retry_search != 0) {
|
||||
usleep (100);
|
||||
}
|
||||
} while((retry_search != 0) && (search_loops-- > 0));
|
||||
}
|
||||
|
||||
return -4;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Try to take all locks. Called with false lock order
|
||||
* one of the list locks (iflock or nullif_lock) taken
|
||||
* Used by CLI/AMI
|
||||
*/
|
||||
static int pbx_capi_get_all_locks (struct capi_pvt *i, struct ast_channel** usedChannel)
|
||||
{
|
||||
struct ast_channel* c = (i->channeltype != CAPI_CHANNELTYPE_NULL) ? i->owner : i->used;
|
||||
if (c != 0) {
|
||||
if (ast_channel_trylock(c) == 0) {
|
||||
if (ast_mutex_trylock(&i->lock) == 0) {
|
||||
struct ast_channel* cref = (i->channeltype != CAPI_CHANNELTYPE_NULL) ? i->owner : i->used;
|
||||
if (cref == c) {
|
||||
*usedChannel = c;
|
||||
return (0);
|
||||
} else {
|
||||
ast_mutex_unlock(&i->lock);
|
||||
ast_channel_unlock (c);
|
||||
}
|
||||
} else {
|
||||
ast_channel_unlock (c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (-1);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef __CC_MANAGEMENT_COMMON_INTERFACE_H__
|
||||
#define __CC_MANAGEMENT_COMMON_INTERFACE_H__
|
||||
|
||||
|
||||
int pbx_capi_management_capicommand(const char *requiredChannelName, const char *chancapiCommand);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue