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; }
int ooH323EpDestroy(void) { /* free any internal memory allocated close trace file free context structure */ OOH323CallData * cur, *temp; if(OO_TESTFLAG(gH323ep.flags, OO_M_ENDPOINTCREATED)) { OOTRACEINFO1("Destroying H323 Endpoint\n"); if(gH323ep.callList) { cur = gH323ep.callList; while(cur) { temp = cur; cur = cur->next; temp->callEndReason = OO_REASON_LOCAL_CLEARED; ooCleanCall(temp); } gH323ep.callList = NULL; } if(gH323ep.listener) { ooSocketClose(*(gH323ep.listener)); gH323ep.listener = NULL; } ooGkClientDestroy(); if(gH323ep.fptraceFile) { fclose(gH323ep.fptraceFile); gH323ep.fptraceFile = NULL; } freeContext(&(gH323ep.ctxt)); freeContext(&(gH323ep.msgctxt)); OO_CLRFLAG(gH323ep.flags, OO_M_ENDPOINTCREATED); } return OO_OK; }
void ooH323EpPrintConfig(void) { OOTRACEINFO1("H.323 Endpoint Configuration is as follows:\n"); OOTRACEINFO2("\tTrace File: %s\n", gH323ep.traceFile); if(!OO_TESTFLAG(gH323ep.flags, OO_M_FASTSTART)) { OOTRACEINFO1("\tFastStart - disabled\n"); } else{ OOTRACEINFO1("\tFastStart - enabled\n"); } if(!OO_TESTFLAG(gH323ep.flags, OO_M_TUNNELING)) { OOTRACEINFO1("\tH245 Tunneling - disabled\n"); } else{ OOTRACEINFO1("\tH245 Tunneling - enabled\n"); } if(!OO_TESTFLAG(gH323ep.flags, OO_M_MEDIAWAITFORCONN)) { OOTRACEINFO1("\tMediaWaitForConnect - disabled\n"); } else{ OOTRACEINFO1("\tMediaWaitForConnect - enabled\n"); } if(OO_TESTFLAG(gH323ep.flags, OO_M_AUTOANSWER)) OOTRACEINFO1("\tAutoAnswer - enabled\n"); else OOTRACEINFO1("\tAutoAnswer - disabled\n"); OOTRACEINFO2("\tTerminal Type - %d\n", gH323ep.termType); OOTRACEINFO2("\tT35 CountryCode - %d\n", gH323ep.t35CountryCode); OOTRACEINFO2("\tT35 Extension - %d\n", gH323ep.t35Extension); OOTRACEINFO2("\tManufacturer Code - %d\n", gH323ep.manufacturerCode); OOTRACEINFO2("\tProductID - %s\n", gH323ep.productID); OOTRACEINFO2("\tVersionID - %s\n", gH323ep.versionID); OOTRACEINFO2("\tLocal signalling IP address - %s\n", gH323ep.signallingIP); OOTRACEINFO2("\tH225 ListenPort - %d\n", gH323ep.listenPort); OOTRACEINFO2("\tCallerID - %s\n", gH323ep.callerid); OOTRACEINFO2("\tCall Establishment Timeout - %d seconds\n", gH323ep.callEstablishmentTimeout); OOTRACEINFO2("\tMasterSlaveDetermination Timeout - %d seconds\n", gH323ep.msdTimeout); OOTRACEINFO2("\tTerminalCapabilityExchange Timeout - %d seconds\n", gH323ep.tcsTimeout); OOTRACEINFO2("\tLogicalChannel Timeout - %d seconds\n", gH323ep.logicalChannelTimeout); OOTRACEINFO2("\tSession Timeout - %d seconds\n", gH323ep.sessionTimeout); return; }
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; }
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; }
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; }
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; }