[Asterisk-cvs] asterisk-addons/asterisk-ooh323c/ooh323c/src context.c, NONE, 1.1 decode.c, NONE, 1.1 dlist.c, NONE, 1.1 encode.c, NONE, 1.1 errmgmt.c, NONE, 1.1 eventHandler.c, NONE, 1.1 eventHandler.h, NONE, 1.1 memheap.c, NONE, 1.1 memheap.h, NONE, 1.1 ooCalls.c, NONE, 1.1 ooCalls.h, NONE, 1.1 ooCapability.c, NONE, 1.1 ooCapability.h, NONE, 1.1 ooCommon.h, NONE, 1.1 ooDateTime.c, NONE, 1.1 ooDateTime.h, NONE, 1.1 ooGkClient.c, NONE, 1.1 ooGkClient.h, NONE, 1.1 ooSocket.c, NONE, 1.1 ooSocket.h, NONE, 1.1 ooStackCmds.c, NONE, 1.1 ooStackCmds.h, NONE, 1.1 ooTimer.c, NONE, 1.1 ooTimer.h, NONE, 1.1 ooUtils.c, NONE, 1.1 ooUtils.h, NONE, 1.1 ooasn1.h, NONE, 1.1 oochannels.c, NONE, 1.1 oochannels.h, NONE, 1.1 ooh245.c, NONE, 1.1 ooh245.h, NONE, 1.1 ooh323.c, NONE, 1.1 ooh323.h, NONE, 1.1 ooh323ep.c, NONE, 1.1 ooh323ep.h, NONE, 1.1 oohdr.h, NONE, 1.1 ooper.h, NONE, 1.1 ooports.c, NONE, 1.1 ooports.h, NONE, 1.1 ooq931.c, NONE, 1.1 ooq931.h, NONE, 1.1 ootrace.c, NONE, 1.1 ootrace.h, NONE, 1.1 ootypes.h, NONE, 1.1 perutil.c, NONE, 1.1 printHandler.c, NONE, 1.1 printHandler.h, NONE, 1.1 rtctype.c, NONE, 1.1 rtctype.h, NONE, 1.1

vphirke at lists.digium.com vphirke at lists.digium.com
Mon May 23 16:59:34 CDT 2005


Update of /usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src
In directory mongoose.digium.com:/tmp/cvs-serv20453

Added Files:
	context.c decode.c dlist.c encode.c errmgmt.c eventHandler.c 
	eventHandler.h memheap.c memheap.h ooCalls.c ooCalls.h 
	ooCapability.c ooCapability.h ooCommon.h ooDateTime.c 
	ooDateTime.h ooGkClient.c ooGkClient.h ooSocket.c ooSocket.h 
	ooStackCmds.c ooStackCmds.h ooTimer.c ooTimer.h ooUtils.c 
	ooUtils.h ooasn1.h oochannels.c oochannels.h ooh245.c ooh245.h 
	ooh323.c ooh323.h ooh323ep.c ooh323ep.h oohdr.h ooper.h 
	ooports.c ooports.h ooq931.c ooq931.h ootrace.c ootrace.h 
	ootypes.h perutil.c printHandler.c printHandler.h rtctype.c 
	rtctype.h 
Log Message:
Added

--- NEW FILE: context.c ---
/*
 * Copyright (C) 1997-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 "ooasn1.h"
#include <stdlib.h>

int initContext (OOCTXT* pctxt)
{
   memset (pctxt, 0, sizeof(OOCTXT));

   memHeapCreate (&pctxt->pTypeMemHeap);
   pctxt->pMsgMemHeap = pctxt->pTypeMemHeap;
   memHeapAddRef (&pctxt->pMsgMemHeap);

   return ASN_OK;
}

int initContextBuffer 
(OOCTXT* pctxt, const ASN1OCTET* bufaddr, ASN1UINT bufsiz)
{
   if (bufaddr == 0) {
      /* dynamic buffer */
      if (bufsiz == 0) bufsiz = ASN_K_ENCBUFSIZ;
      pctxt->buffer.data = (ASN1OCTET*) 
         memHeapAlloc (&pctxt->pMsgMemHeap, bufsiz);
      if (!pctxt->buffer.data) return ASN_E_NOMEM;
      pctxt->buffer.size = bufsiz;
      pctxt->buffer.dynamic = TRUE;
   }
   else {
      /* static buffer */
      pctxt->buffer.data = (ASN1OCTET*) bufaddr;
      pctxt->buffer.size = bufsiz;
      pctxt->buffer.dynamic = FALSE;
   }

   pctxt->buffer.byteIndex = 0;
   pctxt->buffer.bitOffset = 8;

   return ASN_OK;
}

int initSubContext (OOCTXT* pctxt, OOCTXT* psrc) 
{
   int stat = ASN_OK;
   memset (pctxt, 0, sizeof(OOCTXT));
   pctxt->pTypeMemHeap = psrc->pTypeMemHeap;
   memHeapAddRef (&pctxt->pTypeMemHeap);
   pctxt->pMsgMemHeap = psrc->pMsgMemHeap;
   memHeapAddRef (&pctxt->pMsgMemHeap);
   pctxt->flags = psrc->flags;
   pctxt->buffer.dynamic = TRUE;
   pctxt->buffer.byteIndex = 0;
   pctxt->buffer.bitOffset = 8;
   return stat;
}

void freeContext (OOCTXT* pctxt)
{
   ASN1BOOL saveBuf = (pctxt->flags & ASN1SAVEBUF) != 0;
   
   if (pctxt->buffer.dynamic && pctxt->buffer.data) {
      if (saveBuf) {
         memHeapMarkSaved (&pctxt->pMsgMemHeap, pctxt->buffer.data, TRUE);
      }
      else {
         memHeapFreePtr (&pctxt->pMsgMemHeap, pctxt->buffer.data);
      }
   }

   errFreeParms (&pctxt->errInfo);

   memHeapRelease (&pctxt->pTypeMemHeap);
   memHeapRelease (&pctxt->pMsgMemHeap);
}

void copyContext (OOCTXT* pdest, OOCTXT* psrc)
{
   memcpy (&pdest->buffer, &psrc->buffer, sizeof(ASN1BUFFER));
   pdest->flags = psrc->flags;
}

void setCtxtFlag (OOCTXT* pctxt, ASN1USINT mask)
{
   pctxt->flags |= mask;
}

void clearCtxtFlag (OOCTXT* pctxt, ASN1USINT mask)
{
   pctxt->flags &= ~mask;
}

int setPERBufferUsingCtxt (OOCTXT* pTarget, OOCTXT* pSource)
{
   int stat = initContextBuffer 
      (pTarget, pSource->buffer.data, pSource->buffer.size);

   if (ASN_OK == stat) {
      pTarget->buffer.byteIndex = pSource->buffer.byteIndex;
      pTarget->buffer.bitOffset = pSource->buffer.bitOffset;
   }

   return stat;
}

int setPERBuffer (OOCTXT* pctxt,
                  ASN1OCTET* bufaddr, ASN1UINT bufsiz, ASN1BOOL aligned)
{
   int stat = initContextBuffer (pctxt, bufaddr, bufsiz);
   if(stat != ASN_OK) return stat;

   
   return ASN_OK;
}

OOCTXT* newContext () 
{
   OOCTXT* pctxt = (OOCTXT*) ASN1CRTMALLOC0 (sizeof(OOCTXT));
   if (pctxt) {
      if (initContext(pctxt) != ASN_OK) {
         ASN1CRTFREE0 (pctxt);
         pctxt = 0;
      }
      pctxt->flags |= ASN1DYNCTXT;
   }
   return (pctxt);
}

--- NEW FILE: decode.c ---
/*
 * Copyright (C) 1997-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 "ooasn1.h"

static int decode16BitConstrainedString 
[...1011 lines suppressed...]

   return totalLen;
}

int moveBitCursor (OOCTXT* pctxt, int bitOffset)
{
   int currBitOffset =
      (pctxt->buffer.byteIndex * 8) + (8 - pctxt->buffer.bitOffset);

   currBitOffset += bitOffset;

   pctxt->buffer.byteIndex = (currBitOffset / 8);
   pctxt->buffer.bitOffset = 8 - (currBitOffset % 8);

   if (pctxt->buffer.byteIndex > pctxt->buffer.size) {
      return (ASN_E_ENDOFBUF);
   }
      
   return ASN_OK;
}

--- NEW FILE: dlist.c ---
/*
 * Copyright (C) 1997-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 "ooasn1.h"

void dListInit (DList* pList)
{
   if (pList) {
      pList->count = 0;
      pList->head = (DListNode*) 0;
      pList->tail = (DListNode*) 0;
   }
}

DListNode* dListAppend (OOCTXT* pctxt, DList* pList, void* pData)
{
   DListNode* pListNode = (DListNode*) 
      memAlloc (pctxt, sizeof(DListNode));

   if (0 != pListNode) {
      pListNode->data = pData;
      pListNode->next = (DListNode*) 0;
      if (0 != pList->tail) {
         pList->tail->next = pListNode;
         pListNode->prev = pList->tail;
      }
      if (0 == pList->head) {
         pList->head = pListNode;
         pListNode->prev = (DListNode*) 0;
      }
      pList->tail = pListNode;
      pList->count++;
   }

   return pListNode;
}

DListNode* dListAppendNode (OOCTXT* pctxt, DList* pList, void* pData)
{
   DListNode* pListNode = 
      (DListNode*) (((char*)pData) - sizeof(DListNode));

   if (0 != pListNode) {
      pListNode->data = pData;
      pListNode->next = (DListNode*) 0;
      if (0 != pList->tail) {
         pList->tail->next = pListNode;
         pListNode->prev = pList->tail;
      }
      if (0 == pList->head) {
         pList->head = pListNode;
         pListNode->prev = (DListNode*) 0;
      }
      pList->tail = pListNode;
      pList->count++;
   }

   return pListNode;
}

/* Free all nodes, but not the data */
void dListFreeNodes (OOCTXT* pctxt, DList* pList)
{
   DListNode* pNode, *pNextNode;

   for (pNode = pList->head; pNode != 0; pNode = pNextNode) {
      pNextNode = pNode->next;
      memFreePtr (pctxt, pNode);
   }
   pList->count = 0;
   pList->head = pList->tail = 0;
}

/* Free all nodes and their data */
void dListFreeAll (OOCTXT* pctxt, DList* pList)
{
   DListNode* pNode, *pNextNode;

   for (pNode = pList->head; pNode != 0; pNode = pNextNode) {
      pNextNode = pNode->next;
      
      memFreePtr (pctxt, pNode->data);
      memFreePtr (pctxt, pNode);
   }
   pList->count = 0;
   pList->head = pList->tail = 0;
}

/* Remove node from list. Node is not freed */
void dListRemove (DList* pList, DListNode* node)
{
   if(node->next != 0) {
      node->next->prev = node->prev;
   }
   else { /* tail */
      pList->tail = node->prev;
   }
   if(node->prev != 0) {
      node->prev->next = node->next;
   }
   else { /* head */
      pList->head = node->next;
   }
   pList->count--;
}

void dListFindAndRemove(DList* pList, void *data)
{
   DListNode *pNode, *pNextNode;
   for(pNode = pList->head; pNode !=0; pNode = pNextNode){
      pNextNode = pNode->next;
      if(pNode->data == data) /* pointer comparison*/
         break;
   }
   if(pNode)
      dListRemove(pList, pNode);
}
    
DListNode* dListFindByIndex (DList* pList, int index) 
{
   DListNode* curNode;
   int i;

   if(index >= (int)pList->count) return 0;
   for(i = 0, curNode = pList->head; i < index && curNode != 0; i++) {
      curNode = curNode->next;
   }
   return curNode;
}

/* Insert item before given node */

DListNode* dListInsertBefore 
(OOCTXT* pctxt, DList* pList, DListNode* node, const void* pData)
{
   DListNode* pListNode = (DListNode*) memAlloc (pctxt, sizeof(DListNode));
  
   if (0 != pListNode) {
      pListNode->data = (void*)pData;

      if (node == 0) { /* insert before end (as last element) */
         pListNode->next = (DListNode*) 0;
         if (0 != pList->tail) {
            pList->tail->next = pListNode;
            pListNode->prev = pList->tail;
         }
         if (0 == pList->head) {
            pList->head = pListNode;
            pListNode->prev = (DListNode*) 0;
         }
         pList->tail = pListNode;
      }
      else if (node == pList->head) { /* insert as head (head case) */
         pListNode->next = pList->head;
         pListNode->prev = (DListNode*) 0;
         if(pList->head != 0) {
            pList->head->prev = pListNode;
         }
         if(pList->tail == 0) {
            pList->tail = pListNode;
         }
         pList->head = pListNode;
      }
      else { /* other cases */
         pListNode->next = node;
         pListNode->prev = node->prev;
         node->prev = pListNode;
         /* here, pListNode->prev always should be non-zero,
          * because if pListNode->prev is zero - it is head case (see above).
          */
         pListNode->prev->next = pListNode;
      }

      pList->count++;
   }

   return pListNode;
}

/* Insert item after given node */

DListNode* dListInsertAfter 
(OOCTXT* pctxt, DList* pList, DListNode* node, const void* pData)
{
   DListNode* pListNode = (DListNode*) memAlloc (pctxt, sizeof(DListNode));

   if (0 != pListNode) {
      pListNode->data = (void*)pData;

      if (node == 0) { /* insert as head (as first element) */
         pListNode->next = pList->head;
         pListNode->prev = (DListNode*) 0;
         if (pList->head != 0) {
            pList->head->prev = pListNode;
         }
         if (pList->tail == 0) {
            pList->tail = pListNode;
         }
         pList->head = pListNode;
      }
      else if (node == pList->tail) { /* insert as tail (as last element) */
         pListNode->next = (DListNode*) 0;
         if (0 != pList->tail) {
            pList->tail->next = pListNode;
            pListNode->prev = pList->tail;
         }
         if (0 == pList->head) {
            pList->head = pListNode;
            pListNode->prev = (DListNode*) 0;
         }
         pList->tail = pListNode;
      }
      else { /* other cases */
         pListNode->next = node->next;
         pListNode->prev = node;
         node->next = pListNode;
         /* here, pListNode->next always should be non-zero,
          * because if pListNode->next is zero - it is tail case (see above).
          */
         pListNode->next->prev = pListNode;
      }

      pList->count++;
   }

   return pListNode;
}


--- NEW FILE: encode.c ---
/*
 * Copyright (C) 1997-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 <stdlib.h>
#include "ooasn1.h"

[...1064 lines suppressed...]

   return enclen;
}

static int getIdentByteCount (ASN1UINT ident) 
{
   if (ident < (1u << 7)) {         /* 7 */
      return 1;
   }
   else if (ident < (1u << 14)) {   /* 14 */
      return 2;
   }
   else if (ident < (1u << 21)) {   /* 21 */
      return 3;
   }
   else if (ident < (1u << 28)) {   /* 28 */
      return 4;
   }
   return 5;
}

--- NEW FILE: errmgmt.c ---
/*
 * Copyright (C) 1997-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.
 *
 *****************************************************************************/

/* Error management functions */

#include <stdlib.h>
#include "ooasn1.h"

/* Error status text */
static const char* g_status_text[] = {
    "Encode buffer overflow",
    "Unexpected end of buffer on decode",
    "Unexpected tag encountered: expected = %s, parsed = %s",
    "Invalid object identifier",
    "Invalid field length detected",
    "Enumerated value %s not in defined set",
    "Duplicate element in SET",
    "Missing required element in SET",
    "Element with tag %s not part of SET",
    "Max elements defined for SEQUENCE field exceeded",
    "Element with tag %s is an invalid option in choice",
    "No dynamic memory available",
    "Invalid string type",
    "Invalid hex string",
    "Invalid binary string",
    "Invalid real value",
    "Max items in sized BIT or OCTET STRING field exceeded",
    "Invalid value specification",
    "No definition found for referenced defined value",
    "No definition found for referenced defined type",
    "Invalid tag value",
    "Nesting level too deep",
    "Value constraint violation: field %s, value %s",
    "Value range error: lower bound is greater than upper",
    "Unexpected end of file detected",
    "Invalid UTF-8 character at index %d", 
    "List error: concurrent modification attempt while iterating", 
    "List error: illegal state for attempted operation",
    "Array index out of bounds",
    "Invalid parameter passed to function or method",
    "Invalid time string format",
    "Context is not initialized", 
    "ASN.1 value will not fit in target variable", 
    "Character is not within the defined character set", 
    "Invalid XML state for attempted operation", 
    "Error condition returned from XML parser:\n%s", 
    "SEQUENCE elements not in correct order",
    "Invalid index for table constraint identifier",
    "Invalid value for relational table constraint fixed type field", 
    "File not found", 
    "File read error",
    "File write error",
    "Invalid Base64 string",
    "Socket error",
    "XML interface library not found",
    "Invalid XML interface library"
} ;

#define ASN1_K_MAX_STAT (sizeof(g_status_text)/sizeof(char *))

/* Add an integer parameter to an error message */

int errAddIntParm (ASN1ErrInfo* pErrInfo, int errParm)
{
   char lbuf[16];
   sprintf (lbuf, "%d", errParm);
   return errAddStrParm (pErrInfo, lbuf);
}

/* Add a character string parameter to an error message */

int errAddStrParm (ASN1ErrInfo* pErrInfo, const char* errprm_p)
{
#if defined(_NO_THREADS) || !defined(_NO_MALLOC)
   if (pErrInfo->parmcnt < ASN_K_MAXERRP) {
      char* tmpstr = (char*) ASN1CRTMALLOC0 (strlen(errprm_p)+1);
      strcpy (tmpstr, errprm_p);
      pErrInfo->parms[pErrInfo->parmcnt] = tmpstr;
      pErrInfo->parmcnt++;
      return TRUE;
   }
   else
#endif
      return FALSE;
}

/* Add an unsigned integer parameter to an error message */

int errAddUIntParm (ASN1ErrInfo* pErrInfo, unsigned int errParm)
{
   char lbuf[16];
   sprintf (lbuf, "%u", errParm);
   return errAddStrParm (pErrInfo, lbuf);
}

/* Free error parameter memory */

void errFreeParms (ASN1ErrInfo* pErrInfo)
{
#if defined(_NO_THREADS) || !defined(_NO_MALLOC)
   int i;

   for (i = 0; i < pErrInfo->parmcnt; i++)
      ASN1CRTFREE0 ((char*)pErrInfo->parms[i]);
#endif

   pErrInfo->parmcnt = 0;
   pErrInfo->status = 0;
}

/* Reset error */

int errReset (ASN1ErrInfo* pErrInfo)
{
   errFreeParms (pErrInfo);
   pErrInfo->stkx = 0;
   return ASN_OK;
}

/* Format error message */

char* errFmtMsg (ASN1ErrInfo* pErrInfo, char* bufp)
{
   const char* tp;
   int  i, j, pcnt;

   if (pErrInfo->status < 0)
   {
      i = abs (pErrInfo->status + 1);

      if (i >= 0 && i < ASN1_K_MAX_STAT)
      {
         /* Substitute error parameters into error message */

         j  = pcnt = 0;
         tp = g_status_text[i];

         while (*tp) 
         {
            if (*tp == '%' && *(tp+1) == 's')
            {
               /* Plug in error parameter */

               if (pcnt < pErrInfo->parmcnt && pErrInfo->parms[pcnt])
               {
                  strcpy (&bufp[j], pErrInfo->parms[pcnt]);
                  j += strlen (pErrInfo->parms[pcnt++]);
               }
               else
                  bufp[j++] = '?';

               tp += 2;
            }
            else
               bufp[j++] = *tp++;
         }

         bufp[j] = '\0';        /* null terminate string */
      }
      else
         strcpy (bufp, "unrecognized completion status");
   }    
   else strcpy (bufp, "normal completion status");

   return (bufp);
}

/* Get error text in a dynamic memory buffer.  This allocates memory    */
/* using the 'memAlloc' function.  This memory is automatically freed */ 
/* at the time the 'memFree' function is called.                      */

char* errGetText (OOCTXT* pctxt)
{
   char lbuf[500];
   char* pBuf = (char*) ASN1MALLOC (pctxt,
      (sizeof(lbuf) + 100 * (2 + pctxt->errInfo.stkx)) * sizeof(char));

   sprintf (pBuf, "ASN.1 ERROR: Status %d\n", pctxt->errInfo.status);
   sprintf (lbuf, "%s\nStack trace:", errFmtMsg (&pctxt->errInfo, lbuf));
   strcat(pBuf, lbuf);

   while (pctxt->errInfo.stkx > 0) {
      pctxt->errInfo.stkx--;
      sprintf (lbuf, "  Module: %s, Line %d\n", 
               pctxt->errInfo.stack[pctxt->errInfo.stkx].module,
               pctxt->errInfo.stack[pctxt->errInfo.stkx].lineno);
      strcat(pBuf, lbuf);
   }

   errFreeParms (&pctxt->errInfo);

   return pBuf;
}

/* Print error information to the standard output */

void errPrint (ASN1ErrInfo* pErrInfo)
{
   char lbuf[200];
   printf ("ASN.1 ERROR: Status %d\n", pErrInfo->status);
   printf ("%s\n", errFmtMsg (pErrInfo, lbuf));
   printf ("Stack trace:");
   while (pErrInfo->stkx > 0) {
      pErrInfo->stkx--;
      printf ("  Module: %s, Line %d\n", 
              pErrInfo->stack[pErrInfo->stkx].module,
              pErrInfo->stack[pErrInfo->stkx].lineno);
   }
   errFreeParms (pErrInfo);
}

/* Copy error data from one error structure to another */

int errCopyData (ASN1ErrInfo* pSrcErrInfo, ASN1ErrInfo* pDestErrInfo)
{
   int i;
   pDestErrInfo->status = pSrcErrInfo->status;

   /* copy error parameters */

   for (i = 0; i < pSrcErrInfo->parmcnt; i++) {
      errAddStrParm (pDestErrInfo, pSrcErrInfo->parms[i]);
   }

   /* copy stack info */

   for (i = 0; i < pSrcErrInfo->stkx; i++) {
      if (pDestErrInfo->stkx < ASN_K_MAXERRSTK) {
         pDestErrInfo->stack[pDestErrInfo->stkx].module = 
            pSrcErrInfo->stack[i].module;
         pDestErrInfo->stack[pDestErrInfo->stkx++].lineno = 
            pSrcErrInfo->stack[i].lineno;
      }
   }

   return (pSrcErrInfo->status);
}


int errSetData (ASN1ErrInfo* pErrInfo, int status, 
                  const char* module, int lno) 
{ 
   if (pErrInfo->status == 0) {
      pErrInfo->status = status;
   }
   ooLogAsn1Error(status, module, lno);
   return status; 
}

--- NEW FILE: eventHandler.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 "eventHandler.h"

void setEventHandler (OOCTXT* pctxt, EventHandler* pHandler)
{
   pctxt->pEventHandler = pHandler;
}

void removeEventHandler (OOCTXT* pctxt)
{
   pctxt->pEventHandler = 0;
}

void invokeStartElement (OOCTXT* pctxt, const char* name, int index)
{
   if (0 != pctxt->pEventHandler) {
      pctxt->pEventHandler->startElement (name, index);
   }
}

void invokeEndElement (OOCTXT* pctxt, const char* name, int index)
{
   if (0 != pctxt->pEventHandler) {
      pctxt->pEventHandler->endElement (name, index);
   }
}

void invokeBoolValue (OOCTXT* pctxt, ASN1BOOL value)
{
   if (0 != pctxt->pEventHandler) {
      pctxt->pEventHandler->boolValue (value);
   }
}

void invokeIntValue (OOCTXT* pctxt, ASN1INT value)
{
   if (0 != pctxt->pEventHandler) {
      pctxt->pEventHandler->intValue (value);
   }
}

void invokeUIntValue (OOCTXT* pctxt, ASN1UINT value)
{
   if (0 != pctxt->pEventHandler) {
      pctxt->pEventHandler->uIntValue (value);
   }
}

void invokeBitStrValue (OOCTXT* pctxt, ASN1UINT numbits, 
			const ASN1OCTET* data)
{
   if (0 != pctxt->pEventHandler) {
      pctxt->pEventHandler->bitStrValue (numbits, data);
   }
}

void invokeOctStrValue (OOCTXT* pctxt, ASN1UINT numocts, 
			const ASN1OCTET* data)
{
   if (0 != pctxt->pEventHandler) {
      pctxt->pEventHandler->octStrValue (numocts, data);
   }
}

void invokeCharStrValue (OOCTXT* pctxt, const char* value)
{
   if (0 != pctxt->pEventHandler) {
      pctxt->pEventHandler->charStrValue (value);
   }
}

void invokeCharStr16BitValue (OOCTXT* pctxt, ASN1UINT nchars, 
			      ASN116BITCHAR* data)
{
   if (0 != pctxt->pEventHandler) {
      pctxt->pEventHandler->charStr16BitValue (nchars, data);
   }
}

void invokeNullValue (OOCTXT* pctxt)
{
   if (0 != pctxt->pEventHandler) {
      pctxt->pEventHandler->nullValue ();
   }
}

void invokeOidValue (OOCTXT* pctxt, ASN1UINT numSubIds, ASN1UINT* pSubIds)
{
   if (0 != pctxt->pEventHandler) {
      pctxt->pEventHandler->oidValue (numSubIds, pSubIds);
   }
}

void invokeEnumValue (OOCTXT* pctxt, ASN1UINT value)
{
   if (0 != pctxt->pEventHandler) {
      pctxt->pEventHandler->enumValue (value);
   }
}

void invokeOpenTypeValue (OOCTXT* pctxt, ASN1UINT numocts, 
			  const ASN1OCTET* data)
{
   if (0 != pctxt->pEventHandler) {
      pctxt->pEventHandler->openTypeValue (numocts, data);
   }
}

--- NEW FILE: eventHandler.h ---
/*
 * 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.
 *
 *****************************************************************************/
/**
 * @file eventHandler.h 
 * C event handler structure.  This structure holds event handler function 
 * callbacks for use by the generated code.
 */
/**
 * @defgroup EventHandler event handler
 * Event handler structures and callback function definitions.
 * @{
 */
#ifndef _EVENTHANDLER_H_
#define _EVENTHANDLER_H_

#include <stdio.h>
#include "ooasn1.h"

#ifdef __cplusplus
extern "C" {
#endif


#ifndef EXTERN
#ifdef _WIN32
#define EXTERN __declspec(dllexport)
#else
#define EXTERN
#endif /* _WIN32 */
#endif /* EXTERN */


/**
 * This is a function pointer for a callback function which is invoked 
 * from within a decode function when an element of a SEQUENCE, SET, 
 * SEQUENCE OF, SET OF, or CHOICE construct is parsed.
 *
 * @param name         For SEQUENCE, SET, or CHOICE, this is the name of the
 *                       element as defined in the ASN.1 defination. For
 *                       SEQUENCE OF or SET OF, this is set to the name
 *                       "element".
 * @param index        For SEQUENCE, SET, or CHOICE, this is not used and is
 *                       set to the value
 *                       -1. For SEQUENCE OF or SET OF, this contains the
 *                       zero-based index of the element in the conceptual
 *                       array associated with the construct.
 * @return             - none
 */
typedef void (*StartElement) (const char* name, int index) ;


/**
 * This is a function pointer for a callback function which is invoked from 
 * within a decode function when parsing is complete on an element of a 
 * SEQUENCE, SET, SEQUENCE OF, SET OF, or CHOICE construct.
 *
 * @param name         For SEQUENCE, SET, or CHOICE, this is the name of the
 *                       element as defined in the ASN.1 defination. For
 *                       SEQUENCE OF or SET OF, this is set to the name
 *                       "element".
 * @param index        For SEQUENCE, SET, or CHOICE, this is not used and is
 *                       set to the value
 *                       -1. For SEQUENCE OF or SET OF, this contains the
 *                       zero-based index of the element in the conceptual
 *                       array associated with the construct.
 * @return             - none
 */
typedef void (*EndElement) (const char* name, int index) ;


/**
 * This is a function pointer for a callback function which is invoked from 
 * within a decode function when a value of the BOOLEAN ASN.1 type is parsed.
 *
 * @param value        Parsed value.
 * @return             - none
 */
typedef void (*BoolValue) (ASN1BOOL value);

/**
 * This is a function pointer for a callback function which is invoked from 
 * within a decode function when a value of the INTERGER ASN.1 type is parsed.
 *
 * @param value        Parsed value.
 * @return             - none
 */
typedef void (*IntValue) (ASN1INT value);

/**
 * This is a function pointer for a callback function which is invoked 
 * from within a decode function when a value of the INTEGER ASN.1 type 
 * is parsed. In this case, constraints on the integer value forced the 
 * use of unsigned integer C type to represent the value.
 *
 * @param value        Parsed value.
 * @return             - none
 */
typedef void (*UIntValue) (ASN1UINT value);

/**
 * This is a function pointer for a callback function which is invoked from 
 * within a decode function when a value of the BIT STRING ASN.1 type is 
 * parsed.
 *
 * @param numbits      - Number of bits in the parsed value. 
 * @param data         - Pointer to a byte array that contains the bit 
 *                         string data.
 * @return             - none
 */ 
typedef void (*BitStrValue) (ASN1UINT numbits, const ASN1OCTET* data);

/**
 * This is a function pointer for a callback function which is invoked from 
 * within a decode function when a value of one of the OCTET STRING ASN.1 type
 * is parsed.
 *
 * @param numocts      Number of octets in the parsed value.
 * @param data         Pointer to byte array containing the octet string
 *                       data.
 * @return             - none
 */
typedef void (*OctStrValue) (ASN1UINT numocts, const ASN1OCTET* data) ;

/**
 * This is a function pointer for a callback function which is invoked from 
 * within a decode function when a value of one of the 8-bit ASN.1 character 
 * string types is parsed.
 *
 * @param value        Null terminated character string value.
 * @return             - none
 */
typedef void (*CharStrValue) (const char* value) ;

/**
 * This is a function pointer for a callback function which is invoked from 
 * within a decode function when a value of one of the 16-bit ASN.1 character 
 * string types is parsed.
 *
 * This is used for the ASN.1 BmpString type.
 *
 * @param nchars       Number of characters in the parsed value.
 * @param data         Pointer to an array containing 16-bit values.
 *                       These are represented using unsigned short integer
 *                       values.
 * @return             - none
 */
typedef void (*CharStrValue16Bit) (ASN1UINT nchars, ASN116BITCHAR* data) ;

/**
 * This is a function pointer for a callback function which is invoked from 
 * within a decode function when a value of the NULL ASN.1 type is parsed.
 *
 * @param             - none
 * @return             - none
 */
typedef void (*NullValue) () ;

/**
 * This is a function pointer for a callback function which is invoked from 
 * within a decode function whn a value the OBJECT IDENTIFIER ASN.1 type is 
 * parsed.
 *
 * @param numSubIds    Number of subidentifiers in the object identifier.
 * @param pSubIds      Pointer to array containing the subidentifier values.
 * @return             -none
 */
typedef void (*OidValue) (ASN1UINT numSubIds, ASN1UINT* pSubIds) ;

/**
 * This is a function pointer for a callback function which is invoked from 
 * within a decode function when a value of the ENUMERATED ASN.1 type is 
 * parsed.
 *
 * @param value        - Parsed enumerated value
 * @return             - none
 */
typedef void (*EnumValue) (ASN1UINT value) ;

/**
 * This is a function pointer for a callback function which is invoked from 
 * within a decode function when an ASN.1 open type is parsed.
 *
 * @param numocts      Number of octets in the parsed value.
 * @param data         Pointer to byet array contain in tencoded ASN.1
 *                       value.
 * @return             - none
 */
typedef void (*OpenTypeValue) (ASN1UINT numocts, const ASN1OCTET* data) ;


/**
 * This is a basic C based event handler structure, which can be used
 * to define user-defined event handlers.
 */
typedef struct EventHandler {
   StartElement      startElement;
   EndElement        endElement;
   BoolValue         boolValue;
   IntValue          intValue;
   UIntValue         uIntValue;
   BitStrValue       bitStrValue;
   OctStrValue       octStrValue;
   CharStrValue      charStrValue;
   CharStrValue16Bit charStr16BitValue;
   NullValue         nullValue;
   OidValue          oidValue;
   EnumValue         enumValue;
   OpenTypeValue     openTypeValue;
} EventHandler;


/**
 * This function sets the event handler object within the context.  It 
 * will overwrite the definition of any handler that was set previously.
 *
 * @param pctxt       Context to which event handler has to be added.
 * @param pHandler    Pointer to the event handler structure.
 * @return            none
 */
EXTERN void setEventHandler (OOCTXT* pctxt, EventHandler* pHandler);

/**
 * This function is called to remove the event handler current defined 
 * in the context.  This is done by setting the event handler object 
 * pointer to NULL.
 *
 * @param pctxt       Context from which event handler has to be removed.
 * @return            none
 */
EXTERN void removeEventHandler (OOCTXT* pctxt);

/**
 * The following functions are invoked from within the generated 
 * code to call the various user-defined event handler methods ..
 */
EXTERN void invokeStartElement (OOCTXT* pctxt, const char* name, int index);
EXTERN void invokeEndElement (OOCTXT* pctxt, const char* name, int index);
EXTERN void invokeBoolValue (OOCTXT* pctxt, ASN1BOOL value);
EXTERN void invokeIntValue (OOCTXT* pctxt, ASN1INT value);
EXTERN void invokeUIntValue (OOCTXT* pctxt, ASN1UINT value);

EXTERN void invokeBitStrValue 
(OOCTXT* pctxt, ASN1UINT numbits, const ASN1OCTET* data);

EXTERN void invokeOctStrValue 
(OOCTXT* pctxt, ASN1UINT numocts, const ASN1OCTET* data);

EXTERN void invokeCharStrValue (OOCTXT* pctxt, const char* value);

EXTERN void invokeCharStr16BitValue 
(OOCTXT* pctxt, ASN1UINT nchars, ASN116BITCHAR* data);

EXTERN void invokeNullValue (OOCTXT* pctxt);

EXTERN void invokeOidValue 
(OOCTXT* pctxt, ASN1UINT numSubIds, ASN1UINT* pSubIds);

EXTERN void invokeEnumValue (OOCTXT* pctxt, ASN1UINT value);

EXTERN void invokeOpenTypeValue 
(OOCTXT* pctxt, ASN1UINT numocts, const ASN1OCTET* data);

/** 
 * @} 
 */

#ifdef __cplusplus
}
#endif

#endif 

--- NEW FILE: memheap.c ---
/*
 * Copyright (C) 1997-2004 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 LICENSE.txt 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 <stdlib.h>
#include "memheap.h"

[...1292 lines suppressed...]
         pMemHeap->flags &= ((~(*(ASN1UINT*)pProp)) | RT_MH_INTERNALMASK);
         break;
   }
} 

int memHeapCreate (void** ppvMemHeap) 
{
   OSMemHeap* pMemHeap;
   if (ppvMemHeap == 0) return ASN_E_INVPARAM;

   pMemHeap = (OSMemHeap*) g_malloc_func (sizeof (OSMemHeap));
   if (pMemHeap == NULL) return ASN_E_NOMEM;
   memset (pMemHeap, 0, sizeof (OSMemHeap));
   pMemHeap->defBlkSize = g_defBlkSize;
   pMemHeap->refCnt = 1;
   pMemHeap->flags = RT_MH_FREEHEAPDESC;
   *ppvMemHeap = (void*)pMemHeap;
   return ASN_OK;
}


--- NEW FILE: memheap.h ---
/*
 * 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.
 *
 *****************************************************************************/

#ifndef __RTMEMHEAP_HH__
#define __RTMEMHEAP_HH__

#include "ooasn1.h"

/* internal heap flags */
#define RT_MH_INTERNALMASK 0xF0000000u
#define RT_MH_FREEHEAPDESC 0x10000000u

typedef struct OSMemLink {
   struct OSMemLink* pnext;
   struct OSMemLink* pprev;
   struct OSMemLink* pnextRaw;  /* next RAW block                           */
   void*           pMemBlk;
   ASN1OCTET       blockType;   /* 1 = standard, 2 = raw (see RTMEM* flags) */
} OSMemLink;

/* MemLink blockTypes */
#define RTMEMSTD        0x0001
#define RTMEMRAW        0x0002
#define RTMEMMALLOC     0x0004
#define RTMEMSAVED      0x0008
#define RTMEMLINK       0x0010  /* contains MemLink */

/* ASN.1 memory allocation structures */

typedef struct OSMemHeap {
   OSMemLink*      phead;
   ASN1UINT        usedUnits;
   ASN1UINT        usedBlocks;
   ASN1UINT        freeUnits;
   ASN1UINT        freeBlocks;
   ASN1UINT        keepFreeUnits;
   ASN1UINT        defBlkSize;
   ASN1UINT        refCnt;
   ASN1UINT        flags;
} OSMemHeap;

/* see rtMemDefs.c file */
extern ASN1UINT      g_defBlkSize;
extern OSMallocFunc  g_malloc_func;
extern OSReallocFunc g_realloc_func;
extern OSFreeFunc    g_free_func;

#endif /* __RTMEMHEAP_HH__ */

--- NEW FILE: ooCalls.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 "ootrace.h"
#include "ootypes.h"
#include "ooCalls.h"
[...971 lines suppressed...]
      return OO_FAILED;
   }
   memset(newMediaInfo, 0, sizeof(ooMediaInfo));
   strcpy(newMediaInfo->dir, mediaInfo.dir);
   newMediaInfo->lMediaCntrlPort = mediaInfo.lMediaCntrlPort;
   strcpy(newMediaInfo->lMediaIP,mediaInfo.lMediaIP);
   newMediaInfo->lMediaPort = mediaInfo.lMediaPort;
   newMediaInfo->cap = mediaInfo.cap;
   newMediaInfo->next = NULL;
   OOTRACEDBGC4("Configured mediainfo for cap %s (%s, %s)\n", 
                ooGetAudioCapTypeText(mediaInfo.cap),
                call->callType, call->callToken);
   if(!call->mediaInfo)
      call->mediaInfo = newMediaInfo;
   else{
      newMediaInfo->next = call->mediaInfo;
      call->mediaInfo = newMediaInfo;
   }
   return OO_OK;
}

--- NEW FILE: ooCalls.h ---
/*
 * 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.
 *
 *****************************************************************************/
/**
 * @file ooCalls.h 
 * This file contains call management functions. 
 */
#ifndef _OOCALLS_H_
#define _OOCALLS_H_

#include "ooCapability.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef EXTERN
#ifdef _WIN32
#define EXTERN __declspec(dllexport)
#else
#define EXTERN
#endif /* _WIN32 */
#endif /* EXTERN */

/** 
 * @defgroup callmgmt  Call Management
 * @{
 */
/* Flag mask values */
/* DISABLEGK is used to selectively disable gatekeeper use. For incoming calls
   DISABLEGK can be set in onReceivedSetup callback by application.
   Very useful in pbx applications where gk is used only when call is
   to or from outside pbx domian. For outgoing calls, ooMakeCallNoGk
   disables use of gk for specific call.
*/
#define OO_M_DATASESSION        0x00800000
#define OO_M_VIDEOSESSION       0x00400000
#define OO_M_AUDIOSESSION       0x00200000
#define OO_M_ENDPOINTCREATED    0x00100000
#define OO_M_ENDSESSION_BUILT   0x08000000
#define OO_M_RELEASE_BUILT      0x04000000
#define OO_M_GKROUTED           0x02000000
#define OO_M_AUTOANSWER         0x01000000
#define OO_M_TUNNELING	        0x80000000
#define OO_M_FASTSTART	        0x40000000
#define OO_M_DISABLEGK          0x20000000
#define OO_M_AUDIO              0x10000000

typedef struct OOH323CallData {
   OOCTXT               *pctxt;
   char                 callToken[20]; /* ex: ooh323c_call_1 */
   char                 callType[10]; /* incoming/outgoing */
   ASN1USINT            callReference;
   char                 ourCallerId[256];
   H225CallIdentifier   callIdentifier;/* The call identifier for the active 
                                          call. */
   char                 *callingPartyNumber;
   char                 *calledPartyNumber; 
   H225ConferenceIdentifier confIdentifier;
   ASN1UINT             flags;
   OOCallState          callState;
   OOCallClearReason    callEndReason;
   OOH245SessionState   h245SessionState;
   int                  dtmfmode;
   ooMediaInfo          *mediaInfo;
   OOCallFwdData        *pCallFwdData;
   char                 localIP[20];/* Local IP address */
   OOH323Channel*	pH225Channel;
   OOH323Channel*	pH245Channel;
   OOSOCKET             *h245listener;
   int                  *h245listenport;
   char                 remoteIP[20];/* Remote IP address */
   int                  remotePort;
   int                  remoteH245Port;
   char                 *remoteDisplayName;
   ooAliases            *remoteAliases;
   ooAliases            *ourAliases; /*aliases used in the call for us */
   OOMasterSlaveState   masterSlaveState;   /* Master-Slave state */ 
   ASN1UINT             statusDeterminationNumber;
   OOCapExchangeState   localTermCapState;
   OOCapExchangeState   remoteTermCapState;
   struct ooH323EpCapability* ourCaps;
   struct ooH323EpCapability* remoteCaps; /* TODO: once we start using jointCaps, get rid of remoteCaps*/
   struct ooH323EpCapability* jointCaps;
   DList                remoteFastStartOLCs;
   ASN1UINT8            remoteTermCapSeqNo;
   ASN1UINT8            localTermCapSeqNo;
   ooCapPrefs           capPrefs;   
   ooLogicalChannel*    logicalChans; 
   int                  noOfLogicalChannels;
   int                  logicalChanNoBase;
   int                  logicalChanNoMax;
   int                  logicalChanNoCur;
   unsigned             nextSessionID; /* Note by default 1 is audio session, 2 is video and 3 is data, from 3 onwards master decides*/
   DList		timerList;
   ASN1UINT             msdRetries;
   void                 *usrData; /* User can set this to user specific data */
   struct OOH323CallData* next;
   struct OOH323CallData* prev;
} OOH323CallData;

#define ooCallData OOH323CallData

/**
 * This function is used to create a new call entry.
 * @param type         Type of the call (incoming/outgoing)
 * @param callToken    Call Token, an uniques identifier for the call
 *
 * @return             Pointer to a newly created call
 */
EXTERN OOH323CallData* ooCreateCall(char *type, char *callToken);

/**
 * This function is used to add a call to the list of existing calls.
 * @param h323ep       Pointer to the H323 Endpoint structure.
 * @param call         Pointer to the call to be added.
 *
 * @return             OO_OK, on success. OO_FAILED, on failure
 */
EXTERN int ooAddCallToList (OOH323CallData *call);

/**
 * This function is used to set callerid for the call.
 * @param call          Handle to the call
 * @param callerid      caller id value
 *
 * @return              OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooCallSetCallerId
(OOH323CallData* call, const char* callerid);

/**
 * This function is used to set calling party number for a particular call.
 * @param call          Handle to the call.
 * @param number        Calling Party number value.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCallSetCallingPartyNumber
(OOH323CallData *call, const char *number);

/**
 * This function is used to retrieve calling party number of a particular call.
 * @param call          Handle to the call.
 * @param buffer        Handle to the buffer in which value will be returned.
 * @param len           Length of the supplied buffer.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCallGetCallingPartyNumber
(OOH323CallData *call, char *buffer, int len);

/**
 * This function is used to retrieve called party number of a particular call.
 * @param call          Handle to the call.
 * @param buffer        Handle to the buffer in which value will be returned.
 * @param len           Length of the supplied buffer.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCallGetCalledPartyNumber
(OOH323CallData *call, char *buffer, int len);

/**
 * This function is used to set called party number for a particular call.
 * @param call          Handle to the call.
 * @param number        Called Party number value.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCallSetCalledPartyNumber
(OOH323CallData *call, const char *number);

/**
 * This function is used to clear the local aliases used by this call.
 * @param call          Handle to the call.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCallClearAliases(OOH323CallData *call);

/**
 * This function is used to add an H323ID alias to be used by local endpoint 
 * for a particular call.
 * @param call          Handle to the call
 * @param h323id        H323ID to add for the local endpoint for the call.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCallAddAliasH323ID(OOH323CallData *call, const char* h323id);

/**
 * This function is used to add an dialedDigits alias to be used by local 
 * endpoint for a particular call.
 * @param call          Handle to the call
 * @param dialedDigits  DialedDigits to add for the local endpoint for call.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCallAddAliasDialedDigits
                             (OOH323CallData *call, const char* dialedDigits);

/**
 * This function is used to add an email-id alias to be used by local 
 * endpoint for a particular call.
 * @param call          Handle to the call
 * @param email         Email-id to add for the local endpoint for call.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCallAddAliasEmailID(OOH323CallData *call, const char* email);


/**
 * This function is used to add an email-id alias to be used by local 
 * endpoint for a particular call.
 * @param call          Handle to the call
 * @param url           URL-id to add for the local endpoint for call.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCallAddAliasURLID(OOH323CallData *call, const char* url);

/**
 * This function is used to add an H323ID alias for the remote endpoint 
 * involved in a particular call.
 * @param call          Handle to the call
 * @param h323id        H323ID to add for the remote endpoint.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCallAddRemoteAliasH323ID(OOH323CallData *call, const char* h323id);


/**
 * This function is used to add G7231 capability for the call. The 
 * "ooCallAdd...Capability" functions allow to override the global endpoint 
 * capabilities and use specific capabilities for specific calls.
 * @param call                 Call for which capability has to be added.
 * @param cap                  Capability to be added.
 * @param txframes             Number of frames per packet for transmission. 
 * @param rxframes             Number of frames per packet for reception.
 * @param silenceSuppression   Indicates support for silenceSuppression.
 * @param dir                  Direction of capability.OORX, OOTX, OORXANDTX
 * @param startReceiveChannel  Callback function to start receive channel.
 * @param startTransmitChannel Callback function to start transmit channel.
 * @param stopReceiveChannel   Callback function to stop receive channel.
 * @param stopTransmitChannel  Callback function to stop transmit channel.
 *
 * @return                     OO_OK, on success. OO_FAILED, on failure. 
 */
EXTERN int ooCallAddG7231Capability(OOH323CallData *call, int cap, int txframes, 
                            int rxframes, OOBOOL silenceSuppression, int dir,
                            cb_StartReceiveChannel startReceiveChannel,
                            cb_StartTransmitChannel startTransmitChannel,
                            cb_StopReceiveChannel stopReceiveChannel,
                            cb_StopTransmitChannel stopTransmitChannel);

/**
 * This function is used to add G729 capability for the call. The 
 * "ooCallAdd...Capability" functions allow to override the global endpoint 
 * capabilities and use specific capabilities for specific calls.
 * @param call                 Call for which capability has to be added.
 * @param cap                  Capability to be added.
 * @param txframes             Number of frames per packet for transmission. 
 * @param rxframes             Number of frames per packet for reception.
 * @param dir                  Direction of capability.OORX, OOTX, OORXANDTX
 * @param startReceiveChannel  Callback function to start receive channel.
 * @param startTransmitChannel Callback function to start transmit channel.
 * @param stopReceiveChannel   Callback function to stop receive channel.
 * @param stopTransmitChannel  Callback function to stop transmit channel.
 *
 * @return                     OO_OK, on success. OO_FAILED, on failure. 
 */
EXTERN int ooCallAddG729Capability(OOH323CallData *call, int cap, int txframes, 
                            int rxframes, int dir,
                            cb_StartReceiveChannel startReceiveChannel,
                            cb_StartTransmitChannel startTransmitChannel,
                            cb_StopReceiveChannel stopReceiveChannel,
                            cb_StopTransmitChannel stopTransmitChannel);

/**
 * This function is used to add G711 capability for the call. The 
 * "ooCallAdd...Capability" functions allow to override the global endpoint 
 * capabilities and use specific capabilities for specific calls.
 * @param call                 Call for which capability has to be added.
 * @param cap                  Capability to be added.
 * @param txframes             Number of frames per packet for transmission. 
 * @param rxframes             Number of frames per packet for reception.
 * @param dir                  Direction of capability.OORX, OOTX, OORXANDTX
 * @param startReceiveChannel  Callback function to start receive channel.
 * @param startTransmitChannel Callback function to start transmit channel.
 * @param stopReceiveChannel   Callback function to stop receive channel.
 * @param stopTransmitChannel  Callback function to stop transmit channel.
 *
 * @return                     OO_OK, on success. OO_FAILED, on failure. 
 */
EXTERN int ooCallAddG711Capability(OOH323CallData *call, int cap, int txframes, 
                            int rxframes, int dir,
                            cb_StartReceiveChannel startReceiveChannel,
                            cb_StartTransmitChannel startTransmitChannel,
                            cb_StopReceiveChannel stopReceiveChannel,
                            cb_StopTransmitChannel stopTransmitChannel);


/**
 * This function is used to add GSM capability for the call. The 
 * "ooCallAdd...Capability" functions allow to override the global endpoint 
 * capabilities and use specific capabilities for specific calls.
 * @param call                 Call for which capability has to be added.
 * @param cap                  Type of GSM capability to be added.
 * @param framesPerPkt         Number of GSM frames pre packet. 
 * @param comfortNoise         Comfort noise spec for the capability. 
 * @param scrambled            Scrambled enabled/disabled for the capability.
 * @param dir                  Direction of capability.OORX, OOTX, OORXANDTX
 * @param startReceiveChannel  Callback function to start receive channel.
 * @param startTransmitChannel Callback function to start transmit channel.
 * @param stopReceiveChannel   Callback function to stop receive channel.
 * @param stopTransmitChannel  Callback function to stop transmit channel.
 *
 * @return                     OO_OK, on success. OO_FAILED, on failure. 
 */
EXTERN int ooCallAddGSMCapability(OOH323CallData* call, int cap, 
                                  ASN1USINT framesPerPkt, OOBOOL comfortNoise, 
                                  OOBOOL scrambled, int dir,
                                  cb_StartReceiveChannel startReceiveChannel,
                                  cb_StartTransmitChannel startTransmitChannel,
                                  cb_StopReceiveChannel stopReceiveChannel,
				  cb_StopTransmitChannel stopTransmitChannel);

/**
 * This function is used to enable rfc 2833 capability for the call. By default
 * the stack uses the dtmf settings for the endpoint. But if you want to
 * enable/disable dtmf for a specific call, then you can override end-point
 * settings using this function
 * @param call                  Call for which rfc2833 has to be enabled.
 * @param dynamicRTPPayloadType dynamicRTPPayloadType to be used.
 *
 * @return                      OO_OK, on success. OO_FAILED, on failure
 */
EXTERN int ooCallEnableDTMFRFC2833(OOH323CallData *call, int dynamicRTPPayloadType);


/**
 * This function is used to disable rfc 2833 capability for the call. 
 * By default the stack uses the dtmf settings for the endpoint. But if you 
 * want to enable/disable dtmf for a specific call, then you can override 
 * end-point settings using this function
 * @param call                  Call for which rfc2833 has to be disabled.
 *
 * @return                      OO_OK, on success. OO_FAILED, on failure
 */
EXTERN int ooCallDisableDTMFRFC2833(OOH323CallData *call);

/**
 * This function is used to find a call by using the unique token for the call.
 * @param callToken      The unique token for the call.
 *
 * @return               Pointer to the call if found, NULL otherwise.
 */
EXTERN OOH323CallData* ooFindCallByToken(char *callToken);

/**
 * This function is used to clear a call. Based on what stage of clearance the
 * call is it takes appropriate action.
 * @param call   Handle to the call which has to be cleared.
 *
 * @return       OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooEndCall(OOH323CallData *call);

/**
 * This function is used to remove a call from the list of existing calls.
 * @param h323ep        Pointer to the H323 Endpoint.
 * @param call          Pointer to the call to be removed.
 * 
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooRemoveCallFromList (OOH323CallData *call);

/**
 * This function is used to clean a call. It closes all associated sockets, 
 * removes call from list and frees up associated memory.
 * @param call          Pointer to the call to be cleared.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCleanCall(OOH323CallData *call);

/**
 * This function is used to add a new logical channel entry into the list
 * of currently active logical channels.
 * @param call      Pointer to the call for which new logical channel 
 *                  entry has to be created.
 * @param channelNo Channel number for the new channel entry.
 * @param sessionID Session identifier for the new channel.
 * @param type      Type of the channel(audio/video/data)
 * @param dir       Direction of the channel(transmit/receive)
 * @param epCap     Capability to be used for the new channel.
 *
 * @return          Pointer to logical channel, on success. NULL, on failure
 */
EXTERN ooLogicalChannel* ooAddNewLogicalChannel
         (OOH323CallData *call, int channelNo, int sessionID, char *type, 
          char * dir, ooH323EpCapability *epCap);

/**
 * This function is used to find a logical channel by logical channel number.
 * @param call          Pointer to the call for which logical channel is 
 *                      required.
 * @param channelNo     Forward Logical Channel number for the logical channel
 *
 * @return              Pointer to the logical channel if found, NULL 
 *                      otherwise.   
 */
EXTERN ooLogicalChannel* ooFindLogicalChannelByLogicalChannelNo
                                  (OOH323CallData *call,int channelNo);

/**
 * This function is called when a new logical channel is established. It is 
 * particularly useful in case of faststart. When the remote endpoint selects 
 * one of the proposed alternatives, other channels for the same session type 
 * need to be closed. This function is used for that.
 * @param call      Handle to the call which owns the logical channel.
 * @param pChannel  Handle to the newly established logical channel.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooOnLogicalChannelEstablished
(OOH323CallData *call, ooLogicalChannel * pChannel);

/**
 * This fuction is used to check whether a specified session in specified 
 * direction is active for the call.
 * @param call       Handle to call for which session has to be queried.
 * @param sessionID  Session id to identify the type of session(1 for audio, 
 *                   2 for voice and 3 for data)
 * @param dir        Direction of the session(transmit/receive)
 *
 * @return           1, if session active. 0, otherwise. 
 */
EXTERN ASN1BOOL ooIsSessionEstablished
(OOH323CallData *call, int sessionID, char* dir);

/**
 * This function is used to retrieve a logical channel with particular 
 * sessionID. Note that there can be two entries of logical channel, one in 
 * each direction. This function will return the first channel which has the 
 * same session ID.
 * @param call      Handle to the call which owns the channels to be searched.
 * @param sessionID Session id of the session which is to be searched for.
 *
 * @return          Returns a pointer to the logical channel if found, NULL 
 *                  otherwise.
 */
EXTERN ooLogicalChannel* ooGetLogicalChannel
(OOH323CallData *call, int sessionID);

/**
 * This function is used to remove a logical channel from the list of logical 
 * channels.
 * @param call              Pointer to the call from which logical channel has 
 *                          to be removed.
 * @param ChannelNo         Forward logical channel number of the channel to be
 *                          removed.
 */
EXTERN int ooRemoveLogicalChannel(OOH323CallData *call, int ChannelNo);

/**
 * This function is used to cleanup a logical channel. It first stops media, if
 * it is still active and then removes the channel from the list, freeing up 
 * all the associated memory.
 * @param call       Handle to the call which owns the logical channel.
 * @param channelNo  Channel number identifying the channel.
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooClearLogicalChannel(OOH323CallData *call, int channelNo);

/**
 * This function is used to cleanup all the logical channels associated with 
 * the call.
 * @param call      Handle to the call which owns the channels.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooClearAllLogicalChannels(OOH323CallData *call);

/**
 * This function can be used by an application to specify media endpoint 
 * information for different types of media. The stack by default uses local IP
 * and port for media. An application can provide mediainfo if it wants to 
 * override default.
 * @param call      Handle to the call
 * @param mediaInfo mediainfo structure which defines the media endpoint to be 
 *                  used.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooAddMediaInfo(OOH323CallData *call, ooMediaInfo mediaInfo);

/**
 * This function is used to find a logical channel from a received
 * olc.
 * @param call     Handle to the related call.
 * @param olc      Handle to the received OLC.
 *
 * @return         Returns the corresponding logical channel if found,
 *                 else returns NULL.
 */
EXTERN ooLogicalChannel * ooFindLogicalChannelByOLC
(OOH323CallData *call, H245OpenLogicalChannel *olc);

/**
 * This function is used to find a logical channel based on session Id,
 * direction of channel and datatype.
 * @param call       Handle to the call
 * @param sessionID  Session ID for the channel to be searched.
 * @param dir        Direction of the channel wrt local endpoint.
 *                   (transmit/receive)
 * @param dataType   Handle to the data type for the channel.
 *
 * @return           Logical channel, if found, NULL otherwise.
 */
EXTERN ooLogicalChannel * ooFindLogicalChannel
(OOH323CallData *call, int sessionID, char *dir, H245DataType * dataType);

/** 
 * @} 
 */

#ifdef __cplusplus
}
#endif



#endif

--- NEW FILE: ooCapability.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 "ooCapability.h"
#include "ootrace.h"
#include "ooCalls.h"
#include "ooh323ep.h"
[...1227 lines suppressed...]
      OOTRACEDBGC3("Adding cap to joint capabilities(%s, %s)\n",call->callType,
                   call->callToken);
      /* Note:we add jointCaps in remote endpoints preference order.*/
      if(call->jointCaps)
      {
         cur = call->jointCaps;
         while(cur->next) cur = cur->next;
         cur->next = epCap;
      }
      call->jointCaps = epCap;
      return OO_OK;
   }

   OOTRACEDBGC3("Not adding to joint capabilities. (%s, %s)\n", call->callType,
		call->callToken);
   return OO_FAILED;
}




--- NEW FILE: ooCapability.h ---
/*
 * 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.
 *
 *****************************************************************************/
/**
 * @file ooCapability.h 
 * This file contains Capability management functions. 
 */
#ifndef OO_CAPABILITY_H_
#define OO_CAPABILITY_H_
#include "ootypes.h"
#include "ooasn1.h"

#define OO_GSMFRAMESIZE 33 /* standard frame size for gsm is 33 bytes */

#define OORX      (1<<0)
#define OOTX      (1<<1)
#define OORXANDTX (1<<2)
#define OORXTX    (1<<3) /* For symmetric capabilities */
/* Various types of caps. Note that not all 
   supported */

#define OO_CAP_AUDIO_BASE      0
#define OO_G711ALAW64K         2
#define OO_G711ALAW56K         3
#define OO_G711ULAW64K         4
#define OO_G711ULAW56K         5
#define OO_G7231               9
#define OO_G729                11
#define OO_G729A               12
#define OO_GSMFULLRATE         18
#define OO_GSMHALFRATE         19
#define OO_GSMENHANCEDFULLRATE 20

#define OO_CAP_VIDEO_BASE 26
#define OO_CAP_DATA_BASE -1 /* place holder */

#define OOABSAUDIOCAP(cap) cap-OO_CAP_AUDIO_BASE
#define OOABSVIDEOCAP(cap) cap-OO_CAP_VIDEO_BASE
#define OOABSDATACAP(cap)  cap-OO_CAP_DATA_BASE

/*DTMF capabilities*/
#define OO_CAP_DTMF_RFC2833 (1<<0)
#define OO_CAP_DTMF_Q931    (1<<1)
#define OO_CAP_DTMF_H245    (1<<2)


typedef struct ooCapParams {
   int txframes;
   int rxframes;
   OOBOOL silenceSuppression;
} ooCapParams;

typedef struct ooGSMCapParams {
   unsigned txframes; 
   unsigned rxframes;
   OOBOOL scrambled;
   OOBOOL comfortNoise;
} ooGSMCapParams;

struct OOH323CallData;

#ifdef __cplusplus
extern "C" {
#endif

/** Call back for starting media receive channel */
typedef int (*cb_StartReceiveChannel)
     (struct OOH323CallData *call, ooLogicalChannel *pChannel);

/** callback for starting media transmit channel */
typedef int (*cb_StartTransmitChannel)
     (struct OOH323CallData *call, ooLogicalChannel *pChannel);

/** callback to stop media receive channel */
typedef int (*cb_StopReceiveChannel)
     (struct OOH323CallData *call, ooLogicalChannel *pChannel);

/** callback to stop media transmit channel */
typedef int (*cb_StopTransmitChannel)
     (struct OOH323CallData *call, ooLogicalChannel *pChannel);

typedef enum OOCapType {
   OO_CAP_TYPE_AUDIO,
   OO_CAP_TYPE_VIDEO,
   OO_CAP_TYPE_DATA
} OOCapType;

/**
 * Structure to store information related to end point
 * capability
 */
typedef struct ooH323EpCapability {
   int dir; 
   int cap;
   OOCapType capType;
   void *params;
   cb_StartReceiveChannel startReceiveChannel;
   cb_StartTransmitChannel startTransmitChannel;
   cb_StopReceiveChannel stopReceiveChannel;
   cb_StopTransmitChannel stopTransmitChannel;
   struct ooH323EpCapability *next;
} ooH323EpCapability;


#ifndef EXTERN
#ifdef _WIN32
#define EXTERN __declspec(dllexport)
#else
#define EXTERN
#endif /* _WIN32 */
#endif /* EXTERN */

/** 
 * @defgroup capmgmt  Capability Management
 * @{
 */

/**
 * This function is used to add rfc2833 based dtmf detection capability
 * @param call                   Call if enabling for call, else null for 
 *                               endpoint.
 * @param dynamicRTPPayloadType  dynamicRTPPayloadType to be used.
 * @return                       OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCapabilityEnableDTMFRFC2833
   (struct OOH323CallData *call, int dynamicRTPPayloadType);

/**
 * This function is used to remove rfc2833 dtmf detection capability.
 * @param call             Handle to call, if disabling for the call, else NULL
 *                         for end-point.
 * @return                 OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCapabilityDisableDTMFRFC2833(struct OOH323CallData *call);



/**
 * This function is used to add simple capabilities which have only rxframes
 * and txframes parameters to the endpoint or call.(ex. G711, G729)
 * @param call                 Handle to a call. If this is not Null, then 
 *                             capability is added to call's remote enpoint 
 *                             capability list, else it is added to local H323 
 *                             endpoint list.
 * @param cap                  Type of G711 capability to be added.
 * @param txframes             Number of frames per packet for transmission. 
 * @param rxframes             Number of frames per packet for reception.
 * @param silenceSuppression   Indicates support for silence suppression.
 *                             Used only in case of g7231, otherwise ignored.
 * @param dir                  Direction of capability.OORX, OOTX, OORXANDTX
 * @param startReceiveChannel  Callback function to start receive channel.
 * @param startTransmitChannel Callback function to start transmit channel.
 * @param stopReceiveChannel   Callback function to stop receive channel.
 * @param stopTransmitChannel  Callback function to stop transmit channel.
 * @param remote               TRUE, if adding call's remote capability.
 *
 * @return                     OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCapabilityAddSimpleCapability
   (struct OOH323CallData *call, int cap, int txframes, int rxframes, 
    OOBOOL silenceSuppression, int dir, 
    cb_StartReceiveChannel startReceiveChannel,
    cb_StartTransmitChannel startTransmitChannel,
    cb_StopReceiveChannel stopReceiveChannel,
    cb_StopTransmitChannel stopTransmitChannel,
    OOBOOL remote);

#if 0
/**
 * This is an internal helper function which is used to add a G729 capability
 * to local endpoints capability list or to remote endpoints capability list or
 * to a calls capability list.
 * @param call                 Handle to a call. If this is not Null, then 
 *                             capability is added to call's remote enpoint 
 *                             capability list, else it is added to local H323 
 *                             endpoint list.
 * @param cap                  Type of G729 capability to be added.
 * @param txframes             Number of frames per packet for transmission. 
 * @param rxframes             Number of frames per packet for reception.
 * @param dir                  Direction of capability.OORX, OOTX, OORXANDTX
 * @param startReceiveChannel  Callback function to start receive channel.
 * @param startTransmitChannel Callback function to start transmit channel.
 * @param stopReceiveChannel   Callback function to stop receive channel.
 * @param stopTransmitChannel  Callback function to stop transmit channel.
 * @param remote               TRUE, if adding call's remote capability.
 *
 * @return                     OO_OK, on success. OO_FAILED, on failure.
 * 
 */
EXTERN int ooCapabilityAddG729Capability(struct OOH323CallData *call, int cap, 
                                         int txframes, int rxframes, int dir, 
                                 cb_StartReceiveChannel startReceiveChannel,
                                 cb_StartTransmitChannel startTransmitChannel,
                                 cb_StopReceiveChannel stopReceiveChannel,
                                 cb_StopTransmitChannel stopTransmitChannel,
				  OOBOOL remote);

/**
 * This is an internal helper function which is used to add a G711 capability
 * to local endpoints capability list or to remote endpoints capability list or
 * to a call's capability list.
 * @param call                 Handle to a call. If this is not Null, then 
 *                             capability is added to call's remote enpoint 
 *                             capability list, else it is added to local H323 
 *                             endpoint list.
 * @param cap                  Type of G711 capability to be added.
 * @param txframes             Number of frames per packet for transmission. 
 * @param rxframes             Number of frames per packet for reception.
 * @param dir                  Direction of capability.OORX, OOTX, OORXANDTX
 * @param startReceiveChannel  Callback function to start receive channel.
 * @param startTransmitChannel Callback function to start transmit channel.
 * @param stopReceiveChannel   Callback function to stop receive channel.
 * @param stopTransmitChannel  Callback function to stop transmit channel.
 * @param remote               TRUE, if adding call's remote capability.
 *
 * @return                     OO_OK, on success. OO_FAILED, on failure.
 * 
 */
int ooCapabilityAddG711Capability(struct OOH323CallData *call, 
				  int cap, int txframes, 
                                 int rxframes, int dir, 
                                 cb_StartReceiveChannel startReceiveChannel,
                                 cb_StartTransmitChannel startTransmitChannel,
                                 cb_StopReceiveChannel stopReceiveChannel,
                                 cb_StopTransmitChannel stopTransmitChannel,
                                 OOBOOL remote);


#endif

/**
 * This is an internal helper function which is used to add a GSM capability
 * to local endpoints capability list or to remote endpoints capability list.
 * @param call                 Handle to a call. If this is not Null, then 
 *                             capability is added to call's remote enpoint 
 *                             capability list, else it is added to local H323 
 *                             endpoint list.
 * @param cap                  Type of GSM capability to be added.
 * @param framesPerPkt         Number of GSM frames per packet. 
 * @param comfortNoise         Comfort noise spec for the capability. 
 * @param scrambled            Scrambled enabled/disabled for the capability.
 * @param dir                  Direction of capability.OORX, OOTX, OORXANDTX
 * @param startReceiveChannel  Callback function to start receive channel.
 * @param startTransmitChannel Callback function to start transmit channel.
 * @param stopReceiveChannel   Callback function to stop receive channel.
 * @param stopTransmitChannel  Callback function to stop transmit channel.
 * @param remote               TRUE, if adding call's remote capabilities.
 *
 * @return                     OO_OK, on success. OO_FAILED, on failure. 
 */
int ooCapabilityAddGSMCapability(struct OOH323CallData *call, int cap, 
                                unsigned framesPerPkt, OOBOOL comfortNoise,
                                OOBOOL scrambled, int dir, 
                                cb_StartReceiveChannel startReceiveChannel,
                                cb_StartTransmitChannel startTransmitChannel,
                                cb_StopReceiveChannel stopReceiveChannel,
                                cb_StopTransmitChannel stopTransmitChannel, 
                                OOBOOL remote);


/**
 * This function is used to add a audio capability to calls remote  
 * capability list.
 * @param call                Handle to the call.
 * @param audioCap            Handle to the remote endpoint's audio capability.
 * @param dir                 Direction in which capability is supported by 
 *                            remote endpoint.
 *
 * @return                    OO_OK, on success. OO_FAILED, otherwise.
 */
int ooAddRemoteAudioCapability(struct OOH323CallData *call, 
			       H245AudioCapability *audioCap,
                               int dir);


/**
 * This function is used to add a capability to call's remote  capability list.
 * The capabilities to be added are extracted from received TCS message.
 * @param call           Handle to the call.
 * @param cap            Handle to the remote endpoint's H245 capability.
 *
 * @return               OO_OK, on success. OO_FAILED, otherwise.
 */
int ooAddRemoteCapability(struct OOH323CallData *call, H245Capability *cap);

/**
 * This function is used to update joint capabilities for call. It checks
 * whether remote capability can be supported by local capabilities for the
 * call and if supported makes entry into the joint capability list for the 
 * call.
 * @param call           Handle to the call
 * @param cap            Remote cap which will be tested for compatibility.
 *
 * @return               returns OO_OK, if updated else OO_FAILED;  
 */
EXTERN int ooCapabilityUpdateJointCapabilities
(struct OOH323CallData* call, H245Capability *cap);

/**
 * This function is used to test the compatibility of the two capabilities.
 * It checks whether tx capability can be received by rx capability.
 * @param call                Handle to the call.
 * @param txCap               Transmit capability to be tested for 
 *                            compatibility.
 * @param rxCap               Receive capability to be tested for compatibility
 *
 * @return                    TRUE, if compatible, FALSE otherwise.
 */
ASN1BOOL ooCheckCompatibility
(struct OOH323CallData *call, ooH323EpCapability *txCap, 
 ooH323EpCapability *rxCap);

/**
 * This function is used to test whether the endpoint capability in the 
 * specified direction can be supported by the audio capability.
 * @param call               Handle to the call.
 * @param epCap              Endpoint capability.
 * @param audioCap           Audio capability with which compatibility has to 
 *                           be tested.
 * @param dir                Direction indicating whether endpoint capability
 *                           will be used for transmission or reception.
 *
 * @return                   TRUE, if compatible. FALSE, otherwise. 
 */

ASN1BOOL ooCheckCompatibility_1(struct OOH323CallData *call, 
				ooH323EpCapability *epCap, 
				H245AudioCapability * audioCap, int dir);


/**
 * This function is used to create a audio capability structure using the
 * capability type.
 * @param epCap       Capability.
 * @param pctxt       Handle to OOCTXT which will be used to allocate memory 
 *                    for new audio capability.
 * @param dir         Direction in which the newly created capability will be 
 *                    used.
 *
 * @return            Newly created audio capability on success, NULL on 
 *                    failure.
 */
struct H245AudioCapability* ooCreateAudioCapability 
(ooH323EpCapability* epCap, OOCTXT *pctxt, int dir);

/**
 * This function is used to create a dtmf capability which can be added to
 * a TCS message.
 * @param cap         Type of dtmf capability to be created.
 * @param pctxt       Pointer to OOCTXT structure to be used for memory 
 *                    allocation.
 *
 * @return            Pointer to the created DTMF capability, NULL in case of
 *                    failure.
 */
void * ooCreateDTMFCapability(int cap, OOCTXT *pctxt);


/**
 * This function is used to create a GSM Full Rate capability structure.
 * @param epCap       Handle to the endpoint capability.
 * @param pctxt       Handle to OOCTXT which will be used to allocate memory
 *                    for new audio capability.
 * @param dir         Direction for the newly created capability.
 *
 * @return            Newly created audio capability on success, NULL on 
 *                    failure.
 */
struct H245AudioCapability* ooCreateGSMFullRateCapability
   (ooH323EpCapability *epCap, OOCTXT* pctxt, int dir);

/**
 * This function is used to create a simple(g711, g729) audio capability 
 * structure.
 * @param epCap       Handle to the endpoint capability
 * @param pctxt       Handle to OOCTXT which will be used to allocate memory 
 *                    for new audio capability.
 * @param dir         Direction in which the newly created capability will be 
 *                    used.
 *
 * @return            Newly created audio capability on success, NULL on 
 *                    failure.
 */
struct H245AudioCapability* ooCreateSimpleCapability
   (ooH323EpCapability *epCap, OOCTXT* pctxt, int dir);


/**
 * This function is used to determine whether a particular capability
 * can be supported by the endpoint.
 * @param call       Handle to the call.
 * @param audioCap   Handle to the audio capability.
 * @param dir        Direction in which support is desired. 
 *
 * @return          Handle to the copyof capability which supports audioCap, 
 *                  Null if none found
 */
ooH323EpCapability* ooIsAudioDataTypeSupported
(struct OOH323CallData *call, H245AudioCapability* audioCap, int dir);

/**
 * This function is used to determine whether a particular capability type
 * can be supported by the endpoint.
 * @param call       Handle to the call.
 * @param data       Handle to the capability type.
 * @param dir        Direction in which support is desired. 
 *
 * @return          Handle to the copy of capability which supports specified 
 *                  capability type, Null if none found
 */
ooH323EpCapability* ooIsDataTypeSupported
(struct OOH323CallData *call, H245DataType *data, int dir);

/**
 * This function is used to clear the capability preference order.
 * @param call      Handle to call, if capability preference order for call
 *                  has to be cleared, NULL for endpoint.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure
 */
EXTERN  int ooResetCapPrefs(struct OOH323CallData *call);

/**
 * This function is used to remove a particular capability from preference
 * list.
 * @param call     Handle to call, if call's preference list has to be modified
 *                 else NULL, to modify endpoint's preference list.
 * @param cap      Capability to be removed
 *
 * @return         OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN  int ooRemoveCapFromCapPrefs(struct OOH323CallData *call, int cap);

/**
 * This function is used to append a particular capability to preference
 * list.
 * @param call     Handle to call, if call's preference list has to be modified
 *                 else NULL, to modify endpoint's preference list.
 * @param cap      Capability to be appended.
 *
 * @return         OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooAppendCapToCapPrefs(struct OOH323CallData *call, int cap);

/**
 * This function is used to change preference order of a particular capability 
 * in the preference list.
 * @param call     Handle to call, if call's preference list has to be modified
 *                 else NULL, to modify endpoint's preference list.
 * @param cap      Capability concerned
 * @param pos      New position in the preference order
 *
 * @return         OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooChangeCapPrefOrder(struct OOH323CallData *call, int cap, int pos);

/**
 * This function is used to preppend a particular capability to preference
 * list.
 * @param call     Handle to call, if call's preference list has to be modified
 *                 else NULL, to modify endpoint's preference list.
 * @param cap      Capability to be preppended.
 *
 * @return         OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooPreppendCapToCapPrefs(struct OOH323CallData *call, int cap);


/** 
 * @} 
 */
#ifdef __cplusplus
}
#endif

#endif



--- NEW FILE: ooCommon.h ---
/*
 * 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 LICENSE.txt 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.
 *
 *****************************************************************************/
/** 
 * @file ooCommon.h 
 * Common runtime constant and type definitions.
 */
#ifndef _OOCOMMON_H_
#define _OOCOMMON_H_

#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#ifdef _WIN32_WCE
#include <winsock.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <sys/types.h>
#define INCL_WINSOCK_API_TYPEDEFS   1
#define INCL_WINSOCK_API_PROTOTYPES 0
#include <winsock2.h>
#else
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#endif

/** 
 * @ingroup cruntime C Runtime Common Constant and Type Definitions.
 * @{
 */

/* Basic type definitions */

typedef char            OOCHAR;
typedef unsigned char   OOUCHAR;
typedef signed char     OOINT8;
typedef unsigned char   OOUINT8;
typedef short           OOINT16;
typedef unsigned short  OOUINT16;
typedef int             OOINT32;
typedef unsigned int    OOUINT32;
typedef OOUINT8         OOBOOL;

#define OOUINT32_MAX    4294967295U
#define OOINT32_MAX     ((OOINT32)2147483647L)
#define OOINT32_MIN     ((OOINT32)(-OOINT32_MAX-1))

#ifndef FALSE
#define FALSE           0
#define TRUE            1
#endif

/* Common error codes */

#define OOERRINVPARAM   (-50)   /* Invalid parameter    */
#define OOERRBUFOVFLW   (-51)   /* Buffer overflow      */
#define OOERRNOMEM      (-52)   /* No dynamic memory available */

/* Message buffer: this is used for asynchronous transfers */

typedef struct _OOMsgBuf {
   OOUINT8* pdata;      /* Pointer to binary or text data               */
   OOUINT32 bufsiz;     /* Size of the buffer in bytes                  */
   OOUINT32 length;     /* # bytes to send (write) or # received (read) */
   OOUINT32 offset;     /* Offset into buffer of first byte to send     */
   OOBOOL   dynamic;    /* pdata is dynamic (allocated with OOMEMALLOC) */
} OOMsgBuf;

/* Memory allocation and free function definitions.  These definitions  */
/* can be changed if a non-standard allocation/free function is to be   */
/* used..                                                               */

#define OOMEMALLOC  malloc
#define OOMEMFREE   free

/* Min/max macros */

#ifndef OOMAX
#define OOMAX(a,b)  (((a)>(b))?(a):(b))
#endif

#ifndef OOMIN
#define OOMIN(a,b)  (((a)<(b))?(a):(b))
#endif

/* This is used for creating a Windows DLL.  Specify -DMAKE_DLL to      */
/* compile code for inclusion in a DLL.                                 */

#ifndef EXTERN
#if defined (MAKE_DLL)
#define EXTERN __declspec(dllexport)
#elif defined (USE_DLL)
#define EXTERN __declspec(dllimport)
#else
#define EXTERN
#endif /* _DLL */
#endif /* EXTERN */

/** 
 * @} 
 */
#endif /* _OOCOMMON_H_ */

--- NEW FILE: ooDateTime.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 LICENSE.txt 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 "ooCommon.h"

#if defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)
#include <SYS\TIMEB.H>
int gettimeofday (struct timeval *tv, struct timezone *tz)
{
   struct _timeb currSysTime;
   _ftime(&currSysTime);
	
   tv->tv_sec = currSysTime.time;
   tv->tv_usec = currSysTime.millitm * 1000;

   return 0;
}
#endif

int ooGetTimeOfDay (struct timeval *tv, struct timezone *tz)
{
   return gettimeofday (tv, tz);
}


long ooGetTimeDiff(struct timeval *tv1, struct timeval *tv2)
{
   return ( ((tv2->tv_sec-tv1->tv_sec)*1000) + 
            ((tv2->tv_usec-tv1->tv_usec)/1000) );
}


--- NEW FILE: ooDateTime.h ---
/*
 * 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 LICENSE.txt 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.
 *
 *****************************************************************************/
/** 
 * @file ooDateTime.h 
 * Time functions that reconcile differences between Windows and UNIX.
 */
#ifndef _OOTIME_H_
#define _OOTIME_H_

#include "ooCommon.h"
#include <time.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * This function provides an abstraction for the UNIX 'gettimeofday' 
 * function which is not available on Windows.
 *
 * @param tv           Pointer to time value structure to receive 
 *                     current time value.
 * @param tz           Point to time zone information.
 * @return             Completion status of operation: 0 = success,
 *                     negative return value is error.
 */
EXTERN int ooGetTimeOfDay (struct timeval *tv, struct timezone *tz);

/**
 * This function subtracts first timeval parameter from second and provides
 * the difference in milliseconds.
 * @param tv1          Pointer to timeval value.
 * @param tv2          Pointer to timeval value.
 *
 * @return             Difference between two timevals in milliseconds.
 */
EXTERN long ooGetTimeDiff(struct timeval *tv1, struct timeval *tv2);
#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE: ooGkClient.c ---
/*
 * Copyright (C) 2005 by Page Iberica, S.A.
 * Copyright (C) 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.
 *
 *****************************************************************************/

/**
 * @file ooGkClient.c 
[...2216 lines suppressed...]
         OOTRACEERR1("Error:Unhandled alias type found in registered "
                     "aliases\n");
      }
      if(bAdd)
      {
         pAlias = ooH323AddAliasToList(&gH323ep.aliases, 
                                           &gH323ep.ctxt, pAliasAddress);
         if(pAlias){
            pAlias->registered = registered?TRUE:FALSE;
         }
         else{
            OOTRACEERR2("Warning:Could not add registered alias of "
                        "type %d to list.\n", pAliasAddress->t);
         }
         bAdd = FALSE;
      }
      pAlias = NULL;
   }
   return OO_OK;
}

--- NEW FILE: ooGkClient.h ---
/*
 * Copyright (C) 2005 by Page Iberica, S.A.
 * Copyright (C) 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.
 *
 *****************************************************************************/

/**
 * @file ooGkClient.h 
 * This file contains functions to support RAS protocol. 
 *
 *
 */
#ifndef _OOGKCLIENT_H_
#define _OOGKCLIENT_H_

#include "ooasn1.h"
#include "ootypes.h"
#include "H323-MESSAGES.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef EXTERN
#ifdef _WIN32
#define EXTERN __declspec(dllexport)
#else
#define EXTERN
#endif /* _WIN32 */
#endif /* EXTERN */


/*-------------------------------------------------------------------*/
/*  Public definitions                                               */
/*-------------------------------------------------------------------*/



#define MAX_IP_LEN 15
#define DEFAULT_GKPORT 1719
#define MULTICAST_GKADDRESS "224.0.1.41"
#define MULTICAST_GKPORT 1718
#define DEFAULT_BW_REQUEST  100000

/* Various timeouts in seconds */
#define DEFAULT_REG_TTL 300
#define DEFAULT_TTL_OFFSET 20
#define DEFAULT_ARQ_TIMEOUT 5
#define DEFAULT_DRQ_TIMEOUT 5
#define DEFAULT_GRQ_TIMEOUT 15
#define DEFAULT_RRQ_TIMEOUT 10

/* Number of retries before giving up */
#define OO_MAX_GRQ_RETRIES 3
#define OO_MAX_RRQ_RETRIES 3
#define OO_MAX_ARQ_RETRIES 3

/* Gk Client timers */
#define OO_GRQ_TIMER (1<<0)
#define OO_RRQ_TIMER (1<<1)
#define OO_REG_TIMER (1<<2)
#define OO_ARQ_TIMER (1<<3)
#define OO_DRQ_TIMER (1<<4)

/** 
 * @defgroup gkclient Gatekeeper client
 * @{
 */

struct OOH323CallData;
struct ooGkClient;
struct RasCallAdmissionInfo;

typedef struct ooGkClientTimerCb{
   int timerType;
   struct ooGkClient *pGkClient;
   struct RasCallAdmissionInfo *pAdmInfo;
}ooGkClientTimerCb;

enum RasGatekeeperMode {
   RasNoGatekeeper = 0,
   RasDiscoverGatekeeper = 1,
   RasUseSpecificGatekeeper = 2,
};

enum RasCallType{
   RasPointToPoint =0,
   RasOneToN,
   RasnToOne,
   RasnToN,
};


enum OOGkClientState {
   GkClientIdle = 0,
   GkClientDiscovered, /* Gk Discovery is complete */
   GkClientRegistered, /* registered with gk */
   GkClientUnregistered,
   GkClientGkErr,/*Gk is not responding, in discover mode can look for new GK*/
   GkClientFailed
};
   

typedef struct RasGatekeeperInfo
{
   ASN1BOOL willRespondToIRR;
   H225UUIEsRequested uuiesRequested;
   H225BandWidth bw;
   H225RegistrationConfirm_preGrantedARQ preGrantedARQ;
}RasGatekeeperInfo;

/**
 *  Call Admission Information
 */
typedef struct RasCallAdmissionInfo
{
   struct OOH323CallData *call;
   unsigned int retries;
   unsigned short requestSeqNum;
   ASN1USINT irrFrequency;
} RasCallAdmissionInfo;

/** GkClient callbacks:
 *  The first parameter is the message received. The second parameter provides
 *  updated list of aliases after the message was processed by the stack.
 */
typedef int (*cb_OnReceivedRegistrationConfirm)
                         (H225RegistrationConfirm *rcf, ooAliases *aliases);
typedef int (*cb_OnReceivedUnregistrationConfirm)
                       (H225UnregistrationConfirm *ucf, ooAliases *aliases);
typedef int (*cb_OnReceivedUnregistrationRequest)
                       (H225UnregistrationRequest *urq, ooAliases *aliases);

typedef struct OOGKCLIENTCALLBACKS{
   cb_OnReceivedRegistrationConfirm onReceivedRegistrationConfirm;
   cb_OnReceivedUnregistrationConfirm onReceivedUnregistrationConfirm;
   cb_OnReceivedUnregistrationRequest onReceivedUnregistrationRequest;
}OOGKCLIENTCALLBACKS;


typedef struct ooGkClient{
   ASN1BOOL discoveryComplete;
   OOCTXT ctxt;
   OOCTXT msgCtxt;
   OOSOCKET rasSocket;
   int localRASPort;
   char gkRasIP[20];
   char gkCallSignallingIP[20];
   RasGatekeeperInfo gkInfo;
   int gkRasPort;
   int gkCallSignallingPort;
   unsigned short requestSeqNum;
   enum RasGatekeeperMode gkMode; /* Current Gk mode */
   struct timeval registrationTime;
   H225GatekeeperIdentifier gkId;
   H225EndpointIdentifier endpointId;
   DList callsPendingList;
   DList callsAdmittedList;
   DList timerList;
   OOGKCLIENTCALLBACKS callbacks;
   ASN1UINT grqRetries;
   ASN1UINT rrqRetries;
   ASN1UINT grqTimeout;
   ASN1UINT rrqTimeout;
   ASN1UINT regTimeout;
   ASN1UINT arqTimeout;
   ASN1UINT drqTimeout;
   enum OOGkClientState  state;
} ooGkClient;

struct OOH323CallData;

/**
 * This function is used to initialize the Gatekeeper client.
 * @param eGkMode          Gatekeeper mode.
 * @param szGkAddr         Dotted gk ip address, if gk has to be specified.
 * @param iGkPort          Gk port.
 *
 * @return                 OO_OK, on success. OO_FAILED, on failure.
 * 
 */
EXTERN int ooGkClientInit
   (enum RasGatekeeperMode eGkMode, char *szGkAddr, int iGkPort );

/**
 * This function is used to print the gatekeeper client configuration 
 * information.
 * @param pGkClient        Handle to gatekeeper client.
 */
EXTERN void ooGkClientPrintConfig(ooGkClient *pGkClient);

/**
 * This function is used to destroy Gatekeeper client. It releases all the 
 * associated memory.
 *
 * @return     OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientDestroy(void);

/**
 * This function is used to start the Gatekeeper client functionality.
 * @param pGkClient        Pointer to the Gatekeeper Client.
 * 
 * @return                 OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientStart(ooGkClient *pGkClient);

/**
 * This function is invoked to set a gatekeeper mode. 
 * @param pGkClient Handle to gatekeeper client. 
 * @param eGkMode   Gatekeeper mode selected. One of the following: 
 *                    - RasNoGatekeeper (DEFAULT), No Gatekeeper.              
 *                    - RasDiscoverGatekeeper, to discover a gatekeeper 
 *                      automatically.					       
 *                    - RasUseSpecificGatekeeper, to use a specific gatekeeper.
 * @param szGkAddr  Gatekeeper address (only when using specific gatekeeper).
 * @param iGkPort   Gatekeeper RAS port
 *
 * @return         Completion status - OO_OK on success, OO_FAILED on failure
 */
EXTERN int ooGkClientSetGkMode(ooGkClient *pGkClient, 
                               enum RasGatekeeperMode eGkMode, char *szGkAddr, 
                               int iGkPort );

/**
 * This function is used to create a RAS channel for the gatekeeper.
 * @param pGkClient     Pointer to the Gatekeeper client for which RAS channel
 *                      has to be created.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientCreateChannel(ooGkClient *pGkClient);

/**
 * This function is used to close a RAS channel of the gatekeeper client.
 * @param pGkClient    Pointer to the gatekeeper client.
 *
 * @return             OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientCloseChannel(ooGkClient *pGkClient);


/**
 * This function is used to fill endpoint's vendor information into vendor
 * identifier.
 * @param pGkClient    Pointer to gatekeeper client.
 * @param psVendor     Pointer to vendor identifier to be filled.
 * 
 */
EXTERN void ooGkClientRasFillVendor
   (ooGkClient *pGkClient, H225VendorIdentifier *psVendor);


/**
 * This function is invoked to receive data on Gatekeeper client's RAS channel.
 * @param pGkClient    Handle to Gatekeeper client for which message has to be
 *                     received.
 *
 * @return             Completion status - OO_OK on success, OO_FAILED on 
 *                     failure
 */
EXTERN int ooGkClientReceive(ooGkClient *pGkClient);


/**
 * This function is used to handle a received RAS message by a gatekeeper 
 * client.
 * @param pGkClient   Handle to gatekeeper client.
 * @param pRasMsg     Handle to received Ras message.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientHandleRASMessage
   (ooGkClient *pGkClient, H225RasMessage *pRasMsg);


/**
 * This function is used to send a message on Gatekeeper clien't RAS channel.
 * @param pGkClient   Handle to the gatekeeper client.
 * @param pRasMsg     Handle to Ras message to be sent.
 *
 * @return            OO_OK, on success. OO_FAILED, otherwise. 
 */
EXTERN int ooGkClientSendMsg(ooGkClient *pGkClient, H225RasMessage *pRasMsg);


/**
 * This function is used to send Gatekeeper request message.
 * @param pGkClient  Handle to gatekeeper client for which GRQ message has to 
 *                   be sent.
 *
 * @return           OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooGkClientSendGRQ(ooGkClient *pGkClient);


/**
 * This function is used to handle a received gatekeeper reject message.
 * @param pGkClient          Handle to gatekeeper client.
 * @param pGatekeeperReject  Handle to received reject message.
 *
 * @return                   OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooGkClientHandleGatekeeperReject
   (ooGkClient *pGkClient, H225GatekeeperReject *pGatekeeperReject);

/**
 * This function is used to handle a received gatekeeper confirm message.
 * @param pGkClient          Handle to gatekeeper client.
 * @param pGatekeeperConfirm Handle to received confirmed message.
 *
 * @return                   OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooGkClientHandleGatekeeperConfirm
   (ooGkClient *pGkClient, H225GatekeeperConfirm *pGatekeeperConfirm);


/**
 * This function is used to send Registration request message.
 * @param pGkClient  Handle to gatekeeper client for which RRQ message has to 
 *                   be sent.
 * @param keepAlive  Indicates whether keepalive lightweight registration has 
 *                   to be sent.
 *
 * @return           OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooGkClientSendRRQ(ooGkClient *pGkClient, ASN1BOOL keepAlive);

/**
 * This function is used to handle a received registration confirm message.
 * @param pGkClient            Handle to gatekeeper client.
 * @param pRegistrationConfirm Handle to received confirmed message.
 *
 * @return                     OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooGkClientHandleRegistrationConfirm
   (ooGkClient *pGkClient, H225RegistrationConfirm *pRegistrationConfirm);

/**
 * This function is used to handle a received registration reject message.
 * @param pGkClient           Handle to gatekeeper client.
 * @param pRegistrationReject Handle to received reject message.
 *
 * @return                    OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooGkClientHandleRegistrationReject
   (ooGkClient *pGkClient, H225RegistrationReject *pRegistrationReject);


/**
 * This function is used to send UnRegistration request message.
 * @param pGkClient  Handle to gatekeeper client for which URQ message has to 
 *                   be sent.
 * @param aliases    List of aliases to be unregistered. NULL, if all the 
 *                   aliases have to be unregistered.
 *
 * @return           OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooGkClientSendURQ(ooGkClient *pGkClient, ooAliases *aliases);

/**
 * This function is used to handle a received Unregistration request message.
 * @param pGkClient              Handle to gatekeeper client.
 * @param punregistrationRequest Handle to received unregistration request.
 *
 * @return                   OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooGkClientHandleUnregistrationRequest
   (ooGkClient *pGkClient, H225UnregistrationRequest *punregistrationRequest);


/**
 * This function is used to send an unregistration confirm messsage to 
 * gatekeeper.
 * @param pGkClient        Handle to gatekeeper client.
 * @param reqNo            Request Sequence number for the confirm message.
 *
 * @return                 OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientSendUnregistrationConfirm(ooGkClient *pGkClient, 
                                                               unsigned reqNo);

/**
 * This function is invoked to request bandwith admission for a call. 
 * @param pGkClient     Gatekeeper client to be used
 * @param call          Handle to the call.
 * @param retransmit    Indicates whether new call or retransmitting for 
 *                      existing call.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientSendAdmissionRequest
   (ooGkClient *pGkClient, struct OOH323CallData *call, ASN1BOOL retransmit);

/**
 * This function is used to handle a received Admission confirm message.
 * @param pGkClient         Handle to gatekeeper client.
 * @param pAdmissionConfirm Handle to received confirmed message.
 *
 * @return                  OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooGkClientHandleAdmissionConfirm
   (ooGkClient *pGkClient, H225AdmissionConfirm *pAdmissionConfirm);

/**
 * This function is invoked to request call disengage to gatekeeper. 
 * @param pGkClient  Gatekeeper client to be used.
 * @param call       Call Handle
 *
 * @return           Completion status - OO_OK on success, OO_FAILED on failure
 */
EXTERN int ooGkClientSendDisengageRequest
   (ooGkClient *pGkClient, struct OOH323CallData *call);

/**
 * This function is used to handle a received disengage confirm message.
 * @param pGkClient            Handle to gatekeeper client.
 * @param pDCF                 Handle to received confirmed message.
 *
 * @return                     OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooGkClientHandleDisengageConfirm
   (ooGkClient *pGkClient, H225DisengageConfirm *pDCF);

/**
 * This function is used to handle an expired registration request timer.
 * @param pdata     Handle to callback data
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientRRQTimerExpired(void*pdata);

/**
 * This function is used to handle an expired gatekeeper request timer.
 * @param pdata     Handle to callback data
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientGRQTimerExpired(void* pdata);

/**
 * This function is used to handle an expired registration time-to-live timer.
 * @param pdata     Handle to callback data
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientREGTimerExpired(void *pdata);

/**
 * This function is used to handle an expired admission request timer.
 * @param pdata     Handle to callback data
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientARQTimerExpired(void* pdata);

/**
 * This function is used to clean call related data from gatekeeper client.
 * @param pGkClient  Handle to the gatekeeper client.
 * @param call       Handle to the call to be cleaned.
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientCleanCall(ooGkClient *pGkClient, struct OOH323CallData *call);

/**
 * This function is used to handle gatekeeper client failure or gatekeeper 
 * failure which can be detected by unresponsiveness of gk.
 * @param pGkClient  Handle to gatekeeper client.
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientHandleClientOrGkFailure(ooGkClient *pGkClient);

/**
 * This function is used to update the registration status of aliases.
 * @param pGkClient  Handle to the GK client.
 * @param pAddresses List of newly registered addresses. NULL means all
 *                   aliases have been successfully registered.
 * @param registered Indicates whether aliases are registered or unregistered.
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGkClientUpdateRegisteredAliases
   (ooGkClient *pGkClient, H225_SeqOfH225AliasAddress *pAddresses, 
    OOBOOL registered);


/**
 * This function is used to set callbacks for a gatekeeper client. It is never
 * directly called by applications. Applications use 
 * ooH323EpSetGkClientCallbacks(..), which in turn calls this function.
 * @param callbacks            Structure holding callback values.
 * 
 * @return                     OO_OK, on success. OO_FAILED, otherwise.
 */
int ooGkClientSetCallbacks
   (ooGkClient *pGkClient, OOGKCLIENTCALLBACKS callbacks);
/** 
 * @} 
 */

#ifdef __cplusplus
}
#endif

#endif /* __GKCLIENT_H */

--- NEW FILE: ooSocket.c ---
/*
 * Copyright (C) 1997-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 "ooSocket.h"
#include "ootrace.h"
#if defined(_WIN32_WCE)
static int inited = 0;
#define SEND_FLAGS     0
#define SHUTDOWN_FLAGS 0
#elif defined (_WIN32)
static LPFN_SEND send;
static LPFN_SOCKET socket;
static LPFN_SETSOCKOPT setsockopt;
static LPFN_BIND bind;
static LPFN_HTONL htonl;
static LPFN_HTONS htons;
static LPFN_CONNECT connect;
static LPFN_INET_ADDR inet_addr;
static LPFN_LISTEN listen;
static LPFN_ACCEPT accept;
static LPFN_NTOHL ntohl;
static LPFN_NTOHS ntohs;
static LPFN_RECV recv;
static LPFN_SHUTDOWN shutdown;


static LPFN_SENDTO sendto;
static LPFN_INET_NTOA inet_ntoa;
static LPFN_RECVFROM recvfrom;
static LPFN_SELECT select;
static LPFN_GETHOSTNAME gethostname;
static LPFN_GETHOSTBYNAME gethostbyname;
static LPFN_WSAGETLASTERROR  WSAGetLastError;
static LPFN_WSACLEANUP WSACleanup;
static LPFN_CLOSESOCKET closesocket;
static LPFN_GETSOCKNAME getsockname;
static HMODULE ws32 = 0;
#define SEND_FLAGS     0
#define SHUTDOWN_FLAGS SD_BOTH
#else
#define SEND_FLAGS     0
#define SHUTDOWN_FLAGS SHUT_RDWR
#define closesocket close
#endif

int ooSocketsInit ()
{
#if defined(_WIN32_WCE)
   WORD wVersionRequested;
   WSADATA wsaData;
   int err;

   if (inited) return ASN_OK; 

   wVersionRequested = MAKEWORD( 1, 1 );
    
   err = WSAStartup (wVersionRequested, &wsaData);
   if ( err != 0 ) {
      /* Tell the user that we could not find a usable */
      /* WinSock DLL.   */
      return ASN_E_NOTINIT;
   }
   inited = 1;

#elif defined (_WIN32)
   LPFN_WSASTARTUP wsaStartup = NULL;
   WSADATA wsaData;

   if (ws32 != 0) return ASN_OK;

//   ws32 = LoadLibrary ("WSOCK32.DLL");
  ws32 = LoadLibrary ("WS2_32.DLL");
   if (ws32 == NULL) return ASN_E_NOTINIT;
   
   wsaStartup = (LPFN_WSASTARTUP) GetProcAddress (ws32, "WSAStartup");
   if (wsaStartup == NULL) return ASN_E_NOTINIT;
   
   send = (LPFN_SEND) GetProcAddress (ws32, "send");
   if (send == NULL) return ASN_E_NOTINIT;
   
   socket = (LPFN_SOCKET) GetProcAddress (ws32, "socket");
   if (socket == NULL) return ASN_E_NOTINIT;
   
   setsockopt = (LPFN_SETSOCKOPT) GetProcAddress (ws32, "setsockopt");
   if (setsockopt == NULL) return ASN_E_NOTINIT;
   
   bind = (LPFN_BIND) GetProcAddress (ws32, "bind");
   if (bind == NULL) return ASN_E_NOTINIT;
   
   htonl = (LPFN_HTONL) GetProcAddress (ws32, "htonl");
   if (htonl == NULL) return ASN_E_NOTINIT;
   
   htons = (LPFN_HTONS) GetProcAddress (ws32, "htons");
   if (htons == NULL) return ASN_E_NOTINIT;
   
   connect = (LPFN_CONNECT) GetProcAddress (ws32, "connect");
   if (connect == NULL) return ASN_E_NOTINIT;
   
   listen = (LPFN_LISTEN) GetProcAddress (ws32, "listen");
   if (listen == NULL) return ASN_E_NOTINIT;
   
   accept = (LPFN_ACCEPT) GetProcAddress (ws32, "accept");
   if (accept == NULL) return ASN_E_NOTINIT;
   
   inet_addr = (LPFN_INET_ADDR) GetProcAddress (ws32, "inet_addr");
   if (inet_addr == NULL) return ASN_E_NOTINIT;
   
   ntohl = (LPFN_NTOHL) GetProcAddress (ws32, "ntohl");
   if (ntohl == NULL) return ASN_E_NOTINIT;
   
   ntohs = (LPFN_NTOHS) GetProcAddress (ws32, "ntohs");
   if (ntohs == NULL) return ASN_E_NOTINIT;
   
   recv = (LPFN_RECV) GetProcAddress (ws32, "recv");
   if (recv == NULL) return ASN_E_NOTINIT;
   
   shutdown = (LPFN_SHUTDOWN) GetProcAddress (ws32, "shutdown");
   if (shutdown == NULL) return ASN_E_NOTINIT;
   
   closesocket = (LPFN_CLOSESOCKET) GetProcAddress (ws32, "closesocket");
   if (closesocket == NULL) return ASN_E_NOTINIT;

   getsockname = (LPFN_GETSOCKNAME) GetProcAddress (ws32, "getsockname");
   if (getsockname == NULL) return ASN_E_NOTINIT;
   
   sendto = (LPFN_SENDTO) GetProcAddress (ws32, "sendto");
   if (sendto == NULL) return ASN_E_NOTINIT;

   inet_ntoa = (LPFN_INET_NTOA) GetProcAddress (ws32, "inet_ntoa");
   if (inet_ntoa == NULL) return ASN_E_NOTINIT;

   recvfrom = (LPFN_RECVFROM) GetProcAddress (ws32, "recvfrom");
   if (recvfrom == NULL) return ASN_E_NOTINIT;

   select = (LPFN_SELECT) GetProcAddress (ws32, "select");
   if (select == NULL) return ASN_E_NOTINIT;

   gethostname = (LPFN_GETHOSTNAME) GetProcAddress (ws32, "gethostname");
   if (gethostname == NULL) return ASN_E_NOTINIT;

   gethostbyname = (LPFN_GETHOSTBYNAME) GetProcAddress (ws32, "gethostbyname");
   if (gethostbyname == NULL) return ASN_E_NOTINIT;
   
   WSAGetLastError = (LPFN_WSAGETLASTERROR) GetProcAddress (ws32, 
                                                           "WSAGetLastError");
   if (WSAGetLastError == NULL) return ASN_E_NOTINIT;

   WSACleanup = (LPFN_WSACLEANUP) GetProcAddress (ws32, "WSACleanup");
   if (WSACleanup == NULL) return ASN_E_NOTINIT;
   
      
   if (wsaStartup (MAKEWORD(1, 1), &wsaData) == -1) return ASN_E_NOTINIT;
#endif
   return ASN_OK;
}

#if defined (_WIN32) || \
defined(_HP_UX) || defined(__hpux) || defined(_HPUX_SOURCE)
typedef int OOSOCKLEN;
#else
typedef size_t OOSOCKLEN;
#endif

int ooSocketCreate (OOSOCKET* psocket) 
{
   int on;

   struct linger linger;
   OOSOCKET sock = socket (AF_INET,
                             SOCK_STREAM,
                             0);
  
   if (sock == OOSOCKET_INVALID){
      OOTRACEERR1("Error:Failed to create TCP socket\n");
      return ASN_E_INVSOCKET;
   }

   on = 1;
   if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, 
                   (const char* ) &on, sizeof (on)) == -1)
   {
      OOTRACEERR1("Error:Failed to set socket option SO_REUSEADDR\n");
      return ASN_E_INVSOCKET;
   }
   linger.l_onoff = 1;
   linger.l_linger = 0;
   if (setsockopt (sock, SOL_SOCKET, SO_LINGER, 
                   (const char* ) &linger, sizeof (linger)) == -1)
   {
      OOTRACEERR1("Error:Failed to set socket option linger\n");
      return ASN_E_INVSOCKET;
   }
   *psocket = sock;
   return ASN_OK;
}

int ooSocketCreateUDP (OOSOCKET* psocket) 
{
   int on;
   struct linger linger;

   OOSOCKET sock = socket (AF_INET,
                             SOCK_DGRAM,
                             0);

   if (sock == OOSOCKET_INVALID){
      OOTRACEERR1("Error:Failed to create UDP socket\n");
      return ASN_E_INVSOCKET;
   }

   on = 1;
   if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, 
                   (const char* ) &on, sizeof (on)) == -1)
   {
      OOTRACEERR1("Error:Failed to set socket option SO_REUSEADDR\n");
      return ASN_E_INVSOCKET;
   }
   linger.l_onoff = 1;
   linger.l_linger = 0;
   /*if (setsockopt (sock, SOL_SOCKET, SO_LINGER, 
                 (const char* ) &linger, sizeof (linger)) == -1)
      return ASN_E_INVSOCKET;
   */
   *psocket = sock;
   return ASN_OK;
}

int ooSocketClose (OOSOCKET socket)
{
   shutdown (socket, SHUTDOWN_FLAGS);
   if (closesocket (socket) == -1)
      return ASN_E_INVSOCKET;
   return ASN_OK;
}

int ooSocketBind (OOSOCKET socket, OOIPADDR addr, int port) 
{
   struct sockaddr_in m_addr;

   if (socket == OOSOCKET_INVALID)
   { 
      OOTRACEERR1("Error:Invalid socket passed to bind\n");
      return ASN_E_INVSOCKET;
   }

   memset (&m_addr, 0, sizeof (m_addr));
   m_addr.sin_family = AF_INET;
   m_addr.sin_addr.s_addr = (addr == 0) ? INADDR_ANY : htonl (addr);
   m_addr.sin_port = htons ((unsigned short)port);

   if (bind (socket, (struct sockaddr *) (void*) &m_addr,
                     sizeof (m_addr)) == -1)
   {
      perror ("bind");
      OOTRACEERR1("Error:Bind failed\n");
      return ASN_E_INVSOCKET;
   }

   return ASN_OK;
}

#ifdef _WIN32
int ooGetSockName(OOSOCKET socket, struct sockaddr_in *name, int *size)
{
   int ret;
   ret = getsockname(socket, (struct sockaddr*)name, size);
   if(ret == 0)
      return ASN_OK;
   else
      return ASN_E_INVSOCKET;
}
#endif

int ooSocketListen (OOSOCKET socket, int maxConnection) 
{
   if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;

   if (listen (socket, maxConnection) == -1)
      return ASN_E_INVSOCKET;

   return ASN_OK;
}

int ooSocketAccept (OOSOCKET socket, OOSOCKET *pNewSocket, 
                    OOIPADDR* destAddr, int* destPort) 
{
   struct sockaddr_in m_addr;
   OOSOCKLEN addr_length = sizeof (m_addr);

   if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;
   if (pNewSocket == 0) return ASN_E_INVPARAM;

   *pNewSocket = accept (socket, (struct sockaddr *) (void*) &m_addr, 
                         &addr_length);
   if (*pNewSocket <= 0) return ASN_E_INVSOCKET;

   if (destAddr != 0) 
      *destAddr = ntohl (m_addr.sin_addr.s_addr);
   if (destPort != 0)
      *destPort = ntohs (m_addr.sin_port);

   return ASN_OK;
}

int ooSocketConnect (OOSOCKET socket, const char* host, int port) 
{
   struct sockaddr_in m_addr;

   if (socket == OOSOCKET_INVALID)
   { 
      return ASN_E_INVSOCKET;
   }
   
   memset (&m_addr, 0, sizeof (m_addr));

   m_addr.sin_family = AF_INET;
   m_addr.sin_port = htons ((unsigned short)port);
   m_addr.sin_addr.s_addr = inet_addr (host);

   if (connect (socket, (struct sockaddr *) (void*) &m_addr, 
                sizeof (struct sockaddr_in)) == -1)
   {
      return ASN_E_INVSOCKET;
   }
   return ASN_OK;
}
/*
// **Need to add check whether complete data was sent by checking the return
// **value of send and if complete data is not sent then add mechanism to 
// **send remaining bytes. This will make ooSocketSend call atomic.
*/
int ooSocketSend (OOSOCKET socket, const ASN1OCTET* pdata, ASN1UINT size)
{
   if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;
   
   if (send (socket, (const char*) pdata, size, SEND_FLAGS) == -1)
      return ASN_E_INVSOCKET;
   return ASN_OK;
}

int ooSocketSendTo(OOSOCKET socket, const ASN1OCTET* pdata, ASN1UINT size,
                     const char* host, int port)
{
   struct sockaddr_in m_addr;
   if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;
   
   memset (&m_addr, 0, sizeof (m_addr));

   m_addr.sin_family = AF_INET;
   m_addr.sin_port = htons ((unsigned short)port);
   m_addr.sin_addr.s_addr = inet_addr (host);
   if (sendto (socket, (const char*) pdata, size, SEND_FLAGS, 
                                    (const struct sockaddr*)&m_addr, 
                                    sizeof(m_addr)) == -1)
      return ASN_E_INVSOCKET;
   return ASN_OK;
}

int ooSocketRecv (OOSOCKET socket, ASN1OCTET* pbuf, ASN1UINT bufsize)
{
   int len;
   if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;

   if ((len = recv (socket, (char*) pbuf, bufsize, 0)) == -1)
      return ASN_E_INVSOCKET;
   return len;
}

int ooSocketRecvFrom (OOSOCKET socket, ASN1OCTET* pbuf, ASN1UINT bufsize,
                      char* remotehost, ASN1UINT hostBufLen, int * remoteport)
{
   struct sockaddr_in m_addr;
   int len, addrlen;
   char * host=NULL;
   if (socket == OOSOCKET_INVALID) return ASN_E_INVSOCKET;
   addrlen = sizeof(m_addr);

   memset (&m_addr, 0, sizeof (m_addr));
      
   if ((len = recvfrom (socket, (char*) pbuf, bufsize, 0, 
                        (struct sockaddr*)&m_addr, &addrlen)) == -1)
      return ASN_E_INVSOCKET;

   if(remoteport)
      *remoteport = ntohs(m_addr.sin_port);
   if(remotehost)
   {
      host = inet_ntoa(m_addr.sin_addr);
      if(strlen(host) < (hostBufLen-1))
         strcpy(remotehost, host);
      else
         return -1;
   }
   return len;
}

int ooSocketSelect(int nfds, fd_set *readfds, fd_set *writefds, 
                     fd_set *exceptfds, struct timeval * timeout)
{
   int ret;   
#if defined (_WIN32)
  ret = select(nfds, readfds, writefds, exceptfds, 
             (const struct timeval *) timeout);
#else
   ret = select(nfds, readfds, writefds, exceptfds, timeout);
#endif
   return ret;
}

int ooGetLocalIPAddress(char * pIPAddrs)
{
   int ret;
   struct hostent *phost;
   struct in_addr addr;
   char hostname[100];

   if(pIPAddrs == NULL)
      return -1; /* Need to find suitable return value */
   ret = gethostname(hostname, 100);
   if(ret == 0)
   {
      phost = gethostbyname(hostname);
      if(phost == NULL)
         return -1; /* Need to define a return value if made part of rtsrc */
      memcpy(&addr, phost->h_addr_list[0], sizeof(struct in_addr));
      strcpy(pIPAddrs, inet_ntoa(addr));
     
   }
   else{
      return -1;
   }
   return ASN_OK;
}

int ooSocketStrToAddr (const char* pIPAddrStr, OOIPADDR* pIPAddr) 
{
   int b1, b2, b3, b4;
   int rv = sscanf (pIPAddrStr, "%d.%d.%d.%d", &b1, &b2, &b3, &b4);
   if (rv != 4 ||
      (b1 < 0 || b1 > 256) || (b2 < 0 || b2 > 256) ||
      (b3 < 0 || b3 > 256) || (b4 < 0 || b4 > 256))
      return ASN_E_INVPARAM;
   *pIPAddr = ((b1 & 0xFF) << 24) | ((b2 & 0xFF) << 16) | 
              ((b3 & 0xFF) << 8) | (b4 & 0xFF);
   return ASN_OK;
}

int ooConvertIpToNwAddr(char *inetIp, char *netIp)
{
  int ret=0;
   struct sockaddr_in sin = {0};
#ifdef _WIN32
   sin.sin_addr.s_addr = inet_addr(inetIp);
   if(sin.sin_addr.s_addr == INADDR_NONE)
   {
      OOTRACEERR1("Error:Failed to convert address\n");
      return -1;
   }
#else
   if(!inet_aton(inetIp, &sin.sin_addr))
   {
      OOTRACEERR1("Error:Failed to convert address\n");
      return -1;
   }
  
#endif
   
   memcpy(netIp, (char*)&sin.sin_addr.s_addr, sizeof(unsigned long));
   return ASN_OK;
}

int ooSocketAddrToStr (OOIPADDR ipAddr, char* pbuf, int bufsize)
{
   char buf1[5], buf2[5], buf3[5], buf4[5];
   int cnt = 0;

   if (bufsize < 8) 
      return ASN_E_BUFOVFLW;

   cnt += sprintf (buf1, "%d", (ipAddr >> 24) & 0xFF);
   cnt += sprintf (buf2, "%d", (ipAddr >> 16) & 0xFF);
   cnt += sprintf (buf3, "%d", (ipAddr >> 8) & 0xFF);
   cnt += sprintf (buf4, "%d", ipAddr & 0xFF);
   if (bufsize < cnt + 4)
      return ASN_E_BUFOVFLW;
   sprintf (pbuf, "%s.%s.%s.%s", buf1, buf2, buf3, buf4);
   return ASN_OK;
}

int ooSocketsCleanup (void)
{
#ifdef _WIN32
   int ret = WSACleanup();
   if(ret == 0)
      return ASN_OK;
   else
      return ret;
#endif
   return ASN_OK;
}

long ooHTONL(long val)
{
   return htonl(val);
}

short ooHTONS(short val)
{
   return htons(val);
}

--- NEW FILE: ooSocket.h ---
/*
 * Copyright (C) 1997-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.
 *
 *****************************************************************************/

/** 
 * @file ooSocket.h 
 * Common runtime constants, data structure definitions, and run-time functions
 * to support the sockets' operations.
 */
#ifndef _OOSOCKET_H_
#define _OOSOCKET_H_

#ifdef _WIN32_WCE
#include <winsock.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <sys/types.h>
#define INCL_WINSOCK_API_TYPEDEFS   1
#define INCL_WINSOCK_API_PROTOTYPES 0
#include <winsock2.h>
#else
#include <sys/types.h>
#include "sys/time.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#endif

#include "ooasn1.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef EXTERN
#ifdef ASN1DLL
#define EXTERN __declspec(dllexport)
#elif defined (USEASN1DLL)
#define EXTERN __declspec(dllimport)
#else
#define EXTERN
#endif /* ASN1DLL */
#endif /* EXTERN */

/** 
 * @defgroup sockets Socket Layer
 * @{
 */
#if defined (_WIN64)
typedef unsigned __int64 OOSOCKET; /**< Socket's handle */
#elif defined (_WIN32)
typedef unsigned int OOSOCKET; /**< Socket's handle */
#else
typedef int OOSOCKET;          /**< Socket's handle */
#endif

#define OOSOCKET_INVALID ((OOSOCKET)-1)


/** 
 * The IP address represented as unsigned long value. The most significant 8
 * bits in this unsigned long value represent the first number of the IP
 * address. The least significant 8 bits represent the last number of the IP
 * address.
 */
typedef unsigned long OOIPADDR;

#define OOIPADDR_ANY   ((OOIPADDR)0)
#define OOIPADDR_LOCAL ((OOIPADDR)0x7f000001UL) /* 127.0.0.1 */


/**
 * This function permits an incoming connection attempt on a socket. It
 * extracts the first connection on the queue of pending connections on socket.
 * It then creates a new socket and returns a handle to the new socket. The
 * newly created socket is the socket that will handle the actual connection
 * and has the same properties as original socket. See description of 'accept'
 * socket function for further details.
 *
 * @param socket       The socket's handle created by call to ::rtSocketCreate
 *                     function.
 * @param pNewSocket   The pointer to variable to receive the new socket's
 *                     handle.
 * @param destAddr     Optional pointer to a buffer that receives the IP
 *                     address of the connecting entity. It may be NULL.
 * @param destPort     Optional pointer to a buffer that receives the port of
 *                     the connecting entity. It may be NULL.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */
EXTERN int ooSocketAccept (OOSOCKET socket, OOSOCKET *pNewSocket, 
                             OOIPADDR* destAddr, int* destPort);

/**
 * This function converts an IP address to its string representation.
 *
 * @param ipAddr       The IP address to be converted.
 * @param pbuf         Pointer to the buffer to receive a string with the IP
 *                     address.
 * @param bufsize      Size of the buffer.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */
EXTERN int ooSocketAddrToStr (OOIPADDR ipAddr, char* pbuf, int bufsize);

/**
 * This function associates a local address with a socket. It is used on an
 * unconnected socket before subsequent calls to the ::rtSocketConnect or
 * ::rtSocketListen functions. See description of 'bind' socket function for
 * further details.
 *
 * @param socket       The socket's handle created by call to ::rtSocketCreate
 *                     function.
 * @param addr         The local IP address to assign to the socket.
 * @param port         The local port number to assign to the socket.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */
EXTERN int ooSocketBind (OOSOCKET socket, OOIPADDR addr, int port);

/**
 * This function closes an existing socket.
 *
 * @param socket       The socket's handle created by call to ::rtSocketCreate
 *                     or ::rtSocketAccept function.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */
EXTERN int ooSocketClose (OOSOCKET socket);

/**
 * This function establishes a connection to a specified socket. It is used to
 * create a connection to the specified destination. When the socket call
 * completes successfully, the socket is ready to send and receive data. See
 * description of 'connect' socket function for further details.
 *
 * @param socket       The socket's handle created by call to ::rtSocketCreate
 *                     function.
 * @param host         The null-terminated string with the IP address in the
 *                     following format: "NNN.NNN.NNN.NNN", where NNN is a
 *                     number in the range (0..255).
 * @param port         The destination port to connect.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */
EXTERN int ooSocketConnect (OOSOCKET socket, const char* host, int port);

/**
 * This function creates a socket. The only streaming TCP/IP sockets are
 * supported at the moment.
 *
 * @param psocket      The pointer to the socket's handle variable to receive
 *                     the handle of new socket.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */
EXTERN int ooSocketCreate (OOSOCKET* psocket);

/**
 * This function creates a UDP datagram socket. 
 *
 * @param psocket      The pointer to the socket's handle variable to receive
 *                     the handle of new socket.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */
EXTERN int ooSocketCreateUDP (OOSOCKET* psocket);

/**
 * This function initiates use of sockets by an application. This function must
 * be called first before use sockets.
 *
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */
EXTERN int ooSocketsInit (void);

/**
 * This function terminates use of sockets by an application. This function 
 * must be called after done with sockets.
 *
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */
EXTERN int ooSocketsCleanup (void);

/**
 * This function places a socket a state where it is listening for an incoming
 * connection. To accept connections, a socket is first created with the
 * ::rtSocketCreate function and bound to a local address with the
 * ::rtSocketBind function, a maxConnection for incoming connections is
 * specified with ::rtSocketListen, and then the connections are accepted with
 * the ::rtSocketAccept function. See description of 'listen' socket function
 * for further details.
 *
 * @param socket        The socket's handle created by call to
 *                      ::rtSocketCreate function.
 * @param maxConnection Maximum length of the queue of pending connections.
 * @return              Completion status of operation: 0 (ASN_OK) =
 *                      success, negative return value is error.
 */
EXTERN int ooSocketListen (OOSOCKET socket, int maxConnection);

/**
 * This function receives data from a connected socket. It is used to read
 * incoming data on sockets. The socket must be connected before calling this
 * function. See description of 'recv' socket function for further details.
 *
 * @param socket       The socket's handle created by call to ::rtSocketCreate
 *                     or ::rtSocketAccept function.
 * @param pbuf         Pointer to the buffer for the incoming data.
 * @param bufsize      Length of the buffer.
 * @return             If no error occurs, returns the number of bytes
 *                     received. Otherwise, the negative value is error code.
 */
EXTERN int ooSocketRecv (OOSOCKET socket, ASN1OCTET* pbuf, 
                           ASN1UINT bufsize);

/**
 * This function receives data from a connected/unconnected socket. It is used
 * to read incoming data on sockets. It populates the remotehost and 
 * remoteport parameters with information of remote host. See description of 
 * 'recvfrom' socket function for further details.
 *
 * @param socket       The socket's handle created by call to ooSocketCreate
 *                     
 * @param pbuf         Pointer to the buffer for the incoming data.
 * @param bufsize      Length of the buffer.
 * @param remotehost   Pointer to a buffer in which remote ip address
 *                     will be returned.
 * @param hostBufLen   Length of the buffer passed for remote ip address.
 * @param remoteport   Pointer to an int in which remote port number
 *                     will be returned.
 *
 * @return             If no error occurs, returns the number of bytes
 *                     received. Otherwise, negative value.
 */
EXTERN int ooSocketRecvFrom (OOSOCKET socket, ASN1OCTET* pbuf,
			     ASN1UINT bufsize, char * remotehost, 
                             ASN1UINT hostBufLen, int * remoteport);
/**
 * This function sends data on a connected socket. It is used to write outgoing
 * data on a connected socket. See description of 'send' socket function for
 * further details.
 *
 * @param socket       The socket's handle created by call to ::rtSocketCreate
 *                     or ::rtSocketAccept function.
 * @param pdata        Buffer containing the data to be transmitted.
 * @param size         Length of the data in pdata.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */
EXTERN int ooSocketSend (OOSOCKET socket, const ASN1OCTET* pdata, 
                           ASN1UINT size);

/**
 * This function sends data on a connected or unconnected socket. See 
 * description of 'sendto' socket function for further details.
 *
 * @param socket       The socket's handle created by call to ::rtSocketCreate
 *                       or ::rtSocketAccept function.
 * @param pdata        Buffer containing the data to be transmitted.
 * @param size         Length of the data in pdata.
 * @param remotehost   Remote host ip address to which data has to 
 *                     be sent.
 * @param remoteport   Remote port ip address to which data has to 
 *                     be sent.
 *
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */
EXTERN int ooSocketSendTo(OOSOCKET socket, const ASN1OCTET* pdata, 
                            ASN1UINT size, const char* remotehost,
                            int remoteport);

/**
 * This function is used for synchronous monitoring of multiple sockets.
 * For more information refer to documnetation of "select" system call. 
 *
 * @param nfds         The highest numbered descriptor to be monitored 
 *                     plus one.
 * @param readfds      The descriptors listed in readfds will be watched for 
 *                     whether read would block on them.
 * @param writefds     The descriptors listed in writefds will be watched for
 *                     whether write would block on them.
 * @param exceptfds    The descriptors listed in exceptfds will be watched for
 *                     exceptions.
 * @param timeout      Upper bound on amout of time elapsed before select 
 *                     returns. 
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */                                                       
EXTERN int ooSocketSelect(int nfds, fd_set *readfds, fd_set *writefds, 
                            fd_set *exceptfds, struct timeval * timeout);

/**
 * This function converts the string with IP address to a double word
 * representation. The converted address may be used with the ::rtSocketBind
 * function.
 *
 * @param pIPAddrStr   The null-terminated string with the IP address in the
 *                     following format: "NNN.NNN.NNN.NNN", where NNN is a
 *                     number in the range (0..255).
 * @param pIPAddr      Pointer to the converted IP address.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */
EXTERN int ooSocketStrToAddr (const char* pIPAddrStr, OOIPADDR* pIPAddr);

/**
 * This function converts an internet dotted ip address to network address
 *
 * @param inetIp       The null-terminated string with the IP address in the
 *                     following format: "NNN.NNN.NNN.NNN", where NNN is a
 *                     number in the range (0..255).
 * @param netIp        Buffer in which the converted address will be returned.

 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                     negative return value is error.
 */
int ooConvertIpToNwAddr(char *inetIp, char *netIp);

/**
 * This function retrives the IP address of the local host.
 *
 * @param pIPAddrs   Pointer to a char buffer in which local IP address will be
 *                   returned.
 * @return           Completion status of operation: 0 (ASN_OK) = success,
 *                   negative return value is error.
 */
EXTERN int ooGetLocalIPAddress(char * pIPAddrs);

#ifdef _WIN32
EXTERN int ooGetSockName(OOSOCKET socket, struct sockaddr_in *name, int *size);
#endif

EXTERN long ooHTONL(long val);

EXTERN short ooHTONS(short val);
/** 
 * @} 
 */
#ifdef __cplusplus
}
#endif

#endif /* _OOSOCKET_H_ */


--- NEW FILE: ooStackCmds.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 "ooStackCmds.h"
#include "ootrace.h"
#include "ooq931.h"
#include "ooh323ep.h"

/** Global endpoint structure */
extern OOH323EndPoint gH323ep;

extern OO_MUTEX gCmdMutex;

int ooMakeCall 
   (const char* dest, char* callToken, size_t bufsiz, ooCallOptions *opts)
{
   ooCommand *cmd;
   int ret;
#ifdef _WIN32
   EnterCriticalSection(&gCmdMutex);
#else
   pthread_mutex_lock(&gCmdMutex);
#endif
   cmd = (ooCommand*) memAlloc (&gH323ep.ctxt, sizeof(ooCommand));
   if(!cmd)
   {
      OOTRACEERR1("Error:Memory - ooMakeCall - cmd\n");
      return OO_FAILED;
   }
   cmd->type = OO_CMD_MAKECALL;
   cmd->param1 = (void*) memAlloc(&gH323ep.ctxt, strlen(dest)+1);
   if(!cmd->param1)
   {
      OOTRACEERR1("ERROR:Memory - ooMakeCall - param1\n");
      memFreePtr(&gH323ep.ctxt, cmd);
      return OO_FAILED;
   }
   strcpy((char*)cmd->param1, dest);

   /* Generate call token*/
   if(!callToken)
   {
      OOTRACEERR1("ERROR:Invalid 'callToken' parameter to 'ooMakeCall'\n");
      memFreePtr(&gH323ep.ctxt, cmd->param1);
      memFreePtr(&gH323ep.ctxt, cmd);
      return OO_FAILED;
   }

   if ((ret = ooGenerateCallToken (callToken, bufsiz)) != 0)
      return ret;

   cmd->param2 = (void*) memAlloc(&gH323ep.ctxt, strlen(callToken)+1);
   if(!cmd->param2)
   {
      OOTRACEERR1("ERROR:Memory - ooMakeCall - param2\n");
      memFreePtr(&gH323ep.ctxt, cmd->param1);
      memFreePtr(&gH323ep.ctxt, cmd);
      return OO_FAILED;
   }
   
   strcpy((char*)cmd->param2, callToken);

   if(!opts)
   {
      cmd->param3 = 0;
   }else {
      cmd->param3 = (void*) memAlloc(&gH323ep.ctxt, sizeof(ooCallOptions));
      if(!cmd->param3)
      {
         OOTRACEERR1("ERROR:Memory - ooMakeCall - param3\n");
         memFreePtr(&gH323ep.ctxt, cmd->param1);
         memFreePtr(&gH323ep.ctxt, cmd->param2);
         memFreePtr(&gH323ep.ctxt, cmd);
         return OO_FAILED;
      }
      memcpy((void*)cmd->param3, opts, sizeof(ooCallOptions));
   }


   dListAppend (&gH323ep.ctxt, &gH323ep.stkCmdList, cmd);
#ifdef HAVE_PIPE
   if(write(gH323ep.cmdPipe[1], "c", 1)<0)
   {
      OOTRACEERR1("ERROR:Failed to write to command pipe\n");
   }
#endif

#ifdef _WIN32
   LeaveCriticalSection(&gCmdMutex);
#else
   pthread_mutex_unlock(&gCmdMutex);
#endif

   return OO_OK;
}

int ooAnswerCall(char *callToken)
{
   ooCommand *cmd;
#ifdef _WIN32
   EnterCriticalSection(&gCmdMutex);
#else
   pthread_mutex_lock(&gCmdMutex);
#endif
   cmd = (ooCommand*)memAlloc(&gH323ep.ctxt, sizeof(ooCommand));
   if(!cmd)
   {
      OOTRACEERR1("Error:Memory - ooAnswerCall - cmd\n");
      return OO_FAILED;
   }
   memset(cmd, 0, sizeof(ooCommand));
   cmd->type = OO_CMD_ANSCALL;

   cmd->param1 = (void*) memAlloc(&gH323ep.ctxt, strlen(callToken)+1);
   if(!cmd->param1)
   {
      OOTRACEERR1("ERROR:Memory - ooAnswerCall - param1\n");
      return OO_FAILED;
   }
   strcpy((char*)cmd->param1, callToken);
   
   dListAppend(&gH323ep.ctxt, &gH323ep.stkCmdList, cmd);
   
#ifdef HAVE_PIPE
   if(write(gH323ep.cmdPipe[1], "c", 1)<0)
   {
      OOTRACEERR1("ERROR:Failed to write to command pipe\n");
   }
#endif

#ifdef _WIN32
   LeaveCriticalSection(&gCmdMutex);
#else
   pthread_mutex_unlock(&gCmdMutex);
#endif

   return OO_OK;
}

int ooForwardCall(char* callToken, char *dest)
{
   ooCommand *cmd;
#ifdef _WIN32
   EnterCriticalSection(&gCmdMutex);
#else
   pthread_mutex_lock(&gCmdMutex);
#endif
   cmd = (ooCommand*)memAlloc(&gH323ep.ctxt, sizeof(ooCommand));
   if(!cmd)
   {
      OOTRACEERR1("Error:Memory - ooForwardCall - cmd\n");
      return OO_FAILED;
   }
   memset(cmd, 0, sizeof(ooCommand));
   cmd->type = OO_CMD_FWDCALL;

   cmd->param1 = (void*) memAlloc(&gH323ep.ctxt, strlen(callToken)+1);
   cmd->param2 = (void*) memAlloc(&gH323ep.ctxt, strlen(dest)+1);
   if(!cmd->param1)
   {
      OOTRACEERR1("ERROR:Memory - ooForwardCall - param1/param2\n");
      return OO_FAILED;
   }
   strcpy((char*)cmd->param1, callToken);
   strcpy((char*)cmd->param2, dest);
   dListAppend(&gH323ep.ctxt, &gH323ep.stkCmdList, cmd);
   
#ifdef HAVE_PIPE
   if(write(gH323ep.cmdPipe[1], "c", 1)<0)
   {
      OOTRACEERR1("ERROR:Failed to write to command pipe\n");
   }
#endif
#ifdef _WIN32
   LeaveCriticalSection(&gCmdMutex);
#else
   pthread_mutex_unlock(&gCmdMutex);
#endif

   return OO_OK;
}


int ooHangCall(char * callToken, OOCallClearReason reason)
{
   ooCommand *cmd;
#ifdef _WIN32
   EnterCriticalSection(&gCmdMutex);
#else
   pthread_mutex_lock(&gCmdMutex);
#endif
   cmd = (ooCommand*)memAlloc(&gH323ep.ctxt, sizeof(ooCommand));
   if(!cmd)
   {
      OOTRACEERR1("Error:Allocating memory for command structure - HangCall\n");
      return OO_FAILED;
   }

   memset(cmd, 0, sizeof(ooCommand));
   cmd->type = OO_CMD_HANGCALL;
   cmd->param1 = (void*) memAlloc(&gH323ep.ctxt, strlen(callToken)+1);
   cmd->param2 = (void*)memAlloc(&gH323ep.ctxt, sizeof(OOCallClearReason));
   if(!cmd->param1 || !cmd->param2)
   {
      OOTRACEERR1("ERROR:Allocating memory for cmd param1/param2- HangCall\n");
      return OO_FAILED;
   }
   strcpy((char*)cmd->param1, callToken);
   *((OOCallClearReason*)cmd->param2) = reason;
   
   dListAppend(&gH323ep.ctxt, &gH323ep.stkCmdList, cmd);
   
#ifdef HAVE_PIPE
   if(write(gH323ep.cmdPipe[1], "c", 1)<0)
   {
      OOTRACEERR1("ERROR:Failed to write to command pipe\n");
   }
#endif
#ifdef _WIN32
   LeaveCriticalSection(&gCmdMutex);
#else
   pthread_mutex_unlock(&gCmdMutex);
#endif

   return OO_OK;
}

int ooStopMonitor()
{
   ooCommand *cmd;
#ifdef _WIN32
   EnterCriticalSection(&gCmdMutex);
#else
   pthread_mutex_lock(&gCmdMutex);
#endif
   cmd = (ooCommand*)memAlloc(&gH323ep.ctxt, sizeof(ooCommand));
   if(!cmd)
   {
      OOTRACEERR1("Error:Allocating memory for command structure - StopMonitor\n");
      return OO_FAILED;
   }
   memset(cmd, 0, sizeof(ooCommand));
   cmd->type = OO_CMD_STOPMONITOR;
   
   dListAppend (&gH323ep.ctxt, &gH323ep.stkCmdList, cmd);

#ifdef HAVE_PIPE
   if(write(gH323ep.cmdPipe[1], "c", 1)<0)
   {
      OOTRACEERR1("ERROR:Failed to write to command pipe\n");
   }
#endif
   
#ifdef _WIN32
   LeaveCriticalSection(&gCmdMutex);
#else
   pthread_mutex_unlock(&gCmdMutex);
#endif
   return OO_OK;
}

--- NEW FILE: ooStackCmds.h ---
/*
 * 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.
 *
 *****************************************************************************/
/**
 * @file ooStackCmds.h 
 * This file contains stack commands which an user application can use to make
 * call, hang call etc. 
 */

#ifndef OO_STACKCMDS_H
#define OO_STACKCMDS_H

#include "ootypes.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef EXTERN
#ifdef _WIN32
#define EXTERN __declspec(dllexport)
#else
#define EXTERN
#endif /* _WIN32 */
#endif /* EXTERN */
/** 
 * @defgroup stackcmds Stack Control Commands
 * @{
 */
/**
 * This function is used by an application to place a call.
 * @param dest        Call Destination - IP:port / alias
 * @param callToken   Pointer to a buffer in which callToken will be returned
 * @param bufsiz      Size of the callToken buffer passed.
 * @param opts        These are call specific options and if passed a non-null
 *                    value, will override global endpoint options.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooMakeCall 
   (const char* dest, char *callToken, size_t bufsiz, ooCallOptions *opts);


/**
 * This function is used to answer a call
 * @param callToken   Unique token for the call
 * 
 * @return            OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooAnswerCall(char *callToken);

/**
 * This function is used to forward an existing call to third party.
 * @param callToken   Unique token for the call.
 * @param dest        Address to which the call has to be forwarded. Can be
 *                    IP:PORT or alias.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooForwardCall(char* callToken, char *dest);

/**
 * This function is used by an user application to hang a call.
 * @param callToken   The uinque token for the call.
 * @param reason      Reason for hanging call.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooHangCall(char * callToken, OOCallClearReason reason);

/**
 * This function is used by the user application to stop monitoring calls.
 * @param None
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooStopMonitor(void);

/** 
 * @} 
 */

#ifdef __cplusplus
}
#endif

#endif

--- NEW FILE: ooTimer.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 LICENSE.txt 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 "ooDateTime.h"
#include "ooTimer.h"
#include "ootrace.h"

#define USECS_IN_SECS 1000000
#define NSECS_IN_USECS 1000

#ifndef MICROSEC
#define MICROSEC USECS_IN_SECS
#endif

/**
 * This is a timer list used by test application chansetup only. 
 */

DList g_TimerList;

OOTimer* ooTimerCreate 
(OOCTXT* pctxt, DList *pList, OOTimerCbFunc cb, OOUINT32 deltaSecs, void *data, 
 OOBOOL reRegister)
{
   OOTimer* pTimer = (OOTimer*) memAlloc (pctxt, sizeof(OOTimer));
   if (0 == pTimer) return 0;

   memset (pTimer, 0, (sizeof(OOTimer)));
   pTimer->timeoutCB = cb;
   pTimer->cbData = data;
   pTimer->reRegister = reRegister;
   pTimer->timeout.tv_sec  = deltaSecs;
   pTimer->timeout.tv_usec = 0;

   /* Compute the absolute time at which this timer should expire */

   ooTimerComputeExpireTime (pTimer);

   /* Insert this timer into the complete list */
   if(pList)
      ooTimerInsertEntry (pctxt, pList, pTimer);
   else
      ooTimerInsertEntry (pctxt, &g_TimerList, pTimer);

   return pTimer;
}

void ooTimerComputeExpireTime (OOTimer* pTimer)
{
   struct timeval tv;
   ooGetTimeOfDay (&tv, 0);

   /* Compute delta time to expiration */

   pTimer->expireTime.tv_usec = tv.tv_usec + pTimer->timeout.tv_usec;
   pTimer->expireTime.tv_sec  = tv.tv_sec  + pTimer->timeout.tv_sec;

   while (pTimer->expireTime.tv_usec >= MICROSEC) {
      pTimer->expireTime.tv_usec -= MICROSEC;
      pTimer->expireTime.tv_sec++;
   }
}

void ooTimerDelete (OOCTXT* pctxt, DList *pList, OOTimer* pTimer)
{
   dListFindAndRemove (pList, pTimer);
   memFreePtr (pctxt, pTimer);
}

OOBOOL ooTimerExpired (OOTimer* pTimer)
{
   struct timeval tvstr;
   ooGetTimeOfDay (&tvstr, 0);

   if (tvstr.tv_sec > pTimer->expireTime.tv_sec)
      return TRUE;

   if ((tvstr.tv_sec == pTimer->expireTime.tv_sec) &&
       (tvstr.tv_usec > pTimer->expireTime.tv_usec))
      return TRUE;

   return FALSE;
}

void ooTimerFireExpired (OOCTXT* pctxt, DList *pList)
{
   OOTimer* pTimer;
   int stat;

   while (pList->count > 0) {
      pTimer = (OOTimer*) pList->head->data;

      if (ooTimerExpired (pTimer)) {
         /*
          * Re-register before calling callback function in case it is
          * a long duration callback.                                   
          */
         if (pTimer->reRegister) ooTimerReset (pctxt, pList, pTimer);

         stat = (*pTimer->timeoutCB)(pTimer->cbData);

         if (0 != stat || !pTimer->reRegister) {
            ooTimerDelete (pctxt, pList, pTimer);
	 }
      }
      else break;
   }
}

int ooTimerInsertEntry (OOCTXT* pctxt, DList *pList, OOTimer* pTimer)
{  DListNode* pNode;
   OOTimer* p;
   int i = 0;

   for (pNode = pList->head; pNode != 0; pNode = pNode->next) {
      p = (OOTimer*) pNode->data;
      if (pTimer->expireTime.tv_sec  <  p->expireTime.tv_sec) break;
      if (pTimer->expireTime.tv_sec  == p->expireTime.tv_sec &&
          pTimer->expireTime.tv_usec <= p->expireTime.tv_usec) break;
      i++;
   }

   dListInsertBefore (pctxt, pList, pNode, pTimer);

   return i;
}

struct timeval* ooTimerNextTimeout (DList *pList, struct timeval* ptimeout)
{
   OOTimer* ptimer;
   struct timeval tvstr;

   if (pList->count == 0) return 0;
   ptimer = (OOTimer*) pList->head->data;

   ooGetTimeOfDay (&tvstr, 0);

   ptimeout->tv_sec = 
      OOMAX ((int) 0, (int) (ptimer->expireTime.tv_sec - tvstr.tv_sec));   

   ptimeout->tv_usec = ptimer->expireTime.tv_usec - tvstr.tv_usec;

   while (ptimeout->tv_usec < 0) {
      ptimeout->tv_sec--;
      ptimeout->tv_usec += USECS_IN_SECS;
   }

   if (ptimeout->tv_sec < 0)
      ptimeout->tv_sec = ptimeout->tv_usec = 0;

   return (ptimeout);
}

/* 
 * Reregister a timer entry.  This function is responsible for moving
 * the current pointer in the timer list to the next element to be
 * processed..
 */
void ooTimerReset (OOCTXT* pctxt, DList *pList, OOTimer* pTimer)
{
   if (pTimer->reRegister) {
      dListFindAndRemove (pList, pTimer);
      ooTimerComputeExpireTime (pTimer);
      ooTimerInsertEntry (pctxt, pList, pTimer);
   }
   else
      ooTimerDelete (pctxt, pList, pTimer);
}

int ooCompareTimeouts(struct timeval *to1, struct timeval *to2)
{

   if(to1->tv_sec > to2->tv_sec)   return 1;
   if(to1->tv_sec < to2->tv_sec)   return -1;

   if(to1->tv_usec > to2->tv_usec)   return 1;
   if(to1->tv_usec < to2->tv_usec)   return -1;

   return 0;
}

--- NEW FILE: ooTimer.h ---
/*
 * 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 LICENSE.txt 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.
 *
 *****************************************************************************/
/** 
 * @file ooTimer.h 
 * Timer structures and functions.
 */
#ifndef _OOTIMER_H_
#define _OOTIMER_H_

#include "ooasn1.h"
#include "ooSocket.h"   /* needed for timeval */

struct _OOTimer;

typedef int (*OOTimerCbFunc)(void *data);

typedef struct _OOTimer {
   struct timeval expireTime, timeout;
   void*	cbData;
   OOBOOL       reRegister;

   /* Callback functions */
   OOTimerCbFunc timeoutCB;
} OOTimer;

#ifdef __cplusplus
extern "C" {
#endif

/**
 * This function computes the relative expiration time from the current 
 * time for the given timer object.
 *
 * @param pTimer       Pointer to timer object.
 */
EXTERN void ooTimerComputeExpireTime (OOTimer* pTimer);

/**
 * This function creates and initializes a new timer object.
 * @param pctxt        OOCTXT structure used for timer memory allocation.
 * @param pList        Pointer to timer list in which newly created timer will
 *                     be inserted.
 * @param cb           Timer callback function.
 * @param deltaSecs    Time in seconds to timer expiration.
 * @param data         Callback user data argument.
 * @param reRegister   Should timer be re-registered after it expires?
 * @return             Pointer to created timer object.
 */
EXTERN OOTimer* ooTimerCreate 
(OOCTXT* pctxt, DList *pList, OOTimerCbFunc cb, OOUINT32 deltaSecs, void *data,
 OOBOOL reRegister);

/**
 * This function deletes the given timer object.
 * @param pctxt        Handle to OOCTXT structure used for timer memory.
 * @param pList        timer list to operate on
 * @param pTimer       Pointer to timer object.
 */
EXTERN void ooTimerDelete (OOCTXT* pctxt, DList* pList, OOTimer* pTimer);

/**
 * This function checks a timer to determine if it is expired.
 *
 * @param pTimer       Pointer to timer object.
 * @return             True if timer expired, false if not.
 */
EXTERN OOBOOL ooTimerExpired (OOTimer* pTimer);

/**
 * This function loops through the global timer list and fires all 
 * expired timers by calling the registered callback functions.
 */
EXTERN void ooTimerFireExpired (OOCTXT* pctxt, DList* pList);

/**
 * This function inserts the given timer object into the correct 
 * chronological position in the global timer list.
 * @param pctxt        Pointer to OOCTXT structure used for memory allocation.
 * @param pList        List in which timer has to be inserted.
 * @param pTimer       Pointer to timer object.
 * @return             Index to position where inserted in list.
 */
EXTERN int ooTimerInsertEntry (OOCTXT* pctxt, DList* pList, OOTimer* pTimer);

/**
 * This function calculates the relative time from the current time 
 * that the first timer in global timer list will expire.
 * @param pList         Handle to timer list
 * @param ptimeout      timeval structure to receive timeout value.
 * @return              ptimeout
 */
EXTERN struct timeval* ooTimerNextTimeout (DList* pList, struct timeval* ptimeout);

/**
 * This function resets the given timer object if its reregister flag 
 * is set.  Otherwise, it is deleted.
 * @param pctxt        Pointer to OOCTXT structre used for memory allocation.
 * @param pList        Pointer to timer list.
 * @param pTimer       Pointer to timer object.
 */
EXTERN void ooTimerReset (OOCTXT* pctxt, DList* pList, OOTimer* pTimer);


/**
 * This function is used to compare two timeout values.
 * @param to1          First timeout value.
 * @param to2          Second timeout value.
 *
 * @return             1, if to1 > to2; 0, if to1 == to2; -1, if to1 < to2
 */
int ooCompareTimeouts(struct timeval *to1, struct timeval *to2);
#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE: ooUtils.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 "ooUtils.h"


OOBOOL ooUtilsIsStrEmpty(char * str)
{
   return (str == NULL || *str =='\0');
}


--- NEW FILE: ooUtils.h ---
/*
 * 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.
 *
 *****************************************************************************/
/**
 * @file ooUtils.h 
 * This file contains general utility functions. 
 */
#ifndef _OOUTILS_H_
#define _OOUTILS_H_
#include "ootypes.h"
EXTERN OOBOOL ooUtilsIsStrEmpty(char * str);

#endif

--- NEW FILE: ooasn1.h ---
/*
 * Copyright (C) 1997-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.
 *
 *****************************************************************************/
/** 
 * @file ooasn1.h 
 * Common ASN.1 runtime constants, data structure definitions, and run-time
 * functions to support BER/DER/PER as defined in the ITU-T standards.
[...1949 lines suppressed...]
EXTERN int checkSizeConstraint(OOCTXT* pctxt, int size);
EXTERN ASN1UINT getUIntBitCount (ASN1UINT value);

EXTERN Asn1SizeCnst* checkSize 
(Asn1SizeCnst* pSizeList, ASN1UINT value, ASN1BOOL* pExtendable);

EXTERN void init16BitCharSet 
(Asn116BitCharSet* pCharSet, ASN116BITCHAR first,
 ASN116BITCHAR last, ASN1UINT abits, ASN1UINT ubits);

EXTERN ASN1BOOL isExtendableSize (Asn1SizeCnst* pSizeList);

EXTERN void set16BitCharSet 
(OOCTXT* pctxt, Asn116BitCharSet* pCharSet, Asn116BitCharSet* pAlphabet);

#ifdef __cplusplus
}
#endif

#endif 

--- NEW FILE: oochannels.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 "ooports.h" 
#include "oochannels.h"
#include "ootrace.h"
[...1648 lines suppressed...]
            call->callEndReason = OO_REASON_LOCAL_CLEARED;
            ooCleanCall(call);
            call = NULL;
            call = gH323ep.callList;
         }
         gH323ep.callList = NULL;
      }
      OOTRACEINFO1("Stopping listener for incoming calls\n");   
      if(gH323ep.listener)
      {
         ooSocketClose(*(gH323ep.listener));
         memFreePtr(&gH323ep.ctxt, gH323ep.listener);
         gH323ep.listener = NULL;
      }

      gMonitor = FALSE;
      OOTRACEINFO1("Done ooStopMonitorCalls\n");
   }
   return OO_OK;
}

--- NEW FILE: oochannels.h ---
/*
 * 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.
 *
 *****************************************************************************/

/**
 * @file oochannels.h 
 * This file contains functions to create and use channels. 
 */
#ifndef _OOCHANNELS_H_
#define _OOCHANNELS_H_

#include "H323-MESSAGES.h"
#include "MULTIMEDIA-SYSTEM-CONTROL.h"
#include "ootypes.h"
#include "ooSocket.h"

#define OORECEIVER 1
#define OOTRANSMITTER 2
#define OODUPLEX 3

#ifdef __cplusplus
extern "C" {
#endif

#ifndef EXTERN
#ifdef _WIN32
#define EXTERN __declspec(dllexport)
#else
#define EXTERN
#endif /* _WIN32 */
#endif /* EXTERN */

struct OOH323CallData;

/** 
 * @defgroup channels Channel Management
 * @{
 */
/**
 * This function is used to create a listener for incoming calls.
 * @param None
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCreateH323Listener(void);

/**
 * This function is used to create a listener for incoming H.245 connections.
 * @param call      Pointer to call for which H.245 listener has to be created
 * 
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCreateH245Listener(struct OOH323CallData *call);

/**
 * This function is used to accept incoming H.225 connections.
 * @param None
 * 
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooAcceptH225Connection(void);

/**
 * This function is used to accept an incoming H.245 connection.
 * @param call        Pointer to a call for which H.245 connection request has
 *                    arrived.
 * 
 * @return            OO_OK, on succes. OO_FAILED, on failure.
 */
EXTERN int ooAcceptH245Connection(struct OOH323CallData *call);

/**
 * This function is used to create an H.225 connection to the remote end point.
 * @param call       Pointer to the call for which H.225 connection has to be 
 *                   setup.
 * @return           OO_OK, on succes. OO_FAILED, on failure. 
 */
EXTERN int ooCreateH225Connection(struct OOH323CallData *call);

/**
 * This function is used to setup an H.245 connection with the remote endpoint
 * for control negotiations.
 * @param call      Pointer to call for which H.245 connection has to be setup.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCreateH245Connection(struct OOH323CallData *call);

/**
 * This function is used to close an H.225 connection
 * @param call       Pointer to the call for which H.225 connection has to be 
 *                   closed.
 * 
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCloseH225Connection(struct OOH323CallData *call);

/**
 * This function is used to close an H.245 connection for a call. 
 * @param call       Pointer to call for which H.245 connection has to be closed.
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCloseH245Connection(struct OOH323CallData *call);

/**
 * This function is used to start monitoring channels for the calls. It has
 * an infinite loop which uses select to monitor various channels.
 * @param None
 * 
 */
EXTERN int ooMonitorChannels(void);

/**
 * This function is called to stop the monitor channels thread.
 * It cleans up all the active calls, before stopping monitor thread.
 * @param None
 *
 * @return           OO_OK, on success. OO_FAILED, on failure
 */
EXTERN int ooStopMonitorCalls(void);

/**
 * This function is used to receive an H.2250 message received on a calls
 * H.225 channel. It receives the message, decodes it and calls 
 * 'ooHandleH2250Message' to process the message.
 * @param call       Pointer to the call for which the message has to be 
 *                   received.
 * 
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH2250Receive(struct OOH323CallData *call);

/**
 * This function is used to receive an H.245 message received on a calls
 * H.245 channel. It receives the message, decodes it and calls 
 * 'ooHandleH245Message' to process it.
 * @param call       Pointer to the call for which the message has to be 
 *                   received.
 * 
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH245Receive(struct OOH323CallData *call);

/**
 * This function is used to enqueue an H.225 message into an outgoing queue for
 * the call.
 * @param call      Pointer to call for which message has to be enqueued.
 * @param msg       Pointer to the H.225 message to be sent.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooSendH225Msg(struct OOH323CallData *call, Q931Message *msg);

/**
 * This function is used to enqueue an H.245 message into an outgoing queue for
 * the call.
 * @param call      Pointer to call for which message has to be enqueued.
 * @param msg       Pointer to the H.245 message to be sent.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooSendH245Msg(struct OOH323CallData *call, H245Message *msg);

/**
 * This function is used to Send a message on the channel, when channel is 
 * available for write.
 * @param call       Pointer to call for which message has to be sent.
 * @param type       Type of the message.
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooSendMsg(struct OOH323CallData *call, int type);

/**
 * This function is called after a message is sent on the call's channel.
 * It can be used to some followup action after message has been sent.
 * @param call            Pointer to call for which message has been sent.
 * @param msgType         Type of message
 * @param tunneledMsgType If this message is carrying a tunneled message, then
 *                        type of the tunneled message.
 * @param associatedChan  The channel number associated with the message sent,
 *                        or tunneled message. 0, if no channel is associated.
 *
 * @return                OO_OK, on success. OO_FAILED, on failure
 */
EXTERN int ooOnSendMsg
   (struct OOH323CallData *call, int msgType, int tunneledMsgType, 
    int associatedChan);



/** 
 * @} 
 */
#ifdef __cplusplus
}
#endif
#endif


--- NEW FILE: ooh245.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 "ooh245.h"
#include "ooCalls.h"
#include "printHandler.h"
[...2882 lines suppressed...]
   if(call->h245SessionState != OO_H245SESSION_IDLE && 
      call->h245SessionState != OO_H245SESSION_CLOSED)  
   {
      ret = ooCloseH245Connection(call);
   
      if(ret != OO_OK)
      {
         OOTRACEERR3("Error:Failed to close H.245 connection (%s, %s)\n",
                     call->callType, call->callToken);
      } 
   }

   ASN1MEMFREEPTR(call->pctxt, cbData);

   if(call->callState == OO_CALL_CLEAR_RELEASESENT)
      call->callState = OO_CALL_CLEARED;
   
   return OO_OK;
}


--- NEW FILE: ooh245.h ---
/*
 * 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.
 *
 *****************************************************************************/

/**
 * @file ooh245.h 
 * This file contains functions to support H245 negotiations. 
 */
#ifndef _OOH245HDR_H_
#define _OOH245HDR_H_

#include "ooasn1.h"
#include "ooCapability.h"
#include "oochannels.h"
#include "ootrace.h"

#include "ooq931.h"
#include "MULTIMEDIA-SYSTEM-CONTROL.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef EXTERN
#ifdef _WIN32
#define EXTERN __declspec(dllexport)
#else
#define EXTERN
#endif /* _WIN32 */
#endif /* EXTERN */

struct OOH323CallData;

/** 
 * @defgroup h245 H.245 Message Handling
 * @{
 */
/**
 * Creates an outgoing H245 message of the type specified by the type
 * argument for the Application context. 
 *
 * @param msg       A pointer to pointer to message which will be assigned to 
 *                  allocated memory.
 * @param type      Type of the message to be created.
 *                  (Request/Response/Command/Indication)
 *
 * @return          Completion status of operation: 0 (OO_OK) = success,
 *                  negative return value is error.         
 */
EXTERN int ooCreateH245Message(H245Message **msg, int type);

/**
 * Frees up the memory used by the H245 message.
 *
 * @param call      Handle to the call
 * @param pmsg      Pointer to an H245 message structure.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure         
 */
EXTERN int ooFreeH245Message(struct OOH323CallData *call, H245Message *pmsg);

/**
 * This function is used to retrieve an H.245 message enqueued in the outgoing 
 * queue. 
 * @param call      Pointer to the call for which message has to be retrieved.
 * @param msgbuf    Pointer to a buffer in which the message will be returned.
 * @param len       Pointer to an int variable which will contain length of
 *                  the message data after returning.
 * @param msgType   Pointer to an int variable, which will contain message type
 *                  on return from the function.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGetOutgoingH245Msgbuf(struct OOH323CallData *call, 
				   ASN1OCTET *msgbuf, 
                                   int *len, int *msgType);

/**
 * This function is used to send out a treminal capability set message. 
 * @param call      Pointer to a call, for which TerminalCapabilitySet message
 *                  has to be sent.
 * 
 * @return          OO_OK, on success. OO_FAILED, on failure.  
 */
EXTERN int ooSendTermCapMsg(struct OOH323CallData *call);

/**
 * This function is used to generate a random status determination number
 * for MSD procedure.
 * @param None
 *
 * @return          Generated status determination number.
 */
EXTERN ASN1UINT ooGenerateStatusDeterminationNumber();

/**
 * This fuction is used to handle received MasterSlaveDetermination procedure
 * messages. 
 * @param call       Pointer to the call for which a message is received.
 * @param pmsg       Pointer to MSD message
 * @param msgType    Message type indicating whether received message is MSD, 
 *                   MSDAck, MSDReject etc...
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooHandleMasterSlave
(struct OOH323CallData *call, void * pmsg, int msgType);

/**
 * This function is used to send MSD message.
 * @param call       Pointer to call for which MasterSlaveDetermination has to
 *                   be sent.
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooSendMasterSlaveDetermination(struct OOH323CallData *call);

/**
 * This function is used to send a MasterSlaveDeterminationAck message.
 * @param call        Pointer to call for which MasterSlaveDeterminationAck has
 *                    to be sent.
 * @param status      Result of the determination process(Master/Slave as it 
 *                    applies to remote endpoint)
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */ 
EXTERN int ooSendMasterSlaveDeterminationAck
(struct OOH323CallData* call, char * status);

/**
 * This function is used to send a MasterSlaveDeterminationReject message.
 * @param call        Pointer to call for which message is to be sent.
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */ 
EXTERN int ooSendMasterSlaveDeterminationReject (struct OOH323CallData* call);


/**
 * This function is used to handle MasterSlaveReject message. If number of
 * retries is less than max allowed, then it restarts the 
 * MasterSlaveDetermination procedure.
 * @param call        Handle to the call for which MasterSlaveReject is 
 *                    received.
 * @param reject      Poinetr to the received reject message.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure. 
 */
EXTERN int ooHandleMasterSlaveReject
   (struct OOH323CallData *call, H245MasterSlaveDeterminationReject* reject);

/**
 * This function is used to handle received OpenLogicalChannel message.
 * @param call        Pointer to call for which OpenLogicalChannel message is
 *                    received.
 * @param olc         Pointer to the received OpenLogicalChannel message.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooHandleOpenLogicalChannel
                   (struct OOH323CallData* call, H245OpenLogicalChannel *olc);

/**
 * This function is used to handle a received OpenLogicalChannel message which
 * is trying to open a audio channel.
 * @param call        Pointer to cll for which OLC was received.
 * @param olc         The received OpenLogicalChannel message.
 * 
 * @return            OO_OK, on success. OO_FAILED, on failure.         
 */
EXTERN int ooHandleOpenLogicalAudioChannel
(struct OOH323CallData *call, H245OpenLogicalChannel*olc);

/**
 * This function is used to build and send OpenLogicalChannelReject message.
 * @param call        Pointer to call for which OLCReject has to be sent.
 * @param channelNum  LogicalChannelNumber to be rejected.
 * @param cause       Cause of rejection.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
int ooSendOpenLogicalChannelReject
   (struct OOH323CallData *call, ASN1UINT channelNum, ASN1UINT cause);

/**
 * This function is used to handle a received OpenLogicalChannelAck message.
 * @param call         Pointer to call for which OLCAck is received
 * @param olcAck       Pointer to received olcAck message.
 *
 * @return             OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooOnReceivedOpenLogicalChannelAck(struct OOH323CallData *call, 
                                            H245OpenLogicalChannelAck *olcAck);


/**
 * This function is used to handle the received OpenLogicalChannelReject 
 * message.
 * @param call         Handle to the call for which the message is received.
 * @param olcRejected  Pointer to received OpenLogicalChannelReject message.
 *
 * @return             OO_OK, on success. OO_FAILED, on failure.
 */
int ooOnReceivedOpenLogicalChannelRejected(struct OOH323CallData *call, 
                                    H245OpenLogicalChannelReject *olcRejected);
/**
 * This message is used to send an EndSession command. It builds a EndSession 
 * command message and queues it into the calls outgoing queue.
 * @param call          Pointer to call for which EndSession command has to be
 *                      sent.
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooSendEndSessionCommand(struct OOH323CallData *call);

/**
 * This function is used to handle a received H245Command message. 
 * @param call          Pointer to call for which an H245Command is received.
 * @param command       Pointer to a command message.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure
 */
EXTERN int ooHandleH245Command
(struct OOH323CallData *call, H245CommandMessage *command);

/**
 * This function is called on receiving a TreminalCapabilitySetAck message.
 * If the MasterSlaveDetermination process is also over, this function 
 * initiates the process of opening logical channels.
 * @param call          Pointer to call for which TCSAck is received.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooOnReceivedTerminalCapabilitySetAck(struct OOH323CallData* call);

/**
 * This function is called to close all the open logical channels. It sends
 * CloseLogicalChannel message for all the forward channels and sends 
 * RequestCloseLogicalChannel message for all the reverse channels.
 * @param call          Pointer to call for which logical channels have to be 
 *                      closed.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooCloseAllLogicalChannels(struct OOH323CallData *call);


/**
 * This function is used to send out a CloseLogicalChannel message for a particular
 * logical channel.
 * @param call           Pointer to a call, to which logical channel to be closed belongs.
 * @param logicalChan    Pointer to the logical channel to be closed.
 *
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooSendCloseLogicalChannel
(struct OOH323CallData *call, ooLogicalChannel *logicalChan);

/**
 * This function is used to process a received closeLogicalChannel request. It closes the
 * logical channel and removes the logical channel entry from the list. It also, sends
 * closeLogicalChannelAck message to the remote endpoint.
 * @param call           Pointer to call for which CloseLogicalChannel message is received.
 * @param clc            Pointer to received CloseLogicalChannel message.
 * 
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooOnReceivedCloseLogicalChannel(struct OOH323CallData *call, 
                                           H245CloseLogicalChannel* clc);

/**
 * This function is used to process a received CloseLogicalChannelAck message. It closes the
 * channel and removes it from the list of active logical channels.
 * @param call           Pointer to call for which CLCAck message is received.
 * @param clcAck         Pointer to the received CloseLogicalChannelAck message.
 * 
 * @return               OO_OK, on success. OO_FAILED, on failure
 */
EXTERN int ooOnReceivedCloseChannelAck(struct OOH323CallData* call, 
                                           H245CloseLogicalChannelAck* clcAck);

/**
 * This function is used to handle received H245 message. Based on the type of message received,
 * it calls helper functions to process those messages.
 * @param call           Pointer to call for which a message is received.
 * @param pmsg           Pointer to the received H245 message.
 *
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooHandleH245Message
(struct OOH323CallData *call, H245Message * pmsg);

/**
 * This function is used to process received TCS message. It builds TCSAck message and queues it
 * into the calls outgoing queue. Also, starts Logical channel opening procedure if TCS and MSD
 * procedures have finished.
 * @param call           Pointer to call for which TCS is received.
 * @param pmsg           Pointer to the received message.
 *
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooOnReceivedTerminalCapabilitySet
(struct OOH323CallData *call, H245Message *pmsg);

/**
 * This function is used to send a TCSAck message to remote endpoint.
 * @param call           Pointer to call on which TCSAck has to be sent.
 *
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH245AcknowledgeTerminalCapabilitySet(struct OOH323CallData *call);

/**
 * This function is used to start OpenLogicalChannel procedure for all the
 * channels to be opened for the call.
 * @param call            Pointer to call for which logical channels have to be opened.
 *
 * @return                OO_OK, on success. OO_FAILED, on failure.
 */ 
EXTERN int ooOpenLogicalChannels(struct OOH323CallData *call);

/**
 * This function is used to send OpenLogicalChannel message for audio channel.
 * It uses the first capability match in the local and remote audio capabilities
 * for the audio channel and calls corresponding helper function.
 * @param call            Pointer to call for which audio channel ahs to be opened.
 *
 * @return                OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooOpenLogicalAudioChannel(struct OOH323CallData *call);

/**
 * This function is used to build aand send OpenLogicalChannel message using
 * audio capability passed as parameter.
 * @param call            Pointer to call for which OpenLogicalChannel message 
 *                        has to be built.
 * @param epCap           Pointer to audio capability
 * 
 * @return                OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooOpenAudioChannel
(struct OOH323CallData* call, ooH323EpCapability *epCap);

/**
 * This function is used to request a remote end point to close a logical
 * channel. 
 * @param call            Pointer to call for which the logical channel has to
 *                        be closed.
 * @param logicalChan     Pointer to the logical channel structure which needs
 *                        to be closed.
 *
 * @return                OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooSendRequestCloseLogicalChannel(struct OOH323CallData *call, 
                                            ooLogicalChannel *logicalChan);

/**
 * This function is used to send a RequestChannelCloseRelease message when the
 * corresponding timer has expired.
 * @param call            Handle to the call
 * @param channelNum      Channel number.
 *
 * @return                OO_OK, on success. OO_FAILED, otherwise.
 */
int ooSendRequestChannelCloseRelease
(struct OOH323CallData *call, int channelNum);

/**
 * This function handles the received RequestChannelClose message, verifies
 * that the requested channel is forward channel. It sends an acknowledgement
 * for the message followed by CloseLogicalChannel message.
 * @param call             Pointer to the call for which RequestChannelClose is
 *                         received.
 * @param rclc             Pointer to the received message.
 *
 * @return                 OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooOnReceivedRequestChannelClose(struct OOH323CallData *call, 
                                           H245RequestChannelClose *rclc);

/**
 * This function is used to handle a received RequestChannelCloseReject 
 * response message.
 * @param call             Handle to the call.
 * @param rccReject        Pointer to the received reject response message.
 *
 * @return                 OO_OK, on success. OO_FAILED, on failure.
 */
int ooOnReceivedRequestChannelCloseReject
   (struct OOH323CallData *call, H245RequestChannelCloseReject *rccReject);

/**
 * This function is used to handle a received RequestChannelCloseAck 
 * response message.
 * @param call             Handle to the call.
 * @param rccAck           Pointer to the received ack response message.
 *
 * @return                 OO_OK, on success. OO_FAILED, on failure.
 */
int ooOnReceivedRequestChannelCloseAck
   (struct OOH323CallData *call, H245RequestChannelCloseAck *rccAck);

/**
 * Builds an OLC with an audio capability passed as parameter.
 * @param call             Handle to call for which OLC has to be built.
 * @param olc              Pointer to an OLC structure which will be populated.
 * @param epCap            Pointer to the capability which will be used to 
 *                         build OLC.
 * @param pctxt            Pointer to an OOCTXT structure which will be used 
 *                         to allocate additional memory for OLC.
 * @param dir              Direction of OLC
 *
 * @return                 OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooBuildOpenLogicalChannelAudio(struct OOH323CallData *call, 
                                          H245OpenLogicalChannel *olc, 
                                          ooH323EpCapability *epCap, 
                                          OOCTXT*pctxt, int dir);

/**
 * This function is used to encode an H245 message and return encoded data
 * into the buffer passed as a parameter to the function.
 * @param call            Handle to the call
 * @param ph245Msg        Handle to the message to be encoded.
 * @param msgbuf          buffer in which encoded message will be returned.
 * @param size            Size of the buffer.
 *
 * @return                OO_OK, on success. OO_FAILED, on failure
 */
EXTERN int ooEncodeH245Message
(struct OOH323CallData *call, H245Message *ph245Msg, char *msgbuf, int size);

/**
 * This function is used to send a master-slave determination release message.
 * @param call             Handle to call, for which MSDRelease message has
 *                         to be sent.
 *
 * @return                 OO_OK, on success. OO_FAILED, on failure.
 */
int ooSendMasterSlaveDeterminationRelease(struct OOH323CallData * call);

/**
 * This function is used to send a terminal capability set reject message
 * to the remote endpoint.
 * @param call             Handle to the call for which reject message has to 
 *                         be sent.
 * @param seqNo            Sequence number of the TCS message to be rejected.
 * @param cause            Cause for rejecting a TCS message.
 *
 * @return                 OO_OK, on success; OO_FAILED, otherwise.
 */
int ooSendTerminalCapabilitySetReject
    (struct OOH323CallData *call, int seqNo, ASN1UINT cause);

/**
 * This function is used to send a TerminalCapabilitySetRelease message after
 * capability exchange timer has expired.
 * @param call            Handle to call for which release message has to be 
 *                        sent.
 *
 * @return                OO_OK, on success; OO_FAILED, on failure.
 */
int ooSendTerminalCapabilitySetRelease(struct OOH323CallData * call);

/**
 * This is a callback function for handling an expired master-slave 
 * determination timer.
 * @param data             Callback data registered at the time of creation of 
 *                         the timer.
 *
 * @return                 OO_OK, on success. OO_FAILED, otherwise.
 */
int ooMSDTimerExpired(void *data);

/**
 * This is a callback function for handling an expired capability exchange 
 * timer.
 * @param data             Callback data registered at the time of creation of 
 *                         the timer.
 *
 * @return                 OO_OK, on success. OO_FAILED, otherwise.
 */
int ooTCSTimerExpired(void *data);

/**
 * This is a callback function for handling an expired OpenLogicalChannel 
 * timer.
 * @param pdata            Callback data registered at the time of creation of 
 *                         the timer.
 *
 * @return                 OO_OK, on success. OO_FAILED, otherwise.
 */
int ooOpenLogicalChannelTimerExpired(void *pdata);

/**
 * This is a callback function for handling an expired CloseLogicalChannel 
 * timer.
 * @param pdata            Callback data registered at the time of creation of 
 *                         the timer.
 *
 * @return                 OO_OK, on success. OO_FAILED, otherwise.
 */
int ooCloseLogicalChannelTimerExpired(void *pdata);

/**
 * This is a callback function for handling an expired RequestChannelClose 
 * timer.
 * @param pdata            Callback data registered at the time of creation of 
 *                         the timer.
 *
 * @return                 OO_OK, on success. OO_FAILED, otherwise.
 */
int ooRequestChannelCloseTimerExpired(void *pdata);

/**
 * This is a callback function for handling an expired EndSession timer.
 * @param pdata            Callback data registered at the time of creation of 
 *                         the timer.
 *
 * @return                 OO_OK, on success. OO_FAILED, otherwise.
 */
int ooSessionTimerExpired(void *pdata);
/** 
 * @} 
 */
#ifdef __cplusplus
}
#endif

#endif

--- NEW FILE: ooh323.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 "ootypes.h"
#include "ooq931.h"
#include "ootrace.h"
[...1315 lines suppressed...]
                               pTransportAddrss->u.ipAddress->ip.data[3],
                               pTransportAddrss->u.ipAddress->port);
      break;
   case T_H225AliasAddress_email_ID:
      newAlias->type = T_H225AliasAddress_email_ID;
      newAlias->value = (char*)memAlloc(pctxt, 
                 strlen(pAliasAddress->u.email_ID)*sizeof(char)+1);

      strcpy(newAlias->value, pAliasAddress->u.email_ID);
      break;
   default:
      OOTRACEERR1("Error:Unhandled Alias type \n");
      memFreePtr(pctxt, newAlias);
      return NULL;

   }
   newAlias->next = *pAliasList;
   *pAliasList= newAlias;
   return newAlias;
}

--- NEW FILE: ooh323.h ---
/*
 * 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.
 *
 *****************************************************************************/

/**
 * @file ooh323.h 
 * This file contains functions to support H.225 messages. 
 */
#ifndef _OOH323HDR_H_
#define _OOH323HDR_H_

#include "ooasn1.h"
#include "ootypes.h"
#include "ootrace.h"
#include "ooq931.h"
#include "MULTIMEDIA-SYSTEM-CONTROL.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef EXTERN
#ifdef _WIN32
#define EXTERN __declspec(dllexport)
#else
#define EXTERN
#endif /* _WIN32 */
#endif /* EXTERN */

struct OOH323CallData;

/**
 * @addtogroup q931
 * @{
 */
/**
 * This function is used to process a received SETUP message.
 * @param call     Pointer to call for which SETUP message is received.
 * @param q931Msg  Pointer to the received SETUP message.
 *
 * @return         OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooOnReceivedSetup
(struct OOH323CallData *call, Q931Message *q931Msg);

/**
 * This function is used to process a received CONNECT message.
 * It creates H.245 negotiation channel, and starts TCS and MSD
 * procedures.
 * @param call      Pointer to call for which CONNECT message is received.
 * @param q931Msg   Pointer to the received q931Msg
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooOnReceivedSignalConnect
(struct OOH323CallData* call, Q931Message *q931Msg);

/**
 * This function is used to handle received H.2250 messages. It
 * calls helper functions based on the type of message received.
 * @param call       Pointer to the call for which a H.2250 message is received
 * @param q931Msg    Pointer to the received q931Msg
 *
 * @return           OO_OK, on success. OO_FAILED, on failure
 */
EXTERN int ooHandleH2250Message
(struct OOH323CallData *call, Q931Message *q931Msg);

/**
 * This function is used to process a received Facility message.
 * @param call       Handle to the call for which message has been received.
 * @param pQ931Msg   Pointer the the received Facility message.
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooOnReceivedFacility
(struct OOH323CallData *call, Q931Message * pQ931Msg);

/**
 * This function is used to process tunneled H245 messages
 * @param call       Handle to the call
 * @param pH323UUPdu Pointer to the pdu containing tunneled messages.
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooHandleTunneledH245Messages(struct OOH323CallData *call, 
                                        H225H323_UU_PDU * pH323UUPdu);

/**
 * This is a helper function used to handle an startH245 Facility message.
 * @param call       Handle to the call
 * @param facility   Pointer to the facility message.
 */
EXTERN int ooHandleStartH245FacilityMessage(struct OOH323CallData *call, 
                                            H225Facility_UUIE *facility);

/**
 * This function is used to retrieve the aliases from Sequence of alias
 * addresses.
 * @param call       Handle to the call.Null when retrieving registered
 *                   aliases.
 * @param pAddresses Pointer to the sequence of alias addresses.
 * @param aliasList  Handle to alias list to be populated with retrieved 
 *                   aliases.
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323RetrieveAliases
   (struct OOH323CallData *call, H225_SeqOfH225AliasAddress *pAddresses, 
    ooAliases **aliasList);

/**
 * This is a helper function used to populate alias list using aliases.
 * @param pctxt      Pointer to OOCTXT structure which will be used for memory
 *                   allocations.
 * @param pAliases   Pointer to aliases to be used for populating list.
 * @param pAliasList Pointer to alias list to be populated.
 *
 * @return           OO_OK, on success. OO_FAILED, otherwise. 
 */
EXTERN int ooPopulateAliasList(OOCTXT *pctxt, ooAliases *pAliases,
                               H225_SeqOfH225AliasAddress *pAliasList); 

/**
 * This function is used to search a particular alias in the alias list. The
 * search can be on the basis of alias type or value or both.
 * @param aliasList Handle to the alias list to be searched.
 * @param type      Type of the alias, if search has to consider type as 
 *                  criterion, otherwise 0.
 * @param value     Value of the alias, if the search has to consider value as
 *                  criterion, NULL otherwise.
 */
EXTERN ooAliases* ooH323GetAliasFromList
                               (ooAliases *aliasList, int type, char *value);

/**
 * This function is used to add a new alias to alias list.
 * @param pAliasList    Pointer to Alias list.
 * @param pctxt         Pointer to OOCTXT structure to be used for memory 
 *                      allocation.
 * @param pAliasAddress New alias address to be added.
 *
 * @return              Handle to newly added alias or NULL in case of failure.
 */
EXTERN ooAliases* ooH323AddAliasToList(ooAliases **pAliasList, OOCTXT *pctxt, 
                                H225AliasAddress *pAliasAddress);
/**
 * @}
 */
#ifdef __cplusplus
}
#endif

#endif


--- NEW FILE: ooh323ep.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 "ooh323ep.h"
#include "ootrace.h"
#include "ooCalls.h"
#include "ooCapability.h"
#include "ooGkClient.h"

/** Global endpoint structure */
ooEndPoint gH323ep;

/**
 * Mutex to protect ooGenerateCallReference function.
 * This is required as this function will be called by
 * multiple threads trying to place calls using stack commands
 */
OO_MUTEX gCallRefMutex;

/**
 * Mutex to protect access to global call token variables.
 * This is required as these variables will be used by
 * multiple threads trying to place calls using stack commands
 */
OO_MUTEX gCallTokenMutex;

/**
 * Mutex to protect access to stack commands list
 */
OO_MUTEX gCmdMutex;

extern DList g_TimerList;

int ooH323EpInitialize
   (int callMode, const char* tracefile)
{
   
   memset(&gH323ep, 0, sizeof(ooEndPoint));

   initContext(&(gH323ep.ctxt));
   initContext(&(gH323ep.msgctxt));

   if(tracefile)
   {
      if(strlen(tracefile)>= MAXFILENAME)
      {
         printf("Error:File name longer than allowed maximum %d\n", 
                 MAXFILENAME-1);
         return OO_FAILED;
      }
      strcpy(gH323ep.traceFile, tracefile);
   }else{
      strcpy(gH323ep.traceFile, DEFAULT_TRACEFILE);      
   }

   gH323ep.fptraceFile = fopen(gH323ep.traceFile, "w");
   if(gH323ep.fptraceFile == NULL)
   {
      printf("Error:Failed to open trace file %s for write.\n", 
                  gH323ep.traceFile);
      return OO_FAILED;
   }

   /* Initialize default port ranges that will be used by stack. 
      Apps can override these by explicitely setting port ranges
   */

   gH323ep.tcpPorts.start = TCPPORTSSTART;
   gH323ep.tcpPorts.max = TCPPORTSEND;
   gH323ep.tcpPorts.current=TCPPORTSSTART;

   gH323ep.udpPorts.start = UDPPORTSSTART;
   gH323ep.udpPorts.max = UDPPORTSEND;
   gH323ep.udpPorts.current = UDPPORTSSTART;

   gH323ep.rtpPorts.start = RTPPORTSSTART;
   gH323ep.rtpPorts.max = RTPPORTSEND;
   gH323ep.rtpPorts.current = RTPPORTSSTART;
   
   OO_SETFLAG(gH323ep.flags, OO_M_FASTSTART);
   OO_SETFLAG(gH323ep.flags, OO_M_TUNNELING);
   OO_SETFLAG(gH323ep.flags, OO_M_AUTOANSWER);
   OO_CLRFLAG(gH323ep.flags, OO_M_GKROUTED);
   
   gH323ep.aliases = NULL;

   gH323ep.termType = DEFAULT_TERMTYPE;

   gH323ep.t35CountryCode = DEFAULT_T35COUNTRYCODE;

   gH323ep.t35Extension = DEFAULT_T35EXTENSION;

   gH323ep.manufacturerCode = DEFAULT_MANUFACTURERCODE;

   gH323ep.productID = DEFAULT_PRODUCTID;

   gH323ep.versionID = OOH323C_VERSION;

   gH323ep.callType = T_H225CallType_pointToPoint;
   ooGetLocalIPAddress(gH323ep.signallingIP);
   gH323ep.listenPort = DEFAULT_H323PORT;

   gH323ep.listener = NULL;

   ooH323EpSetCallerID(DEFAULT_CALLERID);


   gH323ep.myCaps = NULL;
   gH323ep.noOfCaps = 0;
   gH323ep.callList = NULL;
   gH323ep.dtmfmode = 0;
   gH323ep.callingPartyNumber[0]='\0';     
   gH323ep.callMode = callMode;
#ifdef _WIN32
   InitializeCriticalSection(&gCmdMutex);
   InitializeCriticalSection(&gCallTokenMutex);
   InitializeCriticalSection(&gCallRefMutex);
#else
   pthread_mutex_init(&gCmdMutex, 0);
   pthread_mutex_init(&gCallTokenMutex, 0);
   pthread_mutex_init(&gCallRefMutex, 0);
#endif
   dListInit(&g_TimerList);/* This is for test application chansetup only*/

   gH323ep.callEstablishmentTimeout = DEFAULT_CALLESTB_TIMEOUT;

   gH323ep.msdTimeout = DEFAULT_MSD_TIMEOUT;

   gH323ep.tcsTimeout = DEFAULT_TCS_TIMEOUT;

   gH323ep.logicalChannelTimeout = DEFAULT_LOGICALCHAN_TIMEOUT;

   gH323ep.sessionTimeout = DEFAULT_ENDSESSION_TIMEOUT;
#ifdef HAVE_PIPE
   if(pipe(gH323ep.cmdPipe)<0){
      OOTRACEERR1("Error:Failed to create command pipe\n");
      return OO_FAILED;
   }
#endif
   ooSetTraceThreshold(OOTRCLVLINFO);
   OO_SETFLAG(gH323ep.flags, OO_M_ENDPOINTCREATED);
   return OO_OK;
}

int ooH323EpSetLocalAddress(char * localip, int listenport)
{
   if(localip)
   {
      memset(gH323ep.signallingIP, 0, sizeof(gH323ep.signallingIP));
      strcpy(gH323ep.signallingIP, localip);
      OOTRACEINFO2("Signalling IP address is set to %s\n", localip);
   }
   
   if(listenport)
   {
      gH323ep.listenPort = listenport;
      OOTRACEINFO2("Listen port number is set to %d\n", listenport);
   }
   return OO_OK;
}

int ooH323EpAddAliasH323ID(char *h323id)
{
   ooAliases * psNewAlias=NULL;
   psNewAlias = (ooAliases*)memAlloc(&gH323ep.ctxt, sizeof(ooAliases));
   if(!psNewAlias)
   {
      OOTRACEERR1("Error: Failed to allocate memory for new H323-ID alias\n");
      return OO_FAILED;
   }
   psNewAlias->type = T_H225AliasAddress_h323_ID;
   psNewAlias->registered = FALSE;
   psNewAlias->value = (char*) memAlloc(&gH323ep.ctxt, strlen(h323id)+1);
   if(!psNewAlias->value)
   {
      OOTRACEERR1("Error: Failed to allocate memory for the new H323-ID alias "
                  "value\n");
      memFreePtr(&gH323ep.ctxt, psNewAlias);
      return OO_FAILED;
   }
   strcpy(psNewAlias->value, h323id);
   psNewAlias->next = gH323ep.aliases;
   gH323ep.aliases = psNewAlias;
   OOTRACEDBGA2("Added alias: H323ID - %s\n", h323id);
   return OO_OK;
}

int ooH323EpAddAliasDialedDigits(char * dialedDigits)
{
   ooAliases * psNewAlias=NULL;
   psNewAlias = (ooAliases*)memAlloc(&gH323ep.ctxt, sizeof(ooAliases));
   if(!psNewAlias)
   {
      OOTRACEERR1("Error: Failed to allocate memory for new DialedDigits alias\n");
      return OO_FAILED;
   }
   psNewAlias->type = T_H225AliasAddress_dialedDigits;
   psNewAlias->registered = FALSE;
   psNewAlias->value = (char*) memAlloc(&gH323ep.ctxt, strlen(dialedDigits)+1);
   if(!psNewAlias->value)
   {
      OOTRACEERR1("Error: Failed to allocate memory for the new DialedDigits alias value\n");
      memFreePtr(&gH323ep.ctxt, psNewAlias);
      return OO_FAILED;
   }
   strcpy(psNewAlias->value, dialedDigits);
   psNewAlias->next = gH323ep.aliases;
   gH323ep.aliases = psNewAlias;
   OOTRACEDBGA2("Added alias: DialedDigits - %s\n", dialedDigits);
   return OO_OK;
}

int ooH323EpAddAliasURLID(char * url)
{
   ooAliases * psNewAlias=NULL;
   psNewAlias = (ooAliases*)memAlloc(&gH323ep.ctxt, sizeof(ooAliases));
   if(!psNewAlias)
   {
      OOTRACEERR1("Error: Failed to allocate memory for new URL-ID alias\n");
      return OO_FAILED;
   }
   psNewAlias->type = T_H225AliasAddress_url_ID;
   psNewAlias->registered = FALSE;
   psNewAlias->value = (char*) memAlloc(&gH323ep.ctxt, strlen(url)+1);
   if(!psNewAlias->value)
   {
      OOTRACEERR1("Error: Failed to allocate memory for the new URL-ID alias value\n");
      memFreePtr(&gH323ep.ctxt, psNewAlias);
      return OO_FAILED;
   }
   strcpy(psNewAlias->value, url);
   psNewAlias->next = gH323ep.aliases;
   gH323ep.aliases = psNewAlias;
   OOTRACEDBGA2("Added alias: URL-ID - %s\n", url);
   return OO_OK;
}

int ooH323EpAddAliasEmailID(char * email)
{
   ooAliases * psNewAlias=NULL;
   psNewAlias = (ooAliases*)memAlloc(&gH323ep.ctxt, sizeof(ooAliases));
   if(!psNewAlias)
   {
      OOTRACEERR1("Error: Failed to allocate memory for new Email-ID alias\n");
      return OO_FAILED;
   }
   psNewAlias->type = T_H225AliasAddress_email_ID;
   psNewAlias->registered = FALSE;
   psNewAlias->value = (char*) memAlloc(&gH323ep.ctxt, strlen(email)+1);
   if(!psNewAlias->value)
   {
      OOTRACEERR1("Error: Failed to allocate memory for the new Email-ID alias"
                  " value\n");
      memFreePtr(&gH323ep.ctxt, psNewAlias);
      return OO_FAILED;
   }
   strcpy(psNewAlias->value, email);
   psNewAlias->next = gH323ep.aliases;
   gH323ep.aliases = psNewAlias;
   OOTRACEDBGA2("Added alias: Email-ID - %s\n", email);
   return OO_OK;
}

int ooH323EpAddAliasTransportID(char * ipaddress)
{
   ooAliases * psNewAlias=NULL;
   psNewAlias = (ooAliases*)memAlloc(&gH323ep.ctxt, sizeof(ooAliases));
   if(!psNewAlias)
   {
      OOTRACEERR1("Error: Failed to allocate memory for new Transport-ID alias\n");
      return OO_FAILED;
   }
   psNewAlias->type = T_H225AliasAddress_transportID;
   psNewAlias->registered = FALSE;
   psNewAlias->value = (char*) memAlloc(&gH323ep.ctxt, strlen(ipaddress)+1);
   if(!psNewAlias->value)
   {
      OOTRACEERR1("Error: Failed to allocate memory for the new Transport-ID "
                  "alias value\n");
      memFreePtr(&gH323ep.ctxt, psNewAlias);
      return OO_FAILED;
   }
   strcpy(psNewAlias->value, ipaddress);
   psNewAlias->next = gH323ep.aliases;
   gH323ep.aliases = psNewAlias;
   OOTRACEDBGA2("Added alias: Transport-ID - %s\n", ipaddress);
   return OO_OK;
}

int ooH323EpClearAllAliases(void)
{
   if(gH323ep.aliases)
   {
      memFreePtr(&gH323ep.ctxt, gH323ep.aliases);
      gH323ep.aliases = NULL;
   }
   return OO_OK;
}


int ooH323EpSetH225MsgCallbacks(OOH225MsgCallbacks h225Callbacks)
{
   gH323ep.h225Callbacks.onReceivedSetup = h225Callbacks.onReceivedSetup;
   gH323ep.h225Callbacks.onReceivedConnect = h225Callbacks.onReceivedConnect;
   gH323ep.h225Callbacks.onBuiltSetup = h225Callbacks.onBuiltSetup;
   gH323ep.h225Callbacks.onBuiltConnect = h225Callbacks.onBuiltConnect;

   return OO_OK;
}
    
int ooH323EpSetH323Callbacks(OOH323CALLBACKS h323Callbacks)
{
   gH323ep.h323Callbacks.onNewCallCreated = h323Callbacks.onNewCallCreated;
   gH323ep.h323Callbacks.onAlerting = h323Callbacks.onAlerting;
   gH323ep.h323Callbacks.onIncomingCall = h323Callbacks.onIncomingCall;
   gH323ep.h323Callbacks.onOutgoingCall = h323Callbacks.onOutgoingCall;
   gH323ep.h323Callbacks.onCallAnswered = h323Callbacks.onCallAnswered;
   gH323ep.h323Callbacks.onCallEstablished = h323Callbacks.onCallEstablished;
   gH323ep.h323Callbacks.onCallForwarded = h323Callbacks.onCallForwarded;
   gH323ep.h323Callbacks.onOutgoingCallAdmitted = h323Callbacks.onOutgoingCallAdmitted;
   gH323ep.h323Callbacks.onCallCleared = h323Callbacks.onCallCleared;
   gH323ep.h323Callbacks.openLogicalChannels = h323Callbacks.openLogicalChannels;
   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));

#ifdef _WIN32
      DeleteCriticalSection(&gCmdMutex);
      DeleteCriticalSection(&gCallTokenMutex);
      DeleteCriticalSection(&gCallRefMutex);
#endif
      OO_CLRFLAG(gH323ep.flags, OO_M_ENDPOINTCREATED);
   }
   return OO_OK;
}

int ooH323EpEnableGkRouted(void)
{
   OO_SETFLAG(gH323ep.flags, OO_M_GKROUTED);
   return OO_OK;
}

int ooH323EpDisableGkRouted(void)
{
   OO_CLRFLAG(gH323ep.flags, OO_M_GKROUTED);
   return OO_OK;
}

int ooH323EpEnableAutoAnswer(void)
{
   OO_SETFLAG(gH323ep.flags, OO_M_AUTOANSWER);
   return OO_OK;
}

int ooH323EpDisableAutoAnswer(void)
{
   OO_CLRFLAG(gH323ep.flags, OO_M_AUTOANSWER);
   return OO_OK;
}

int ooH323EpEnableFastStart(void)
{
   OO_SETFLAG(gH323ep.flags, OO_M_FASTSTART);
   return OO_OK;
}

int ooH323EpDisableFastStart(void)
{
   OO_CLRFLAG(gH323ep.flags, OO_M_FASTSTART);
   return OO_OK;
}

int ooH323EpEnableH245Tunneling(void)
{
   OO_SETFLAG(gH323ep.flags, OO_M_TUNNELING);
   return OO_OK;
}
 
int ooH323EpDisableH245Tunneling(void)
{
   OO_CLRFLAG(gH323ep.flags, OO_M_TUNNELING);
   return OO_OK;
}

int ooH323EpSetTermType(int value)
{
   gH323ep.termType = value;
   return OO_OK;
}

int ooH323EpSetProductID (const char* productID)
{
   if (0 != productID) {
      char* pstr = (char*) memAlloc (&gH323ep.ctxt, strlen(productID)+1);
      strcpy (pstr, productID);
      if(gH323ep.productID)
         memFreePtr(&gH323ep.ctxt, gH323ep.productID);
      gH323ep.productID = pstr;
      return OO_OK;
   }
   else return OO_FAILED;
}

int ooH323EpSetVersionID (const char* versionID)
{
   if (0 != versionID) {
      char* pstr = (char*) memAlloc (&gH323ep.ctxt, strlen(versionID)+1);
      strcpy (pstr, versionID);
      if(gH323ep.versionID)
         memFreePtr(&gH323ep.ctxt, gH323ep.versionID);
      gH323ep.versionID = pstr;
      return OO_OK;
   }
   else return OO_FAILED;
}

int ooH323EpSetCallerID (const char* callerID)
{
   if (0 != callerID) {
      char* pstr = (char*) memAlloc (&gH323ep.ctxt, strlen(callerID)+1);
      strcpy (pstr, callerID);
      if(gH323ep.callerid)
         memFreePtr(&gH323ep.ctxt, gH323ep.callerid);
      gH323ep.callerid = pstr;
      return OO_OK;
   }
   else return OO_FAILED;
}

int ooH323EpSetCallingPartyNumber(const char* number)
{
   int ret=OO_OK;
   if(number)
   {
      strncpy(gH323ep.callingPartyNumber, number, 
                                        sizeof(gH323ep.callingPartyNumber)-1);
      ret = ooH323EpAddAliasDialedDigits((char*)number);
      return ret;
   }
   else return OO_FAILED;
}

int ooH323EpSetTraceLevel(int traceLevel)
{
   ooSetTraceThreshold(traceLevel);
   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_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;   
}


int ooH323EpAddG711Capability(int cap, int txframes, int rxframes, int dir,
                              cb_StartReceiveChannel startReceiveChannel,
                              cb_StartTransmitChannel startTransmitChannel,
                              cb_StopReceiveChannel stopReceiveChannel,
                              cb_StopTransmitChannel stopTransmitChannel)
{
   return ooCapabilityAddSimpleCapability(NULL, cap, txframes, rxframes, FALSE,
                            dir, startReceiveChannel, startTransmitChannel, 
                            stopReceiveChannel, stopTransmitChannel, FALSE);
}

int ooH323EpAddG729Capability(int cap, int txframes, int rxframes, int dir,
                              cb_StartReceiveChannel startReceiveChannel,
                              cb_StartTransmitChannel startTransmitChannel,
                              cb_StopReceiveChannel stopReceiveChannel,
                              cb_StopTransmitChannel stopTransmitChannel)
{
   return ooCapabilityAddSimpleCapability(NULL, cap, txframes, rxframes, FALSE,
                               dir, startReceiveChannel, startTransmitChannel, 
                               stopReceiveChannel, stopTransmitChannel, FALSE);
}


int ooH323EpAddG7231Capability(int cap, int txframes, int rxframes, 
                              OOBOOL silenceSuppression, int dir,
                              cb_StartReceiveChannel startReceiveChannel,
                              cb_StartTransmitChannel startTransmitChannel,
                              cb_StopReceiveChannel stopReceiveChannel,
                              cb_StopTransmitChannel stopTransmitChannel)
{
   return ooCapabilityAddSimpleCapability(NULL, cap, txframes, rxframes, 
                             silenceSuppression, dir, startReceiveChannel, 
                             startTransmitChannel, stopReceiveChannel, 
                             stopTransmitChannel, FALSE);
}

int ooH323EpAddGSMCapability(int cap, ASN1USINT framesPerPkt, 
                             OOBOOL comfortNoise, OOBOOL scrambled, int dir,
                             cb_StartReceiveChannel startReceiveChannel,
                             cb_StartTransmitChannel startTransmitChannel,
                             cb_StopReceiveChannel stopReceiveChannel,
                             cb_StopTransmitChannel stopTransmitChannel)
{
   return ooCapabilityAddGSMCapability(NULL, cap, framesPerPkt, comfortNoise, 
                                     scrambled, dir, startReceiveChannel, 
                                     startTransmitChannel, stopReceiveChannel,
                                     stopTransmitChannel, FALSE);
}

int ooH323EpEnableDTMFRFC2833(int dynamicRTPPayloadType)
{
   return ooCapabilityEnableDTMFRFC2833(NULL, dynamicRTPPayloadType);
}

int ooH323EpDisableDTMFRFC2833(void)
{
   return ooCapabilityDisableDTMFRFC2833(NULL);
}

int ooH323EpSetGkClientCallbacks(OOGKCLIENTCALLBACKS gkClientCallbacks)
{

   if(gH323ep.gkClient)
   {
      return ooGkClientSetCallbacks(gH323ep.gkClient, gkClientCallbacks);
   }else{
      OOTRACEERR1("Error:Gk Client hasn't been initialized yet\n");
      return OO_FAILED;
   }

}

--- NEW FILE: ooh323ep.h ---
/*
 * 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.
 *
 *****************************************************************************/
/**
 * @file ooh323ep.h 
 * This file contains H323 endpoint related functions. 
 */
#ifndef OO_H323EP_H_
#define OO_H323EP_H_
#include "ooCapability.h"
#include "ooCalls.h"
#include "ooGkClient.h"

#define DEFAULT_TRACEFILE "trace.log"
#define DEFAULT_TERMTYPE 50
#define DEFAULT_PRODUCTID  "objsys"
#define DEFAULT_CALLERID   "objsyscall"
#define DEFAULT_T35COUNTRYCODE 1
#define DEFAULT_T35EXTENSION 0
#define DEFAULT_MANUFACTURERCODE 71
#define DEFAULT_CALLESTB_TIMEOUT 60
#define DEFAULT_MSD_TIMEOUT 30
#define DEFAULT_TCS_TIMEOUT 30
#define DEFAULT_LOGICALCHAN_TIMEOUT 30
#define DEFAULT_ENDSESSION_TIMEOUT 15
#define DEFAULT_H323PORT 1720

#ifdef __cplusplus
extern "C" {
#endif

#ifndef EXTERN
#ifdef _WIN32
#define EXTERN __declspec(dllexport)
#else
#define EXTERN
#endif /* _WIN32 */
#endif /* EXTERN */

/** 
 * @defgroup h323ep  H323 Endpoint management functions
 * @{
 */
/** 
 * Structure to store all configuration information related to the
 * endpoint created by an application 
 */
typedef struct OOH323EndPoint {
   /** 
    * This context should be used for allocation of memory for
    * items within the endpoint structure.
    */
   OOCTXT ctxt;

   /** 
    * This context should be used for allocation of memory for
    * message structures.
    */
   OOCTXT msgctxt;

   char   traceFile[MAXFILENAME];
   FILE * fptraceFile;

   /** Range of port numbers to be used for TCP connections */
   struct ooH323Ports tcpPorts;

   /** Range of port numbers to be used for UDP connections */
   struct ooH323Ports udpPorts;

   /** Range of port numbers to be used for RTP connections */
   struct ooH323Ports rtpPorts;
  
   ASN1UINT  flags;

   int termType; /* 50 - Terminal entity with No MC, 
                    60 - Gateway entity with no MC, 
                    70 - Terminal Entity with MC, but no MP etc.*/
   int t35CountryCode;
   int t35Extension;
   int manufacturerCode;
   const char *productID;
   const char *versionID;
   const char *callerid;
   char callingPartyNumber[50];
   OOSOCKET *stackSocket;
   ooAliases *aliases;

   int callType;

   struct ooH323EpCapability *myCaps;
   ooCapPrefs     capPrefs;
   int noOfCaps;
   OOH225MsgCallbacks h225Callbacks;
   OOH323CALLBACKS h323Callbacks;
   char signallingIP[20];
   int listenPort;
   OOSOCKET *listener;
   OOH323CallData *callList;

   OOCallMode callMode; /* audio/audiorx/audiotx/video/fax */
   int dtmfmode;
   ASN1UINT callEstablishmentTimeout;
   ASN1UINT msdTimeout;
   ASN1UINT tcsTimeout;
   ASN1UINT logicalChannelTimeout;
   ASN1UINT sessionTimeout;
   int cmdPipe[2];
   struct ooGkClient *gkClient;
   DList stkCmdList;	/* stack command list */
} OOH323EndPoint;

#define ooEndPoint OOH323EndPoint

/**
 * This function is the first function to be invoked before using stack. It
 * initializes the H323 Endpoint.
 * @param callMode       Type of calls to be made(audio/video/fax).
 *                       (OO_CALLMODE_AUDIO, OO_CALLMODE_VIDEO)
 * @param tracefile      Trace file name.
 *
 * @return               OO_OK, on success. OO_FAILED, on failure
 */
EXTERN int ooH323EpInitialize
   (int callMode, const char* tracefile);


/**
 * This function is used to assign a local ip address to be used for call
 * signalling.
 * @param localip        Dotted IP address to be used for call signalling.
 * @param listenport     Port to be used for listening for incoming calls.
 *
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */ 
EXTERN int ooH323EpSetLocalAddress(char * localip, int listenport);

/**
 * This function is used to set the trace level for the H.323 endpoint.
 * @param traceLevel     Level of tracing.
 *
 * @return               OO_OK, on success. OO_FAILED, otherwise.
 */
EXTERN int ooH323EpSetTraceLevel(int traceLevel);

/**
 * This function is used to add the h323id alias for the endpoint.
 * @param h323id         H323-ID to be set as alias.
 *
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpAddAliasH323ID(char * h323id);

/**
 * This function is used to add the dialed digits alias for the
 * endpoint.
 * @param dialedDigits   Dialed-Digits to be set as alias.
 *
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpAddAliasDialedDigits(char * dialedDigits);

/**
 * This function is used to add the url alias for the endpoint.
 * @param url            URL to be set as an alias.
 *
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpAddAliasURLID(char * url);

/**
 * This function is used to add an email id as an alias for the endpoint.
 * @param email          Email id to be set as an alias.
 * 
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpAddAliasEmailID(char * email);

/**
 * This function is used to add an ip address as an alias.
 * @param ipaddress      IP address to be set as an alias.
 *
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpAddAliasTransportID(char * ipaddress);

/**
 * This function is used to clear all the aliases used by the 
 * H323 endpoint.
 *
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpClearAllAliases(void);

/**
 * This function is used to set the H225 message callbacks for the
 * endpoint.
 * @param h225Callbacks  Callback structure containing various callbacks.
 *
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpSetH225MsgCallbacks(OOH225MsgCallbacks h225Callbacks);

/**
 * This function is used to set high level H323 call backs for the endpoint.
 * Make sure all unused callbacks in the structure are set to NULL before 
 * calling this function.
 * @param h323Callbacks    Callback structure containing various high level 
 *                         callbacks.
 * @return                 OO_OK, on success. OO_FAILED, on failure
 */
EXTERN int ooH323EpSetH323Callbacks(OOH323CALLBACKS h323Callbacks);


/**
 * This function is the last function to be invoked after done using the 
 * stack. It closes the H323 Endpoint for an application, releasing all 
 * the associated memory.
 *
 * @param None
 *
 * @return          OO_OK on success
 *                  OO_FAILED on failure
 */
EXTERN int ooH323EpDestroy(void);


/**
 * This function is used to enable the auto answer feature for
 * incoming calls
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpEnableAutoAnswer(void);

/**
 * This function is used to disable the auto answer feature for
 * incoming calls.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpDisableAutoAnswer(void);

/**
 * This function is used to enable faststart.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpEnableFastStart(void);

/**
 * This function is used to disable faststart.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpDisableFastStart(void);

/**
 * This function is used to enable tunneling.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpEnableH245Tunneling(void);

/**
 * This function is used to disable tunneling.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpDisableH245Tunneling(void);

/**
 * This function is used to enable GkRouted calls.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpEnableGkRouted(void);

/**
 * This function is used to disable Gkrouted calls.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpDisableGkRouted(void);

/**
 * This function is used to set the product ID.
 * @param productID  New value for the product id.
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */ 
EXTERN int ooH323EpSetProductID (const char * productID);

/**
 * This function is used to set version id.
 * @param versionID  New value for the version id.
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpSetVersionID (const char * versionID);

/**
 * This function is used to set callerid to be used for outbound
 * calls.
 * @param callerID  New value for the caller id.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpSetCallerID (const char * callerID);

/**
 * This function is used to set calling party number to be used for outbound
 * calls.Note, you can override it for a specific call by using 
 * ooCallSetCallingPartyNumber function.
 * @param number   e164 number to be used as calling party number.
 *
 * @return         OO_OK, on success; OO_FAILED, otherwise.
 */
EXTERN int ooH323EpSetCallingPartyNumber(const char * number);

/**
 * This function is used to print the current configuration information of 
 * the H323 endpoint to log file.
 */
void ooH323EpPrintConfig(void);



/**
 * This function is used to add G729 capability to the H323 endpoint.
 * @param cap                  Type of G729 capability to be added.
 * @param txframes             Number of frames per packet for transmission. 
 * @param rxframes             Number of frames per packet for reception.
 * @param dir                  Direction of capability.OORX, OOTX, OORXANDTX
 * @param startReceiveChannel  Callback function to start receive channel.
 * @param startTransmitChannel Callback function to start transmit channel.
 * @param stopReceiveChannel   Callback function to stop receive channel.
 * @param stopTransmitChannel  Callback function to stop transmit channel.
 *
 * @return                     OO_OK, on success. OO_FAILED, on failure. 
 */
EXTERN int ooH323EpAddG729Capability
   (int cap, int txframes, int rxframes, int dir, 
    cb_StartReceiveChannel startReceiveChannel,
    cb_StartTransmitChannel startTransmitChannel,
    cb_StopReceiveChannel stopReceiveChannel,
    cb_StopTransmitChannel stopTransmitChannel);


/**
 * This function is used to add G7231 capability to the H323 endpoint.
 * @param cap                  Type of G7231 capability to be added.
 * @param txframes             Number of frames per packet for transmission. 
 * @param rxframes             Number of frames per packet for reception.
 * @param silenceSuppression   Silence Suppression support
 * @param dir                  Direction of capability.OORX, OOTX, OORXANDTX
 * @param startReceiveChannel  Callback function to start receive channel.
 * @param startTransmitChannel Callback function to start transmit channel.
 * @param stopReceiveChannel   Callback function to stop receive channel.
 * @param stopTransmitChannel  Callback function to stop transmit channel.
 *
 * @return                     OO_OK, on success. OO_FAILED, on failure. 
 */
EXTERN int ooH323EpAddG7231Capability(int cap, int txframes, int rxframes, 
                              OOBOOL silenceSuppression, int dir,
                              cb_StartReceiveChannel startReceiveChannel,
                              cb_StartTransmitChannel startTransmitChannel,
                              cb_StopReceiveChannel stopReceiveChannel,
			       cb_StopTransmitChannel stopTransmitChannel);

/**
 * This function is used to add G711 capability to the H323 endpoint.
 * @param cap                  Type of G711 capability to be added.
 * @param txframes             Number of frames per packet for transmission. 
 * @param rxframes             Number of frames per packet for reception.
 * @param dir                  Direction of capability.OORX, OOTX, OORXANDTX
 * @param startReceiveChannel  Callback function to start receive channel.
 * @param startTransmitChannel Callback function to start transmit channel.
 * @param stopReceiveChannel   Callback function to stop receive channel.
 * @param stopTransmitChannel  Callback function to stop transmit channel.
 *
 * @return                     OO_OK, on success. OO_FAILED, on failure. 
 */
EXTERN int ooH323EpAddG711Capability
   (int cap, int txframes, int rxframes, int dir, 
    cb_StartReceiveChannel startReceiveChannel,
    cb_StartTransmitChannel startTransmitChannel,
    cb_StopReceiveChannel stopReceiveChannel,
    cb_StopTransmitChannel stopTransmitChannel);


/**
 * This function is used to add a new GSM capability to the endpoint.
 * @param cap                  Type of GSM capability to be added.
 * @param framesPerPkt         Number of GSM frames pre packet. 
 * @param comfortNoise         Comfort noise spec for the capability. 
 * @param scrambled            Scrambled enabled/disabled for the capability.
 * @param dir                  Direction of capability.OORX, OOTX, OORXANDTX
 * @param startReceiveChannel  Callback function to start receive channel.
 * @param startTransmitChannel Callback function to start transmit channel.
 * @param stopReceiveChannel   Callback function to stop receive channel.
 * @param stopTransmitChannel  Callback function to stop transmit channel.
 *
 * @return                     OO_OK, on success. OO_FAILED, on failure. 
 */
EXTERN int ooH323EpAddGSMCapability(int cap, ASN1USINT framesPerPkt, 
                             OOBOOL comfortNoise,OOBOOL scrambled,int dir, 
                             cb_StartReceiveChannel startReceiveChannel,
                             cb_StartTransmitChannel startTransmitChannel,
                             cb_StopReceiveChannel stopReceiveChannel,
                             cb_StopTransmitChannel stopTransmitChannel);

/**
 * This function is used to enable rfc 2833 support for the endpoint.
 * @param dynamicRTPPayloadType   Payload type value to use.
 *
 * @return                        OO_OK, on success; OO_FAILED, on failure
 */
EXTERN int ooH323EpEnableDTMFRFC2833(int dynamicRTPPayloadType);

/**
 * This function is used to disable rfc 2833 support for the endpoint.
 *
 * @return                        OO_OK, on success; OO_FAILED, on failure
 */
EXTERN int ooH323EpDisableDTMFRFC2833(void);

/**
 * This function is used to add callbacks to the gatekeeper client. If user
 * application wants to do some special processing of various gatekeeper client
 * events, that can be done through these callbacks.
 * @param gkClientCallbacks      Handle to the callback structure.Make sure all
 *                               the members of the structure are appropriately
 *                               initialized.
 *
 * @retun                        OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323EpSetGkClientCallbacks(OOGKCLIENTCALLBACKS gkClientCallbacks);

/**
 * @}
 */
#ifdef __cplusplus
}
#endif

#endif

--- NEW FILE: oohdr.h ---
/*
 * Copyright (C) 1997-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.
 *
 *****************************************************************************/

--- NEW FILE: ooper.h ---
/*
 * Copyright (C) 1997-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.
 *
 *****************************************************************************/

#ifndef _OOPER_H_
#define _OOPER_H_


#endif


--- NEW FILE: ooports.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 "ooports.h"
#include "ooh323ep.h"
#include "ootrace.h"

/** Global endpoint structure */
extern OOH323EndPoint gH323ep;

int ooSetTCPPorts( int start, int max)
{
   if(start < 1024)
      gH323ep.tcpPorts.start = 1024;
   else
      gH323ep.tcpPorts.start = start;
   if(max > 65500)
      gH323ep.tcpPorts.max = 65500;
   else 
      gH323ep.tcpPorts.max = max;

   if(gH323ep.tcpPorts.max<gH323ep.tcpPorts.start)
   {
      OOTRACEERR1("Error: Failed to set tcp ports- "
                  "Max port number less than Start port number\n");
      return OO_FAILED;
   }
   gH323ep.tcpPorts.current = start;
        
   OOTRACEINFO1("TCP port range initialize - successful\n");
   return OO_OK;
}

/* Sets the range of ports that can be potentially used for UDP
   transport
*/
int ooSetUDPPorts(int start, int max)
{
   if(start < 1024)
      gH323ep.udpPorts.start = 1024;
   else
      gH323ep.udpPorts.start = start;
   if(max > 65500)
      gH323ep.udpPorts.max = 65500;
   else 
      gH323ep.udpPorts.max = max;
        
   if(gH323ep.udpPorts.max<gH323ep.udpPorts.start)
   {
      OOTRACEERR1("Error: Failed to set udp ports- Max port number"
                  " less than Start port number\n");
      return OO_FAILED;
   }
        
   gH323ep.udpPorts.current = start;
        
   OOTRACEINFO1("UDP port range initialize - successful\n");

   return OO_OK;
}

/* Sets the range of ports that can be potentially used for RTP
   RTCP transport
*/
int ooSetRTPPorts(int start, int max)
{
   if(start < 1024)
      gH323ep.rtpPorts.start = 1024;
   else
      gH323ep.rtpPorts.start = start;
   if(max > 65500)
      gH323ep.rtpPorts.max = 65500;
   else 
      gH323ep.rtpPorts.max = max;
        
   if(gH323ep.rtpPorts.max<gH323ep.rtpPorts.start)
   {
      OOTRACEERR1("Error: Failed to set rtp ports- Max port number"
                  " less than Start port number\n");
      return OO_FAILED;
   }
        
   gH323ep.rtpPorts.current = start;
   OOTRACEINFO1("RTP port range initialize - successful\n");
   return OO_OK;
}

/* Get the next port of type TCP/UDP/RTP */
int ooGetNextPort (OOH323PortType type)
{
   if(type==OOTCP)
   {
      if(gH323ep.tcpPorts.current <= gH323ep.tcpPorts.max)
         return gH323ep.tcpPorts.current++;
      else
      {
         gH323ep.tcpPorts.current = gH323ep.tcpPorts.start;
         return gH323ep.tcpPorts.current++;
      }
   }
   if(type==OOUDP)
   {
      if(gH323ep.udpPorts.current <= gH323ep.udpPorts.max)
         return gH323ep.udpPorts.current++;
      else
      {
         gH323ep.udpPorts.current = gH323ep.udpPorts.start;
         return gH323ep.udpPorts.current++;
      }
   }
   if(type==OORTP)
   {
      if(gH323ep.rtpPorts.current <= gH323ep.rtpPorts.max)
         return gH323ep.rtpPorts.current++;
      else
      {
         gH323ep.rtpPorts.current = gH323ep.rtpPorts.start;
         return gH323ep.rtpPorts.current++;
      }
   }
   return OO_FAILED;
}

int ooBindPort (OOH323PortType type, OOSOCKET socket)
{
   int initialPort, bindPort, ret;
   OOIPADDR ipAddrs;

   initialPort = ooGetNextPort (type);
   bindPort = initialPort;

   ret= ooSocketStrToAddr (gH323ep.signallingIP, &ipAddrs);

   while(1)
   {
      if((ret=ooSocketBind(socket, ipAddrs, bindPort))==0)
      {
	 return bindPort;
      }
      else
      {
         bindPort = ooGetNextPort (type);
         if (bindPort == initialPort) return OO_FAILED;
      }
   }
}

#ifdef _WIN32        
int ooBindOSAllocatedPort(OOSOCKET socket)
{
   OOIPADDR ipAddrs;
/*   char localip[40];*/
   int size, ret;
   struct sockaddr_in name;
   size = sizeof(struct sockaddr_in);
   /*ooGetLocalIPAddress(localip);
   ret= ooSocketStrToAddr (localip, &ipAddrs);*/
   ret= ooSocketStrToAddr (gH323ep.signallingIP, &ipAddrs);
   if((ret=ooSocketBind(socket, ipAddrs, 
                     0))==ASN_OK)
   {
      ret = ooGetSockName(socket, &name, &size);
      if(ret == ASN_OK)
      {
         return name.sin_port;
         
      }
   }

   return OO_FAILED;
}
#endif

--- NEW FILE: ooports.h ---
/*
 * 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.
 *
 *****************************************************************************/

/**
 * @file ooports.h 
 * This file contains functions to manage ports used by the stack. 
 */

#ifndef _OOPORTS_H_
#define _OOPORTS_H_

#include "ootypes.h"

typedef enum OOH323PortType {
   OOTCP, OOUDP, OORTP
} OOH323PortType;


#ifdef __cplusplus
extern "C" {
#endif

#ifndef EXTERN
#ifdef _WIN32
#define EXTERN __declspec(dllexport)
#else
#define EXTERN
#endif /* _WIN32 */
#endif /* EXTERN */

/**
 * Sets the range of ports that can be potentially used for TCP 
 * connections.
 *
 * @param start     Starting port number for the range.
 * @param max       Ending port number for the range
 *
 * @return          Completion status of operation: 0 (OO_OK) = success,
 *                  negative return value is error.
 */
EXTERN int ooSetTCPPorts(int start, int max);

/**
 *  Sets the range of ports that can be potentially used for UDP
 *  transport
 *
 * @param start     Starting port number for the range.
 * @param max       Ending port number for the range
 *
 * @return          Completion status of operation: 0 (OO_OK) = success,
 *                  negative return value is error.
 */

EXTERN int ooSetUDPPorts(int start, int max);

/**
 * Sets the range of ports that can be potentially used for RTP
 * RTCP transport.
 *
 * @param start     Starting port number for the range.
 * @param max       Ending port number for the range
 *
 * @return           Completion status of operation: 0 (OO_OK) = success,
 *                   negative return value is error.
 */

EXTERN int ooSetRTPPorts(int start, int max);

/**
 * Get the next port of type TCP/UDP/RTP from the corresponding range.
 * When max value for the range is reached, it starts again from the 
 * first port number of the range.
 *
 * @param ep         Reference to the H323 Endpoint structure.
 * @param type       Type of the port to be retrieved(OOTCP/OOUDP/OORTP).
 *
 * @return           The next port number for the specified type is returned.
 */
EXTERN int ooGetNextPort (OOH323PortType type);

/**
 * Bind socket to a port within the port range specified by the
 * application at the startup.
 *
 * @param ep        Reference to H323 Endpoint structure.
 * @param type      Type of the port required for the socket.
 * @param socket    The socket to be bound.
 *
 * @return          In case of success returns the port number to which
 *                  socket is bound and in case of failure just returns
 *                  a negative value.
*/
EXTERN int ooBindPort (OOH323PortType type, OOSOCKET socket);

/**
 * This function is supported for windows version only. 
 *  Windows sockets have problem in reusing the addresses even after
 *  setting SO_REUSEADDR, hence in windows we just allow os to bind
 *  to any random port.
*/

#ifdef _WIN32        
EXTERN int ooBindOSAllocatedPort(OOSOCKET socket);
#endif

#ifdef __cplusplus
}
#endif

#endif

--- NEW FILE: ooq931.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 "ooq931.h"
#include "ootrace.h"
#include "ooasn1.h"
[...2967 lines suppressed...]
   if(!psNewAlias)
   {
      OOTRACEERR1("Error:Memory - ooParseDestination - psNewAlias\n");
      return OO_FAILED;
   }
   psNewAlias->type = T_H225AliasAddress_h323_ID;
   psNewAlias->value = (char*) memAlloc(pctxt, strlen(alias)+1);
   if(!psNewAlias->value)
   {
      OOTRACEERR1("Error:Memory - ooParseDestination - psNewAlias->value\n");
      memFreePtr(pctxt, psNewAlias);
      return OO_FAILED;
   }
   strcpy(psNewAlias->value, alias);
   psNewAlias->next = *aliasList;
   *aliasList = psNewAlias;
   OOTRACEINFO2("Destination for new call is parsed as h323-id %s \n",
		psNewAlias->value);
   return OO_OK;
}

--- NEW FILE: ooq931.h ---
/*
 * 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.
 *
 *****************************************************************************/

/**
 * @file ooq931.h 
 * This file contains functions to support call signalling. 
 */

#ifndef _OOQ931HDR_H_
#define _OOQ931HDR_H_

#include "ooasn1.h"
#include "ootypes.h"
#include "H323-MESSAGES.h"

#ifdef __cplusplus
extern "C" {
#endif

#ifndef EXTERN
#ifdef _WIN32
#define EXTERN __declspec(dllexport)
#else
#define EXTERN
#endif /* _WIN32 */
#endif /* EXTERN */

/** 
 * @defgroup q931 Q931/H.2250 Message Handling
 * @{
 */
/* Maximum length of the Calling/Called party number number */
#define OO_MAX_NUMBER_LENGTH 50

/* Maximum value for a call token identifier */
#define OO_MAX_CALL_TOKEN 9999

/* Q.931 packet must be at least 5 bytes long */
#define Q931_E_TOOSHORT         (-1001)  
/* callReference field must be 2 bytes long */
#define Q931_E_INVCALLREF       (-1002)  
/* invalid length of message */
#define Q931_E_INVLENGTH        (-1003)  

enum Q931MsgTypes {
   Q931NationalEscapeMsg  = 0x00,
   Q931AlertingMsg        = 0x01,
   Q931CallProceedingMsg  = 0x02,
   Q931ConnectMsg         = 0x07,
   Q931ConnectAckMsg      = 0x0f,
   Q931ProgressMsg        = 0x03,
   Q931SetupMsg           = 0x05,
   Q931SetupAckMsg        = 0x0d,
   Q931ResumeMsg          = 0x26,
   Q931ResumeAckMsg       = 0x2e,
   Q931ResumeRejectMsg    = 0x22,
   Q931SuspendMsg         = 0x25,
   Q931SuspendAckMsg      = 0x2d,
   Q931SuspendRejectMsg   = 0x21,
   Q931UserInformationMsg = 0x20,
   Q931DisconnectMsg      = 0x45,
   Q931ReleaseMsg         = 0x4d,
   Q931ReleaseCompleteMsg = 0x5a,
   Q931RestartMsg         = 0x46,
   Q931RestartAckMsg      = 0x4e,
   Q931SegmentMsg         = 0x60,
   Q931CongestionCtrlMsg  = 0x79,
   Q931InformationMsg     = 0x7b,
   Q931NotifyMsg          = 0x6e,
   Q931StatusMsg          = 0x7d,
   Q931StatusEnquiryMsg   = 0x75,
   Q931FacilityMsg        = 0x62
};

enum Q931IECodes {
   Q931BearerCapabilityIE   = 0x04,
   Q931CauseIE              = 0x08,
   Q931FacilityIE           = 0x1c,
   Q931ProgressIndicatorIE  = 0x1e,
   Q931CallStateIE          = 0x14,
   Q931DisplayIE            = 0x28,
   Q931SignalIE             = 0x34,
   Q931CallingPartyNumberIE = 0x6c,
   Q931CalledPartyNumberIE  = 0x70,
   Q931RedirectingNumberIE  = 0x74,
   Q931UserUserIE           = 0x7e
};

enum Q931InformationTransferCapability {
   Q931TransferSpeech,
   Q931TransferUnrestrictedDigital = 8,
   Q931TransferRestrictedDigital = 9,
   Q931Transfer3_1kHzAudio = 16,
   Q931TrasnferUnrestrictedDigitalWithTones = 17,
   Q931TransferVideo = 24
};

enum Q931CauseValues {
   Q931UnallocatedNumber           = 0x01,
   Q931NoRouteToNetwork            = 0x02,
   Q931NoRouteToDestination        = 0x03,
   Q931ChannelUnacceptable         = 0x06,
   Q931NormalCallClearing          = 0x10,
   Q931UserBusy                    = 0x11,
   Q931NoResponse                  = 0x12,
   Q931NoAnswer                    = 0x13,
   Q931SubscriberAbsent            = 0x14,
   Q931CallRejected                = 0x15,
   Q931NumberChanged               = 0x16,
   Q931Redirection                 = 0x17,
   Q931DestinationOutOfOrder       = 0x1b,
   Q931InvalidNumberFormat         = 0x1c,
   Q931NormalUnspecified           = 0x1f,
   Q931StatusEnquiryResponse       = 0x1e,
   Q931NoCircuitChannelAvailable   = 0x22,
   Q931NetworkOutOfOrder           = 0x26,
   Q931TemporaryFailure            = 0x29,
   Q931Congestion                  = 0x2a,
   Q931RequestedCircuitUnAvailable = 0x2c,
   Q931ResourcesUnavailable        = 0x2f,
   Q931IncompatibleDestination     = 0x58,
   Q931ProtocolErrorUnspecified    = 0x6f,
   Q931RecoveryOnTimerExpiry       = 0x66,
   Q931InvalidCallReference        = 0x51,
   Q931ErrorInCauseIE              = 0
};

enum Q931SignalInfo {
   Q931SignalDialToneOn,
   Q931SignalRingBackToneOn,
   Q931SignalInterceptToneOn,
   Q931SignalNetworkCongestionToneOn,
   Q931SignalBusyToneOn,
   Q931SignalConfirmToneOn,
   Q931SignalAnswerToneOn,
   Q931SignalCallWaitingTone,
   Q931SignalOffhookWarningTone,
   Q931SignalPreemptionToneOn,
   Q931SignalTonesOff = 0x3f,
   Q931SignalAlertingPattern0 = 0x40,
   Q931SignalAlertingPattern1,
   Q931SignalAlertingPattern2,
   Q931SignalAlertingPattern3,
   Q931SignalAlertingPattern4,
   Q931SignalAlertingPattern5,
   Q931SignalAlertingPattern6,
   Q931SignalAlertingPattern7,
   Q931SignalAlretingOff = 0x4f,
   Q931SignalErrorInIE = 0x100
};

enum Q931NumberingPlanCodes {
   Q931UnknownPlan          = 0x00,
   Q931ISDNPlan             = 0x01,
   Q931DataPlan             = 0x03,
   Q931TelexPlan            = 0x04,
   Q931NationalStandardPlan = 0x08,
   Q931PrivatePlan          = 0x09,
   Q931ReservedPlan         = 0x0f
};

enum Q931TypeOfNumberCodes {
   Q931UnknownType          = 0x00,
   Q931InternationalType    = 0x01,
   Q931NationalType         = 0x02,
   Q931NetworkSpecificType  = 0x03,
   Q931SubscriberType       = 0x04,
   Q931AbbreviatedType      = 0x06,
   Q931ReservedType         = 0x07
};

enum Q931CodingStandard{
  Q931CCITTStd = 0,
  Q931ReservedInternationalStd,
  Q931NationalStd,
  Q931NetworkStd
};


enum Q931TransferMode {
  Q931TransferCircuitMode,   /* 00 */
  Q931TransferPacketMode     /* 10 */
};

enum Q931TransferRate{
  Q931TransferRatePacketMode = 0x00,  /* 00000 */
  Q931TransferRate64Kbps     = 0x10,  /* 10000 */
  Q931TransferRate128kbps    = 0x11,  /* 10001 */
  Q931TransferRate384kbps    = 0x13,  /* 10011 */
  Q931TransferRate1536kbps   = 0x15,  /* 10101 */
  Q931TransferRate1920kbps   = 0x17   /* 10111 */
};

enum Q931UserInfoLayer1Protocol{
  Q931UserInfoLayer1CCITTStdRate = 1,
  Q931UserInfoLayer1G711ULaw,
  Q931UserInfoLayer1G711ALaw,
  Q931UserInfoLayer1G721ADPCM,
  Q931UserInfoLayer1G722G725,
  Q931UserInfoLayer1H261,
  Q931UserInfoLayer1NonCCITTStdRate,
  Q931UserInfoLayer1CCITTStdRateV120,
  Q931UserInfoLayer1X31
};

/*
  Structure to build store outgoing encoded UUIE
  The different fields in the structure have octet lengths 
  as specified in the spec. 
*/
typedef struct Q931InformationElement {
   int discriminator;
   int offset;
   int length;
   ASN1OCTET data[1];
} Q931InformationElement;


struct OOH323CallData;

/**
 * This function is invoked to decode a Q931 message. 
 * 
 * @param call     Handle to call which owns the message.
 * @param msg      Pointer to the Q931 message
 * @param length   Length of the encoded data
 * @param data     Pointer to the data to be decoded
 *
 * @return         Completion status - 0 on success, -1 on failure
 */
EXTERN int ooQ931Decode 
(struct OOH323CallData *call, Q931Message* msg, int length, ASN1OCTET *data);

/**
 * This function is used to decode the UUIE of the message from the list of
 * ies. It decodes the User-User ie and populates the userInfo field of the
 * message.
 * @param q931Msg    Pointer to the message whose User-User ie has to be 
 *                   decoded.    
 *
 * @return           OO_OK, on success. OO_FAILED, on failure.
 */ 
EXTERN int ooDecodeUUIE(Q931Message *q931Msg);

/**
 * This function is used to encode the UUIE field of the Q931 message.
 * It encodes UUIE and adds the encoded data to the list of ies.
 * @param q931msg        Pointer to the Q931 message whose UUIE field has to be
 *                       encoded.
 *
 * @return               OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooEncodeUUIE(Q931Message *q931msg);

/**
 * This function is invoked to retrieve an IE element from a Q931 message. 
 * 
 * @param q931msg  Pointer to the Q931 message
 * @param ieCode   IE code for the IE element to be retrieved
 *
 * @return         Pointer to a Q931InformationElement contating 
 *                 the IE element.
 */
EXTERN Q931InformationElement* ooQ931GetIE (const Q931Message* q931msg, 
                                            int ieCode);

/**
 * This function is invoked to print a Q931 message. 
 * 
 * @param q931msg  Pointer to the Q931 message
 *
 * @return         - none
 */
EXTERN void ooQ931Print (const Q931Message* q931msg);


/**
 * This function is invoked to create an outgoing Q931 message. 
 * 
 * @param msg      Reference to the pointer of type Q931 message.
 * @param msgType  Type of Q931 message to be created
 *
 * @return         Completion status - 0 on success, -1 on failure
 */
EXTERN int ooCreateQ931Message(Q931Message **msg, int msgType);

/**
 * This function is invoked to generate a unique call reference number. 
 * @param None
 *
 * @return         - call reference number
 */
EXTERN ASN1USINT ooGenerateCallReference(void);


/**
 * This function is used to generate a unique call identifier for the call.
 * @param callid      Pointer to the callid structure, which will be populated
 *                    with the generated callid.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooGenerateCallIdentifier(H225CallIdentifier *callid);

/**
 * This function is invoked to release the memory used up by a Q931 message 
 * 
 * @param q931Msg  Pointer to a Q931 message which has to be freed.
 *
 * @return         Completion status - 0 on success, -1 on failure
 */
EXTERN int ooFreeQ931Message(Q931Message *q931Msg);

/**
 * This function is invoked to retrive the outgoing message buffer for 
 * Q931 message
 *
 * @param call     Pointer to call for which outgoing Q931 message has to be 
 *                 retrieved.
 * @param msgbuf   Pointer to a buffer in which retrieved message will
 *                 be returned.
 * @param len      Pointer to int in which length of the buffer will
 *                 be returned.
 * @param msgType  Pointer to integer in which message type of the ougoing
 *                 message is returned.
 *
 * @return         Completion status - 0 on success, -1 on failure
 */
EXTERN int ooGetOutgoingQ931Msgbuf
(struct OOH323CallData *call, ASN1OCTET * msgbuf, int* len, int *msgType);

/**
 * This function is invoked to send a ReleaseComplete message for 
 * the currently active call.
 *
 * @param call    Pointer to the call for which ReleaseComplete message have 
 *                to be sent.  
 *
 * @return         Completion status - 0 on success, -1 on failure
 */
EXTERN int ooSendReleaseComplete(struct OOH323CallData *call);

/**
 * This function is invoked to send a call proceeding message in response to
 * received setup message.
 *
 * @param call    Pointer to the call for which CallProceeding message have to
 *                be sent.  
 *
 * @return        Completion status - 0 on success, -1 on failure
 */
EXTERN int ooSendCallProceeding(struct OOH323CallData *call);

/**
 * This function is invoked to send alerting message in response to received  
 * setup message. 
 *
 * @param call     Pointer to the call for which Alerting message have to be 
 *                 sent.  
 *
 * @return         Completion status - 0 on success, -1 on failure
 */
EXTERN int ooSendAlerting(struct OOH323CallData *call);

/**
 * This function is invoked to send Facility message.
 *
 * @param call     Pointer to the call for which Facility message have to be 
 *                 sent.  
 *
 * @return         Completion status - 0 on success, -1 on failure
 */
EXTERN int ooSendFacility(struct OOH323CallData *call);

/**
 * This function is invoked to send a Connect message in response to received  
 * setup message. 
 *
 * @param call      Pointer to the call for which connect message has to be 
 *                  sent.  
 *
 * @return          Completion status - 0 on success, -1 on failure
 */
EXTERN int ooSendConnect(struct OOH323CallData *call);

/**
 * This function is used to send a SETUP message for outgoing call. It first
 * creates an H.225 TCP connection with the remote end point and then sends 
 * SETUP message over this connection.
 * @param dest      Destination - IP:Port/alias.
 * @param callToken Unique token for the new call.
 * @param opts      Call specific options. If passed a non-null value, these
 *                  options will override global endpoint settings.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure
 */
EXTERN int ooH323MakeCall(char *dest, char *callToken, ooCallOptions *opts);

/**
 * Helper function used to make a call once it is approved by the Gk.
 * In case of no gk, this function is directly called to make a call.
 * @param call        Handle to the new call.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure
 */
int ooH323CallAdmitted( struct OOH323CallData *call);

/**
 * This function is used to handle a call forward request sent to local
 * endpoint by remote endpoint.
 * @param call        Handle to the call which is being forwarded
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323HandleCallFwdRequest(struct OOH323CallData *call);

/**
 * This function is used for forwarding/redirecting a call to third party.
 * @param callToken   callToken for the call which has to be redirected.
 * @param dest        Address to which call has to be forwarded. Can be 
 *                    IP:Port or alias.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323ForwardCall(char* callToken, char *dest);

/**
 * This function is used to hangup a currently active call. It sets the call
 * state to CLEARING and initiates closing of all logical channels.
 * @param callToken Unique token of the call to be hanged.
 * @param reason    Reason for ending call.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323HangCall(char * callToken, OOCallClearReason reason);


/** 
 * Function to accept a call by sending connect. This function is used
 * as a helper function to ooSendConnect.
 * @param call      Pointer to the call for which connect has to be sent
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooAcceptCall(struct OOH323CallData *call);

/*
 * An helper function to ooMakeCall.
 * @param call      Pointer to the new call.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooH323MakeCall_helper(struct OOH323CallData *call);

/**
 * This function is used to parse the destination
 * @param pctxt     Handle to context to be used for memory allocation
 * @param dest      Destination string to be parsed.
 * @param parsedIP  Pointer to buffer in which parsed ip:port will be returned.
 * @param len       Length of the buffer passed.
 * @param aliasList Aliase List in which new aliases will be added.
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
int ooParseDestination(OOCTXT* pctxt, char *dest, char *parsedIP, unsigned len,
                       ooAliases**aliasList);

/**
 * This function is used to generate a new call token
 * @param callToken Handle to the buffer in which new call token will be
 *                  returned
 * @param size      size of the buffer
 *
 * @return          OO_OK, on success. OO_FAILED, on failure.
 */
int ooGenerateCallToken (char *callToken, size_t size);


/**
 * This function sends an encoded H.245 message buffer as a tunneled 
 * H.245 Facility message.
 * @param call             Pointer to the call for which H.245 message has to
 *                         be tunneled.
 * @param msgbuf           Pointer to the encoded H.245 message to be tunneled.
 *
 * @param h245Len          Length of the encoded H.245 message buffer.
 * @param h245MsgType      Type of the H245 message
 * @param associatedChan   The logical channel number with which the tunneled
 *                         message is associated. In case of no channel, this
 *                         value should be 0.
 *
 * @return                 OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooSendAsTunneledMessage
(struct OOH323CallData *call, ASN1OCTET* msgbuf, 
 int h245Len, int h245MsgType, int associatedChan); 
 

/**
 * This function is used to encode an H.225 message.
 * @param call            Handle to the call.
 * @param pq931Msg        Pointer to the message to be encoded.
 * @param msgbuf          Pointer to the buffer in which encoded message will 
 *                        be returned.
 * @param size            Size of the buffer passed.
 *
 * @return                OO_OK, on success. OO_FAILED, on failure.
 */
int ooEncodeH225Message(struct OOH323CallData *call, Q931Message *pq931Msg, 
                        char *msgbuf, int size);

/**
 * This is a callback function which is called when there is no CONNECT 
 * response from the remote endpoint after the SETUP has been sent and timeout
 * period has passed.
 * @param data            The callback data registered at the time of timer 
 *                        creation.
 *
 * @return                OO_OK, on success. OO_FAILED, on failure.
 */
int ooCallEstbTimerExpired(void *data);

/**
 * This function is used to add a bearer capability IE to a Q931 message.
 * @param pmsg            Q931 message to which bearer capability ie has to be
 *                        added.
 * @param codingStandard  Coding standard to be used.
 * @param capability      Information transfer capability
 * @param transferMode    Information transfer mode.(circuit/packet modes).
 * @param transferRate    Information transfer rate.
 * @param userInfoLayer1  User information layer 1 protocol.
 *
 * @return                OO_OK on success, OO_FAILED, on failure.
 */
EXTERN int ooSetBearerCapabilityIE
   (Q931Message *pmsg, enum Q931CodingStandard codingStandard, 
    enum Q931InformationTransferCapability capability, 
    enum Q931TransferMode transferMode, enum Q931TransferRate transferRate,
    enum Q931UserInfoLayer1Protocol userInfoLayer1);

/**
 * This function is used to add a called party number ie to a q931 message.
 * @param pmsg            Q931 message to which CalledPartyNumber IE has to be
 *                        added.
 * @param number          Number for called party.
 * @param plan            Numbering Plan used
 * @param type            Type of number
 *
 * @return                OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooQ931SetCalledPartyNumberIE
   (Q931Message *pmsg, const char *number, unsigned plan, unsigned type);


/**
 * This function is used to add a CallingPartyNumber ie to a q931 message.
 * @param pmsg            Q931 message to which CallingPartyNumber IE has to be
 *                        added.
 * @param number          Number for calling party.
 * @param plan            Numbering Plan used
 * @param type            Type of number
 * @param presentation    Presentation of the address is allowed or restricted.
 * @param screening       Whether address was provided by endpoint or screened
 *                        by gatekeeper.
 *
 * @return                OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooQ931SetCallingPartyNumberIE
   (Q931Message *pmsg, const char *number, unsigned plan, unsigned type, 
    unsigned presentation, unsigned screening);

/** 
 * This function is used to set a cause ie for a q931 message.
 * @param pmsg        Valid Q931 Message
 * @param cause       Q931 Cause Value
 * @param coding      coding standard used. 0 for ITU-T standard coding
 * @param location    location. 0 for user.
 *
 * @return            OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooQ931SetCauseIE
   (Q931Message *pmsg,enum Q931CauseValues cause, unsigned coding, 
    unsigned location);

/**
 * This function is used to convert a call clear reason to cause and 
 * reason code. It is used when local user is endoing the call and 
 * sending releaseComplete.
 * @param clearReason   Reason for ending call.
 * @param cause         Pointer to Q931CauseVaules enum in which cause
 *                      will be returned.
 * @param reasonCode    Pointer to unsigned int in which reasonCode will
 *                      be returned.
 *
 * @return              OO_OK, on success. OO_FAILED, on failure.
 */
EXTERN int ooQ931GetCauseAndReasonCodeFromCallClearReason
   (OOCallClearReason clearReason, enum Q931CauseValues *cause, 
    unsigned *reasonCode);

/**
 * This function is used to convert a cause value and reason code received
 * in ReleaseComplete message from remote endpoint into a CallClearReason.
 * @param cause         cause value received.
 * @param reasonCode    reasonCode received.
 *
 * @return              Returns a CallClearReason.
 */
EXTERN OOCallClearReason ooGetCallClearReasonFromCauseAndReasonCode
   (enum Q931CauseValues cause, unsigned reasonCode);
/** 
 * @} 
 */
#ifdef __cplusplus
}
#endif

#endif /* __Q931HDR_H */

--- NEW FILE: ootrace.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 <stdarg.h>
#include <stdlib.h>
#include <stdio.h>

#include "ootypes.h"
#include "ootrace.h"
#include "ooCommon.h"
#include "ooCapability.h"
#include "ooq931.h"
#include "ooh245.h"
#include "ooh323ep.h"

/** Global endpoint structure */
extern OOH323EndPoint gH323ep;

static OOUINT32 gs_traceLevel = TRACELVL;

#define OONUMBEROF(items) (sizeof(items)/sizeof(items[0]))

/**
 * Reasons for ending call 
 */
static const char* reasonCodeText[] = {
   "OO_REASON_UNKNOWN", 
   "OO_REASON_INVALIDMESSAGE",
   "OO_REASON_TRANSPORTFAILURE", 
   "OO_REASON_NOROUTE",
   "OO_REASON_NOUSER",
   "OO_REASON_NOBW",
   "OO_REASON_GK_NOCALLEDUSER",
   "OO_REASON_GK_NOCALLERUSER",
   "OO_REASON_GK_NORESOURCES",
   "OO_REASON_GK_UNREACHABLE",
   "OO_REASON_GK_CLEARED",
   "OO_REASON_NOCOMMON_CAPABILITIES",
   "OO_REASON_REMOTE_FWDED",   
   "OO_REASON_LOCAL_FWDED",
   "OO_REASON_REMOTE_CLEARED", 
   "OO_REASON_LOCAL_CLEARED", 
   "OO_REASON_REMOTE_BUSY",
   "OO_REASON_LOCAL_BUSY",
   "OO_REASON_REMOTE_NOANSWER",
   "OO_REASON_LOCAL_NOTANSWERED",
   "OO_REASON_REMOTE_REJECTED",
   "OO_REASON_LOCAL_REJECTED",
   "OO_REASON_REMOTE_CONGESTED",
   "OO_REASON_LOCAL_CONGESTED"
};

static const char* callStateText[] = {
   "OO_CALL_CREATED",
   "OO_CALL_WAITING_ADMISSION",
   "OO_CALL_CONNECTING",
   "OO_CALL_CONNECTED",
   "OO_CALL_CLEAR",
   "OO_CALL_CLEAR_RELEASERECVD",
   "OO_CALL_CLEAR_RELEASESENT",
   "OO_CALL_CLEARED"
};

static const char *msgTypeText[]={
   "OOQ931MSG",
   "OOH245MSG",
   "OOSetup",
   "OOCallProceeding",
   "OOAlert",
   "OOConnect",
   "OOReleaseComplete",
   "OOFacility",
   "OOMasterSlaveDetermination",
   "OOMasterSlaveAck",
   "OOMasterSlaveReject",
   "OOMasterSlaveRelease",
   "OOTerminalCapabilitySet",
   "OOTerminalCapabilitySetAck",
   "OOTerminalCapabilitySetReject",
   "OOTerminalCapabilitySetRelease",
   "OOOpenLogicalChannel",
   "OOOpenLogicalChannelAck",
   "OOOpenLogicalChannelReject",
   "OOOpenLogicalChannelRelease",
   "OOOpenLogicalChannelConfirm",
   "OOCloseLogicalChannel",
   "OOCloseLogicalChannelAck",
   "OORequestChannelClose",
   "OORequestChannelCloseAck",
   "OORequestChannelCloseReject",
   "OORequestChannelCloseRelease",
   "OOEndSessionCommand"
};

static const char *capTypes[]={
   "unknown",
   "OO_NONSTANDARD",
   "OO_G711ALAW64K",
   "OO_G711ALAW56K",
   "OO_G711ULAW64K",
   "OO_G711ULAW56K",
   "OO_G72264K",
   "OO_G72256K",
   "OO_G72248K",
   "OO_G7231",
   "OO_G728",
   "OO_G729",
   "OO_G729ANNEXA",
   "OO_IS11172AUDIO",
   "OO_IS13818AUDIO",
   "OO_G729WANNEXB",
   "OO_G729ANNEXAWANNEXB",
   "OO_G7231ANNEXC",
   "OO_GSMFULLRATE",
   "OO_GSMHALFRATE",
   "OO_GSMENHANCEDFULLRATE",
   "OO_GENERICAUDIO",
   "OO_G729EXTENSIONS",
   "OO_VBD",
   "OO_AUDIOTELEPHONYEVENT",
   "OO_AUDIOTONE",
   "OO_EXTELEM1"
};

/*DTMF capabilities*/
static const char* dtmfCaps []={
   "OO_CAP_DTMF_RFC2833",
   "OO_CAP_DTMF_Q931",
   "OO_CAP_DTMF_H245"
};

static const char* ooGetText (int idx, const char** table, size_t tabsiz)
{
   return (idx < (int)tabsiz) ? table[idx] : "?";
}

const char* ooGetReasonCodeText (int code)
{
   return ooGetText (code, reasonCodeText, OONUMBEROF(reasonCodeText));
}

const char* ooGetCallStateText (int callState)
{
   return ooGetText (callState, callStateText, OONUMBEROF(callStateText));
}

const char* ooGetAudioCapTypeText(int cap)
{
   return ooGetText (cap, capTypes, OONUMBEROF(capTypes));
}

const char* ooGetMsgTypeText (int msgType)
{
   int idx = msgType - OO_MSGTYPE_MIN;
   return ooGetText (idx, msgTypeText, OONUMBEROF(msgTypeText));
}


void ooSetTraceThreshold(OOUINT32 traceLevel)
{
   gs_traceLevel = traceLevel;
}

void ooTrace(OOUINT32 traceLevel, const char * fmtspec, ...)
{
   va_list arglist;
   char logMessage[MAXLOGMSGLEN];
   if(traceLevel > gs_traceLevel) return;
   va_start (arglist, fmtspec);
   /*   memset(logMessage, 0, MAXLOGMSGLEN);*/
   vsprintf(logMessage, fmtspec, arglist);   
   va_end(arglist);
   ooTraceLogMessage(logMessage);
}

void ooTraceLogMessage(const char * logMessage)
{
   char timeString[100];
   char currtime[3];
   static int lasttime=25;
   int printDate =0;
   static int printTime=1;
   
#ifdef _WIN32
   
   SYSTEMTIME systemTime;
   GetLocalTime(&systemTime);
   GetTimeFormat(LOCALE_SYSTEM_DEFAULT,0, &systemTime, "HH':'mm':'ss", timeString, 100);
   GetTimeFormat(LOCALE_SYSTEM_DEFAULT,0, &systemTime, "H", currtime, 3);
   if(lasttime> atoi(currtime))
      printDate=1;
   lasttime = atoi(currtime);
   
#else
   struct tm *ptime;
   struct timeval systemTime;
   char dateString[10];
   gettimeofday(&systemTime, NULL);
   ptime = (struct tm*)localtime(&systemTime.tv_sec);
   strftime(timeString, 100, "%H:%M:%S", ptime);
   strftime(currtime, 3, "%H", ptime);
   if(lasttime>atoi(currtime))
       printDate = 1;
   lasttime = atoi(currtime);   
#endif

      
#ifdef _WIN32
   if(printDate)
   {
      printDate = 0;
      fprintf(gH323ep.fptraceFile, "---------Date %d/%d/%d---------\n",
                      systemTime.wMonth, systemTime.wDay, systemTime.wYear);
   }
   if(printTime)
     fprintf(gH323ep.fptraceFile, "%s:%03d  %s", timeString, 
             systemTime.wMilliseconds, logMessage);
   else
      fprintf(gH323ep.fptraceFile, "%s", logMessage);
   
   fflush(gH323ep.fptraceFile);
#else
   if(printDate)
   {
      printDate = 0;
      strftime(dateString, 10, "%D", ptime);
      fprintf(gH323ep.fptraceFile, "---------Date %s---------\n", 
	          dateString);
   }
   if(printTime)
      fprintf(gH323ep.fptraceFile, "%s:%03d  %s", timeString, 
	          systemTime.tv_usec/1000, logMessage);
   else
      fprintf(gH323ep.fptraceFile, "%s", logMessage);

   fflush(gH323ep.fptraceFile);
#endif
   
   if(strchr(logMessage, '\n'))
      printTime = 1;
   else
      printTime = 0;

}

int ooLogAsn1Error(int stat, const char * fname, int lno)
{
   OOTRACEERR4("Asn1Error: %d at %s:%d\n", stat, fname, lno);
   return stat;
}


--- NEW FILE: ootrace.h ---
/*
 * 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.
 *
 *****************************************************************************/

/**
 * @file ootrace.h 
 * This file defines the trace functionality
 */
#include "ooCommon.h"
#ifndef _OOTRACE_H_
#define _OOTRACE_H_


/* tracing */
#define OOTRCLVLERR  1
#define OOTRCLVLWARN 2
#define OOTRCLVLINFO 3
#define OOTRCLVLDBGA 4
#define OOTRCLVLDBGB 5
#define OOTRCLVLDBGC 6

#ifdef _OOWARNING
#define TRACELVL OOTRCLVLWARN
#endif
#ifdef _OOINFO
#define TRACELVL OOTRCLVLINFO
#endif
#ifdef _OODEBUGA
#define TRACELVL OOTRCLVLDBGA
#endif
#ifdef _OODEBUGB
#define TRACELVL OOTRCLVLDBGB
#endif
#ifdef _OODEBUGC
#define TRACELVL OOTRCLVLDBGC
#endif

/* Ensure we always log error messages */
#ifndef TRACELVL
#define TRACELVL 1
#endif

#define OOTRACEERR1(a)        ooTrace(OOTRCLVLERR,a)
#define OOTRACEERR2(a,b)      ooTrace(OOTRCLVLERR,a,b)
#define OOTRACEERR3(a,b,c)    ooTrace(OOTRCLVLERR,a,b,c)
#define OOTRACEERR4(a,b,c,d)  ooTrace(OOTRCLVLERR,a,b,c,d)
#define OOTRACEWARN1(a)       ooTrace(OOTRCLVLWARN,a)
#define OOTRACEWARN2(a,b)     ooTrace(OOTRCLVLWARN,a,b)
#define OOTRACEWARN3(a,b,c)   ooTrace(OOTRCLVLWARN,a,b,c)
#define OOTRACEWARN4(a,b,c,d) ooTrace(OOTRCLVLWARN,a,b,c,d)
#define OOTRACEINFO1(a)       ooTrace(OOTRCLVLINFO, a)
#define OOTRACEINFO2(a,b)     ooTrace(OOTRCLVLINFO,a,b)
#define OOTRACEINFO3(a,b,c)   ooTrace(OOTRCLVLINFO,a,b,c)
#define OOTRACEINFO4(a,b,c,d) ooTrace(OOTRCLVLINFO,a,b,c,d)
#define OOTRACEINFO5(a,b,c,d,e) ooTrace(OOTRCLVLINFO,a,b,c,d,e)
#ifndef _COMPACT 
#define OOTRACEDBGA1(a)       ooTrace(OOTRCLVLDBGA,a)
#define OOTRACEDBGA2(a,b)     ooTrace(OOTRCLVLDBGA,a,b)
#define OOTRACEDBGA3(a,b,c)   ooTrace(OOTRCLVLDBGA,a,b,c)
#define OOTRACEDBGA4(a,b,c,d) ooTrace(OOTRCLVLDBGA,a,b,c,d)
#define OOTRACEDBGA5(a,b,c,d,e) ooTrace(OOTRCLVLDBGA,a,b,c,d,e)
#define OOTRACEDBGB1(a)       ooTrace(OOTRCLVLDBGB,a)
#define OOTRACEDBGB2(a,b)     ooTrace(OOTRCLVLDBGB,a,b)
#define OOTRACEDBGB3(a,b,c)   ooTrace(OOTRCLVLDBGB,a,b,c)
#define OOTRACEDBGB4(a,b,c,d) ooTrace(OOTRCLVLDBGB,a,b,c,d)
#define OOTRACEDBGC1(a)       ooTrace(OOTRCLVLDBGC,a)
#define OOTRACEDBGC2(a,b)     ooTrace(OOTRCLVLDBGC,a,b)
#define OOTRACEDBGC3(a,b,c)   ooTrace(OOTRCLVLDBGC,a,b,c)
#define OOTRACEDBGC4(a,b,c,d) ooTrace(OOTRCLVLDBGC,a,b,c,d)
#define OOTRACEDBGC5(a,b,c,d,e) ooTrace(OOTRCLVLDBGC,a,b,c,d,e)
#else
#define OOTRACEDBGA1(a) 
#define OOTRACEDBGA2(a,b)
#define OOTRACEDBGA3(a,b,c)
#define OOTRACEDBGA4(a,b,c,d)
#define OOTRACEDBGA5(a,b,c,d,e)
#define OOTRACEDBGB1(a)
#define OOTRACEDBGB2(a,b) 
#define OOTRACEDBGB3(a,b,c)
#define OOTRACEDBGB4(a,b,c,d)
#define OOTRACEDBGC1(a)
#define OOTRACEDBGC2(a,b)
#define OOTRACEDBGC3(a,b,c)
#define OOTRACEDBGC4(a,b,c,d)
#define OOTRACEDBGC5(a,b,c,d,e)
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifndef EXTERN
#ifdef _WIN32
#define EXTERN __declspec(dllexport)
#else
#define EXTERN
#endif /* _WIN32 */
#endif /* EXTERN */

/**
 * This function is used to retrieve the description text for a reason
 * code.
 *
 * @param code     Reason code.
 * @return         The text description string.
 */
const char* ooGetReasonCodeText (int code);

/**
 * This function is used to retrieve the description text for a call
 * state.
 *
 * @param callState Call state.
 * @return         The text description string.
 */
const char* ooGetCallStateText (int callState);

/**
 * This function is used to retrieve the description text for a 
 * message type.
 *
 * @param msgType  Message type.
 * @return         The text description string.
 */
const char* ooGetMsgTypeText (int msgType);

/**
 * This function is used to retrieve the description for audio capability
 * type.
 * @param cap     Audio cap type
 * @return        The text description string.
 */
const char* ooGetAudioCapTypeText(int cap);

/**
 * This function is used to set the trace level.
 * @param traceLevel  New trace level. Various values are: OOTRCLVLERR, 
 *                    OOTRCLVLWARN, OOTRCLVLINFO, OOTRCLVLDBGA, OOTRCLVLDBGB,
 *                    OOTRCLVLDBGC
 *
 * @return            None 
 */
EXTERN void ooSetTraceThreshold(OOUINT32 traceLevel);

/**
 * This function is used to write the messages to the trace file.
 *
 * @param traceLevel  Trace level for the message.
 * @param fmtspec     Printf style format spec.
 * @param ...         Printf style variable list of arguments              
 *
 * @return            - none
 */
EXTERN void ooTrace(OOUINT32 traceLevel, const char * fmtspec, ...);

/**
 * Helper function for the trace function. This function performs actual
 * writing to file.
 * @param logMessage  Log message to be writted to file.
 *
 * @return            - none
 */
void ooTraceLogMessage(const char * logMessage);

/**
 *
 */
void ooChangeIPToNWOrder(char * internetIP, char* networkIP);

int ooLogAsn1Error(int stat, const char * fname, int lno);
#ifdef __cplusplus
}
#endif
#endif

--- NEW FILE: ootypes.h ---
/*
 * 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.
 *
 *****************************************************************************/
/**
 * @file ootypes.h 
 * This file contains the definitions of common constants and data structures 
 */

#ifndef _OOTYPES_H_
#define _OOTYPES_H_

#include "ooSocket.h"
#include "MULTIMEDIA-SYSTEM-CONTROL.h"
#include "H323-MESSAGES.h"
#include "ooasn1.h"


#define OOH323C_VERSION "v0.6.1"

/*  types */
#define OO_FAILED -1
#define OO_OK 1

/**
  Various states of master slave determination prcedure
*/
/*TODO: States for both local and remote initiation should be maintained
   separately */
typedef enum OOMasterSlaveState {
   OO_MasterSlave_Idle,
   OO_MasterSlave_DetermineSent, 
   OO_MasterSlave_AckReceived,
   OO_MasterSlave_Master,
   OO_MasterSlave_Slave
} OOMasterSlaveState;

/** States for Capability Exchange Procedure */
typedef enum {
   OO_LocalTermCapExchange_Idle, 
   OO_LocalTermCapSetSent, 
   OO_LocalTermCapSetAckRecvd, 
   OO_RemoteTermCapExchange_Idle, 
   OO_RemoteTermCapSetRecvd, 
   OO_RemoteTermCapSetAckSent
} OOCapExchangeState;

/** Call Clear Reasons */
typedef enum OOCallClearReason {
   OO_REASON_UNKNOWN=0, 
   OO_REASON_INVALIDMESSAGE,
   OO_REASON_TRANSPORTFAILURE, 
   OO_REASON_NOROUTE,
   OO_REASON_NOUSER,
   OO_REASON_NOBW,
   OO_REASON_GK_NOCALLEDUSER,
   OO_REASON_GK_NOCALLERUSER,
   OO_REASON_GK_NORESOURCES,
   OO_REASON_GK_UNREACHABLE,
   OO_REASON_GK_CLEARED,
   OO_REASON_NOCOMMON_CAPABILITIES,
   OO_REASON_REMOTE_FWDED,   
   OO_REASON_LOCAL_FWDED,
   OO_REASON_REMOTE_CLEARED, 
   OO_REASON_LOCAL_CLEARED, 
   OO_REASON_REMOTE_BUSY,
   OO_REASON_LOCAL_BUSY,
   OO_REASON_REMOTE_NOANSWER,
   OO_REASON_LOCAL_NOTANSWERED,
   OO_REASON_REMOTE_REJECTED,
   OO_REASON_LOCAL_REJECTED,
   OO_REASON_REMOTE_CONGESTED,
   OO_REASON_LOCAL_CONGESTED
} OOCallClearReason;

/** call states */
typedef enum {
   OO_CALL_CREATED, 
   OO_CALL_WAITING_ADMISSION, 
   OO_CALL_CONNECTING, 
   OO_CALL_CONNECTED,
   OO_CALL_CLEAR,             /* call marked for clearing */
   OO_CALL_CLEAR_RELEASERECVD,
   OO_CALL_CLEAR_RELEASESENT,     /* Release Sent */
   OO_CALL_CLEARED            /* Call Cleared */
} OOCallState;

/** H245 Session state */
typedef enum {
   OO_H245SESSION_IDLE,
   OO_H245SESSION_ACTIVE,
   OO_H245SESSION_ENDSENT, 
   OO_H245SESSION_ENDRECVD,
   OO_H245SESSION_CLOSED
} OOH245SessionState;

/** Logical Channel states */
typedef enum {
   OO_LOGICAL_CHAN_UNKNOWN, 
   OO_LOGICALCHAN_IDLE, 
   OO_LOGICALCHAN_PROPOSED, 
   OO_LOGICALCHAN_ESTABLISHED
} OOLogicalChannelState;

/**
   Terminal type of the endpoint. Default is 60.
*/
#define OOTERMTYPE 60
#define MAX_IP_LENGTH 15
#define MAXLOGMSGLEN 2048
/**
   Various message types for H225 and H245 messages
*/
#define OO_MSGTYPE_MIN                 101
#define OOQ931MSG                      101
#define OOH245MSG                      102
#define OOSetup                        103
#define OOCallProceeding               104
#define OOAlert                        105
#define OOConnect                      106
#define OOReleaseComplete              107
#define OOFacility                     108
#define OOMasterSlaveDetermination     109
#define OOMasterSlaveAck               110
#define OOMasterSlaveReject            111
#define OOMasterSlaveRelease           112
#define OOTerminalCapabilitySet        113
#define OOTerminalCapabilitySetAck     114
#define OOTerminalCapabilitySetReject  115
#define OOTerminalCapabilitySetRelease 116
#define OOOpenLogicalChannel           117
#define OOOpenLogicalChannelAck        118
#define OOOpenLogicalChannelReject     119
#define OOOpenLogicalChannelRelease    120
#define OOOpenLogicalChannelConfirm    121
#define OOCloseLogicalChannel          122
#define OOCloseLogicalChannelAck       123
#define OORequestChannelClose          124
#define OORequestChannelCloseAck       125
#define OORequestChannelCloseReject    126
#define OORequestChannelCloseRelease   127
#define OOEndSessionCommand            128
#define OO_MSGTYPE_MAX                 128


/* Timer types */
#define OO_CALLESTB_TIMER  (1<<0)
#define OO_MSD_TIMER       (1<<1)
#define OO_TCS_TIMER       (1<<2)
#define OO_OLC_TIMER       (1<<3)
#define OO_CLC_TIMER       (1<<4)
#define OO_RCC_TIMER       (1<<5)
#define OO_SESSION_TIMER   (1<<6)

/**
  Default port ranges used
*/
#define TCPPORTSSTART 12030
#define TCPPORTSEND   12230
#define UDPPORTSSTART 13030
#define UDPPORTSEND   13230
#define RTPPORTSSTART 14030
#define RTPPORTSEND   14230

/**
 Maximum length for received messages 
*/
#define MAXMSGLEN 4096
#define MAXFILENAME 256

#define OO_CMD_MAKECALL      201
#define OO_CMD_ANSCALL       202
#define OO_CMD_FWDCALL       203
#define OO_CMD_HANGCALL      204
#define OO_CMD_STOPMONITOR   205


/**
 Endpoint call modes. The call mode of the endpoint dictates what type
 of channels are created for the calls placed by the endpoint or received
 by the endpoint.
*/
typedef enum OOCallMode {
   OO_CALLMODE_AUDIOCALL, 
   OO_CALLMODE_AUDIORX,
   OO_CALLMODE_AUDIOTX,
   OO_CALLMODE_VIDEOCALL, 
   OO_CALLMODE_FAX
} OOCallMode;

/*
 * Flag macros - these operate on bit mask flags using mask values
 */
#define OO_SETFLAG(flags,mask) (flags |= mask)
#define OO_CLRFLAG(flags,mask) (flags &= ~mask)
#define OO_TESTFLAG(flags,mask) ((flags & mask) != 0)

#define DEFAULT_MAX_RETRIES 3
/** Type of callback functions to be registered at the time of
 * channel creation.
 */
typedef int (*ChannelCallback)(void*);

/**
 * Type of callback function registered at initialization
 * for handling commands
 */
typedef int (*CommandCallback)(void);

/* Define common mutex type */
#ifdef _WIN32
#define OO_MUTEX CRITICAL_SECTION
#else
#define OO_MUTEX pthread_mutex_t
#endif

/**
 * Structure for stack commands */
typedef struct ooCommand {
   int type;
   void * param1;
   void * param2;
   void * param3;
} ooCommand;


/*TODO: Should add caller-id, callername etc. So that they can be changed per
  call basis*/
typedef struct ooCallOptions {
   OOBOOL fastStart; /* faststart for this call. overrides endpoint setting*/
   OOBOOL tunneling; /* tunneling for this call. overrides endpoint setting*/
   OOBOOL disableGk; /* If gk is enabled, then you can avoid going through gk for a specific call */
   OOCallMode callMode; /* Effective when faststart is used. Tells stack which type of channels to setup*/
}ooCallOptions;
 
/**
 * This structure is used to define the port ranges to be used
 * by the application.
 */
struct ooH323Ports
{
   int start;
   int max;
   int current;
};

struct Q931InformationElement;
/**
 Defines the Q931 message structure. Contains
 context for memory allocation, protocol Discriminator,
 call reference, meesage type and list of user user IEs.
*/
typedef struct Q931Message {
   ASN1UINT protocolDiscriminator;
   ASN1UINT callReference;
   ASN1BOOL fromDestination;
   ASN1UINT messageType;      /* Q931MsgTypes */
   ASN1UINT tunneledMsgType;  /* The H245 message this message is tunneling*/
   ASN1INT  logicalChannelNo; /* channel number associated with tunneled */
                              /* message, 0 if no channel */
   DList ies;    
   struct Q931InformationElement *bearerCapabilityIE;
   struct Q931InformationElement *callingPartyNumberIE;
   struct Q931InformationElement *calledPartyNumberIE;
   struct Q931InformationElement *causeIE;
   H225H323_UserInformation *userInfo;
} Q931Message;

/**
 Defines the H245 message structure. All request/response
 and command messages are represented using this structure.
*/
typedef struct H245Message {
   H245MultimediaSystemControlMessage h245Msg;
   ASN1UINT msgType;
   ASN1INT  logicalChannelNo;
} H245Message;

struct ooH323EpCapability;
typedef struct ooCapPrefs {
  int order[20];
  int index;
}ooCapPrefs;

/* Store local and remote media endpoint info, for media type */
typedef struct ooMediaInfo{
   char  dir[15]; /* transmit/receive*/
   int   cap;
   int   lMediaPort;
   int   lMediaCntrlPort;
   char  lMediaIP[20];
   struct ooMediaInfo *next;
} ooMediaInfo;

/**
 * Structure to store information of logical channels for call.
 */
typedef struct ooLogicalChannel {
   int  channelNo;
   int  sessionID;
   char type[10]; /* audio/video/data */
   char dir[10];  /* receive/transmit */
   char remoteIP[20];
   int  mediaPort;
   int  mediaControlPort;
   int  localRtpPort;
   int  localRtcpPort;
   char localIP[20];
   OOLogicalChannelState state;         
   struct ooH323EpCapability *chanCap;
   struct ooLogicalChannel *next;
} ooLogicalChannel;

typedef struct ooAliases{
   int type;
   char *value;
   OOBOOL registered;
   struct ooAliases *next;
}ooAliases;


/**
 * Structure to store all the information related to a particular
 * call.
 */
typedef struct OOH323Channel {
   OOSOCKET	sock;
   int		port;
   DList	outQueue;
} OOH323Channel;


struct OOH323CallData;

typedef struct ooTimerCallback{
   struct OOH323CallData* call;
   ASN1UINT    timerType;
   ASN1UINT    channelNumber;
} ooTimerCallback;

typedef struct OOCallFwdData{
   char ip[20];
   int port;
   ooAliases *aliases;
   OOBOOL fwdedByRemote; /*Set when we are being fwded by remote*/
}OOCallFwdData;      

/**
 * These are message callbacks which can be used by user applications
 * to perform application specific things on receiving a particular 
 * message or before sending a particular message. For ex. user application
 * can change values of some parameters of setup message before it is actually
 * sent out.
 */
typedef int (*cb_OnReceivedSetup)
   (struct OOH323CallData *call, Q931Message *pmsg);

typedef int (*cb_OnReceivedConnect)
   (struct OOH323CallData *call, Q931Message *pmsg);

typedef int (*cb_OnBuiltSetup)
   (struct OOH323CallData *call, Q931Message *pmsg);

typedef int (*cb_OnBuiltConnect)
   (struct OOH323CallData *call, Q931Message *pmsg);

typedef struct OOH225MsgCallbacks{
   cb_OnReceivedSetup onReceivedSetup;
   cb_OnReceivedConnect onReceivedConnect;
   cb_OnBuiltSetup onBuiltSetup;
   cb_OnBuiltConnect onBuiltConnect;
}OOH225MsgCallbacks;


typedef int (*cb_OnNewCallCreated)(struct OOH323CallData * call);
typedef int (*cb_OnAlerting)(struct OOH323CallData * call);
typedef int (*cb_OnIncomingCall)(struct OOH323CallData* call );
typedef int (*cb_OnOutgoingCall)(struct OOH323CallData* call );
typedef int (*cb_OnCallAnswered)(struct OOH323CallData* call);
typedef int (*cb_OnCallEstablished)(struct OOH323CallData* call);
typedef int (*cb_OnOutgoingCallAdmitted)(struct OOH323CallData* call );
typedef int (*cb_OnCallCleared)(struct OOH323CallData* call);
typedef int (*cb_OpenLogicalChannels)(struct OOH323CallData* call);
typedef int (*cb_OnCallForwarded)(struct OOH323CallData* call);

struct ooGkClient;

typedef struct OOH323CALLBACKS{
   cb_OnAlerting onNewCallCreated;
   cb_OnAlerting onAlerting;
   cb_OnIncomingCall onIncomingCall;
   cb_OnOutgoingCall onOutgoingCall;
   cb_OnCallAnswered onCallAnswered;
   cb_OnCallEstablished onCallEstablished;
   cb_OnCallForwarded onCallForwarded;
   cb_OnOutgoingCallAdmitted onOutgoingCallAdmitted;
   cb_OnCallCleared onCallCleared;
   cb_OpenLogicalChannels openLogicalChannels;
} OOH323CALLBACKS;

#endif


--- NEW FILE: perutil.c ---
/*
 * Copyright (C) 1997-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 "ooasn1.h"
#include "ooper.h"

ASN1BOOL isExtendableSize (Asn1SizeCnst* pSizeList);
static ASN1BOOL isFixedSize (Asn1SizeCnst* pSizeList);

ASN1BOOL alignCharStr 
(OOCTXT* pctxt, ASN1UINT len, ASN1UINT nbits, Asn1SizeCnst* pSize)
{
   if (TRUE) {
      ASN1UINT lower, upper;
      ASN1BOOL doAlign = (len > 0), extendable;

      pSize = checkSize (pSize, len, &extendable);

      if (0 != pSize) {
         lower = pSize->lower;
         upper = pSize->upper;
      }
      else {
         lower = 0;
         upper = ASN1UINT_MAX;
      }

      if (!extendable && upper < 65536) {
         ASN1UINT bitRange = upper * nbits;
         if (upper == lower) {
            /* X.691, clause 26.5.6 */
            if (bitRange <= 16) doAlign = FALSE;
         }
         else {
            /* X.691, clause 26.5.7 */
            if (bitRange < 16) doAlign = FALSE;
         }
      }

      return doAlign;
   }
   else
      return FALSE;
}

int bitAndOctetStringAlignmentTest (Asn1SizeCnst* pSizeList, 
                                    ASN1UINT itemCount, 
                                    ASN1BOOL bitStrFlag,
                                    ASN1BOOL* pAlignFlag)
{
   ASN1UINT threshold = (bitStrFlag) ? 16 : 2;

   if (pSizeList == 0 || itemCount > threshold) 
      *pAlignFlag = TRUE;
   else if (isFixedSize(pSizeList)) 
      *pAlignFlag = FALSE;
   else {

      /* Variable length case: check size.. no alignment required if    */
      /* lower == upper and not extended..                              */

      ASN1BOOL extended;
      Asn1SizeCnst* pSize = checkSize (pSizeList, itemCount, &extended);

      if (pSize != 0)
         *pAlignFlag = ((pSize->upper != pSize->lower) || pSize->extended);
      else {
         /* Note: we never should get here because constraint           */
         /* violation should have been caught when length was encoded   */
         /* or decoded..                                                */
         return (ASN_E_CONSVIO);
      }
   }

   return (ASN_OK);
}

Asn1SizeCnst* checkSize (Asn1SizeCnst* pSizeList, 
                         ASN1UINT value, 
                         ASN1BOOL* pExtendable)
{
   Asn1SizeCnst* lpSize = pSizeList;
   *pExtendable = isExtendableSize (lpSize);

   while (lpSize) {
      if (value >= lpSize->lower && value <= lpSize->upper) {
         return (lpSize);
      }
      else lpSize = lpSize->next;
   }

   return 0;
}

int getPERMsgLen (OOCTXT* pctxt)
{
   return (pctxt->buffer.bitOffset == 8) ?
      pctxt->buffer.byteIndex : pctxt->buffer.byteIndex + 1;
}

int addSizeConstraint (OOCTXT* pctxt, Asn1SizeCnst* pSize)
{
   Asn1SizeCnst* lpSize;
   int stat = ASN_OK;

   /* If constraint does not already exist, add it */

   if (!pctxt->pSizeConstraint) {
      pctxt->pSizeConstraint = pSize;
   }

   /* Otherwise, check to make sure given constraint is larger than     */
   /* the existing constraint..                                         */

   else {
      lpSize = pSize;
      while (lpSize) {
         if (pctxt->pSizeConstraint->lower <= lpSize->lower ||
             pctxt->pSizeConstraint->upper >= lpSize->upper) 
         {
            /* Set the extension flag to the value of the size          */
            /* constraint structure that the item falls within..        */

            /* pctxt->pSizeConstraint->extended = lpSize->extended; */

            break;
         }
         lpSize = lpSize->next;
      }

      if (!lpSize)
         stat = ASN_E_CONSVIO;
   }

   return stat;
}

Asn1SizeCnst* getSizeConstraint (OOCTXT* pctxt, ASN1BOOL extbit)
{
   Asn1SizeCnst* lpSize = pctxt->pSizeConstraint;

   while (lpSize) {
      if (lpSize->extended == extbit)
         return lpSize;
      else
         lpSize = lpSize->next;
   }

   return NULL;
}

int checkSizeConstraint(OOCTXT* pctxt, int size)
{
   Asn1SizeCnst* pSize;
   ASN1UINT lower, upper;
   ASN1BOOL extbit;
   int      stat;

   /* If size constraint is present and extendable, decode extension    */
   /* bit..                                                             */

   if (isExtendableSize(pctxt->pSizeConstraint)) {
      stat = DE_BIT (pctxt, &extbit);
      if (stat != ASN_OK) return LOG_ASN1ERR (pctxt, stat);
   }
   else extbit = 0;

   /* Now use the value of the extension bit to select the proper       */
   /* size constraint range specification..                             */

   pSize = getSizeConstraint (pctxt, extbit);

   lower = (pSize) ? pSize->lower : 0;
   upper = (pSize) ? pSize->upper : ASN1UINT_MAX;

   if (upper < (ASN1UINT)size) {
      return LOG_ASN1ERR (pctxt, ASN_E_CONSVIO);
   }

   return ASN_OK;
}

ASN1UINT getUIntBitCount (ASN1UINT value)
{ 
   /* Binary search - decision tree (5 tests, rarely 6) */
   return
      ((value < 1<<15) ?
       ((value < 1<<7) ?
        ((value < 1<<3) ?
         ((value < 1<<1) ? ((value < 1<<0) ? 0 : 1) : 
          ((value < 1<<2) ? 2 : 3)) :
         ((value < 1<<5) ? ((value < 1<<4) ? 4 : 5) : 
          ((value < 1<<6) ? 6 : 7))) :
        ((value < 1<<11) ?
         ((value < 1<<9) ? ((value < 1<<8) ? 8 : 9) : 
          ((value < 1<<10) ? 10 : 11)) :
         ((value < 1<<13) ? ((value < 1<<12) ? 12 : 13) : 
          ((value < 1<<14) ? 14 : 15)))) :
       ((value < 1<<23) ?
        ((value < 1<<19) ?
         ((value < 1<<17) ? ((value < 1<<16) ? 16 : 17) : 
          ((value < 1<<18) ? 18 : 19)) :
         ((value < 1<<21) ? ((value < 1<<20) ? 20 : 21) : 
          ((value < 1<<22) ? 22 : 23))) :
        ((value < 1<<27) ?
         ((value < 1<<25) ? ((value < 1<<24) ? 24 : 25) : 
          ((value < 1<<26) ? 26 : 27)) :
         ((value < 1<<29) ? ((value < 1<<28) ? 28 : 29) : 
          ((value < 1<<30) ? 30 : 
           ((value < 1UL<<31) ? 31 : 32))))));
}

void init16BitCharSet (Asn116BitCharSet* pCharSet, ASN116BITCHAR first,
                       ASN116BITCHAR last, ASN1UINT abits, ASN1UINT ubits)
{
   pCharSet->charSet.nchars = 0;
   pCharSet->charSet.data = 0;
   pCharSet->firstChar = first;
   pCharSet->lastChar  = last;
   pCharSet->unalignedBits = ubits;
   pCharSet->alignedBits = abits;
}

ASN1BOOL isExtendableSize (Asn1SizeCnst* pSizeList)
{
   Asn1SizeCnst* lpSize = pSizeList;
   while (lpSize) {
      if (lpSize->extended)
         return TRUE;
      else
         lpSize = lpSize->next;
   }
   return FALSE;
}

static ASN1BOOL isFixedSize (Asn1SizeCnst* pSizeList)
{
   Asn1SizeCnst* lpSize = pSizeList;
   if (lpSize && !lpSize->extended && !lpSize->next) {
      return (ASN1BOOL) (lpSize->lower == lpSize->upper);
   }
   return FALSE;
}

void set16BitCharSet 
(OOCTXT* pctxt, Asn116BitCharSet* pCharSet, Asn116BitCharSet* pAlphabet)
{
   /* Permitted alphabet range can either be specified as a range of    */
   /* characters or as a discrete set..                                 */

   if (pAlphabet->charSet.data) {
      int nocts = pAlphabet->charSet.nchars * 2;
      pCharSet->charSet.nchars = pAlphabet->charSet.nchars;

      pCharSet->charSet.data = 
         (ASN116BITCHAR*) ASN1MALLOC (pctxt, nocts);

      if (pCharSet->charSet.data != NULL)
         memcpy (pCharSet->charSet.data, pAlphabet->charSet.data, nocts);
   }
   else {
      pCharSet->firstChar = pAlphabet->firstChar;
      pCharSet->lastChar  = pAlphabet->lastChar;
      pCharSet->charSet.nchars = pCharSet->lastChar - pCharSet->firstChar;
   }

   pCharSet->unalignedBits = getUIntBitCount (pCharSet->charSet.nchars);

   pCharSet->alignedBits = 1;
   while (pCharSet->unalignedBits > pCharSet->alignedBits)
      pCharSet->alignedBits <<= 1;

}


--- NEW FILE: printHandler.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.
 *
 *****************************************************************************/
/* This is an implementation of a simple print handler.  It outputs 
   the fields of an encoded PER message to stdout in a structured output 
   format..
*/
#include <stdlib.h>
#include <malloc.h>
#include "printHandler.h"
#include "ootypes.h"
#include "rtctype.h"
#include "ootrace.h"

static const char* pVarName;
static int gIndentSpaces;

static const char* bitStrToString 
(ASN1UINT numbits, const ASN1OCTET* data, char* buffer, size_t bufsiz);

static const char* octStrToString 
(ASN1UINT numocts, const ASN1OCTET* data, char* buffer, size_t bufsiz);

void initializePrintHandler(EventHandler *printHandler, char * varname)
{
   printHandler->startElement = &printStartElement;
   printHandler->endElement = &printEndElement;
   printHandler->boolValue = &printBoolValue;
   printHandler->intValue = &printIntValue;
   printHandler->uIntValue = &printuIntValue ;
   printHandler->bitStrValue = &printBitStrValue;
   printHandler->octStrValue = &printOctStrValue;
   printHandler->charStrValue = &printCharStrValue;
   printHandler->charStr16BitValue = &printCharStr16BitValue ;
   printHandler->nullValue = &printNullValue;
   printHandler->oidValue = &printOidValue;
   printHandler->enumValue = &printEnumValue;
   printHandler->openTypeValue = &printOpenTypeValue;
   pVarName = varname;
   OOTRACEDBGB2("%s = {\n", pVarName);
   gIndentSpaces += 3;

}

void finishPrint()
{
   OOTRACEDBGB1 ("}\n");
   gIndentSpaces -= 3;
   if (gIndentSpaces != 0) {
      OOTRACEDBGB1 ("ERROR: unbalanced structure\n");
   }
}

void indent ()
{
   int i=0;
   for (i = 0; i < gIndentSpaces; i++) OOTRACEDBGB1 (" ");
}

void printStartElement (const char* name, int index)
{
   indent ();
   OOTRACEDBGB1 (name);
   if (index >= 0) OOTRACEDBGB2 ("[%d]", index);
   OOTRACEDBGB1 (" = {\n");
   gIndentSpaces += 3;
}

void printEndElement (const char* name, int index)
{
   gIndentSpaces -= 3;
   indent ();
   OOTRACEDBGB1 ("}\n");
}

void printBoolValue (ASN1BOOL value)
{
   const char* s = value ? "TRUE" : "FALSE";
   indent ();
   OOTRACEDBGB2 ("%s\n", s);
}

void printIntValue (ASN1INT value)
{
   indent ();
   OOTRACEDBGB2 ("%d\n", value);
}

void printuIntValue (ASN1UINT value)
{
   indent ();
   OOTRACEDBGB2 ("%u\n", value);
}

void printBitStrValue (ASN1UINT numbits, const ASN1OCTET* data)
{
   char* s = (char*)malloc(numbits + 8);
   indent ();
   OOTRACEDBGB2("%s\n", bitStrToString (numbits, data, s, numbits+8));
   free(s);
}

void printOctStrValue (ASN1UINT numocts, const ASN1OCTET* data)
{
   int bufsiz = (numocts * 2) + 8;
   char* s = (char*)malloc(bufsiz);
   indent ();
   OOTRACEDBGB2 ("%s\n", octStrToString (numocts, data, s, bufsiz));
   free(s);
}

void printCharStrValue (const char* value)
{
   indent ();
   OOTRACEDBGB2 ("\"%s\"\n", value);
}

void printCharStr16BitValue (ASN1UINT nchars, ASN116BITCHAR* data)
{
   ASN1UINT ui;
   indent ();

   for (ui = 0; ui < nchars; ui++) {
      if (data[ui] >= 32 && data[ui] <= 127)
         OOTRACEDBGB2 ("%c", (char)data[ui]);
      else
         OOTRACEDBGB1 ("?");
   }

   OOTRACEDBGB1 ("\n");
}

void printCharStr32BitValue (ASN1UINT nchars, ASN132BITCHAR* data)
{
   ASN1UINT ui;
   indent ();

   for ( ui = 0; ui < nchars; ui++) {
      if (data[ui] >= 32 && data[ui] <= 127)
         OOTRACEDBGB2 ("%c", (char)data[ui]);
      else
         OOTRACEDBGB2 ("\\%d", data[ui]);
   }

   OOTRACEDBGB1 ("\n");
}

void printNullValue ()
{
   indent ();
   OOTRACEDBGB1 ("NULL\n");
}

void ooPrintOIDValue (ASN1OBJID* pOID)
{
   ASN1UINT ui;
   OOTRACEDBGB1 ("{ \n");
   for (ui = 0; ui < pOID->numids; ui++) {
      OOTRACEDBGB2 ("%d ", pOID->subid[ui]);
   }
   OOTRACEDBGB1 ("}\n");
}

void printOidValue (ASN1UINT numSubIds, ASN1UINT* pSubIds)
{
   ASN1UINT ui;
   ASN1OBJID oid;
   oid.numids = numSubIds;

   for ( ui = 0; ui < numSubIds; ui++)
      oid.subid[ui] = pSubIds[ui];

   indent ();
   ooPrintOIDValue (&oid);
}

void printRealValue (double value)
{
   indent ();
   OOTRACEDBGB2 ("%f\n", value);
}

void printEnumValue (ASN1UINT value)
{
   indent ();
   OOTRACEDBGB2 ("%u\n", value);
}

void printOpenTypeValue (ASN1UINT numocts, const ASN1OCTET* data)
{
   indent ();
   OOTRACEDBGB1 ("< encoded data >\n");
}

static const char* bitStrToString 
(ASN1UINT numbits, const ASN1OCTET* data, char* buffer, size_t bufsiz)
{
   size_t i;
   unsigned char mask = 0x80;

   if (bufsiz > 0) {
      buffer[0] = '\'';
      for (i = 0; i < numbits; i++) {
         if (i < bufsiz - 1) {
            buffer[i+1] = (char) (((data[i/8] & mask) != 0) ? '1' : '0');
            mask >>= 1;
            if (0 == mask) mask = 0x80;
         }
         else break;
      }
     i++;
      if (i < bufsiz - 1) buffer[i++] = '\'';
      if (i < bufsiz - 1) buffer[i++] = 'B';
      if (i < bufsiz - 1) buffer[i] = '\0';
      else buffer[bufsiz - 1] = '\0';
   }

   return buffer;
}

static const char* octStrToString 
(ASN1UINT numocts, const ASN1OCTET* data, char* buffer, size_t bufsiz)
{
   size_t i;
   char lbuf[4];

   if (bufsiz > 0) {
      buffer[0] = '\'';
      if (bufsiz > 1) buffer[1] = '\0';
      for (i = 0; i < numocts; i++) {
         if (i < bufsiz - 1) {
            sprintf (lbuf, "%02x", data[i]);
            strcat (&buffer[(i*2)+1], lbuf);
         }
         else break;
      }
     i = i*2 + 1;
      if (i < bufsiz - 1) buffer[i++] = '\'';
      if (i < bufsiz - 1) buffer[i++] = 'H';
      if (i < bufsiz - 1) buffer[i] = '\0';
      else buffer[bufsiz - 1] = '\0';
   }

   return buffer;
}

--- NEW FILE: printHandler.h ---
/*
 * 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.
 *
 *****************************************************************************/
/**
   @file printHandler.h  
   This is an implementation of a simple print handler.  It outputs 
   the fields of an encoded PER message to stdout in a structured output 
   format..
*/

#ifndef _PRINTHANDLER_H_
#define _PRINTHANDLER_H_

#include "eventHandler.h"

EventHandler printHandler;

void initializePrintHandler(EventHandler *printHandler, char * varname);
void finishPrint();
void indent ();
void printStartElement (const char* name, int index );
void printEndElement (const char* name, int index );
void printBoolValue (ASN1BOOL value);
void printIntValue (ASN1INT value);
void printuIntValue (ASN1UINT value);
void printBitStrValue (ASN1UINT numbits, const ASN1OCTET* data);
void printOctStrValue (ASN1UINT numocts, const ASN1OCTET* data);
void printCharStrValue (const char* value);
void printCharStr16BitValue (ASN1UINT nchars, ASN116BITCHAR* data);
void printNullValue ();
void printOidValue (ASN1UINT numSubIds, ASN1UINT* pSubIds);
void printEnumValue (ASN1UINT value);
void printOpenTypeValue (ASN1UINT numocts, const ASN1OCTET* data);

#endif

--- NEW FILE: rtctype.c ---
/*
 * Copyright (C) 1997-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.
 *
 *****************************************************************************/

/* Run-time ctype substitution */

#include "ooasn1.h"
#include "rtctype.h"

const ASN1OCTET rtCtypeTable[256] = {
   OS_CTYPE_CTRL,                   /* 00 (NUL) */
   OS_CTYPE_CTRL,                   /* 01 (SOH) */
   OS_CTYPE_CTRL,                   /* 02 (STX) */
   OS_CTYPE_CTRL,                   /* 03 (ETX) */
   OS_CTYPE_CTRL,                   /* 04 (EOT) */
   OS_CTYPE_CTRL,                   /* 05 (ENQ) */
   OS_CTYPE_CTRL,                   /* 06 (ACK) */
   OS_CTYPE_CTRL,                   /* 07 (BEL) */
   OS_CTYPE_CTRL,                   /* 08 (BS)  */
   OS_CTYPE_CTRL|OS_CTYPE_SPACE,    /* 09 (HT)  */
   OS_CTYPE_CTRL|OS_CTYPE_SPACE,    /* 0A (LF)  */
   OS_CTYPE_CTRL|OS_CTYPE_SPACE,    /* 0B (VT)  */
   OS_CTYPE_CTRL|OS_CTYPE_SPACE,    /* 0C (FF)  */
   OS_CTYPE_CTRL|OS_CTYPE_SPACE,    /* 0D (CR)  */
   OS_CTYPE_CTRL,                   /* 0E (SI)  */
   OS_CTYPE_CTRL,                   /* 0F (SO)  */
   OS_CTYPE_CTRL,                   /* 10 (DLE) */
   OS_CTYPE_CTRL,                   /* 11 (DC1) */
   OS_CTYPE_CTRL,                   /* 12 (DC2) */
   OS_CTYPE_CTRL,                   /* 13 (DC3) */
   OS_CTYPE_CTRL,                   /* 14 (DC4) */
   OS_CTYPE_CTRL,                   /* 15 (NAK) */
   OS_CTYPE_CTRL,                   /* 16 (SYN) */
   OS_CTYPE_CTRL,                   /* 17 (ETB) */
   OS_CTYPE_CTRL,                   /* 18 (CAN) */
   OS_CTYPE_CTRL,                   /* 19 (EM)  */
   OS_CTYPE_CTRL,                   /* 1A (SUB) */
   OS_CTYPE_CTRL,                   /* 1B (ESC) */
   OS_CTYPE_CTRL,                   /* 1C (FS)  */
   OS_CTYPE_CTRL,                   /* 1D (GS)  */
   OS_CTYPE_CTRL,                   /* 1E (RS)  */
   OS_CTYPE_CTRL,                   /* 1F (US)  */
   OS_CTYPE_SPACE|OS_CTYPE_BLANK,   /* 20 SPACE */
   OS_CTYPE_PUNCT,                  /* 21 !     */
   OS_CTYPE_PUNCT,                  /* 22 "     */
   OS_CTYPE_PUNCT,                  /* 23 #     */
   OS_CTYPE_PUNCT,                  /* 24 $     */
   OS_CTYPE_PUNCT,                  /* 25 %     */
   OS_CTYPE_PUNCT,                  /* 26 &     */
   OS_CTYPE_PUNCT,                  /* 27 '     */
   OS_CTYPE_PUNCT,                  /* 28 (     */
   OS_CTYPE_PUNCT,                  /* 29 )     */
   OS_CTYPE_PUNCT,                  /* 2A *     */
   OS_CTYPE_PUNCT,                  /* 2B +     */
   OS_CTYPE_PUNCT,                  /* 2C ,     */
   OS_CTYPE_PUNCT,                  /* 2D -     */
   OS_CTYPE_PUNCT,                  /* 2E .     */
   OS_CTYPE_PUNCT,                  /* 2F /     */
   OS_CTYPE_NUMBER,                 /* 30 0     */
   OS_CTYPE_NUMBER,                 /* 31 1     */
   OS_CTYPE_NUMBER,                 /* 32 2     */
   OS_CTYPE_NUMBER,                 /* 33 3     */
   OS_CTYPE_NUMBER,                 /* 34 4     */
   OS_CTYPE_NUMBER,                 /* 35 5     */
   OS_CTYPE_NUMBER,                 /* 36 6     */
   OS_CTYPE_NUMBER,                 /* 37 7     */
   OS_CTYPE_NUMBER,                 /* 38 8     */
   OS_CTYPE_NUMBER,                 /* 39 9     */
   OS_CTYPE_PUNCT,                  /* 3A :     */
   OS_CTYPE_PUNCT,                  /* 3B ;     */
   OS_CTYPE_PUNCT,                  /* 3C <     */
   OS_CTYPE_PUNCT,                  /* 3D =     */
   OS_CTYPE_PUNCT,                  /* 3E >     */
   OS_CTYPE_PUNCT,                  /* 3F ?     */
   OS_CTYPE_PUNCT,                  /* 40 @     */
   OS_CTYPE_UPPER|OS_CTYPE_HEX,     /* 41 A     */
   OS_CTYPE_UPPER|OS_CTYPE_HEX,     /* 42 B     */
   OS_CTYPE_UPPER|OS_CTYPE_HEX,     /* 43 C     */
   OS_CTYPE_UPPER|OS_CTYPE_HEX,     /* 44 D     */
   OS_CTYPE_UPPER|OS_CTYPE_HEX,     /* 45 E     */
   OS_CTYPE_UPPER|OS_CTYPE_HEX,     /* 46 F     */
   OS_CTYPE_UPPER,                  /* 47 G     */
   OS_CTYPE_UPPER,                  /* 48 H     */
   OS_CTYPE_UPPER,                  /* 49 I     */
   OS_CTYPE_UPPER,                  /* 4A J     */
   OS_CTYPE_UPPER,                  /* 4B K     */
   OS_CTYPE_UPPER,                  /* 4C L     */
   OS_CTYPE_UPPER,                  /* 4D M     */
   OS_CTYPE_UPPER,                  /* 4E N     */
   OS_CTYPE_UPPER,                  /* 4F O     */
   OS_CTYPE_UPPER,                  /* 50 P     */
   OS_CTYPE_UPPER,                  /* 51 Q     */
   OS_CTYPE_UPPER,                  /* 52 R     */
   OS_CTYPE_UPPER,                  /* 53 S     */
   OS_CTYPE_UPPER,                  /* 54 T     */
   OS_CTYPE_UPPER,                  /* 55 U     */
   OS_CTYPE_UPPER,                  /* 56 V     */
   OS_CTYPE_UPPER,                  /* 57 W     */
   OS_CTYPE_UPPER,                  /* 58 X     */
   OS_CTYPE_UPPER,                  /* 59 Y     */
   OS_CTYPE_UPPER,                  /* 5A Z     */
   OS_CTYPE_PUNCT,                  /* 5B [     */
   OS_CTYPE_PUNCT,                  /* 5C \     */
   OS_CTYPE_PUNCT,                  /* 5D ]     */
   OS_CTYPE_PUNCT,                  /* 5E ^     */
   OS_CTYPE_PUNCT,                  /* 5F _     */
   OS_CTYPE_PUNCT,                  /* 60 `     */
   OS_CTYPE_LOWER|OS_CTYPE_HEX,     /* 61 a     */
   OS_CTYPE_LOWER|OS_CTYPE_HEX,     /* 62 b     */
   OS_CTYPE_LOWER|OS_CTYPE_HEX,     /* 63 c     */
   OS_CTYPE_LOWER|OS_CTYPE_HEX,     /* 64 d     */
   OS_CTYPE_LOWER|OS_CTYPE_HEX,     /* 65 e     */
   OS_CTYPE_LOWER|OS_CTYPE_HEX,     /* 66 f     */
   OS_CTYPE_LOWER,                  /* 67 g     */
   OS_CTYPE_LOWER,                  /* 68 h     */
   OS_CTYPE_LOWER,                  /* 69 i     */
   OS_CTYPE_LOWER,                  /* 6A j     */
   OS_CTYPE_LOWER,                  /* 6B k     */
   OS_CTYPE_LOWER,                  /* 6C l     */
   OS_CTYPE_LOWER,                  /* 6D m     */
   OS_CTYPE_LOWER,                  /* 6E n     */
   OS_CTYPE_LOWER,                  /* 6F o     */
   OS_CTYPE_LOWER,                  /* 70 p     */
   OS_CTYPE_LOWER,                  /* 71 q     */
   OS_CTYPE_LOWER,                  /* 72 r     */
   OS_CTYPE_LOWER,                  /* 73 s     */
   OS_CTYPE_LOWER,                  /* 74 t     */
   OS_CTYPE_LOWER,                  /* 75 u     */
   OS_CTYPE_LOWER,                  /* 76 v     */
   OS_CTYPE_LOWER,                  /* 77 w     */
   OS_CTYPE_LOWER,                  /* 78 x     */
   OS_CTYPE_LOWER,                  /* 79 y     */
   OS_CTYPE_LOWER,                  /* 7A z     */
   OS_CTYPE_PUNCT,                  /* 7B {     */
   OS_CTYPE_PUNCT,                  /* 7C |     */
   OS_CTYPE_PUNCT,                  /* 7D }     */
   OS_CTYPE_PUNCT,                  /* 7E ~     */
   OS_CTYPE_CTRL,                   /* 7F (DEL) */

   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0,
   0, 0, 0, 0, 0, 0, 0, 0
};

--- NEW FILE: rtctype.h ---
/*
 * Copyright (C) 1997-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.
 *
 *****************************************************************************/

/** 
 * @file rtctype.h 
 */
#ifndef _RTCTYPE_H_
#define _RTCTYPE_H_

#include "ooasn1.h"

/* Ctype module constants */

#define  OS_CTYPE_UPPER  0x1
#define  OS_CTYPE_LOWER  0x2
#define  OS_CTYPE_NUMBER 0x4
#define  OS_CTYPE_SPACE  0x8
#define  OS_CTYPE_PUNCT  0x10
#define  OS_CTYPE_CTRL   0x20
#define  OS_CTYPE_HEX    0x40
#define  OS_CTYPE_BLANK  0x80

/* Ctype substitution macros */

#define  OS_ISALPHA(c) \
(rtCtypeTable[(unsigned)(c)]&(OS_CTYPE_UPPER|OS_CTYPE_LOWER))
#define  OS_ISUPPER(c)  \
(rtCtypeTable[(unsigned)(c)]&OS_CTYPE_UPPER)
#define  OS_ISLOWER(c)  \
(rtCtypeTable[(unsigned)(c)]&OS_CTYPE_LOWER)
#define  OS_ISDIGIT(c)  \
(rtCtypeTable[(unsigned)(c)]&OS_CTYPE_NUMBER)
#define  OS_ISXDIGIT(c) \
(rtCtypeTable[(unsigned)(c)]&(OS_CTYPE_HEX|OS_CTYPE_NUMBER))
#define  OS_ISSPACE(c)  \
(rtCtypeTable[(unsigned)(c)]&OS_CTYPE_SPACE)
#define  OS_ISPUNCT(c)  \
(rtCtypeTable[(unsigned)(c)]&OS_CTYPE_PUNCT)
#define  OS_ISALNUM(c)  \
(rtCtypeTable[(unsigned)(c)]&(OS_CTYPE_UPPER|OS_CTYPE_LOWER|OS_CTYPE_NUMBER))
#define  OS_ISPRINT(c)  \
(rtCtypeTable[(unsigned)(c)]& \
(OS_CTYPE_PUNCT|OS_CTYPE_UPPER|OS_CTYPE_LOWER|OS_CTYPE_NUMBER|OS_CTYPE_BLANK))
#define  OS_ISGRAPH(c)  \
(rtCtypeTable[(unsigned)(c)]& \
(OS_CTYPE_PUNCT|OS_CTYPE_UPPER|OS_CTYPE_LOWER|OS_CTYPE_NUMBER))
#define  OS_ISCNTRL(c)  \
(rtCtypeTable[(unsigned)(c)]&OS_CTYPE_CTRL)

#define  OS_TOLOWER(c) (OS_ISUPPER(c) ? (c) - 'A' + 'a' : (c))
#define  OS_TOUPPER(c) (OS_ISLOWER(c) ? (c) - 'a' + 'A' : (c))

#ifdef __cplusplus
extern "C" {
#endif

#ifndef EXTERN
#ifdef _WIN32
#define EXTERN __declspec(dllexport)
#else
#define EXTERN
#endif /* _WIN32 */
#endif /* EXTERN */
/* ctype module table */

extern EXTERN const ASN1OCTET rtCtypeTable[256];

#ifdef __cplusplus
}
#endif

#endif /* _RTCTYPE_H_ */





More information about the svn-commits mailing list