Пример #1
0
int ooRemoveCallFromList (OOH323CallData *call)
{
   if(!call || !gH323ep.callList)
      return OO_OK;

   ast_mutex_lock(&callListLock);

   OOTRACEINFO3("Removing call %lx: %s\n", call, call->callToken);

   if(call == gH323ep.callList)
   {
      if(!call->next)
         gH323ep.callList = NULL;
      else{
         call->next->prev = NULL;
         gH323ep.callList = call->next;
      }
   }
   else{
      call->prev->next = call->next;
      if(call->next)
         call->next->prev = call->prev;
   }

   ast_mutex_unlock(&callListLock);

   return OO_OK;
}
Пример #2
0
int ooEndCall(OOH323CallData *call)
{
   OOTRACEDBGA4("In ooEndCall call state is - %s (%s, %s)\n", 
                 ooGetCallStateText(call->callState), call->callType, 
                 call->callToken);

   if(call->callState == OO_CALL_REMOVED) {
      OOTRACEINFO2("Call already removed %s\n",
                    call->callToken);
     return OO_OK;
   }

   if (call->callIdentifier.guid.numocts == 0) call->callState = OO_CALL_CLEARED;

   if(!call->pH225Channel || call->pH225Channel->sock ==0)
   {
      call->callState = OO_CALL_CLEARED;
   }

   if(call->callState == OO_CALL_CLEARED || call->callState == OO_CALL_CLEAR_RELEASESENT)
   {
      ooCleanCall(call); 
      call->callState = OO_CALL_REMOVED;
      return OO_OK;
   }

   if(call->logicalChans)
   {
      OOTRACEINFO3("Clearing all logical channels. (%s, %s)\n", call->callType,
                    call->callToken);
      ooClearAllLogicalChannels(call);
   }

   if(!OO_TESTFLAG(call->flags, OO_M_ENDSESSION_BUILT))
   {
      if(call->h245SessionState == OO_H245SESSION_ACTIVE ||
         call->h245SessionState == OO_H245SESSION_ENDRECVD)
      {
         ooSendEndSessionCommand(call);
         OO_SETFLAG(call->flags, OO_M_ENDSESSION_BUILT);
      }
   }


   if(!OO_TESTFLAG(call->flags, OO_M_RELEASE_BUILT))   
   {
     if(call->callState == OO_CALL_CLEAR || 
        call->callState == OO_CALL_CLEAR_RELEASERECVD)
     {
        ooSendReleaseComplete(call);
        OO_SETFLAG(call->flags, OO_M_RELEASE_BUILT);
     }
   }
      
   return OO_OK;
}
Пример #3
0
int ooCallH245ConnectionRetryTimerExpired(void *data)
{
   ooTimerCallback *cbData = (ooTimerCallback*) data;
   OOH323CallData *call = cbData->call;

   OOTRACEINFO3("H245 connection retry timer expired. (%s, %s)\n", 
                                            call->callType, call->callToken); 
   memFreePtr(call->pctxt, cbData);

   call->h245ConnectionAttempts++;

   ooCreateH245Connection(call);

   return OO_OK;
}
Пример #4
0
int ooClearAllLogicalChannels(OOH323CallData *call)
{
   OOLogicalChannel * temp = NULL, *prev = NULL;

   OOTRACEINFO3("Clearing all logical channels (%s, %s)\n", call->callType,
                 call->callToken);
   
   temp = call->logicalChans;
   while(temp)
   {
      prev = temp;
      temp = temp->next;
      ooClearLogicalChannel(call, prev->channelNo);/* TODO: efficiency - This causes re-search 
                                                      of of logical channel in the list. Can be
                                                      easily improved.*/
   }
   call->logicalChans = NULL;
   return OO_OK;
}
Пример #5
0
OOH323CallData* ooFindCallByToken(const char *callToken)
{
   OOH323CallData *call;
   if(!callToken)
   {
      OOTRACEERR1("ERROR:Invalid call token passed - ooFindCallByToken\n");
      return NULL;
   }

   ast_mutex_lock(&callListLock);

   if(!gH323ep.callList)
   {
      OOTRACEERR1("ERROR: Empty calllist - ooFindCallByToken failed\n");
      ast_mutex_unlock(&callListLock);
      return NULL;
   }
   call = gH323ep.callList;
   while(call)
   {
      if(!strcmp(call->callToken, callToken))
         break;
      else
         call = call->next;
   }
   
   if(!call)
   {
      OOTRACEERR2("ERROR:Call with token %s not found\n", callToken);
      ast_mutex_unlock(&callListLock);
      return NULL;
   }

   ast_mutex_unlock(&callListLock);

   OOTRACEINFO3("INFO: FinCall returned %lx for call: %s\n", call, callToken);

   return call;
}
Пример #6
0
OOLogicalChannel* ooAddNewLogicalChannel(OOH323CallData *call, int channelNo, 
                                         int sessionID, char *dir, 
                                         ooH323EpCapability *epCap)
{
   OOLogicalChannel *pNewChannel=NULL, *pChannel=NULL;
   OOMediaInfo *pMediaInfo = NULL;
   OOTRACEDBGC5("Adding new media channel for cap %d dir %s (%s, %s)\n",
               epCap->cap, dir, call->callType, call->callToken);
   /* Create a new logical channel entry */
   pNewChannel = (OOLogicalChannel*)memAlloc(call->pctxt, 
                                                     sizeof(OOLogicalChannel));
   if(!pNewChannel)
   {
      OOTRACEERR3("ERROR:Memory - ooAddNewLogicalChannel - pNewChannel "
                  "(%s, %s)\n", call->callType, call->callToken);
      return NULL;
   }
   
   memset(pNewChannel, 0, sizeof(OOLogicalChannel));
   pNewChannel->channelNo = channelNo;
   pNewChannel->sessionID = sessionID;
   pNewChannel->state = OO_LOGICALCHAN_IDLE;
   pNewChannel->type = epCap->capType;
   /*   strcpy(pNewChannel->type, type);*/
   strcpy(pNewChannel->dir, dir);

   pNewChannel->chanCap = epCap;
   OOTRACEDBGC4("Adding new channel with cap %d (%s, %s)\n", epCap->cap,
                call->callType, call->callToken); 
   /* As per standards, media control port should be same for all 
      proposed channels with same session ID. However, most applications
      use same media port for transmit and receive of audio streams. Infact,
      testing of OpenH323 based asterisk assumed that same ports are used. 
      Hence we first search for existing media ports for same session and use 
      them. This should take care of all cases.
   */
   if(call->mediaInfo)
   {
      pMediaInfo = call->mediaInfo;
      while(pMediaInfo)
      {
         if(!strcmp(pMediaInfo->dir, dir) &&
            (pMediaInfo->cap == epCap->cap))
         {
            break;
         }
         pMediaInfo = pMediaInfo->next;
      }
   }
    
   if(pMediaInfo)
   {
      OOTRACEDBGC3("Using configured media info (%s, %s)\n", call->callType,
                   call->callToken);
      pNewChannel->localRtpPort = pMediaInfo->lMediaPort;
      pNewChannel->localRtcpPort = pMediaInfo->lMediaCntrlPort;
      /* If user application has not specified a specific ip and is using 
         multihomed mode, substitute appropriate ip.
      */
      if(!strcmp(pMediaInfo->lMediaIP, "0.0.0.0"))
         strcpy(pNewChannel->localIP, call->localIP);
      else
         strcpy(pNewChannel->localIP, pMediaInfo->lMediaIP);
   }
   else{
      OOTRACEDBGC3("Using default media info (%s, %s)\n", call->callType,
                   call->callToken);
      pNewChannel->localRtpPort = ooGetNextPort (OORTP);

      /* Ensures that RTP port is an even one */
      if((pNewChannel->localRtpPort & 1) == 1)
        pNewChannel->localRtpPort = ooGetNextPort (OORTP);

      pNewChannel->localRtcpPort = ooGetNextPort (OORTP);
      strcpy(pNewChannel->localIP, call->localIP);
   }
   
   /* Add new channel to the list */
   pNewChannel->next = NULL;
   if(!call->logicalChans) {
      call->logicalChans = pNewChannel;
   }
   else{
      pChannel = call->logicalChans;
      while(pChannel->next)  pChannel = pChannel->next;
      pChannel->next = pNewChannel;
   }
   
   /* increment logical channels */
   call->noOfLogicalChannels++;
   OOTRACEINFO3("Created new logical channel entry (%s, %s)\n", call->callType,
                call->callToken);
   return pNewChannel;
}
Пример #7
0
OOH323CallData* ooCreateCall(char* type, char*callToken)
{
   OOH323CallData *call=NULL;
   OOCTXT *pctxt=NULL;

   pctxt = newContext();
   if(!pctxt)
   {
      OOTRACEERR1("ERROR:Failed to create OOCTXT for new call\n");
      return NULL;
   }
   call = (OOH323CallData*)memAlloc(pctxt, sizeof(OOH323CallData));
   if(!call)
   {
      OOTRACEERR1("ERROR:Memory - ooCreateCall - call\n");
      return NULL;
   } 
   /*   memset(call, 0, sizeof(OOH323CallData));*/
   call->pctxt = pctxt;
   call->callMode = gH323ep.callMode;
   sprintf(call->callToken, "%s", callToken);
   sprintf(call->callType, "%s", type);
   call->callReference = 0;
   if(gH323ep.callerid) {
     strncpy(call->ourCallerId, gH323ep.callerid, sizeof(call->ourCallerId)-1);
     call->ourCallerId[sizeof(call->ourCallerId)-1] = '\0';
   }
   else {
      call->ourCallerId[0] = '\0';
   }
   
   memset(&call->callIdentifier, 0, sizeof(H225CallIdentifier));
   memset(&call->confIdentifier, 0, sizeof(H225ConferenceIdentifier));

   call->flags = 0;
   if (OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING))
      OO_SETFLAG (call->flags, OO_M_TUNNELING);

   if(gH323ep.gkClient)
   {
      if(OO_TESTFLAG(gH323ep.flags, OO_M_GKROUTED))
      {
         OO_SETFLAG(call->flags, OO_M_GKROUTED);
      }
   }

   if (OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART))
      OO_SETFLAG (call->flags, OO_M_FASTSTART);

   if (OO_TESTFLAG(gH323ep.flags, OO_M_MEDIAWAITFORCONN))
      OO_SETFLAG (call->flags, OO_M_MEDIAWAITFORCONN);
   
   call->callState = OO_CALL_CREATED;
   call->callEndReason = OO_REASON_UNKNOWN;
   call->pCallFwdData = NULL;

   if(!strcmp(call->callType, "incoming"))
   {
      call->callingPartyNumber = NULL;
   }
   else{      
      if(ooUtilsIsStrEmpty(gH323ep.callingPartyNumber))
      {
         call->callingPartyNumber = NULL;
      }
      else{
         call->callingPartyNumber = (char*) memAlloc(call->pctxt, 
                                         strlen(gH323ep.callingPartyNumber)+1);
         if(call->callingPartyNumber)
         {
            strcpy(call->callingPartyNumber, gH323ep.callingPartyNumber);
         }
         else{
            OOTRACEERR3("Error:Memory - ooCreateCall - callingPartyNumber"
                        ".(%s, %s)\n", call->callType, call->callToken);
            freeContext(pctxt);
            return NULL;
         }
      }
   }

   call->calledPartyNumber = NULL;
   call->h245ConnectionAttempts = 0;
   call->h245SessionState = OO_H245SESSION_IDLE;
   call->dtmfmode = gH323ep.dtmfmode;
   call->mediaInfo = NULL;
   strcpy(call->localIP, gH323ep.signallingIP);
   call->pH225Channel = NULL;
   call->pH245Channel = NULL;
   call->h245listener = NULL;
   call->h245listenport = NULL;
   call->remoteIP[0] = '\0';
   call->remotePort = 0;
   call->remoteH245Port = 0;
   call->remoteDisplayName = NULL;
   call->remoteAliases = NULL;
   call->ourAliases = NULL;
   call->masterSlaveState = OO_MasterSlave_Idle;
   call->statusDeterminationNumber = 0;
   call->localTermCapState = OO_LocalTermCapExchange_Idle;
   call->remoteTermCapState = OO_RemoteTermCapExchange_Idle; 
   call->ourCaps = NULL;
   call->remoteCaps = NULL;
   call->jointCaps = NULL;
   dListInit(&call->remoteFastStartOLCs);
   call->remoteTermCapSeqNo =0;
   call->localTermCapSeqNo = 0;
   memcpy(&call->capPrefs, &gH323ep.capPrefs, sizeof(OOCapPrefs));    
   call->logicalChans = NULL;
   call->noOfLogicalChannels = 0;
   call->logicalChanNoBase = 1001;
   call->logicalChanNoMax = 1100;
   call->logicalChanNoCur = 1001;
   call->nextSessionID = 4; /* 1,2,3 are reserved for audio, video and data */
   dListInit(&call->timerList);
   call->msdRetries = 0;
   call->pFastStartRes = NULL;
   call->usrData = NULL;
   OOTRACEINFO3("Created a new call (%s, %s)\n", call->callType, 
                 call->callToken);
   /* Add new call to calllist */
   ooAddCallToList (call);
   if(gH323ep.h323Callbacks.onNewCallCreated)
     gH323ep.h323Callbacks.onNewCallCreated(call);
   return call;
}
Пример #8
0
int ooCleanCall(OOH323CallData *call)
{
   OOCTXT *pctxt;

   OOTRACEWARN4 ("Cleaning Call (%s, %s)- reason:%s\n", 
                 call->callType, call->callToken, 
                 ooGetReasonCodeText (call->callEndReason));

   /* First clean all the logical channels, if not already cleaned. */
   if(call->logicalChans)
      ooClearAllLogicalChannels(call);
   
   /* Close H.245 connection, if not already closed */
   if(call->h245SessionState != OO_H245SESSION_CLOSED)
      ooCloseH245Connection(call);
   else{
      if(call->pH245Channel && call->pH245Channel->outQueue.count > 0)
      {
         dListFreeAll(call->pctxt, &(call->pH245Channel->outQueue));
         memFreePtr(call->pctxt, call->pH245Channel);
      }
   }

   /* Close H.245 listener, if not already closed */
   if(call->h245listener)
   {
      ooCloseH245Listener(call);
   }
   
   /* Close H225 connection, if not already closed. */
   if (0 != call->pH225Channel && 0 != call->pH225Channel->sock)
   {
      ooCloseH225Connection(call);
   }

   /* Clean timers */
   if(call->timerList.count > 0)
   {
      dListFreeAll(call->pctxt, &(call->timerList));
   }

   if(gH323ep.gkClient && !OO_TESTFLAG(call->flags, OO_M_DISABLEGK))
   {
      ooGkClientCleanCall(gH323ep.gkClient, call);
   }

   ooRemoveCallFromList (call);
   OOTRACEINFO3("Removed call (%s, %s) from list\n", call->callType, 
                 call->callToken);

   if(call->pCallFwdData && call->pCallFwdData->fwdedByRemote)
   {

      if(gH323ep.h323Callbacks.onCallForwarded)
         gH323ep.h323Callbacks.onCallForwarded(call);

      if(ooH323HandleCallFwdRequest(call)!= OO_OK)
      {
         OOTRACEERR3("Error:Failed to forward call (%s, %s)\n", call->callType,
                     call->callToken);
      }
   }
   else {
      if(gH323ep.h323Callbacks.onCallCleared)
         gH323ep.h323Callbacks.onCallCleared(call);
   }

   pctxt = call->pctxt;
   freeContext(pctxt);
   ASN1CRTFREE0(pctxt);
   return OO_OK;
}
Пример #9
0
int ooReadAndProcessCallStackCommand(OOH323CallData* call)
{
   unsigned char buffer[MAXMSGLEN];
   unsigned char *bPoint;
   int recvLen = 0;
   OOStackCommand cmd;
   memset(&cmd, 0, sizeof(OOStackCommand));
   if (call->CmdChanLock) {
    ast_mutex_lock(call->CmdChanLock);
    recvLen = read(call->cmdSock, buffer, MAXMSGLEN);
    ast_mutex_unlock(call->CmdChanLock);
   } else {
    recvLen = read(call->cmdSock, buffer, MAXMSGLEN);
   }
   if(recvLen <= 0)
   {
      OOTRACEERR1("Error:Failed to read CMD message\n");
      return OO_FAILED;
   }

   bPoint = buffer;
   while (bPoint  < buffer + recvLen - sizeof(OOStackCommand)) {

      memcpy(&cmd, bPoint, sizeof(OOStackCommand));
      bPoint +=  sizeof(OOStackCommand);

      if (cmd.plen1 > 0) {
	cmd.param1 = malloc(cmd.plen1 + 1);
	if (!cmd.param1) 
		return OO_FAILED;
	memset(cmd.param1, 0, cmd.plen1 + 1);
	memcpy(cmd.param1, bPoint, cmd.plen1);
	bPoint += cmd.plen1;
      }

      if (cmd.plen2 > 0) {
	cmd.param2 = malloc(cmd.plen2 + 1);
	if (!cmd.param2) 
		return OO_FAILED;
	memset(cmd.param2, 0, cmd.plen2 + 1);
	memcpy(cmd.param2, bPoint, cmd.plen2);
	bPoint += cmd.plen2;
      }

      if (cmd.plen3 > 0) {
	cmd.param3 = malloc(cmd.plen3 + 1);
	if (!cmd.param3) 
		return OO_FAILED;
	memset(cmd.param3, 0, cmd.plen3 + 1);
	memcpy(cmd.param3, bPoint, cmd.plen3);
	bPoint += cmd.plen3;
      }

      if(cmd.type == OO_CMD_NOOP)
         continue;

      if(gH323ep.gkClient && gH323ep.gkClient->state != GkClientRegistered)
      {
         OOTRACEINFO1("Ignoring stack command as Gk Client is not registered"
                      " yet\n");
      }
      else {
         switch(cmd.type) {
            case OO_CMD_MAKECALL: 
               OOTRACEINFO2("Processing MakeCall command %s\n", 
                                    (char*)cmd.param2);
 
               ooH323MakeCall ((char*)cmd.param1, (char*)cmd.param2, 
                               (ooCallOptions*)cmd.param3);
               break;

            case OO_CMD_MANUALPROGRESS:
               ooSendProgress(call);
               break;

            case OO_CMD_MANUALRINGBACK:
               if(OO_TESTFLAG(gH323ep.flags, OO_M_MANUALRINGBACK))
               {
                 ooSendAlerting(call);
                 if(OO_TESTFLAG(gH323ep.flags, OO_M_AUTOANSWER)) {
                   ooSendConnect(call);
                 }
               }
               break;
 
            case OO_CMD_ANSCALL:
                  ooSendConnect(call);
               break;

            case OO_CMD_FWDCALL:
               OOTRACEINFO3("Forwarding call %s to %s\n", (char*)cmd.param1,
                                                          (char*)cmd.param2);
               ooH323ForwardCall((char*)cmd.param1, (char*)cmd.param2);
               break;

            case OO_CMD_HANGCALL: 
               OOTRACEINFO2("Processing Hang call command %s with q931 cause %d\n", 
                             (char*)cmd.param1);
               ooH323HangCall((char*)cmd.param1, 
                              *(OOCallClearReason*)cmd.param2, *(int *) cmd.param3);
               break;
          
            case OO_CMD_SENDDIGIT:
               if(call->jointDtmfMode & OO_CAP_DTMF_H245_alphanumeric) {
                  ooSendH245UserInputIndication_alphanumeric(
                     call, (const char*)cmd.param2);
               }
               else if(call->jointDtmfMode & OO_CAP_DTMF_H245_signal) {
                  ooSendH245UserInputIndication_signal(
                     call, (const char*)cmd.param2);
               }
               else {
                  ooQ931SendDTMFAsKeyPadIE(call, (const char*)cmd.param2);
               }

               break;

	    case OO_CMD_REQMODE:
	       OOTRACEINFO3("Processing RequestMode command %s, requested mode is %d\n",
				(char *)cmd.param1, *(int *)cmd.param2);
	       ooSendRequestMode(call, *(int *)cmd.param2);
	       break;

	    case OO_CMD_SETANI:
		OOTRACEINFO3("Processing SetANI command %s, ani is %s\n",
				(char *)cmd.param1, (char *)cmd.param2);
   		if(cmd.param2) {
     			strncpy(call->ourCallerId, cmd.param2, sizeof(call->ourCallerId)-1);
     			call->ourCallerId[sizeof(call->ourCallerId)-1] = '\0';
   		}
		break;

            default: OOTRACEERR1("ERROR:Unknown command\n");
         }
      }
      if(cmd.param1) free(cmd.param1);
      if(cmd.param2) free(cmd.param2);
      if(cmd.param3) free(cmd.param3);
   }


   return OO_OK;
}
Пример #10
0
int ooReadAndProcessStackCommand()
{
   OOH323CallData *pCall = NULL;   
   unsigned char buffer[MAXMSGLEN];
   int i, recvLen = 0;
   OOStackCommand cmd;
   memset(&cmd, 0, sizeof(OOStackCommand));
   ast_mutex_lock(&gCmdChanLock);
   recvLen = read(gH323ep.cmdSock, buffer, MAXMSGLEN);
   ast_mutex_unlock(&gCmdChanLock);
   if(recvLen <= 0)
   {
      OOTRACEERR1("Error:Failed to read CMD message\n");
      return OO_FAILED;
   }

   for(i=0; (int)(i+sizeof(OOStackCommand)) <= recvLen; i += sizeof(OOStackCommand))
   {
      memcpy(&cmd, buffer+i, sizeof(OOStackCommand));

      if(cmd.type == OO_CMD_NOOP)
         continue;

      if(gH323ep.gkClient && gH323ep.gkClient->state != GkClientRegistered && cmd.type != OO_CMD_STOPMONITOR)
      {
         OOTRACEINFO1("Ignoring stack command as Gk Client is not registered"
                      " yet\n");
      }
      else {
         switch(cmd.type) {
            case OO_CMD_MAKECALL: 
               OOTRACEINFO2("Processing MakeCall command %s\n", 
                                    (char*)cmd.param2);
 
               ooH323NewCall ((char*)cmd.param2);
               break;

            case OO_CMD_MANUALPROGRESS:
                pCall = ooFindCallByToken((char*)cmd.param1);
                if(!pCall) {
                   OOTRACEINFO2("Call \"%s\" does not exist\n",
                                (char*)cmd.param1);
                   OOTRACEINFO1("Call migth be cleared/closed\n");
                }
                else {
                     ooSendProgress(ooFindCallByToken((char*)cmd.param1));
                }
               break;

            case OO_CMD_MANUALRINGBACK:
               if(OO_TESTFLAG(gH323ep.flags, OO_M_MANUALRINGBACK))
               {
                  pCall = ooFindCallByToken((char*)cmd.param1);
                  if(!pCall) {
                     OOTRACEINFO2("Call \"%s\" does not exist\n",
                                  (char*)cmd.param1);
                     OOTRACEINFO1("Call migth be cleared/closed\n");
                  }
                  else {
                     ooSendAlerting(ooFindCallByToken((char*)cmd.param1));
                     if(OO_TESTFLAG(gH323ep.flags, OO_M_AUTOANSWER)) {
                        ooSendConnect(ooFindCallByToken((char*)cmd.param1));
                     }
                  }
               }
               break;
 
            case OO_CMD_ANSCALL:
               pCall = ooFindCallByToken((char*)cmd.param1);
               if(!pCall) {
                  OOTRACEINFO2("Call \"%s\" does not exist\n",
                               (char*)cmd.param1);
                  OOTRACEINFO1("Call might be cleared/closed\n");
               }
               else {
                  OOTRACEINFO2("Processing Answer Call command for %s\n",
                               (char*)cmd.param1);
                  ooSendConnect(pCall);
               }
               break;

            case OO_CMD_FWDCALL:
               OOTRACEINFO3("Forwarding call %s to %s\n", (char*)cmd.param1,
                                                          (char*)cmd.param2);
               ooH323ForwardCall((char*)cmd.param1, (char*)cmd.param2);
               break;

            case OO_CMD_HANGCALL: 
               OOTRACEINFO3("Processing Hang call command %s with q931 cause %d\n", 
                             (char*)cmd.param1, *(int *) cmd.param3);
               ooH323HangCall((char*)cmd.param1, 
                              *(OOCallClearReason*)cmd.param2, *(int *) cmd.param3);
               break;
          
            case OO_CMD_SENDDIGIT:
               pCall = ooFindCallByToken((char*)cmd.param1);
               if(!pCall) {
                  OOTRACEERR2("ERROR:Invalid calltoken %s\n",
                              (char*)cmd.param1);
                  break;
               }
               if(pCall->jointDtmfMode & OO_CAP_DTMF_H245_alphanumeric) {
                  ooSendH245UserInputIndication_alphanumeric(
                     pCall, (const char*)cmd.param2);
               }
               else if(pCall->jointDtmfMode & OO_CAP_DTMF_H245_signal) {
                  ooSendH245UserInputIndication_signal(
                     pCall, (const char*)cmd.param2);
               }
               else {
                  ooQ931SendDTMFAsKeyPadIE(pCall, (const char*)cmd.param2);
               }

               break;

            case OO_CMD_STOPMONITOR: 
               OOTRACEINFO1("Processing StopMonitor command\n");
               ooStopMonitorCalls();
               break;

            default: OOTRACEERR1("ERROR:Unknown command\n");
         }
      }
      if(cmd.param1) free(cmd.param1);
      if(cmd.param2) free(cmd.param2);
      if(cmd.param3) free(cmd.param3);
   }


   return OO_OK;
}