/*! \file connection_fsm.c
* Copyright © 2004-2010 Mindspeed Technologies, Inc.
* Mindspeed Confidential.
* All rights reserved.
*
* This file is a component of the Mindspeed® VAPI software ("VAPI") and is
* distributed under the Mindspeed Software License Agreement (the "Agreement").
* Before using this file, you must agree to be bound by the the terms and conditions of
* the Agreement.
*/
#include"ut.h"
#include"vapi.h"
#include"dmgr.h"
#include"vcore.h"
#include"msp.h"
#include "vcore_voip.h"
#include "appitf.h"
extern SToneGeneric astToneGeneric_g[];
/****************************************************************************
* VFSM_CreateConnection : The function does the following things -
***************************************************************************/
/*!
* - Implementation
* -# Obtain the VAPI request node from the the channel structure.
* -# Check the state of the request usReqState\n
* -# Check the input GTL message (response) for SUCCESS.\n
* -# Send the MSP message according to current state using
* VCORE_SendMSPReq
* -# Update the current state. \n
* -#. Following MSP messages will be sent\n
* -# SPU_FEATURES_CONTROL\n
* -# SUPVSR_CREATE_CHANNEL\n
* -# VCEOPT\n
* -# ECHO_CANCEL\n
* -# JBOPT\n
* -# DGAIN\n
* -# DTMFOPT\n
* -# VOPENA - is sent by default\n
* It depends on the field\n
* stVAPIConfig_g.pstVoIPChnlParams->stVopena.uVoiceOperation status\n
* in global structure for default params SVAPIConfig stVAPIConfig_g.\n
* If it is set to VOIP_VOPENA_MODE_DISABLE (0x00) then VOPENA is ignored and\n
* not issued, else (>= 0x01) VOPENA command is issued.\n
* -# When new channel is created using SUPVSR_CREATE_CHANNEL\n
* -# Initialize it using VCORE_InitChannel\n
* -# Add the request to the new channel and remove it from
* Supervisory channel\n
* -# Launch the pending request on Supvisory channel\n
* -# All of the rest of MSP request are sent on the new channel\n
* -# When request is completed give a calback or signal request
* completion semaphore\n
*
* - Assumptions:\n
* -# Default Parameter settings are done by APPITF\n.
*
*
* \return None
*
* \param pstChnl Firstly this will be a supervisory channel on which
* calls to this processing function will have newly
* created channel as this parameter.
* \param pstMsg Message (response) obtained from GTL. When it is called
* by APPITF this is passed as NULL.
*/
VSTATUS VFSM_CreateConnection(IN SChnl * pstChnl, IN SVapiReq * pstVapiReq, IN U16 Event, IN gtl_msg_t * pstMsg)
{
gtl_msg_t *pstMsgMulti;
VSTATUS Status;
SVoIPChnlParams *pstChnlParams = NULL;
SChnl *pstSupvChnl;
SVapiReq *pstChildVapiReq;
CONNID ConnId = pstChnl->ConnId;
UT_Log(VCORE, DEBUG, "VFSM_CreateConnection: Entering conn(%u) state(%u) \n", ConnId, pstVapiReq->usReqState);
pstSupvChnl = DMGR_GetChannel(pstChnl->pstDev, SUPV_CHANNEL);
/*Take action according to current state of request */
switch (pstVapiReq->usReqState)
{
case CREATE_CONNECTION_INIT:
/* Check if the multi cmd mode is enabled (only for CSME and POS); if not get out */
if ((pstChnl->pstDev->eItfType != ePCI_ITF) && (!pstChnl->pstDev->bMultiCmdEnabled))
{
Status = VAPI_ERR_MULTI_CMD_NOT_INITIALIZED;
goto finish;
}
/* This allocate a new request */
pstChildVapiReq = VCORE_AllocateRequest(sizeof(SChnl *));
if (!pstChildVapiReq)
{
Status = VAPI_ERR_CREATECONN_FAIL;
goto finish;
}
/* User Data for child request is comming from the parent request */
UT_MemCopy(pstChildVapiReq->pvUserData, pstVapiReq->pvUserData, sizeof(SChnl *));
pstVapiReq->usReqState = CREATE_CONNECTION_CONFIG;
/* initialise the Child request
The UserData is the channelID used by the VFSM_CreateChannel handler */
VCORE_SetChildRequest(pstChildVapiReq, /* Child Request */
pstVapiReq, /* Parent Request */
VFSM_CreateChannel, /* Child Request Handler */
CREATE_CHANNEL_INIT); /* Child Request handler state */
/* process request in the supervisor channel */
VCORE_ProcessRequest(pstSupvChnl, pstChildVapiReq);
break;
case CREATE_CONNECTION_CONFIG:
/* retrieve the child status */
Status = pstVapiReq->Status;
if (Status != SUCCESS)
goto finish;
/* The device channel now exists.
add the connection structure to the AVL tree
The channel ID has been added to the device array by VFSM_CreateChannel*/
Status = VCORE_AddConnection(pstChnl);
if (Status != SUCCESS)
{
Status = VAPI_ERR_NOMEM;
goto finish;
}
/* from here new requests can be posted to the connection */
UT_Log(VCORE, DEBUG, "VFSM_CreateConnection: Device channel(%u) created on dev(%u) conn(%u) pstChnl 0x%x\n",
pstChnl->usMSPChnlId, pstChnl->pstDev->DevId, ConnId, pstChnl);
/* Now initialize the channel */
pstVapiReq->usReqState = CREATE_CONNECTION_FINISHED;
switch (pstChnl->usConnType)
{
case eVOIP:
pstChnlParams = (SVoIPChnlParams *) pstChnl->pvChnlParams;;
pstMsgMulti = UT_Calloc(1, sizeof(gtl_msg_t));
if (pstMsgMulti == NULL)
{
Status = VAPI_ERR_NOMEM;
goto finish;
}
pstMsgMulti->fifo = UT_Calloc(1, pstSupvChnl->pstDev->MaxMsgSize); /* alloc the max fifo length */
if (pstMsgMulti->fifo == NULL)
{
UT_FreeMem(pstMsgMulti);
Status = VAPI_ERR_NOMEM;
goto finish;
}
/* init msg fields to defautl values*/
VCORE_InitMsg(pstMsgMulti, pstMsgMulti->fifo, pstSupvChnl->pstDev->MaxMsgSize);
/*Add VCEOPT with packet generation disabled */
Status = VDEV_SetVceopt(pstMsgMulti, &(pstChnlParams->stVoiceOpt));
if (Status != SUCCESS)
goto finish_err;
/*Add ECHO CANCELER depending on choseen option */
if ( (pstChnl->pstDev->usSpuFeatureMask & SPU_FEATURE_DFEC_MASK) == SPU_FEATURE_DFEC_MASK )
{
Status = VDEV_SetVoipDfeCancel(pstMsgMulti, &(pstChnlParams->stDfeCan));
}
else
{
Status = VDEV_SetVoipEchoCancel(pstMsgMulti, &(pstChnlParams->stEchoCan));
}
if (Status != SUCCESS)
goto finish_err;
/*Add Jitter buffer Option */
Status = VDEV_SetVoipJbopt(pstMsgMulti, &(pstChnlParams->stJbopt));
if (Status != SUCCESS)
goto finish_err;
/*Add DGAIN */
Status = VDEV_SetVoipDgain(pstMsgMulti, &(pstChnlParams->stDgain));
if (Status != SUCCESS)
goto finish_err;
/*Add Tone control */
Status = VDEV_SetToneCtrlOpt(pstMsgMulti, &(pstChnlParams->stToneCtrl));
if (Status != SUCCESS)
goto finish_err;
/*Add DTMFOPT */
Status = VDEV_SetVoipDtmfOpt(pstMsgMulti, &(pstChnlParams->stDtmfOpt));
if (Status != SUCCESS)
goto finish_err;
/*Add Tonerelay */
Status = VDEV_SetToneRelayOpt(pstMsgMulti, &(pstChnlParams->stToneRelay));
if (Status != SUCCESS)
goto finish_err;
/*Add VOPENA */
if (pstChnlParams->stVopena.mode == VOIP_VOPENA_MODE_ENABLE_RTP)
{
Status = VDEV_SetVoipVopena(pstMsgMulti, &(pstChnlParams->stVopena));
if (Status != SUCCESS)
goto finish_err;
}
pstVapiReq->pvExecData = pstMsgMulti; /* Save the multilist structure */
pstMsgMulti->channel = pstChnl->usMSPChnlId;
VCORE_SendMSPReq(pstChnl, pstMsgMulti);
break;
case eFOIP:
pstMsgMulti = UT_Calloc(1, sizeof(gtl_msg_t));
if (pstMsgMulti == NULL)
{
Status = VAPI_ERR_NOMEM;
goto finish;
}
pstMsgMulti->fifo = UT_Calloc(1, pstSupvChnl->pstDev->MaxMsgSize); /* alloc the max fifo length */
if (pstMsgMulti->fifo == NULL)
{
UT_FreeMem(pstMsgMulti);
Status = VAPI_ERR_NOMEM;
goto finish;
}
/* init msg fields to defautl values*/
VCORE_InitMsg(pstMsgMulti, pstMsgMulti->fifo, pstSupvChnl->pstDev->MaxMsgSize);
/* send the following commands */
/* Send FAXOPTS */
Statu