properly send call progress and alerting PDUs, re-fix one-way audio on call manager...
authorJeremy McNamara <jj@nufone.net>
Thu, 20 May 2004 07:07:18 +0000 (07:07 +0000)
committerJeremy McNamara <jj@nufone.net>
Thu, 20 May 2004 07:07:18 +0000 (07:07 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@3023 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_h323.c
channels/h323/ast_h323.cpp
channels/h323/ast_h323.h
channels/h323/chan_h323.h

index 6151f68..1f64e45 100755 (executable)
@@ -393,7 +393,7 @@ static int oh323_call(struct ast_channel *c, char *dest, int timeout)
        int res;
        struct oh323_pvt *p = c->pvt->pvt;
        char called_addr[256];
-       char *tmp;
+       char *tmp, *cid, *cidname, oldcid[256];
 
        strtok_r(dest, "/", &(tmp));
 
@@ -424,15 +424,46 @@ static int oh323_call(struct ast_channel *c, char *dest, int timeout)
 
        /* Copy callerid, if there is any */
        if (c->callerid) {
-               char *tmp = strchr(c->callerid, '"');
-               if (!tmp) {
-                       p->calloptions.callerid = malloc(80); // evil
-                       // sprintf(p->calloptions.callerid, "\"%s\"", c->callerid);
-                       sprintf(p->calloptions.callerid, "\"\" <%s>", c->callerid);
-               } else {
-                       p->calloptions.callerid = strdup(c->callerid);
-               }       
-        }
+                memset(oldcid, 0, sizeof(oldcid));
+                memcpy(oldcid, c->callerid, strlen(c->callerid));
+                oldcid[sizeof(oldcid)-1] = '\0';
+                ast_callerid_parse(oldcid, &cidname, &cid);
+                if (p->calloptions.callerid) {
+                        free(p->calloptions.callerid);
+                        p->calloptions.callerid = NULL;
+                }
+                if (p->calloptions.callername) {
+                        free(p->calloptions.callername);
+                        p->calloptions.callername = NULL;
+                }
+                p->calloptions.callerid = (char*)malloc(256);
+                if (p->calloptions.callerid == NULL) {
+                        ast_log(LOG_ERROR, "Not enough memory.\n");
+                        return(-1);
+                }
+                memset(p->calloptions.callerid, 0, 256);
+                if ((cid != NULL)&&(strlen(cid) > 0))
+                        strncpy(p->calloptions.callerid, cid, 255);
+
+                p->calloptions.callername = (char*)malloc(256);
+                if (p->calloptions.callername == NULL) {
+                        ast_log(LOG_ERROR, "Not enough memory.\n");
+                        return(-1);
+                }
+                memset(p->calloptions.callername, 0, 256);
+                if ((cidname != NULL)&&(strlen(cidname) > 0))
+                        strncpy(p->calloptions.callername, cidname, 255);
+
+        } else {
+                if (p->calloptions.callerid) {
+                        free(p->calloptions.callerid);
+                        p->calloptions.callerid = NULL;
+                }
+                if (p->calloptions.callername) {
+                        free(p->calloptions.callername);
+                        p->calloptions.callername = NULL;
+                }
+        }
 
        res = h323_make_call(called_addr, &(p->cd), p->calloptions);
 
@@ -440,12 +471,9 @@ static int oh323_call(struct ast_channel *c, char *dest, int timeout)
                ast_log(LOG_NOTICE, "h323_make_call failed(%s)\n", c->name);
                return -1;
        }
-
-       ast_setstate(c, AST_STATE_RINGING);
        return 0;
 }
 
-
 static int oh323_answer(struct ast_channel *c)
 {
        int res;
@@ -597,24 +625,34 @@ static int oh323_indicate(struct ast_channel *c, int condition)
        
        switch(condition) {
        case AST_CONTROL_RINGING:
-               if (c->_state == AST_STATE_RING) {
-                       return -1;
+               if (c->_state == AST_STATE_RING || c->_state == AST_STATE_RINGING) {
+                       h323_send_alerting(p->cd.call_token);
+                       break;
+               }               
+               return -1;
+       case AST_CONTROL_PROGRESS:
+               if (c->_state != AST_STATE_UP) {
+                       h323_send_progress(p->cd.call_token);
+                       break;
                }
-               return 0;
+               return -1;
+
        case AST_CONTROL_BUSY:
                if (c->_state != AST_STATE_UP) {
-                       p->alreadygone = 1;
-                       ast_softhangup(c, AST_SOFTHANGUP_DEV);
+                       h323_answering_call(p->cd.call_token, 1);
+                       p->alreadygone = 1;
+                       ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);                   
                        break;
                }
-               return 0;
+               return -1;
        case AST_CONTROL_CONGESTION:
                if (c->_state != AST_STATE_UP) {
+                       h323_answering_call(p->cd.call_token, 1);
                        p->alreadygone = 1;
-                       ast_softhangup(c, AST_SOFTHANGUP_DEV);
+                       ast_softhangup_nolock(c, AST_SOFTHANGUP_DEV);
                        break;
                }
-               return 0;
+               return -1;
        case -1:
                return -1;
        default:
@@ -986,13 +1024,14 @@ int setup_incoming_call(call_details_t cd)
        p->cd.call_token = cd.call_token;
        p->cd.call_source_aliases = cd.call_source_aliases;
        p->cd.call_dest_alias = cd.call_dest_alias;
+       p->cd.call_source_name = cd.call_source_name;
        p->cd.call_source_e164 = cd.call_source_e164;
        p->cd.call_dest_e164 = cd.call_dest_e164;
 
        if (h323debug) {
                ast_verbose(VERBOSE_PREFIX_3 "Setting up Call\n");
                ast_verbose(VERBOSE_PREFIX_3 "     Call token:  [%s]\n", p->cd.call_token);
-               ast_verbose(VERBOSE_PREFIX_3 "     Calling party name:  [%s]\n", p->cd.call_source_aliases);
+               ast_verbose(VERBOSE_PREFIX_3 "     Calling party name:  [%s]\n", p->cd.call_source_name);
                ast_verbose(VERBOSE_PREFIX_3 "     Calling party number:  [%s]\n", p->cd.call_source_e164);
                ast_verbose(VERBOSE_PREFIX_3 "     Called  party name:  [%s]\n", p->cd.call_dest_alias);
                ast_verbose(VERBOSE_PREFIX_3 "     Called  party number:  [%s]\n", p->cd.call_dest_e164);
@@ -1014,17 +1053,14 @@ int setup_incoming_call(call_details_t cd)
                        strncpy(p->exten, alias->name, sizeof(p->exten)-1);
                        strncpy(p->context, alias->context, sizeof(p->context)-1);
                }
-
-
-               sprintf(p->callerid, "%s <%s>", p->cd.call_source_aliases, p->cd.call_source_e164);
-
+               sprintf(p->callerid, "%s <%s>", p->cd.call_source_name, p->cd.call_source_e164);
        } else { 
                /* Either this call is not from the Gatekeeper 
                   or we are not allowing gk routed calls */
                user  = find_user(cd);
 
                if (!user) {
-                       sprintf(p->callerid, "%s <%s>", p->cd.call_source_aliases, p->cd.call_source_e164); 
+                       sprintf(p->callerid, "%s <%s>", p->cd.call_source_name, p->cd.call_source_e164);
                        if (!ast_strlen_zero(p->cd.call_dest_e164)) {
                                strncpy(p->exten, cd.call_dest_e164, sizeof(p->exten)-1);
                        } else {
@@ -1061,11 +1097,11 @@ int setup_incoming_call(call_details_t cd)
                        p->bridge = user->bridge;
                       p->nat = user->nat;
 
-                       if (!ast_strlen_zero(user->callerid)) 
+                       if (!ast_strlen_zero(user->callerid)) {
                                strncpy(p->callerid, user->callerid, sizeof(p->callerid) - 1);
-                       else
-                               sprintf(p->callerid, "%s <%s>", p->cd.call_source_aliases, p->cd.call_source_e164); 
-
+                       } else {
+                                sprintf(p->callerid, "%s <%s>", p->cd.call_source_name, p->cd.call_source_e164); 
+                       }
                        if (!ast_strlen_zero(p->cd.call_dest_e164)) {
                                strncpy(p->exten, cd.call_dest_e164, sizeof(p->exten)-1);
                        } else {
@@ -1161,17 +1197,43 @@ void connection_made(unsigned call_reference)
        c = p->owner;   
 
        ast_setstate(c, AST_STATE_UP);
+       ast_queue_control(c, AST_CONTROL_ANSWER);
        return;
 }
 
 /**
+  *  Call-back function to signal asterisk that the channel is ringing
+  *  Returns nothing
+  */
+void chan_ringing(unsigned call_reference)
+{
+        struct ast_channel *c = NULL;
+        struct oh323_pvt *p = NULL;
+
+        p = find_call(call_reference);
+
+        if (!p) {
+                ast_log(LOG_ERROR, "Something is wrong: ringing\n");
+       }
+
+        if (!p->owner) {
+                ast_log(LOG_ERROR, "Channel has no owner\n");
+                return;
+        }
+        c = p->owner;
+        ast_setstate(c, AST_STATE_RINGING);
+        ast_queue_control(c, AST_CONTROL_RINGING);
+        return;
+}
+
+/**
   * Call-back function to cleanup communication
   * Returns nothing,
   */
 void cleanup_connection(call_details_t cd)
 {      
        struct oh323_pvt *p = NULL;
-//     struct oh323_peer *peer = NULL;
+/*     struct oh323_peer *peer = NULL; */
        struct oh323_user *user = NULL;
        struct ast_rtp *rtp = NULL;
        
@@ -1793,6 +1855,7 @@ int load_module()
                                       create_connection, 
                                       setup_rtp_connection, 
                                       cleanup_connection, 
+                                      chan_ringing,
                                       connection_made, 
                                       send_digit);     
        
@@ -1800,7 +1863,6 @@ int load_module()
                /* start the h.323 listener */
                if (h323_start_listener(port, bindaddr)) {
                        ast_log(LOG_ERROR, "Unable to create H323 listener.\n");
-//                     h323_end_process();
                        return -1;
                }
 
@@ -1808,7 +1870,6 @@ int load_module()
                if (gatekeeper_disable == 0) {
                        if (h323_set_gk(gatekeeper_discover, gatekeeper, secret)) {
                                ast_log(LOG_ERROR, "Gatekeeper registration failed.\n");
-//                             h323_end_process();
                                return 0;
                        }
                }
index 867ccd9..9bb122f 100755 (executable)
@@ -218,8 +218,7 @@ H323Codec * AST_G729ACapability::CreateCodec(H323Codec::Direction direction) con
   *                                    transport = ip.
   *                                    port = 1720.
   */
-int MyH323EndPoint::MakeCall(const PString & dest, PString & token, 
-                                                                               unsigned int *callReference, unsigned int port, char *callerid)
+int MyH323EndPoint::MakeCall(const PString & dest, PString & token, unsigned int *callReference, unsigned int port, char *callerid, char *callername)
 {
        PString fullAddress;
        MyH323Connection * connection;
@@ -245,6 +244,15 @@ int MyH323EndPoint::MakeCall(const PString & dest, PString & token,
        
        if (callerid)
                connection->SetLocalPartyName(PString(callerid));
+       if (callername) {
+                localAliasNames.RemoveAll();
+               connection->SetLocalPartyName(PString(callername));
+               if (callerid)
+                  localAliasNames.AppendString(PString(callerid));
+        } else if (callerid) {
+                localAliasNames.RemoveAll();
+                connection->SetLocalPartyName(PString(callerid));
+        }
 
        connection->Unlock();   
 
@@ -486,7 +494,7 @@ H323Connection::AnswerCallResponse MyH323Connection::OnAnswerCall(const PString
 {
        /* The call will be answered later with "AnsweringCall()" function.
         */ 
-       return H323Connection::AnswerCallAlertWithMedia;
+       return H323Connection::AnswerCallDeferred;
 }
 
 BOOL  MyH323Connection::OnAlerting(const H323SignalPDU & /*alertingPDU*/, const PString & username)
@@ -495,6 +503,7 @@ BOOL  MyH323Connection::OnAlerting(const H323SignalPDU & /*alertingPDU*/, const
        if (h323debug) {
                cout << "       -- Ringing phone for \"" << username << "\"" << endl;
        }
+       on_chan_ringing(GetCallReference());
        return TRUE;
 }
 
@@ -508,6 +517,7 @@ BOOL MyH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU)
        call_details_t cd;
        PString sourceE164;
        PString destE164;
+       PString sourceName;
        PString sourceAliases;  
        PString destAliases;
        PIPSocket::Address Ip;
@@ -519,6 +529,8 @@ BOOL MyH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU)
                        
        sourceE164 = "";
        setupPDU.GetSourceE164(sourceE164);
+       sourceName = "";
+       sourceName=setupPDU.GetQ931().GetDisplayName();
        destE164 = "";
        setupPDU.GetDestinationE164(destE164);
 
@@ -540,6 +552,7 @@ BOOL MyH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU)
        cd.call_dest_alias = (const char *)destAliases;
        cd.call_source_e164 = (const char *)sourceE164;
        cd.call_dest_e164 = (const char *)destE164;
+       cd.call_source_name = (const char *)sourceName;
 
        GetSignallingChannel()->GetRemoteAddress().GetIpAndPort(Ip, sourcePort);
        cd.sourceIp = (const char *)Ip.AsString();
@@ -727,11 +740,11 @@ BOOL MyH323Connection::OnStartLogicalChannel(H323Channel & channel)
 
 /* MyH323_ExternalRTPChannel */
 MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection,
-                                                                                                       const H323Capability & capability,
-                                                                                                       Directions direction,
-                                                                                                       unsigned sessionID,
-                                                                                                       const PIPSocket::Address & ip,
-                                                                                                       WORD dataPort)
+                                                    const H323Capability & capability,
+                                                    Directions direction,
+                                                    unsigned sessionID,
+                                                    const PIPSocket::Address & ip,
+                                                    WORD dataPort)
        : H323_ExternalRTPChannel(connection, capability, direction, sessionID, ip, dataPort)
 {
        if (h323debug) {
@@ -740,6 +753,24 @@ MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connecti
        return;
 }
 
+MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection,
+                                                    const H323Capability & capability,
+                                                     Directions direction,
+                                                     unsigned id)
+ : H323_ExternalRTPChannel::H323_ExternalRTPChannel(connection, capability, direction, id)
+{   
+} 
+
+MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection, 
+                                                    const H323Capability & capability,
+                                                     Directions direction,
+                                                     unsigned id,
+                                                     const H323TransportAddress & data,
+                                                     const H323TransportAddress & control) 
+ : H323_ExternalRTPChannel::H323_ExternalRTPChannel(connection, capability, direction, id, data, control)
+{
+} 
+
 MyH323_ExternalRTPChannel::~MyH323_ExternalRTPChannel()
 {
        if (h323debug) {
@@ -748,29 +779,17 @@ MyH323_ExternalRTPChannel::~MyH323_ExternalRTPChannel()
        return;
 }
 
-BOOL MyH323_ExternalRTPChannel::OnReceivedPDU(
-                               const H245_H2250LogicalChannelParameters & param,
-                               unsigned & errorCode)
-{
-       if (h323debug) {
-               cout << "       MyH323_ExternalRTPChannel::OnReceivedPDU " << endl;
-       }
-       return H323_ExternalRTPChannel::OnReceivedPDU( param, errorCode );
-}
-
-BOOL MyH323_ExternalRTPChannel::OnReceivedAckPDU(
-                               const H245_H2250LogicalChannelAckParameters & param)
+BOOL MyH323_ExternalRTPChannel::OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param)
 {
-
-       PIPSocket::Address remoteIpAddress;             // IP Address of remote endpoint
-       WORD                       remotePort;                  // remote endpoint Data port (control is dataPort+1)
+       PIPSocket::Address remoteIpAddress;
+       WORD remotePort;
 
        if (h323debug) {
                cout << "       MyH323_ExternalRTPChannel::OnReceivedAckPDU " << endl;
        }
 
-       if (H323_ExternalRTPChannel::OnReceivedAckPDU( param )) {
-               GetRemoteAddress(remoteIpAddress, remotePort);
+       if (H323_ExternalRTPChannel::OnReceivedAckPDU(param)) {
+               H323_ExternalRTPChannel::GetRemoteAddress(remoteIpAddress, remotePort);
                if (h323debug) {
                        cout << "               -- remoteIpAddress: " << remoteIpAddress << endl;
                        cout << "               -- remotePort: " << remotePort << endl;
@@ -838,7 +857,8 @@ void h323_callback_register(setup_incoming_cb       ifunc,
                            on_connection_cb    confunc,
                            start_logchan_cb    lfunc,
                            clear_con_cb        clfunc,
-                           con_established_cb  efunc,
+                           chan_ringing_cb     rfunc,
+                           con_established_cb  efunc,
                            send_digit_cb       dfunc)
 {
        on_incoming_call = ifunc;
@@ -846,6 +866,7 @@ void h323_callback_register(setup_incoming_cb       ifunc,
        on_create_connection = confunc;
        on_start_logical_channel = lfunc;
        on_connection_cleared = clfunc;
+       on_chan_ringing = rfunc;
        on_connection_established = efunc;
        on_send_digit = dfunc;
 }
@@ -1085,7 +1106,7 @@ int h323_make_call(char *host, call_details_t *cd, call_options_t call_options)
        
        PString dest(host);
 
-       res = endPoint->MakeCall(dest, token, &cd->call_reference, call_options.port, call_options.callerid);
+       res = endPoint->MakeCall(dest, token, &cd->call_reference, call_options.port, call_options.callerid, call_options.callername);
        memcpy((char *)(cd->call_token), (const unsigned char *)token, token.GetLength());
        
        return res;
@@ -1101,6 +1122,45 @@ int h323_clear_call(const char *call_token)
        return 0;
 };
 
+/* Send Alerting PDU to H.323 caller */
+int h323_send_alerting(const char *token)
+{
+        const PString currentToken(token);
+        H323Connection * connection;
+
+        connection = endPoint->FindConnectionWithLock(currentToken);
+
+        if (!connection) {
+                cout << "No connection found for " << token << endl;
+                return -1;
+        }
+
+        connection->AnsweringCall(H323Connection::AnswerCallPending);
+        connection->Unlock();
+
+        return 0; 
+
+}
+
+/* Send Progress PDU to H.323 caller */
+int h323_send_progress(const char *token)
+{
+        const PString currentToken(token);
+        H323Connection * connection;
+
+        connection = endPoint->FindConnectionWithLock(currentToken);
+
+        if (!connection) {
+                cout << "No connection found for " << token << endl;
+                return -1;
+        }
+
+        connection->AnsweringCall(H323Connection::AnswerCallDeferredWithMedia);
+        connection->Unlock();
+
+        return 0;  
+}
+
 /** This function tells the h.323 stack to either 
     answer or deny an incoming call  */
 int h323_answering_call(const char *token, int busy) 
index 91ebab0..966edab 100755 (executable)
@@ -198,7 +198,7 @@ class MyH323EndPoint : public H323EndPoint {
 
        public:
 
-       int MakeCall(const PString &, PString &, unsigned int *, unsigned int, char *);
+       int MakeCall(const PString &, PString &, unsigned int *, unsigned int, char *, char *s);
        BOOL ClearCall(const PString &);
 
        void OnClosedLogicalChannel(H323Connection &, const H323Channel &);
@@ -225,8 +225,10 @@ class MyH323Connection : public H323Connection {
        MyH323Connection(MyH323EndPoint &, unsigned, unsigned);
        ~MyH323Connection();
 
-       H323Channel * CreateRealTimeLogicalChannel(const H323Capability &, H323Channel::Directions, unsigned, 
-                                                                                          const H245_H2250LogicalChannelParameters *);
+       H323Channel * CreateRealTimeLogicalChannel(const H323Capability &, 
+                                                  H323Channel::Directions, 
+                                                  unsigned, 
+                                                  const H245_H2250LogicalChannelParameters *);
        H323Connection::AnswerCallResponse OnAnswerCall(const PString &, const H323SignalPDU &, H323SignalPDU &);
        void OnReceivedReleaseComplete(const H323SignalPDU &);
        BOOL OnAlerting(const H323SignalPDU &, const PString &);
@@ -245,33 +247,53 @@ class MyH323Connection : public H323Connection {
        PString sourceE164;
        PString destE164;
 
-       PIPSocket::Address externalIpAddress;   // IP address of media server
-       PIPSocket::Address remoteIpAddress;             // IP Address of remote endpoint
-       WORD                       externalPort;                // local media server Data port (control is dataPort+1)
-       WORD                       remotePort;                  // remote endpoint Data port (control is dataPort+1)
-       WORD                       sessionId;
-       BOOL                       bridging;                    // Used to help determine which IP to use
+       PIPSocket::Address externalIpAddress;   
+       PIPSocket::Address remoteIpAddress;     
+       WORD externalPort;
+       WORD remotePort;                
+       WORD sessionId;
+       BOOL bridging;                  
 };
 
 class MyH323_ExternalRTPChannel : public H323_ExternalRTPChannel {
 
-       PCLASSINFO(MyH323_ExternalRTPChannel, H323_ExternalRTPChannel);
-
-       public:
-
-    MyH323_ExternalRTPChannel(MyH323Connection &, const H323Capability &, Directions,
-                                               unsigned, const PIPSocket::Address &, WORD);
-
+        PCLASSINFO(MyH323_ExternalRTPChannel, H323_ExternalRTPChannel);
+
+        public:
+       MyH323_ExternalRTPChannel(
+               MyH323Connection & connection,     
+               const H323Capability & capability, 
+               Directions direction,              
+               unsigned sessionID);
+
+       MyH323_ExternalRTPChannel(
+               MyH323Connection & connection,      
+               const H323Capability & capability,  
+               Directions direction,               
+               unsigned sessionID,                 
+               const H323TransportAddress & data,  
+               const H323TransportAddress & control);
+    
+       /* Create a new channel. */
+       MyH323_ExternalRTPChannel(
+               MyH323Connection & connection,        
+               const H323Capability & capability,  
+               Directions direction,               
+               unsigned sessionID,                 
+               const PIPSocket::Address & ip,      
+               WORD dataPort); 
+
+       /* Destructor */
        ~MyH323_ExternalRTPChannel();
 
-    BOOL OnReceivedPDU(
-      const H245_H2250LogicalChannelParameters & param, /// Acknowledgement PDU
-      unsigned & errorCode                              /// Error on failure
-    );
-
-    BOOL OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param);
+       
+       BOOL OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param);
 
-};
+       PIPSocket::Address externalIpAddress;   
+       PIPSocket::Address remoteIpAddress;             
+       WORD externalPort;               
+       WORD remotePort;
+}; 
 
 /**
  * The MyProcess is a necessary descendant PProcess class so that the H323EndPoint 
index 959d79d..198247c 100755 (executable)
@@ -85,10 +85,11 @@ struct oh323_alias {
        PBX application and passed through make_call 
        function*/
 typedef struct call_options {
-       char               *callerid;
-       int                             noFastStart;
-       int                             noH245Tunnelling;
-       int                             noSilenceSuppression;
+       char            *callerid;
+       char            *callername;
+       int             noFastStart;
+       int             noH245Tunnelling;
+       int             noSilenceSuppression;
        unsigned int    port;
 } call_options_t;
 
@@ -101,6 +102,7 @@ typedef struct call_details {
        const char *call_token;                         
        const char *call_source_aliases;
        const char *call_dest_alias;
+       const char *call_source_name;
        const char *call_source_e164;
        const char *call_dest_e164;
        const char *sourceIp;
@@ -136,6 +138,11 @@ setup_outbound_cb  on_outgoing_call;
 typedef void (*start_logchan_cb)(unsigned int, const char *, int);
 start_logchan_cb       on_start_logical_channel; 
 
+/* This is a callback prototype function, called when openh323
+   OnAlerting is invoked */
+typedef void (*chan_ringing_cb)(unsigned);
+chan_ringing_cb                on_chan_ringing;
+
 /* This is a callback protoype function, called when the openh323
    OnConnectionEstablished is inovked */
 typedef void (*con_established_cb)(unsigned);
@@ -164,13 +171,14 @@ extern "C" {
        void h323_debug(int, unsigned);
 
        /* callback function handler*/
-       void h323_callback_register(setup_incoming_cb,
-                                                               setup_outbound_cb,
-                                                               on_connection_cb,
-                                                               start_logchan_cb,
-                                                               clear_con_cb,
-                                                               con_established_cb,
-                                                               send_digit_cb);
+       void h323_callback_register(setup_incoming_cb,  
+                                   setup_outbound_cb,
+                                   on_connection_cb,
+                                   start_logchan_cb,
+                                   clear_con_cb,
+                                   chan_ringing_cb,
+                                   con_established_cb,
+                                   send_digit_cb);
 
 
        int h323_set_capability(int, int);
@@ -191,9 +199,13 @@ extern "C" {
        /* H323 create and destroy sessions */
        int h323_make_call(char *host, call_details_t *cd, call_options_t);
        int h323_clear_call(const char *);
+
+       /* H.323 alerting and progress */
+       int h323_send_alerting(const char *token);
+       int h323_send_progress(const char *token);
+
        int h323_answering_call(const char *token, int);
-       int h323_soft_hangup(const char *data);
-       
+       int h323_soft_hangup(const char *data); 
        int h323_show_codec(int fd, int argc, char *argv[]);