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 \
|
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_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_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)
|
ifeq (${USE_OWN_LIBCAPI},yes)
|
||||||
OBJECTS += libcapi20/convert.o libcapi20/capi20.o libcapi20/capifunc.o
|
OBJECTS += libcapi20/convert.o libcapi20/capi20.o libcapi20/capifunc.o
|
||||||
|
|
154
chan_capi_ami.c
154
chan_capi_ami.c
|
@ -25,23 +25,34 @@
|
||||||
* Based on apps/app_meetme.c
|
* Based on apps/app_meetme.c
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef CC_AST_HAS_VERSION_1_6
|
|
||||||
#include "chan_capi_platform.h"
|
#include "chan_capi_platform.h"
|
||||||
#include "chan_capi20.h"
|
#include "chan_capi20.h"
|
||||||
#include "chan_capi.h"
|
#include "chan_capi.h"
|
||||||
|
#ifdef CC_AST_HAS_VERSION_1_6
|
||||||
#include "chan_capi_qsig.h"
|
#include "chan_capi_qsig.h"
|
||||||
#include "chan_capi_utils.h"
|
#include "chan_capi_utils.h"
|
||||||
#include "chan_capi_chat.h"
|
#include "chan_capi_chat.h"
|
||||||
|
#include "chan_capi_management_common.h"
|
||||||
#include "asterisk/manager.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
|
LOCALS
|
||||||
*/
|
*/
|
||||||
static int pbx_capi_ami_capichat_list(struct mansession *s, const struct message *m);
|
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 capiChatListRegistered;
|
||||||
|
static int capiChatMuteRegistered;
|
||||||
|
static int capiChatUnmuteRegistered;
|
||||||
|
static int capiCommandRegistered;
|
||||||
|
|
||||||
static char mandescr_capichatlist[] =
|
static char mandescr_capichatlist[] =
|
||||||
"Description: Lists all users in a particular CapiChat conference.\n"
|
"Description: Lists all users in a particular CapiChat conference.\n"
|
||||||
|
@ -51,6 +62,28 @@ static char mandescr_capichatlist[] =
|
||||||
" *ActionId: <id>\n"
|
" *ActionId: <id>\n"
|
||||||
" *Conference: <confname>\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)
|
void pbx_capi_ami_register(void)
|
||||||
{
|
{
|
||||||
|
@ -59,12 +92,39 @@ void pbx_capi_ami_register(void)
|
||||||
pbx_capi_ami_capichat_list,
|
pbx_capi_ami_capichat_list,
|
||||||
"List participants in a conference",
|
"List participants in a conference",
|
||||||
mandescr_capichatlist) == 0;
|
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)
|
void pbx_capi_ami_unregister(void)
|
||||||
{
|
{
|
||||||
if (capiChatListRegistered != 0)
|
if (capiChatListRegistered != 0)
|
||||||
ast_manager_unregister(CC_AMI_ACTION_NAME_CHATLIST);
|
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) {
|
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);
|
"\r\n", total, idText);
|
||||||
return 0;
|
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
|
#else
|
||||||
void pbx_capi_ami_register(void)
|
void pbx_capi_ami_register(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -916,6 +916,8 @@ 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* pbx_check_resource_plci(struct ast_channel *c)
|
||||||
{
|
{
|
||||||
struct capi_pvt *i = NULL;
|
struct capi_pvt *i = NULL;
|
||||||
|
|
||||||
|
if (c != NULL) {
|
||||||
const char* id = pbx_builtin_getvar_helper(c, "RESOURCEPLCI");
|
const char* id = pbx_builtin_getvar_helper(c, "RESOURCEPLCI");
|
||||||
|
|
||||||
if (id != 0) {
|
if (id != 0) {
|
||||||
|
@ -925,6 +927,7 @@ struct capi_pvt* pbx_check_resource_plci(struct ast_channel *c)
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
101
chan_capi_cli.c
101
chan_capi_cli.c
|
@ -21,15 +21,11 @@
|
||||||
#include "chan_capi_utils.h"
|
#include "chan_capi_utils.h"
|
||||||
#include "chan_capi_chat.h"
|
#include "chan_capi_chat.h"
|
||||||
#include "chan_capi_cli.h"
|
#include "chan_capi_cli.h"
|
||||||
|
#include "chan_capi_management_common.h"
|
||||||
#ifdef DIVA_STATUS
|
#ifdef DIVA_STATUS
|
||||||
#include "divastatus_ifc.h"
|
#include "divastatus_ifc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
LOCALS
|
|
||||||
*/
|
|
||||||
static int pbx_capi_cli_get_locks(struct capi_pvt *i);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* usages
|
* 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[])
|
static int pbxcli_capi_exec_capicommand(int fd, int argc, char *argv[])
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int ifc_type, found, retry_search, search_loops = 10;
|
|
||||||
struct capi_pvt *i;
|
|
||||||
int required_args = 4;
|
int required_args = 4;
|
||||||
int provided_args;
|
int provided_args;
|
||||||
const char* requiredChannelName = NULL;
|
const char* requiredChannelName = NULL;
|
||||||
const char* chancapiCommand = NULL;
|
const char* chancapiCommand = NULL;
|
||||||
int ret = -1;
|
int ret;
|
||||||
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;
|
|
||||||
|
|
||||||
#ifdef CC_AST_HAS_VERSION_1_6
|
#ifdef CC_AST_HAS_VERSION_1_6
|
||||||
if (cmd == CLI_INIT) {
|
if (cmd == CLI_INIT) {
|
||||||
|
@ -585,57 +567,7 @@ static int pbxcli_capi_exec_capicommand(int fd, int argc, char *argv[])
|
||||||
chancapiCommand = argv[3];
|
chancapiCommand = argv[3];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
do {
|
ret = pbx_capi_management_capicommand(requiredChannelName, chancapiCommand);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CC_AST_HAS_VERSION_1_6
|
#ifdef CC_AST_HAS_VERSION_1_6
|
||||||
return ((ret == 0) ? CLI_SUCCESS : CLI_FAILURE);
|
return ((ret == 0) ? CLI_SUCCESS : CLI_FAILURE);
|
||||||
|
@ -796,30 +728,3 @@ void pbx_capi_cli_unregister(void)
|
||||||
#endif
|
#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