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

Modified Files:
        ooCalls.c ooCalls.h ooCapability.c ooCapability.h ooGkClient.c 
        ooStackCmds.c ooStackCmds.h ooh245.c ooh245.h ooh323.c 
        ooh323ep.c ooh323ep.h ooq931.c ooq931.h ootypes.h 
Log Message:
Update - DTMF using H.245 and Q931 support

Index: ooCalls.c
===================================================================
RCS file: /usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooCalls.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- ooCalls.c   3 Aug 2005 19:03:32 -0000       1.6
+++ ooCalls.c   2 Sep 2005 14:27:10 -0000       1.7
@@ -557,6 +557,38 @@
   return ooCapabilityDisableDTMFRFC2833(call);
 }
 
+
+int ooCallEnableDTMFH245Alphanumeric(OOH323CallData *call)
+{
+   return ooCapabilityEnableDTMFH245Alphanumeric(call);
+}
+
+int ooCallDisableDTMFH245Alphanumeric(OOH323CallData *call)
+{
+   return ooCapabilityDisableDTMFH245Alphanumeric(call);
+}
+
+int ooCallEnableDTMFH245Signal(OOH323CallData *call)
+{
+   return ooCapabilityEnableDTMFH245Signal(call);
+}
+
+int ooCallDisableDTMFH245Signal(OOH323CallData *call)
+{
+   return ooCapabilityDisableDTMFH245Signal(call);
+}
+
+int ooCallEnableDTMFQ931Keypad(OOH323CallData *call)
+{
+   return ooCapabilityEnableDTMFQ931Keypad(call);
+}
+
+int ooCallDisableDTMFQ931Keypad(OOH323CallData *call)
+{
+   return ooCapabilityDisableDTMFQ931Keypad(call);
+}
+
+
 OOH323CallData* ooFindCallByToken(char *callToken)
 {
    OOH323CallData *call;

Index: ooCalls.h
===================================================================
RCS file: /usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooCalls.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- ooCalls.h   3 Aug 2005 19:03:32 -0000       1.4
+++ ooCalls.h   2 Sep 2005 14:27:10 -0000       1.5
@@ -158,6 +158,7 @@
    struct ooH323EpCapability* ourCaps;
    struct ooH323EpCapability* remoteCaps; /* TODO: once we start using 
jointCaps, get rid of remoteCaps*/
    struct ooH323EpCapability* jointCaps;
+   int                  jointDtmfMode;
    DList                remoteFastStartOLCs;
    ASN1UINT8            remoteTermCapSeqNo;
    ASN1UINT8            localTermCapSeqNo;
@@ -254,6 +255,14 @@
 typedef int (*cb_OnCallForwarded)(struct OOH323CallData* call);
 
 /**
+ * This callback function is triggered when dtmf is received over Q.931(keypad)
+ * or H.245(alphanumeric) or H.245(signal). This is not triggered when rfc
+ * 2833 based dtmf is received.
+ */
+typedef int (*cb_OnReceivedDTMF)
+   (struct OOH323CallData *call, const char *dtmf);
+
+/**
  * This structure holds all of the H.323 signaling callback function 
  * addresses.
  * @see ooH323EpSetH323Callbacks
@@ -267,6 +276,7 @@
    cb_OnCallForwarded onCallForwarded;
    cb_OnCallCleared onCallCleared;
    cb_OpenLogicalChannels openLogicalChannels;
+   cb_OnReceivedDTMF onReceivedDTMF;
 } OOH323CALLBACKS;
 
 /**
@@ -587,6 +597,82 @@
  */
 EXTERN int ooCallDisableDTMFRFC2833(OOH323CallData *call);
 
+
+/**
+ * This function is used to enable H.245(alphanumeric) dtmf support for the 
+ * call. By default the stack uses the dtmf settings for the endpoint. But if 
+ * you want to enable H.245(alphanumeric) dtmf for a specific call, then you 
+ * can override end-point settings using this function
+ * @param call                  Call for which H.245(alphanumeric) dtmf support
+ *                              has to be enabled.
+ *
+ * @return                      OO_OK, on success. OO_FAILED, on failure
+ */
+EXTERN int ooCallEnableDTMFH245Alphanumeric(OOH323CallData *call);
+
+/**
+ * This function is used to disable H.245(alphanumeric) dtmf support for the 
+ * call. By default the stack uses the dtmf settings for the endpoint. But if 
+ * you want to disable H.245(alphanumeric) dtmf for a specific call, then you 
+ * can override end-point settings using this function
+ * @param call                  Call for which H.245(alphanumeric) dtmf support
+ *                              has to be disabled.
+ *
+ * @return                      OO_OK, on success. OO_FAILED, on failure
+ */
+EXTERN int ooCallDisableDTMFH245Alphanumeric(OOH323CallData *call);
+
+/**
+ * This function is used to enable H.245(signal) dtmf support for the call. 
+ * By default the stack uses the dtmf settings for the endpoint. But if you 
+ * want to enable H.245(signal) dtmf for a specific call, then you can override
+ * end-point settings using this function
+ * @param call                  Call for which H.245(signal) dtmf support
+ *                              has to be enabled.
+ *
+ * @return                      OO_OK, on success. OO_FAILED, on failure
+ */
+EXTERN int ooCallEnableDTMFH245Signal(OOH323CallData *call);
+
+
+/**
+ * This function is used to disable H.245(signal) dtmf support for the call. 
+ * By default the stack uses the dtmf settings for the endpoint. But if you 
+ * want to disable H.245(signal) dtmf for a specific call, then you can 
+ * override end-point settings using this function
+ * @param call                  Call for which H.245(signal) dtmf support
+ *                              has to be disabled.
+ *
+ * @return                      OO_OK, on success. OO_FAILED, on failure
+ */
+EXTERN int ooCallDisableDTMFH245Signal(OOH323CallData *call);
+
+
+/**
+ * This function is used to enable Q.931(keypad) dtmf support for the call.
+ * By default the stack uses the dtmf settings for the endpoint. But if you 
+ * want to enable Q.931(keypad) dtmf support for a specific call, then you can
+ * override end-point settings using this function
+ * @param call                  Call for which Q.931(keypad) dtmf support
+ *                              has to be enabled.
+ *
+ * @return                      OO_OK, on success. OO_FAILED, on failure
+ */
+EXTERN int ooCallEnableDTMFQ931Keypad(OOH323CallData *call);
+
+/**
+ * This function is used to disable Q.931(keypad) dtmf support for the call.
+ * By default the stack uses the dtmf settings for the endpoint. But if you 
+ * want to disable Q.931(keypad) dtmf support for a specific call, then you can
+ * override end-point settings using this function
+ * @param call                  Call for which Q.931(keypad) dtmf support
+ *                              has to be disabled.
+ *
+ * @return                      OO_OK, on success. OO_FAILED, on failure
+ */
+EXTERN int ooCallDisableDTMFQ931Keypad(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.

Index: ooCapability.c
===================================================================
RCS file: 
/usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooCapability.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- ooCapability.c      4 Aug 2005 14:54:20 -0000       1.7
+++ ooCapability.c      2 Sep 2005 14:27:10 -0000       1.8
@@ -59,7 +59,83 @@
    return OO_OK;
 }
 
+int ooCapabilityEnableDTMFH245Alphanumeric(OOH323CallData *call)
+{
+   if(!call){
+      gH323ep.dtmfmode |= OO_CAP_DTMF_H245_alphanumeric;
+      OOTRACEINFO1("Dtmf mode set to H.245(alphanumeric) for endpoint\n");
+   }else {
+      call->dtmfmode |= OO_CAP_DTMF_H245_alphanumeric;
+      OOTRACEINFO3("Dtmf mode set to H.245(alphanumeric) for (%s, %s)\n", 
+                    call->callType, call->callToken);
+   }
+   return OO_OK;
+}
+
+int ooCapabilityDisableDTMFH245Alphanumeric(OOH323CallData *call)
+{
+   if(!call){
+      gH323ep.dtmfmode ^= OO_CAP_DTMF_H245_alphanumeric;
+      OOTRACEINFO1("Dtmf mode H.245(alphanumeric) disabled for endpoint\n");
+   }else {
+      call->dtmfmode ^= OO_CAP_DTMF_H245_alphanumeric;
+      OOTRACEINFO3("Dtmf mode H.245(alphanumeric) disabled for (%s, %s)\n", 
+                    call->callType, call->callToken);
+   }
+   return OO_OK;
+}
+
+int ooCapabilityEnableDTMFH245Signal(OOH323CallData *call)
+{
+   if(!call){
+      gH323ep.dtmfmode |= OO_CAP_DTMF_H245_signal;
+      OOTRACEINFO1("Dtmf mode set to H.245(signal) for endpoint\n");
+   }else {
+      call->dtmfmode |= OO_CAP_DTMF_H245_signal;
+      OOTRACEINFO3("Dtmf mode set to H.245(signal) for (%s, %s)\n", 
+                    call->callType, call->callToken);
+   }
+   return OO_OK;
+}
 
+int ooCapabilityDisableDTMFH245Signal(OOH323CallData *call)
+{
+   if(!call){
+      gH323ep.dtmfmode ^= OO_CAP_DTMF_H245_signal;
+      OOTRACEINFO1("Dtmf mode H.245(signal) disabled for endpoint\n");
+   }else {
+      call->dtmfmode ^= OO_CAP_DTMF_H245_signal;
+      OOTRACEINFO3("Dtmf mode H.245(signal) disabled for (%s, %s)\n", 
+                    call->callType, call->callToken);
+   }
+   return OO_OK;
+}
+
+int ooCapabilityEnableDTMFQ931Keypad(struct OOH323CallData *call)
+{
+   if(!call){
+      gH323ep.dtmfmode |= OO_CAP_DTMF_Q931;
+      OOTRACEINFO1("Dtmf mode set to Q.931(keypad) for the endpoint\n");
+   }else {
+      call->dtmfmode |= OO_CAP_DTMF_Q931;
+      OOTRACEINFO3("Dtmf mode set to Q.931(keypad) for the call (%s, %s)\n", 
+                    call->callType, call->callToken);
+   }
+   return OO_OK;
+}
+
+int ooCapabilityDisableDTMFQ931Keypad(struct OOH323CallData *call)
+{
+   if(!call){
+      gH323ep.dtmfmode ^= OO_CAP_DTMF_Q931;
+      OOTRACEINFO1("Dtmf mode Q.931(keypad) disabled for the endpoint\n");
+   }else {
+      call->dtmfmode ^= OO_CAP_DTMF_Q931;
+      OOTRACEINFO3("Dtmf mode Q.931(keypad) disabled for the call (%s, %s)\n", 
+                    call->callType, call->callToken);
+   }
+   return OO_OK;
+}
 
 int ooCapabilityAddH263VideoCapability(ooCallData *call, 
                               unsigned sqcifMPI, unsigned qcifMPI, 
@@ -532,6 +608,7 @@
 void* ooCapabilityCreateDTMFCapability(int cap, OOCTXT *pctxt)
 {
    H245AudioTelephonyEventCapability *pATECap=NULL;
+   H245UserInputCapability *userInput = NULL;
    char *events=NULL;
    switch(cap)
    {
@@ -555,6 +632,28 @@
       strncpy(events, "0-16", strlen("0-16"));
       pATECap->audioTelephoneEvent = events;
       return pATECap;
+   case OO_CAP_DTMF_H245_alphanumeric:
+      userInput = (H245UserInputCapability*)memAllocZ(pctxt, 
+                                          sizeof(H245UserInputCapability));
+      if(!userInput)
+      {
+         OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - "
+                     "userInput\n");
+         return NULL;
+      }
+      userInput->t = T_H245UserInputCapability_basicString;
+      return userInput;
+   case OO_CAP_DTMF_H245_signal:
+      userInput = (H245UserInputCapability*)memAllocZ(pctxt, 
+                                          sizeof(H245UserInputCapability));
+      if(!userInput)
+      {
+         OOTRACEERR1("Error:Memory - ooCapabilityCreateDTMFCapability - "
+                     "userInput\n");
+         return NULL;
+      }
+      userInput->t = T_H245UserInputCapability_dtmf;
+      return userInput;
    default:
      OOTRACEERR1("Error:unknown dtmf capability type\n");
    }
@@ -1922,7 +2021,21 @@
    case T_H245Capability_transmitVideoCapability:
       return ooCapabilityUpdateJointCapabilitiesVideo(call, 
                                          cap->u.transmitVideoCapability, OORX);
-   
+   case T_H245Capability_receiveUserInputCapability:
+      if((cap->u.receiveUserInputCapability->t == 
+                                 T_H245UserInputCapability_basicString) &&
+         (call->dtmfmode & OO_CAP_DTMF_H245_alphanumeric))
+      {
+         call->jointDtmfMode |= OO_CAP_DTMF_H245_alphanumeric;
+         return OO_OK;
+      }else if((cap->u.receiveUserInputCapability->t ==
+                                         T_H245UserInputCapability_dtmf) &&
+              (call->dtmfmode & OO_CAP_DTMF_H245_signal))
+      {
+         call->jointDtmfMode |= OO_CAP_DTMF_H245_signal;
+         return OO_OK;
+      }
+      //break;
    default:
      OOTRACEDBGA3("Unsupported cap type encountered. Ignoring. (%s, %s)\n", 
                    call->callType, call->callToken);

Index: ooCapability.h
===================================================================
RCS file: 
/usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooCapability.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- ooCapability.h      16 Jun 2005 19:41:23 -0000      1.5
+++ ooCapability.h      2 Sep 2005 14:27:10 -0000       1.6
@@ -55,9 +55,10 @@
 
 
 /*DTMF capabilities*/
-#define OO_CAP_DTMF_RFC2833 (1<<0)
-#define OO_CAP_DTMF_Q931    (1<<1)
-#define OO_CAP_DTMF_H245    (1<<2)
+#define OO_CAP_DTMF_RFC2833              (1<<0)
+#define OO_CAP_DTMF_Q931                 (1<<1)
+#define OO_CAP_DTMF_H245_alphanumeric    (1<<2)
+#define OO_CAP_DTMF_H245_signal          (1<<3)
 
 /**
  * This structure defines the preference order for capabilities.
@@ -208,6 +209,58 @@
 EXTERN int ooCapabilityDisableDTMFRFC2833(struct OOH323CallData *call);
 
 
+/**
+ * This function is used to enable support for H.245 based alphanumeric dtmf 
+ * capability.
+ * @param call             Handle to call, if enabling for the call, else NULL
+ *                         for end-point.
+ * @return                 OO_OK, on success. OO_FAILED, on failure.
+ */
+EXTERN int ooCapabilityEnableDTMFH245Alphanumeric(struct OOH323CallData *call);
+
+/**
+ * This function is used to disable support for H.245 based alphanumeric dtmf 
+ * 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 ooCapabilityDisableDTMFH245Alphanumeric
+                                             (struct OOH323CallData *call);
+
+/**
+ * This function is used to enable support for H.245 based signal dtmf 
+ * capability.
+ * @param call             Handle to call, if enabling for the call, else NULL
+ *                         for end-point.
+ * @return                 OO_OK, on success. OO_FAILED, on failure.
+ */
+EXTERN int ooCapabilityEnableDTMFH245Signal(struct OOH323CallData *call);
+
+/**
+ * This function is used to disable support for H.245 based signal dtmf 
+ * 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 ooCapabilityDisableDTMFH245Signal(struct OOH323CallData *call);
+
+/**
+ * This function is used to enable support for dtmf using Q.931 Keypad IE.
+ * @param call             Handle to call, if enabling for the call, else NULL
+ *                         for end-point.
+ * @return                 OO_OK, on success. OO_FAILED, on failure.
+ */
+EXTERN int ooCapabilityEnableDTMFQ931Keypad(struct OOH323CallData *call);
+
+/**
+ * This function is used to disable support for dtmf using Q.931 Keypad IE.
+ * @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 ooCapabilityDisableDTMFQ931Keypad(struct OOH323CallData *call);
 
 /**
  * This function is used to add simple capabilities which have only rxframes

Index: ooGkClient.c
===================================================================
RCS file: 
/usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooGkClient.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- ooGkClient.c        10 Aug 2005 17:20:04 -0000      1.6
+++ ooGkClient.c        2 Sep 2005 14:27:10 -0000       1.7
@@ -36,6 +36,7 @@
 #include "ooTimer.h"
 #include "ooSocket.h"
 #include "ooUtils.h"
+
 /** Global endpoint structure */
 extern OOH323EndPoint gH323ep;
 

Index: ooStackCmds.c
===================================================================
RCS file: 
/usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooStackCmds.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- ooStackCmds.c       6 Jul 2005 12:49:54 -0000       1.5
+++ ooStackCmds.c       2 Sep 2005 14:27:10 -0000       1.6
@@ -19,6 +19,7 @@
 #include "ooq931.h"
 #include "ooh323ep.h"
 #include "oochannels.h"
+#include "ooCalls.h"
 
 /** Global endpoint structure */
 extern OOH323EndPoint gH323ep;
@@ -114,7 +115,7 @@
 
    if(!callToken)
    {
-      OOTRACEERR1("ERROR: Invalid callToken passed to ooHangCall\n");
+      OOTRACEERR1("ERROR: Invalid callToken passed to ooAnswerCall\n");
       return OO_FAILED;
    }
 
@@ -164,7 +165,7 @@
 
    if(!callToken || !dest)
    {
-      OOTRACEERR1("ERROR: Invalid callToken/dest passed to ooHangCall\n");
+      OOTRACEERR1("ERROR: Invalid callToken/dest passed to ooForwardCall\n");
       return OO_FAILED;
    }
 #ifdef _WIN32
@@ -183,7 +184,7 @@
 
    cmd->param1 = (void*) memAlloc(&gH323ep.ctxt, strlen(callToken)+1);
    cmd->param2 = (void*) memAlloc(&gH323ep.ctxt, strlen(dest)+1);
-   if(!cmd->param1)
+   if(!cmd->param1 || !cmd->param2)
    {
       OOTRACEERR1("ERROR:Memory - ooForwardCall - param1/param2\n");
       return OO_FAILED;
@@ -262,6 +263,7 @@
 
 int ooProcStackCmds()
 {
+   OOH323CallData *call = NULL;
    if (gH323ep.stkCmdList.count > 0)
    {
       OOStackCommand *cmd;
@@ -320,6 +322,29 @@
                dListRemove(&gH323ep.stkCmdList, pNode);
                memFreePtr(&gH323ep.ctxt, pNode);
                break;
+            
+            case OO_CMD_SENDDIGIT:
+               call = ooFindCallByToken((char*)cmd->param1);
+               if(!call)
+               {
+                  OOTRACEERR2("Error:Invalid calltoken %s\n", 
+                                                         (char*)cmd->param1);
+                  dListRemove(&gH323ep.stkCmdList, pNode);
+                  memFreePtr(&gH323ep.ctxt, pNode);
+                  break;
+               }
+               if(call->jointDtmfMode & OO_CAP_DTMF_H245_alphanumeric)
+                  ooSendH245UserInputIndication_alphanumeric(call, 
+                                                    (const char*)cmd->param2);
+               else if(call->jointDtmfMode & OO_CAP_DTMF_H245_signal)
+                  ooSendH245UserInputIndication_signal(call, 
+                                                     (const char*)cmd->param2);
+               else
+                  ooQ931SendDTMFAsKeyPadIE(call, (const char*)cmd->param2);
+
+               dListRemove(&gH323ep.stkCmdList, pNode);
+               memFreePtr(&gH323ep.ctxt, pNode);
+               break;
 
             case OO_CMD_STOPMONITOR: 
                OOTRACEINFO1("Processing StopMonitor command\n");
@@ -373,3 +398,55 @@
 #endif
    return OO_OK;
 }
+
+int ooSendDTMFDigit(char *callToken, char* dtmf)
+{
+   OOStackCommand *cmd = NULL;
+
+   if(!callToken)
+   {
+      OOTRACEERR1("ERROR: Invalid callToken passed to ooSendDTMFDigit\n");
+      return OO_FAILED;
+   }
+
+#ifdef _WIN32
+   EnterCriticalSection(&gCmdMutex);
+#else
+   pthread_mutex_lock(&gCmdMutex);
+#endif
+   cmd = (OOStackCommand*)memAlloc(&gH323ep.ctxt, sizeof(OOStackCommand));
+   if(!cmd)
+   {
+      OOTRACEERR1("Error:Memory - ooSendDTMFDigit - cmd\n");
+      return OO_FAILED;
+   }
+   memset(cmd, 0, sizeof(OOStackCommand));
+   cmd->type = OO_CMD_SENDDIGIT;
+
+   cmd->param1 = (void*) memAlloc(&gH323ep.ctxt, strlen(callToken)+1);
+   cmd->param2 = (void*) memAlloc(&gH323ep.ctxt, strlen(dtmf)+1);
+   if(!cmd->param1 || !cmd->param2)
+   {
+      OOTRACEERR1("ERROR:Memory - ooSendDTMFDigit - param1/param2\n");
+      return OO_FAILED;
+   }
+   strcpy((char*)cmd->param1, callToken);
+   strcpy((char*)cmd->param2, dtmf);
+   
+   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;
+}

Index: ooStackCmds.h
===================================================================
RCS file: 
/usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooStackCmds.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- ooStackCmds.h       16 Jun 2005 19:41:23 -0000      1.4
+++ ooStackCmds.h       2 Sep 2005 14:27:10 -0000       1.5
@@ -35,6 +35,8 @@
 #define EXTERN
 #endif /* MAKE_DLL */
 #endif /* EXTERN */
+
+
 /** 
  * @defgroup stackcmds Stack Control Commands
  * @{
@@ -47,7 +49,9 @@
    OO_CMD_ANSCALL,           /*!< Answer call */
    OO_CMD_FWDCALL,           /*!< Forward call */
    OO_CMD_HANGCALL,          /*!< Terminate call */
+   OO_CMD_SENDDIGIT,         /*!< Send dtmf */
    OO_CMD_STOPMONITOR        /*!< Stop the event monitor */
+   
 } OOStackCmdID;
 
 /**
@@ -105,6 +109,16 @@
 EXTERN int ooHangCall(char * callToken, OOCallClearReason reason);
 
 /**
+ * This command function can be used by an user application to send a DTMF 
+ * sequence using H.245 UserInputIndication message.
+ * @param callToken  Unique token for the call
+ * @param alpha      Alphanumeric string reperesenting dtmf sequence
+ *
+ * @return           OO_OK, on success. OO_FAILED, on failure.
+ */
+EXTERN int ooSendDTMFDigit(char *callToken, char* alphanumeric);
+
+/**
  * This function is invoked from the main event handling loop to 
  * process queued stack commands.
  */

Index: ooh245.c
===================================================================
RCS file: /usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooh245.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- ooh245.c    5 Aug 2005 20:42:06 -0000       1.8
+++ ooh245.c    2 Sep 2005 14:27:10 -0000       1.9
@@ -316,6 +316,7 @@
    H245TerminalCapabilitySet *termCap=NULL;
    H245AudioCapability *audioCap=NULL;
    H245AudioTelephonyEventCapability *ateCap=NULL;
+   H245UserInputCapability *userInputCap = NULL;
    H245CapabilityTableEntry *entry=NULL;
    H245AlternativeCapabilitySet *altSet=NULL;
    DListNode * curNode=NULL;
@@ -534,7 +535,75 @@
 
          i++;
       }
-   }      
+   }
+
+   if(call->dtmfmode & OO_CAP_DTMF_H245_alphanumeric)
+   {
+      userInputCap = (H245UserInputCapability*)ooCapabilityCreateDTMFCapability
+                                        (OO_CAP_DTMF_H245_alphanumeric, pctxt);
+      if(!userInputCap)
+      {
+         OOTRACEWARN3("WARN:Failed to add H245(alphanumeric) cap to "
+                      "TCS(%s, %s)\n", call->callType, call->callToken);
+      }else {
+         entry = (H245CapabilityTableEntry*) memAlloc(pctxt,
+                      sizeof(H245CapabilityTableEntry));
+         if(!entry)
+         {
+            OOTRACEERR3("Error:Failed to allocate memory for new capability "
+                        "table entry. (%s, %s)\n", call->callType, 
+                        call->callToken);
+            ooFreeH245Message(call, ph245msg);
+            return OO_FAILED;
+         }
+            
+         memset(entry, 0, sizeof(H245CapabilityTableEntry));
+         entry->m.capabilityPresent = 1;
+
+         entry->capability.t = T_H245Capability_receiveUserInputCapability;
+         entry->capability.u.receiveUserInputCapability = userInputCap;
+      
+         entry->capabilityTableEntryNumber = i+1;
+         dListAppend(pctxt , &(termCap->capabilityTable), entry);
+
+         i++;
+      }
+   }
+   userInputCap = NULL;
+   if(call->dtmfmode & OO_CAP_DTMF_H245_signal)
+   {
+      userInputCap = (H245UserInputCapability*)ooCapabilityCreateDTMFCapability
+                                        (OO_CAP_DTMF_H245_signal, pctxt);
+      if(!userInputCap)
+      {
+         OOTRACEWARN3("WARN:Failed to add H245(signal) cap to "
+                      "TCS(%s, %s)\n", call->callType, call->callToken);
+      }else {
+         entry = (H245CapabilityTableEntry*) memAlloc(pctxt,
+                      sizeof(H245CapabilityTableEntry));
+         if(!entry)
+         {
+            OOTRACEERR3("Error:Failed to allocate memory for new capability "
+                        "table entry. (%s, %s)\n", call->callType, 
+                        call->callToken);
+            ooFreeH245Message(call, ph245msg);
+            return OO_FAILED;
+         }
+            
+         memset(entry, 0, sizeof(H245CapabilityTableEntry));
+         entry->m.capabilityPresent = 1;
+
+         entry->capability.t = T_H245Capability_receiveUserInputCapability;
+         entry->capability.u.receiveUserInputCapability = userInputCap;
+      
+         entry->capabilityTableEntryNumber = i+1;
+         dListAppend(pctxt , &(termCap->capabilityTable), entry);
+
+         i++;
+      }
+   }
+
+          
    /*TODO:Add Video and Data capabilities, if required*/
    if(i==0)
    {
@@ -2019,9 +2088,10 @@
       Request/Response/Command/Indication. Each one of them need to be 
       handled separately.
    */   
-   H245RequestMessage *request;
-   H245ResponseMessage *response;
-   H245CommandMessage *command;
+   H245RequestMessage *request = NULL;
+   H245ResponseMessage *response = NULL;
+   H245CommandMessage *command = NULL;
+   H245IndicationMessage *indication = NULL;
    
    OOTRACEDBGC3("Handling H245 message. (%s, %s)\n", call->callType, 
                  call->callToken);
@@ -2284,6 +2354,16 @@
          break;
       /* H.245 Indication message received */
       case (T_H245MultimediaSystemControlMessage_indication):
+         indication = pH245->h245Msg.u.indication;
+         switch(indication->t)
+         {
+            case T_H245IndicationMessage_userInput:
+               ooOnReceivedUserInputIndication(call, indication->u.userInput);
+               break;
+            default:
+               OOTRACEWARN3("Unhandled indication message received.(%s, %s)\n",
+                             call->callType, call->callToken);
+         }
          break;
       default:
         ;
@@ -2293,6 +2373,28 @@
    return OO_OK;
 }
 
+
+int ooOnReceivedUserInputIndication
+   (OOH323CallData *call, H245UserInputIndication *indication)
+{
+   if((indication->t == T_H245UserInputIndication_alphanumeric) && 
+      (call->dtmfmode & OO_CAP_DTMF_H245_alphanumeric))
+   {
+      if(gH323ep.h323Callbacks.onReceivedDTMF)
+         gH323ep.h323Callbacks.onReceivedDTMF(call,indication->u.alphanumeric);
+   }else if((indication->t == T_H245UserInputIndication_signal) && 
+      (call->dtmfmode & OO_CAP_DTMF_H245_signal))
+   {
+      if(gH323ep.h323Callbacks.onReceivedDTMF)
+         gH323ep.h323Callbacks.onReceivedDTMF(call, 
+                                             indication->u.signal->signalType);
+   }else{
+      OOTRACEINFO3("Unsupported userInput message type received - ignoring."
+                   "(%s, %s)\n", call->callType, call->callToken);
+   }
+   return OO_OK;
+}
+
 int ooOnReceivedTerminalCapabilitySet(OOH323CallData *call, H245Message *pmsg)
 {
    int ret = 0,k;
@@ -2525,6 +2627,128 @@
 }
 
 
+int ooSendH245UserInputIndication_alphanumeric
+   (OOH323CallData *call, const char *data)
+{
+   int ret=0;
+   H245IndicationMessage* indication=NULL;
+   H245Message *ph245msg=NULL;
+   OOCTXT *pctxt=&gH323ep.msgctxt;
+
+   ret = ooCreateH245Message
+      (&ph245msg, T_H245MultimediaSystemControlMessage_indication);
+
+   if (ret != OO_OK) {
+      OOTRACEERR3("Error:H245 message creation failed for - H245UserInput"
+                  "Indication_alphanumeric (%s, %s)\n",call->callType, 
+                  call->callToken);
+      return OO_FAILED;
+   }
+   ph245msg->msgType = OOUserInputIndication;
+   indication = ph245msg->h245Msg.u.indication;
+
+   indication->t = T_H245IndicationMessage_userInput;
+   indication->u.userInput = 
+      (H245UserInputIndication*)
+      memAllocZ (pctxt, sizeof(H245UserInputIndication));
+
+   if(!indication->u.userInput)
+   {
+      OOTRACEERR3("Error: Memory - ooH245UserInputIndication_alphanumeric - "
+                  " userInput (%s, %s)\n", call->callType, call->callToken);
+      ooFreeH245Message(call, ph245msg);
+      return OO_FAILED;
+   }
+   indication->u.userInput->t = T_H245UserInputIndication_alphanumeric;
+   indication->u.userInput->u.alphanumeric = (ASN1GeneralString)
+                                              memAlloc(pctxt, strlen(data)+1);
+   if(!indication->u.userInput->u.alphanumeric)
+   {
+      OOTRACEERR3("Error: Memory - ooH245UserInputIndication-alphanumeric - "
+                  "alphanumeric (%s, %s).\n", call->callType, call->callToken);
+      ooFreeH245Message(call, ph245msg);
+      return OO_FAILED;
+   }
+   strcpy((char*)indication->u.userInput->u.alphanumeric, data);
+   OOTRACEDBGA3 ("Built UserInputIndication_alphanumeric (%s, %s)\n", 
+                call->callType, call->callToken);
+
+   ret = ooSendH245Msg (call, ph245msg);
+
+   if (ret != OO_OK) {
+      OOTRACEERR3 
+        ("Error:Failed to enqueue UserInputIndication_alphanumeric "
+          "message to outbound queue.(%s, %s)\n", call->callType, 
+         call->callToken);
+   }
+   
+   ooFreeH245Message (call, ph245msg);
+   return ret;
+}
+
+int ooSendH245UserInputIndication_signal
+   (OOH323CallData *call, const char *data)
+{
+   int ret=0;
+   H245IndicationMessage* indication=NULL;
+   H245Message *ph245msg=NULL;
+   OOCTXT *pctxt=&gH323ep.msgctxt;
+
+   ret = ooCreateH245Message
+      (&ph245msg, T_H245MultimediaSystemControlMessage_indication);
+
+   if (ret != OO_OK) {
+      OOTRACEERR3("Error:H245 message creation failed for - H245UserInput"
+                  "Indication_signal (%s, %s)\n",call->callType, 
+                  call->callToken);
+      return OO_FAILED;
+   }
+   ph245msg->msgType = OOUserInputIndication;
+   indication = ph245msg->h245Msg.u.indication;
+
+   indication->t = T_H245IndicationMessage_userInput;
+   indication->u.userInput = 
+      (H245UserInputIndication*)
+      memAllocZ (pctxt, sizeof(H245UserInputIndication));
+
+   if(!indication->u.userInput)
+   {
+      OOTRACEERR3("Error: Memory - ooH245UserInputIndication_signal - "
+                  " userInput (%s, %s)\n", call->callType, call->callToken);
+      ooFreeH245Message(call, ph245msg);
+      return OO_FAILED;
+   }
+   indication->u.userInput->t = T_H245UserInputIndication_signal;
+   indication->u.userInput->u.signal = (H245UserInputIndication_signal*)
+                      memAllocZ(pctxt, sizeof(H245UserInputIndication_signal));
+   indication->u.userInput->u.signal->signalType = (ASN1IA5String)
+                                              memAlloc(pctxt, strlen(data)+1);
+   if(!indication->u.userInput->u.signal ||
+      !indication->u.userInput->u.signal->signalType)
+   {
+      OOTRACEERR3("Error: Memory - ooH245UserInputIndication_signal - "
+                  "signal (%s, %s).\n", call->callType, call->callToken);
+      ooFreeH245Message(call, ph245msg);
+      return OO_FAILED;
+   }
+   strcpy((char*)indication->u.userInput->u.signal->signalType, data);
+   OOTRACEDBGA3 ("Built UserInputIndication_signal (%s, %s)\n", 
+                call->callType, call->callToken);
+
+   ret = ooSendH245Msg (call, ph245msg);
+
+   if (ret != OO_OK) {
+      OOTRACEERR3 
+        ("Error:Failed to enqueue UserInputIndication_signal "
+          "message to outbound queue.(%s, %s)\n", call->callType, 
+         call->callToken);
+   }
+   
+   ooFreeH245Message (call, ph245msg);
+   return ret;
+}
+
+
 int ooOpenLogicalChannels(OOH323CallData *call)
 {
    int ret=0;

Index: ooh245.h
===================================================================
RCS file: /usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooh245.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- ooh245.h    16 Jun 2005 19:41:23 -0000      1.3
+++ ooh245.h    2 Sep 2005 14:27:10 -0000       1.4
@@ -254,6 +254,21 @@
 EXTERN int ooHandleH245Command
 (struct OOH323CallData *call, H245CommandMessage *command);
 
+
+/**
+ * This function is used to handle a received UserInput Indication message.
+ * It extracts the dtmf received through user-input message and calls endpoints
+ * onReceivedDTMF callback function, if such a function is registered by the 
+ * endpoint.
+ * @param call         Handle to the call for which user-input indication
+ *                     message is received.
+ * @param indication   Handle to the received user-input indication message.
+ *
+ * @return             OO_OK, on success; OO_FAILED, on failure.
+ */
+EXTERN int ooOnReceivedUserInputIndication
+   (OOH323CallData *call, H245UserInputIndication *indication);
+
 /**
  * This function is called on receiving a TreminalCapabilitySetAck message.
  * If the MasterSlaveDetermination process is also over, this function 
@@ -374,6 +389,28 @@
 (struct OOH323CallData* call, ooH323EpCapability *epCap);
 
 /**
+ * This function is used to send dtmf digits as user input indication message
+ * contating alphanumeric string.
+ * @param call            Handle to the call for which dtmf has to be sent.
+ * @param data            DTMF data
+ *
+ * @return                OO_OK, on success; OO_FAILED, on failure.
+ */
+EXTERN int ooSendH245UserInputIndication_alphanumeric
+   (OOH323CallData *call, const char *data);
+
+/**
+ * This function is used to send dtmf digits as user input indication message
+ * contating dtmf signal type.
+ * @param call            Handle to the call for which dtmf has to be sent.
+ * @param data            DTMF data
+ *
+ * @return                OO_OK, on success; OO_FAILED, on failure.
+ */
+EXTERN int ooSendH245UserInputIndication_signal
+   (OOH323CallData *call, const char *data);
+
+/**
  * 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

Index: ooh323.c
===================================================================
RCS file: /usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooh323.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- ooh323.c    22 Aug 2005 17:25:39 -0000      1.7
+++ ooh323.c    2 Sep 2005 14:27:10 -0000       1.8
@@ -29,6 +29,7 @@
 /** Global endpoint structure */
 extern OOH323EndPoint gH323ep;
 
+
 int ooOnReceivedReleaseComplete(OOH323CallData *call, Q931Message *q931Msg)
 {
    int ret = OO_OK;
@@ -319,7 +320,6 @@
 
       for(i=0; i<(int)setup->fastStart.n; i++)
       {
-         
          olc = NULL;
         /*         memset(msgbuf, 0, sizeof(msgbuf));*/
          olc = (H245OpenLogicalChannel*)memAlloc(call->pctxt, 
@@ -336,17 +336,12 @@
             }
             return OO_FAILED;
          }
-         OOTRACEINFO5("Processing %d fast start olc of length %d (%s, %s)\n", 
-                       i, setup->fastStart.elem[i].numocts, call->callType, 
-                       call->callToken);
          memset(olc, 0, sizeof(H245OpenLogicalChannel));
          memcpy(msgbuf, setup->fastStart.elem[i].data, 
                 setup->fastStart.elem[i].numocts);
 
          setPERBuffer(call->pctxt, msgbuf, 
                       setup->fastStart.elem[i].numocts, 1);
-         OOTRACEINFO4("Decoding %d fast start element (%s, %s)\n", i, 
-                      call->callType, call->callToken);
          ret = asn1PD_H245OpenLogicalChannel(call->pctxt, olc);
          if(ret != ASN_OK)
          {

Index: ooh323ep.c
===================================================================
RCS file: /usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooh323ep.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- ooh323ep.c  24 Jun 2005 21:01:49 -0000      1.4
+++ ooh323ep.c  2 Sep 2005 14:27:10 -0000       1.5
@@ -44,7 +44,7 @@
 extern DList g_TimerList;
 
 int ooH323EpInitialize
-   (int callMode, const char* tracefile)
+   (enum OOCallMode callMode, const char* tracefile)
 {
    
    memset(&gH323ep, 0, sizeof(ooEndPoint));
@@ -331,6 +331,7 @@
    gH323ep.h323Callbacks.onCallForwarded = h323Callbacks.onCallForwarded;
    gH323ep.h323Callbacks.onCallCleared = h323Callbacks.onCallCleared;
    gH323ep.h323Callbacks.openLogicalChannels = 
h323Callbacks.openLogicalChannels;
+   gH323ep.h323Callbacks.onReceivedDTMF = h323Callbacks.onReceivedDTMF;
    return OO_OK;
 }
 
@@ -638,6 +639,36 @@
    return ooCapabilityDisableDTMFRFC2833(NULL);
 }
 
+int ooH323EpEnableDTMFH245Alphanumeric()
+{
+   return ooCapabilityEnableDTMFH245Alphanumeric(NULL);
+}
+
+int ooH323EpDisableDTMFH245Alphanumeric()
+{
+   return ooCapabilityDisableDTMFH245Alphanumeric(NULL);
+}
+
+int ooH323EpEnableDTMFH245Signal()
+{
+   return ooCapabilityEnableDTMFH245Signal(NULL);
+}
+
+int ooH323EpDisableDTMFH245Signal()
+{
+   return ooCapabilityDisableDTMFH245Signal(NULL);
+}
+
+int ooH323EpEnableDTMFQ931Keypad()
+{
+   return ooCapabilityEnableDTMFQ931Keypad(NULL);
+}
+
+int ooH323EpDisableDTMFQ931Keypad()
+{
+   return ooCapabilityDisableDTMFQ931Keypad(NULL);
+}
+
 int ooH323EpSetGkClientCallbacks(OOGKCLIENTCALLBACKS gkClientCallbacks)
 {
 
@@ -650,6 +681,9 @@
    }
 
 }
+
+
+
 /* 0-1024 are reserved for well known services */
 int ooH323EpSetTCPPortRange(int base, int max)
 {

Index: ooh323ep.h
===================================================================
RCS file: /usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooh323ep.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- ooh323ep.h  24 Jun 2005 21:01:49 -0000      1.5
+++ ooh323ep.h  2 Sep 2005 14:27:10 -0000       1.6
@@ -65,6 +65,8 @@
 #define RTPPORTSSTART 14030  /*!< Starting RTP port number */
 #define RTPPORTSEND   14230  /*!< Ending RTP port number   */
 
+
+  
 /**
  * This structure is used to define the port ranges to be used
  * by the application.
@@ -156,7 +158,7 @@
  * @return               OO_OK, on success. OO_FAILED, on failure
  */
 EXTERN int ooH323EpInitialize
-   (int callMode, const char* tracefile);
+   (enum OOCallMode callMode, const char* tracefile);
 
 
 /**
@@ -520,6 +522,34 @@
 EXTERN int ooH323EpDisableDTMFRFC2833(void);
 
 /**
+ * This function is used to enable the H245(alphanumeric) dtmf capability for
+ * the endpoint.
+ * @return                        OO_OK, on success; OO_FAILED, on failure
+ */
+EXTERN int ooH323EpEnableDTMFH245Alphanumeric();
+
+/**
+ * This function is used to disable the H245(alphanumeric) dtmf capability for
+ * the endpoint.
+ * @return                        OO_OK, on success; OO_FAILED, on failure
+ */
+EXTERN int ooH323EpDisableDTMFH245Alphanumeric();
+
+/**
+ * This function is used to enable the H245(signal) dtmf capability for
+ * the endpoint.
+ * @return                        OO_OK, on success; OO_FAILED, on failure
+ */
+EXTERN int ooH323EpEnableDTMFH245Signal();
+
+/**
+ * This function is used to disable the H245(signal) dtmf capability for
+ * the endpoint.
+ * @return                        OO_OK, on success; OO_FAILED, on failure
+ */
+EXTERN int ooH323EpDisableDTMFH245Signal();
+
+/**
  * 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.

Index: ooq931.c
===================================================================
RCS file: /usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooq931.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- ooq931.c    2 Aug 2005 20:02:25 -0000       1.13
+++ ooq931.c    2 Sep 2005 14:27:10 -0000       1.14
@@ -159,6 +159,17 @@
          OOTRACEDBGB2("      %s\n", ie->data);
          OOTRACEDBGB1("   }\n");
       }
+
+      if(ie->discriminator == Q931KeypadIE)
+      {
+        OOTRACEDBGB1("   Keypad IE = {\n");
+         OOTRACEDBGB2("      %s\n", ie->data);
+         OOTRACEDBGB1("   }\n");
+         if(gH323ep.h323Callbacks.onReceivedDTMF)
+         {
+           gH323ep.h323Callbacks.onReceivedDTMF(call, ie->data);
+         }
+      }
       /* Extract calling party number TODO:Give respect to presentation and 
          screening indicators ;-) */
       if(ie->discriminator == Q931CallingPartyNumberIE)
@@ -352,7 +363,7 @@
 {
    OOCTXT *pctxt = &gH323ep.msgctxt;
    
-   *q931msg = (Q931Message*)memAlloc(pctxt, sizeof(Q931Message));
+   *q931msg = (Q931Message*)memAllocZ(pctxt, sizeof(Q931Message));
                 
    if(!*q931msg)
    {
@@ -657,6 +668,9 @@
    else if(pq931Msg->messageType == Q931ReleaseCompleteMsg){
       msgbuf[i++] = OOReleaseComplete;
    }
+   else if(pq931Msg->messageType == Q931InformationMsg){
+      msgbuf[i++] = OOInformationMessage;
+   }
    else if(pq931Msg->messageType == Q931FacilityMsg){
       msgbuf[i++] = OOFacility;
       msgbuf[i++] = pq931Msg->tunneledMsgType;
@@ -664,7 +678,8 @@
       msgbuf[i++] = pq931Msg->logicalChannelNo;
    }
    else{
-      OOTRACEERR3("Error:Unknow Q931 message type. (%s, %s)\n", 
call->callType, call->callToken);
+      OOTRACEERR3("Error:Unknow Q931 message type. (%s, %s)\n", call->callType,
+                   call->callToken);
       return OO_FAILED;
    }
 
@@ -747,6 +762,15 @@
                        pq931Msg->calledPartyNumberIE->length);
       i += pq931Msg->calledPartyNumberIE->length;
    }
+   
+   /* Add keypad ie */
+   if(pq931Msg->keypadIE)
+   {
+      msgbuf[i++] = Q931KeypadIE;
+      msgbuf[i++] = pq931Msg->keypadIE->length;
+      memcpy(msgbuf+i, pq931Msg->keypadIE->data, pq931Msg->keypadIE->length);
+      i += pq931Msg->keypadIE->length;
+   }
 
    /* Note: Have to fix this, though it works. Need to get rid of ie list. 
       Right now we only put UUIE in ie list. Can be easily removed.
@@ -1861,8 +1885,9 @@
    H245OpenLogicalChannel *olc, printOlc;
    ASN1BOOL aligned = 1;
    H225AliasAddress * pAliasAddress=NULL;
-   pctxt = &gH323ep.msgctxt;
    ooAliases *pAlias = NULL;
+
+   pctxt = &gH323ep.msgctxt;
      
    ret = ooCreateQ931Message(&q931msg, Q931SetupMsg);
    if(ret != OO_OK)
@@ -2304,7 +2329,81 @@
    return ret;
 }
 
+
+
+int ooQ931SendDTMFAsKeyPadIE(OOH323CallData *call, const char* data)
+{
+   int ret;    
+   H225Information_UUIE *information=NULL;
+   Q931Message *q931msg=NULL;
+   OOCTXT *pctxt = &gH323ep.msgctxt;
+
+   ret = ooCreateQ931Message(&q931msg, Q931InformationMsg);
+   if(ret != OO_OK)
+   {      
+      OOTRACEERR3("Error: In allocating memory for - H225 Information message."
+                  "(%s, %s)\n", call->callType, call->callToken);
+      return OO_FAILED;
+   }
+
+   q931msg->callReference = call->callReference;
+
+   q931msg->userInfo = (H225H323_UserInformation*)memAllocZ(pctxt,
+                             sizeof(H225H323_UserInformation));
+   if(!q931msg->userInfo)
+   {
+      OOTRACEERR3("ERROR:Memory -  ooQ931SendDTMFAsKeypadIE - userInfo"
+                  "(%s, %s)\n", call->callType, call->callToken);
+      memReset(&gH323ep.msgctxt);
+      return OO_FAILED;
+   }
+   q931msg->userInfo->h323_uu_pdu.m.h245TunnelingPresent=1; 
+   q931msg->userInfo->h323_uu_pdu.h245Tunneling = OO_TESTFLAG(gH323ep.flags, 
+                                                              OO_M_TUNNELING); 
+   q931msg->userInfo->h323_uu_pdu.h323_message_body.t = 
+         T_H225H323_UU_PDU_h323_message_body_information;
    
+   information = (H225Information_UUIE*)memAllocZ(pctxt, 
+                                             sizeof(H225Information_UUIE));
+   if(!information)
+   {
+      OOTRACEERR3("ERROR:Memory -  ooQ931SendDTMFAsKeypadIE - information"
+                  "(%s, %s)\n", call->callType, call->callToken);
+      memReset(&gH323ep.msgctxt);
+      return OO_FAILED;
+   }
+   q931msg->userInfo->h323_uu_pdu.h323_message_body.u.information = 
+                                                                  information; 
+   information->m.callIdentifierPresent = 1;
+   information->callIdentifier.guid.numocts = 
+                                   call->callIdentifier.guid.numocts;
+   memcpy(information->callIdentifier.guid.data, 
+          call->callIdentifier.guid.data, 
+          call->callIdentifier.guid.numocts);
+   information->protocolIdentifier = gProtocolID;
+   
+   /*Add keypad IE*/
+   ret = ooQ931SetKeypadIE(q931msg, data);
+   if(ret != OO_OK)
+   {
+      OOTRACEERR3("Error:Creating keypad IE for (%s, %s)\n", call->callType, 
+                   call->callToken);
+      memReset(&gH323ep.msgctxt);
+      return OO_FAILED;
+   }
+
+   ret=ooSendH225Msg(call, q931msg);
+   if(ret != OO_OK)
+   {
+      OOTRACEERR3("Error:Failed to enqueue Information message to outbound "
+                  "queue. (%s, %s)\n", call->callType, call->callToken);
+   }
+   memReset(&gH323ep.msgctxt);
+
+   return ret;
+
+}
+
 int ooH323ForwardCall(char* callToken, char *dest)
 {
    int ret=0;
@@ -2508,6 +2607,29 @@
    return OO_OK;
 }
 
+int ooQ931SetKeypadIE(Q931Message *pmsg, const char* data)
+{
+   unsigned len = 0;
+   OOCTXT *pctxt = &gH323ep.msgctxt;
+
+   len = strlen(data);
+   pmsg->keypadIE = (Q931InformationElement*) 
+                      memAlloc(pctxt, sizeof(Q931InformationElement)+len-1);
+   if(!pmsg->keypadIE)
+   {
+      OOTRACEERR1("Error:Memory - ooQ931SetKeypadIE - keypadIE\n");
+      return OO_FAILED;
+   }
+
+   pmsg->keypadIE->discriminator = Q931KeypadIE;
+   pmsg->keypadIE->length = len;
+   memcpy(pmsg->keypadIE->data, data, len);
+   return OO_OK;
+}
+
+
+
+
 int ooQ931SetCallingPartyNumberIE
    (Q931Message *pmsg, const char *number, unsigned plan, unsigned type, 
     unsigned presentation, unsigned screening)
@@ -3202,11 +3324,12 @@
 
   
    /* e-164 */
-   /* strspn(dest, "1234567890*#") == strlen(dest)*/
+   /* strspn(dest, "1234567890*#,") == strlen(dest)*/
    /* Dialed digits test*/
    for(i=0; *(alias+i) != '\0'; i++)
    {
-      if(!isdigit(alias[i]))
+      if(!isdigit(alias[i]) && alias[i] != '#' && alias[i] != '*' && 
+         alias[i] != ',')
          break;
    }
    if(*(alias+i) == '\0')

Index: ooq931.h
===================================================================
RCS file: /usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ooq931.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- ooq931.h    2 Aug 2005 20:02:25 -0000       1.5
+++ ooq931.h    2 Sep 2005 14:27:10 -0000       1.6
@@ -95,7 +95,8 @@
    Q931CallingPartyNumberIE = 0x6c,
    Q931CalledPartyNumberIE  = 0x70,
    Q931RedirectingNumberIE  = 0x74,
-   Q931UserUserIE           = 0x7e
+   Q931UserUserIE           = 0x7e,
+   Q931KeypadIE             = 0x2c
 };
 
 enum Q931InformationTransferCapability {
@@ -244,6 +245,7 @@
    Q931InformationElement *callingPartyNumberIE;
    Q931InformationElement *calledPartyNumberIE;
    Q931InformationElement *causeIE;
+   Q931InformationElement *keypadIE;
    H225H323_UserInformation *userInfo;
 } Q931Message;
 
@@ -623,6 +625,18 @@
  */
 int ooCallEstbTimerExpired(void *data);
 
+
+
+/**
+ * This function is used to add a keypad IE to a Q931 message for sending dtmf.
+ * @param pmsg            Q931 message to which keypad ie has to be
+ *                        added.
+ * @param data            DTMF data to be sent.
+ *
+ * @return                OO_OK on success, OO_FAILED, on failure.
+ */
+EXTERN int ooQ931SetKeypadIE(Q931Message *pmsg, const char* 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

Index: ootypes.h
===================================================================
RCS file: /usr/cvsroot/asterisk-addons/asterisk-ooh323c/ooh323c/src/ootypes.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- ootypes.h   6 Jul 2005 12:49:54 -0000       1.5
+++ ootypes.h   2 Sep 2005 14:27:10 -0000       1.6
@@ -151,36 +151,38 @@
 /**
    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
+#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 OOUserInputIndication              129
+#define OOInformationMessage               130
+#define OO_MSGTYPE_MAX                     130
 
 /* Timer types */
 #define OO_CALLESTB_TIMER  (1<<0)

_______________________________________________
Asterisk-Cvs mailing list
[email protected]
http://lists.digium.com/mailman/listinfo/asterisk-cvs

Reply via email to