asterisk/addons/ooh323c/src/ooStackCmds.c

682 lines
15 KiB
C

/*
* Copyright (C) 2004-2005 by Objective Systems, Inc.
*
* This software is furnished under an open source license and may be
* used and copied only in accordance with the terms of this license.
* The text of the license may generally be found in the root
* directory of this installation in the COPYING file. It
* can also be viewed online at the following URL:
*
* http://www.obj-sys.com/open/license.html
*
* Any redistributions of this file including modified versions must
* maintain this copyright notice.
*
*****************************************************************************/
#include "asterisk.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "ooStackCmds.h"
#include "ooh323ep.h"
#include "ooCalls.h"
#include "ooCmdChannel.h"
extern OOSOCKET gCmdChan;
extern ast_mutex_t newCallLock;
static int counter = 1;
int ooGenerateOutgoingCallToken (char *callToken, size_t size)
{
char aCallToken[200];
int ret = 0;
ast_mutex_lock(&newCallLock);
sprintf (aCallToken, "ooh323c_o_%d", counter++);
if (counter > OO_MAX_CALL_TOKEN)
counter = 1;
ast_mutex_unlock(&newCallLock);
if ((strlen(aCallToken)+1) < size)
strcpy (callToken, aCallToken);
else {
ret = OO_FAILED;
}
return ret;
}
int isRunning(char *callToken) {
OOH323CallData *call;
if((call = ooFindCallByToken(callToken)))
if (call->Monitor)
return 1;
return 0;
}
OOStkCmdStat ooMakeCall
(const char* dest, char* callToken, size_t bufsiz, ooCallOptions *opts)
{
OOStackCommand cmd;
if(!callToken)
return OO_STKCMD_INVALIDPARAM;
/* Generate call token*/
if (ooGenerateOutgoingCallToken (callToken, bufsiz) != OO_OK){
return OO_STKCMD_INVALIDPARAM;
}
if(gCmdChan == 0)
{
if(ooCreateCmdConnection() != OO_OK)
return OO_STKCMD_CONNECTIONERR;
}
memset(&cmd, 0, sizeof(OOStackCommand));
cmd.type = OO_CMD_MAKECALL;
cmd.param1 = ast_malloc(strlen(dest)+1);
if(!cmd.param1)
{
return OO_STKCMD_MEMERR;
}
strcpy((char*)cmd.param1, dest);
cmd.param2 = ast_malloc(strlen(callToken)+1);
if(!cmd.param2)
{
ast_free(cmd.param1);
return OO_STKCMD_MEMERR;
}
strcpy((char*)cmd.param2, callToken);
if(!opts)
{
cmd.param3 = 0;
}
else {
cmd.param3 = ast_malloc(sizeof(ooCallOptions));
if(!cmd.param3)
{
ast_free(cmd.param1);
ast_free(cmd.param2);
return OO_STKCMD_MEMERR;
}
memcpy((void*)cmd.param3, opts, sizeof(ooCallOptions));
}
if(ooWriteStackCommand(&cmd) != OO_OK)
{
ast_free(cmd.param1);
ast_free(cmd.param2);
if(cmd.param3) ast_free(cmd.param3);
return OO_STKCMD_WRITEERR;
}
return OO_STKCMD_SUCCESS;
}
OOStkCmdStat ooRunCall
(const char* dest, char* callToken, size_t bufsiz, ooCallOptions *opts)
{
OOStackCommand cmd;
OOH323CallData *call;
if(!callToken)
{
return OO_STKCMD_INVALIDPARAM;
}
if(!(call = ooFindCallByToken(callToken))) {
return OO_STKCMD_INVALIDPARAM;
}
if(call->CmdChan == 0)
{
if(ooCreateCallCmdConnection(call) != OO_OK)
return OO_STKCMD_CONNECTIONERR;
}
if(!callToken)
return OO_STKCMD_INVALIDPARAM;
memset(&cmd, 0, sizeof(OOStackCommand));
cmd.type = OO_CMD_MAKECALL;
cmd.param1 = ast_malloc(strlen(dest)+1);
if(!cmd.param1)
{
return OO_STKCMD_MEMERR;
}
strcpy((char*)cmd.param1, dest);
cmd.plen1 = strlen(dest);
cmd.param2 = ast_malloc(strlen(callToken)+1);
if(!cmd.param2)
{
ast_free(cmd.param1);
return OO_STKCMD_MEMERR;
}
strcpy((char*)cmd.param2, callToken);
cmd.plen2 = strlen(callToken);
if(!opts)
{
cmd.param3 = 0;
}
else {
cmd.param3 = ast_malloc(sizeof(ooCallOptions));
if(!cmd.param3)
{
ast_free(cmd.param1);
ast_free(cmd.param2);
return OO_STKCMD_MEMERR;
}
memcpy((void*)cmd.param3, opts, sizeof(ooCallOptions));
cmd.plen3 = sizeof(ooCallOptions);
}
if(ooWriteCallStackCommand(call, &cmd) != OO_OK)
{
ast_free(cmd.param1);
ast_free(cmd.param2);
if(cmd.param3) ast_free(cmd.param3);
return OO_STKCMD_WRITEERR;
}
ast_free(cmd.param1);
ast_free(cmd.param2);
if(cmd.param3) ast_free(cmd.param3);
return OO_STKCMD_SUCCESS;
}
OOStkCmdStat ooManualRingback(const char *callToken)
{
OOStackCommand cmd;
OOH323CallData *call;
if(!callToken)
{
return OO_STKCMD_INVALIDPARAM;
}
if(!(call = ooFindCallByToken(callToken))) {
return OO_STKCMD_INVALIDPARAM;
}
if(call->CmdChan == 0)
{
if(ooCreateCallCmdConnection(call) != OO_OK)
return OO_STKCMD_CONNECTIONERR;
}
memset(&cmd, 0, sizeof(OOStackCommand));
cmd.type = OO_CMD_MANUALRINGBACK;
cmd.param1 = ast_malloc(strlen(callToken)+1);
if(!cmd.param1)
{
return OO_STKCMD_MEMERR;
}
strcpy((char*)cmd.param1, callToken);
cmd.plen1 = strlen(callToken);
if(ooWriteCallStackCommand(call,&cmd) != OO_OK)
{
ast_free(cmd.param1);
return OO_STKCMD_WRITEERR;
}
ast_free(cmd.param1);
return OO_STKCMD_SUCCESS;
}
OOStkCmdStat ooManualProgress(const char *callToken)
{
OOStackCommand cmd;
OOH323CallData *call;
if(!callToken)
{
return OO_STKCMD_INVALIDPARAM;
}
if(!(call = ooFindCallByToken(callToken))) {
return OO_STKCMD_INVALIDPARAM;
}
if(call->CmdChan == 0)
{
if(ooCreateCallCmdConnection(call) != OO_OK)
return OO_STKCMD_CONNECTIONERR;
}
if (call->h225version < 4)
return OO_STKCMD_SUCCESS;
memset(&cmd, 0, sizeof(OOStackCommand));
cmd.type = OO_CMD_MANUALPROGRESS;
cmd.param1 = ast_malloc(strlen(callToken)+1);
if(!cmd.param1)
{
return OO_STKCMD_MEMERR;
}
strcpy((char*)cmd.param1, callToken);
cmd.plen1 = strlen(callToken);
if(ooWriteCallStackCommand(call, &cmd) != OO_OK)
{
ast_free(cmd.param1);
return OO_STKCMD_WRITEERR;
}
ast_free(cmd.param1);
return OO_STKCMD_SUCCESS;
}
OOStkCmdStat ooAnswerCall(const char *callToken)
{
OOStackCommand cmd;
OOH323CallData *call;
if(!callToken)
{
return OO_STKCMD_INVALIDPARAM;
}
if(!(call = ooFindCallByToken(callToken))) {
return OO_STKCMD_INVALIDPARAM;
}
if(call->CmdChan == 0)
{
if(ooCreateCallCmdConnection(call) != OO_OK)
return OO_STKCMD_CONNECTIONERR;
}
memset(&cmd, 0, sizeof(OOStackCommand));
cmd.type = OO_CMD_ANSCALL;
cmd.param1 = ast_malloc(strlen(callToken)+1);
if(!cmd.param1)
{
return OO_STKCMD_MEMERR;
}
strcpy((char*)cmd.param1, callToken);
cmd.plen1 = strlen(callToken);
if(ooWriteCallStackCommand(call, &cmd) != OO_OK)
{
ast_free(cmd.param1);
return OO_STKCMD_WRITEERR;
}
ast_free(cmd.param1);
return OO_STKCMD_SUCCESS;
}
OOStkCmdStat ooForwardCall(const char* callToken, char *dest)
{
OOStackCommand cmd;
OOH323CallData *call;
if(!callToken || !dest)
{
return OO_STKCMD_INVALIDPARAM;
}
if(!(call = ooFindCallByToken(callToken))) {
return OO_STKCMD_INVALIDPARAM;
}
if(call->CmdChan == 0)
{
if(ooCreateCallCmdConnection(call) != OO_OK)
return OO_STKCMD_CONNECTIONERR;
}
memset(&cmd, 0, sizeof(OOStackCommand));
cmd.type = OO_CMD_FWDCALL;
cmd.param1 = ast_malloc(strlen(callToken)+1);
cmd.param2 = ast_malloc(strlen(dest)+1);
if(!cmd.param1 || !cmd.param2)
{
if(cmd.param1) ast_free(cmd.param1); /* Release memory */
if(cmd.param2) ast_free(cmd.param2);
return OO_STKCMD_MEMERR;
}
strcpy((char*)cmd.param1, callToken);
cmd.plen1 = strlen(callToken);
strcpy((char*)cmd.param2, dest);
cmd.plen2 = strlen(dest);
if(ooWriteCallStackCommand(call, &cmd) != OO_OK)
{
ast_free(cmd.param1);
ast_free(cmd.param2);
return OO_STKCMD_WRITEERR;
}
ast_free(cmd.param1);
ast_free(cmd.param2);
return OO_STKCMD_SUCCESS;
}
OOStkCmdStat ooHangCall(const char* callToken, OOCallClearReason reason, int q931cause)
{
OOStackCommand cmd;
OOH323CallData *call;
if(!callToken)
{
return OO_STKCMD_INVALIDPARAM;
}
if(!(call = ooFindCallByToken(callToken))) {
return OO_STKCMD_INVALIDPARAM;
}
if(call->CmdChan == 0)
{
if(ooCreateCallCmdConnection(call) != OO_OK)
return OO_STKCMD_CONNECTIONERR;
}
memset(&cmd, 0, sizeof(OOStackCommand));
cmd.type = OO_CMD_HANGCALL;
cmd.param1 = ast_malloc(strlen(callToken)+1);
cmd.param2 = ast_malloc(sizeof(OOCallClearReason));
cmd.param3 = ast_malloc(sizeof(int));
if(!cmd.param1 || !cmd.param2 || !cmd.param3)
{
if(cmd.param1) ast_free(cmd.param1); /* Release memory */
if(cmd.param2) ast_free(cmd.param2);
if(cmd.param3) ast_free(cmd.param3);
return OO_STKCMD_MEMERR;
}
strcpy((char*)cmd.param1, callToken);
cmd.plen1 = strlen(callToken);
*((OOCallClearReason*)cmd.param2) = reason;
cmd.plen2 = sizeof(OOCallClearReason);
*(int *)cmd.param3 = q931cause;
cmd.plen3 = sizeof(int);
if(ooWriteCallStackCommand(call, &cmd) != OO_OK)
{
ast_free(cmd.param1);
ast_free(cmd.param2);
ast_free(cmd.param3);
return OO_STKCMD_WRITEERR;
}
ast_free(cmd.param1);
ast_free(cmd.param2);
ast_free(cmd.param3);
return OO_STKCMD_SUCCESS;
}
OOStkCmdStat ooStopMonitor()
{
OOStackCommand cmd;
if(gCmdChan == 0)
{
if(ooCreateCmdConnection() != OO_OK)
return OO_STKCMD_CONNECTIONERR;
}
memset(&cmd, 0, sizeof(OOStackCommand));
cmd.type = OO_CMD_STOPMONITOR;
if(ooWriteStackCommand(&cmd) != OO_OK)
return OO_STKCMD_WRITEERR;
return OO_STKCMD_SUCCESS;
}
OOStkCmdStat ooSendDTMFDigit(const char *callToken, const char* dtmf)
{
OOStackCommand cmd;
OOH323CallData *call;
if(!callToken)
{
return OO_STKCMD_INVALIDPARAM;
}
if(!(call = ooFindCallByToken(callToken))) {
return OO_STKCMD_INVALIDPARAM;
}
if(call->CmdChan == 0)
{
if(ooCreateCallCmdConnection(call) != OO_OK)
return OO_STKCMD_CONNECTIONERR;
}
memset(&cmd, 0, sizeof(OOStackCommand));
cmd.type = OO_CMD_SENDDIGIT;
cmd.param1 = ast_malloc(strlen(callToken)+1);
cmd.param2 = ast_malloc(strlen(dtmf)+1);
if(!cmd.param1 || !cmd.param2)
{
if(cmd.param1) ast_free(cmd.param1); /* Release memory */
if(cmd.param2) ast_free(cmd.param2);
return OO_STKCMD_MEMERR;
}
strcpy((char*)cmd.param1, callToken);
cmd.plen1 = strlen(callToken);
strcpy((char*)cmd.param2, dtmf);
cmd.plen2 = strlen(dtmf);
if(ooWriteCallStackCommand(call,&cmd) != OO_OK)
{
ast_free(cmd.param1);
ast_free(cmd.param2);
return OO_STKCMD_WRITEERR;
}
ast_free(cmd.param1);
ast_free(cmd.param2);
return OO_STKCMD_SUCCESS;
}
OOStkCmdStat ooSetANI(const char *callToken, const char* ani)
{
OOStackCommand cmd;
OOH323CallData *call;
if(!callToken)
{
return OO_STKCMD_INVALIDPARAM;
}
if(!(call = ooFindCallByToken(callToken))) {
return OO_STKCMD_INVALIDPARAM;
}
if(call->CmdChan == 0)
{
if(ooCreateCallCmdConnection(call) != OO_OK)
return OO_STKCMD_CONNECTIONERR;
}
memset(&cmd, 0, sizeof(OOStackCommand));
cmd.type = OO_CMD_SETANI;
cmd.param1 = ast_malloc(strlen(callToken)+1);
cmd.param2 = ast_malloc(strlen(ani)+1);
if(!cmd.param1 || !cmd.param2)
{
if(cmd.param1) ast_free(cmd.param1); /* Release memory */
if(cmd.param2) ast_free(cmd.param2);
return OO_STKCMD_MEMERR;
}
strcpy((char*)cmd.param1, callToken);
cmd.plen1 = strlen(callToken);
strcpy((char*)cmd.param2, ani);
cmd.plen2 = strlen(ani);
if(ooWriteCallStackCommand(call,&cmd) != OO_OK)
{
ast_free(cmd.param1);
ast_free(cmd.param2);
return OO_STKCMD_WRITEERR;
}
ast_free(cmd.param1);
ast_free(cmd.param2);
return OO_STKCMD_SUCCESS;
}
OOStkCmdStat ooUpdateLogChannels(const char *callToken, const char* localIP, int port)
{
OOStackCommand cmd;
OOH323CallData *call;
if (!callToken) {
return OO_STKCMD_INVALIDPARAM;
}
if (!(call = ooFindCallByToken(callToken))) {
return OO_STKCMD_INVALIDPARAM;
}
if (localIP == NULL) {
return OO_STKCMD_INVALIDPARAM;
}
if (call->CmdChan == 0) {
if (ooCreateCallCmdConnection(call) != OO_OK) {
return OO_STKCMD_CONNECTIONERR;
}
}
memset(&cmd, 0, sizeof(OOStackCommand));
cmd.type = OO_CMD_UPDLC;
cmd.param1 = ast_malloc(strlen(callToken) + 1);
cmd.param2 = ast_malloc(strlen(localIP) + 1);
cmd.param3 = ast_malloc(sizeof(int) + 1);
if (!cmd.param1 || !cmd.param2 || !cmd.param3) {
if (cmd.param1) {
ast_free(cmd.param1); /* Release memory */
}
if (cmd.param2) {
ast_free(cmd.param2);
}
if (cmd.param3) {
ast_free(cmd.param3);
}
return OO_STKCMD_MEMERR;
}
strcpy((char*)cmd.param1, callToken);
cmd.plen1 = strlen(callToken);
strcpy((char*)cmd.param2, localIP);
cmd.plen2 = strlen(localIP);
*((int *)cmd.param3) = port;
cmd.plen3 = sizeof(int) + 1;
if (ooWriteCallStackCommand(call, &cmd) != OO_OK) {
ast_free(cmd.param1);
ast_free(cmd.param2);
ast_free(cmd.param3);
return OO_STKCMD_WRITEERR;
}
ast_free(cmd.param1);
ast_free(cmd.param2);
ast_free(cmd.param3);
return OO_STKCMD_SUCCESS;
}
OOStkCmdStat ooRequestChangeMode(const char *callToken, int isT38Mode)
{
OOStackCommand cmd;
OOH323CallData *call;
if(!callToken)
{
return OO_STKCMD_INVALIDPARAM;
}
if(!(call = ooFindCallByToken(callToken))) {
return OO_STKCMD_INVALIDPARAM;
}
if(call->CmdChan == 0)
{
if(ooCreateCallCmdConnection(call) != OO_OK)
return OO_STKCMD_CONNECTIONERR;
}
memset(&cmd, 0, sizeof(OOStackCommand));
cmd.type = OO_CMD_REQMODE;
cmd.param1 = ast_malloc(strlen(callToken)+1);
cmd.param2 = ast_malloc(sizeof(int));
if(!cmd.param1 || !cmd.param2)
{
ast_free(cmd.param1); /* Release memory */
ast_free(cmd.param2);
return OO_STKCMD_MEMERR;
}
strcpy((char*)cmd.param1, callToken);
cmd.plen1 = strlen(callToken);
*((int *) cmd.param2) = isT38Mode;
cmd.plen2 = sizeof(int);
if(ooWriteCallStackCommand(call,&cmd) != OO_OK)
{
ast_free(cmd.param1);
ast_free(cmd.param2);
return OO_STKCMD_WRITEERR;
}
ast_free(cmd.param1);
ast_free(cmd.param2);
return OO_STKCMD_SUCCESS;
}
const char* ooGetStkCmdStatusCodeTxt(OOStkCmdStat stat)
{
switch(stat)
{
case OO_STKCMD_SUCCESS:
return "Stack command - successfully issued";
case OO_STKCMD_MEMERR:
return "Stack command - Memory allocation error";
case OO_STKCMD_INVALIDPARAM:
return "Stack command - Invalid parameter";
case OO_STKCMD_WRITEERR:
return "Stack command - write error";
case OO_STKCMD_CONNECTIONERR:
return "Stack command - Failed to create command channel";
default:
return "Invalid status code";
}
}