alpha phase is open, this means:
[lcr.git] / h323_con.cpp
diff --git a/h323_con.cpp b/h323_con.cpp
deleted file mode 100644 (file)
index 069d1f3..0000000
+++ /dev/null
@@ -1,648 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-//                                                                           //
-// PBX4Linux                                                                 //
-//                                                                           //
-//---------------------------------------------------------------------------//
-// Copyright: Andreas Eversberg                                              //
-//                                                                           //
-// h323_con connection class                                                 //
-//                                                                           //
-///////////////////////////////////////////////////////////////////////////////
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include "main.h"
-
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-
-//
-// constructor
-//
-H323_con::H323_con(H323_ep &endpoint, unsigned callReference) : H323Connection(endpoint, callReference)
-{
-       PDEBUG(DEBUG_H323, "H323 connection  constuctor\n");
-
-       SetAudioJitterDelay(0, 0);
-}
-
-
-//
-// destructor
-//
-H323_con::~H323_con()
-{
-       class H323Port *port;
-       const unsigned char *token_string = callToken;
-       struct message *message;
-
-       mutex_h323.Wait();
-
-       // get ioport
-       port = (class H323Port *)find_port_with_token((char *)token_string);
-       if (!port)
-       {
-               PERROR("no port with token '%s'\n", token_string);
-       } else
-       {
-               /* sending release (if not already) */
-               message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
-               message->param.disconnectinfo.cause = 16;
-               message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
-               message_put(message);
-       }
-
-       mutex_h323.Signal();
-
-       PDEBUG(DEBUG_H323, "H323 connection  destuctor\n");
-}
-
-
-//
-// AnswerCallResponse (incoming call)
-//
-H323Connection::AnswerCallResponse H323_con::OnAnswerCall(const PString &, const H323SignalPDU &setupPDU, H323SignalPDU &connectPDU)
-{  
-       class H323Port *port;
-       const char *calleraddress;
-       char callerip[32], *extension;
-       const char *dialing = NULL;
-       const H225_Setup_UUIE &setup = setupPDU.m_h323_uu_pdu.m_h323_message_body;
-       const H225_ArrayOf_AliasAddress &adr = setup.m_destinationAddress;
-       PINDEX i;
-       const unsigned char *token_string = callToken;
-       struct message *message;
-       class Endpoint *epoint;
-
-       const Q931 setup_q931 = setupPDU.GetQ931();
-       PString calling_number;
-       PString redir_number;
-       unsigned type, plan, present, screen, reason;
-
-       struct caller_info *callerinfo;
-       struct dialing_info *dialinginfo;
-       struct capa_info *capainfo;
-       struct redir_info *redirinfo;
-       char option[64] = "";
-
-       PDEBUG(DEBUG_H323, "H323 connection  incoming call\n");
-
-       mutex_h323.Wait();
-
-       // alloc new h323 port structure
-       if (!(port = new H323Port(PORT_TYPE_H323_IN, (char *)token_string, NULL)))
-       {
-               mutex_h323.Signal();
-               return AnswerCallDenied;
-       }
-       callerinfo = &port->p_callerinfo;
-       redirinfo = &port->p_redirinfo;
-       capainfo = &port->p_capainfo;
-       dialinginfo = &port->p_dialinginfo;
-
-       memset(callerinfo, 0, sizeof(struct caller_info));
-       memset(redirinfo, 0, sizeof(struct redir_info));
-       memset(capainfo, 0, sizeof(struct capa_info));
-       memset(dialinginfo, 0, sizeof(struct dialing_info));
-
-       callerinfo->itype = INFO_ITYPE_H323;
-
-       // get calling party information
-       if (setup_q931.GetCallingPartyNumber(calling_number, &plan, &type, &present, &screen))
-       {
-               SCPY(callerinfo->id, calling_number.GetPointer());
-               switch (present)
-               {
-                       case 1:
-                       callerinfo->present = INFO_PRESENT_RESTRICTED;
-                       break;
-                       case 2:
-                       callerinfo->present = INFO_PRESENT_NOTAVAIL;
-                       break;
-                       default:
-                       callerinfo->present = INFO_PRESENT_ALLOWED;
-                       break;
-               }
-               switch (type)
-               {
-                       case Q931::InternationalType:
-                       callerinfo->ntype = INFO_NTYPE_INTERNATIONAL;
-                       break;
-                       case Q931::NationalType:
-                       callerinfo->ntype = INFO_NTYPE_NATIONAL;
-                       break;
-                       case Q931::SubscriberType:
-                       callerinfo->ntype = INFO_NTYPE_SUBSCRIBER;
-                       break;
-                       default:
-                       callerinfo->ntype = INFO_NTYPE_UNKNOWN;
-                       break;
-               }
-               switch (screen)
-               {
-                       case 0:
-                       callerinfo->screen = INFO_SCREEN_USER;
-                       break;
-                       default:
-                       callerinfo->screen = INFO_SCREEN_NETWORK;
-                       break;
-               }
-       }
-       redirinfo->itype = INFO_ITYPE_H323;
-       // get redirecting number information
-       if (setup_q931.GetRedirectingNumber(redir_number, &plan, &type, &present, &screen, &reason))
-       {
-               SCPY(redirinfo->id, redir_number.GetPointer());
-               switch (present)
-               {
-                       case 1:
-                       redirinfo->present = INFO_PRESENT_RESTRICTED;
-                       break;
-                       case 2:
-                       redirinfo->present = INFO_PRESENT_NOTAVAIL;
-                       break;
-                       default:
-                       redirinfo->present = INFO_PRESENT_ALLOWED;
-                       break;
-               }
-               switch (type)
-               {
-                       case Q931::InternationalType:
-                       redirinfo->ntype = INFO_NTYPE_INTERNATIONAL;
-                       break;
-                       case Q931::NationalType:
-                       redirinfo->ntype = INFO_NTYPE_NATIONAL;
-                       break;
-                       case Q931::SubscriberType:
-                       redirinfo->ntype = INFO_NTYPE_SUBSCRIBER;
-                       break;
-                       default:
-                       redirinfo->ntype = INFO_NTYPE_UNKNOWN;
-                       break;
-               }
-               switch (screen)
-               {
-                       case 0:
-                       redirinfo->screen = INFO_SCREEN_USER;
-                       break;
-                       default:
-                       redirinfo->screen = INFO_SCREEN_NETWORK;
-                       break;
-               }
-               switch (reason)
-               {
-                       case 1:
-                       redirinfo->reason = INFO_REDIR_BUSY;
-                       break;
-                       case 2:
-                       redirinfo->reason = INFO_REDIR_NORESPONSE;
-                       break;
-                       case 15:
-                       redirinfo->reason = INFO_REDIR_UNCONDITIONAL;
-                       break;
-                       case 10:
-                       redirinfo->reason = INFO_REDIR_CALLDEFLECT;
-                       break;
-                       case 9:
-                       redirinfo->reason = INFO_REDIR_OUTOFORDER;
-                       break;
-                       default:
-                       redirinfo->reason = INFO_REDIR_UNKNOWN;
-                       break;
-               }
-       }
-
-       // get remote party h323-address information
-       calleraddress = GetRemotePartyAddress();
-       callerip[0] = '\0';
-       if (calleraddress)
-       {
-               if (strstr(calleraddress, "ip$"))
-               {
-                       SCPY(callerip, strstr(calleraddress, "ip$")+3);
-                       if (strchr(callerip, ':'))
-                               *strchr(callerip, ':') = '\0';
-                       memmove(strstr(calleraddress, "ip$"), strstr(calleraddress, "ip$")+3, strlen(strstr(calleraddress, "ip$")+3)+1);
-               }
-               if (strchr(calleraddress, ':'))
-                       *strchr(calleraddress, ':') = '\0';
-       }
-
-       // get dialing information
-       for(i=0; i<adr.GetSize(); i++)
-               if (adr[i].GetTag() == H225_AliasAddress::e_dialedDigits)
-                       dialing = H323GetAliasAddressString(adr[i]);
-       if (!dialing)
-               dialing = "";
-
-       // fill port's information
-       if (calleraddress)
-               SCPY(callerinfo->voip, (char *)calleraddress);
-       capainfo->bearer_mode = INFO_BMODE_CIRCUIT;
-       capainfo->bearer_info1 = (options.law=='u')?INFO_INFO1_ULAW:INFO_INFO1_ALAW;
-       capainfo->bearer_capa = INFO_BC_SPEECH;
-
-       // change to incoming setup state
-       port->new_state(PORT_STATE_IN_OVERLAP);
-
-       // allocate new endpoint
-       if (!(epoint = new Endpoint(port->p_serial, 0)))
-       {
-               // error allocating endpoint
-               PDEBUG(DEBUG_H323, "h323-connection(%s) rejecting call because cannot create epoint for '%s'\n", port->p_name, callerinfo->id);
-               delete port;
-               port = NULL;
-               mutex_h323.Signal();
-               return AnswerCallDenied;
-       }
-       if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint)))
-       {
-               PERROR("no memory for application\n");
-               exit(-1);
-       }
-       if (!(port->epointlist_new(epoint->ep_serial)))
-       {
-               PERROR("no memory for epointlist\n");
-               exit(-1);
-       }
-       port->set_tone(NULL, "");
-
-       // send setup message to endpoint
-       message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_SETUP);
-       message->param.setup.port_type = port->p_type;
-
-       // before we start, we may check for h323_gateway entry
-       if (callerip[0])
-       {
-               extension = parse_h323gateway(callerip, option, sizeof(option));
-               if (extension)
-               {
-                       PDEBUG(DEBUG_H323, "h323-connection(%s) gateway '%s' is mapped to extension '%s' (option= '%s')\n", port->p_name, callerip, extension, option);
-                       SCPY(callerinfo->id, extension);
-                       SCPY(callerinfo->intern, extension);
-                       callerinfo->itype = INFO_ITYPE_INTERN;
-                       callerinfo->screen = INFO_SCREEN_NETWORK;
-               } else
-               {
-                       PDEBUG(DEBUG_H323, "h323-connection(%s) gateway '%s' is not mapped to any extension. (port_type=0x%x)\n", port->p_name, callerip, port->p_type);
-                       // get the default dialing external dialing string
-               }
-       }
-
-       // default dialing for extenal calls
-       if (!callerinfo->intern[0] && !dialing[0])
-               dialing = options.h323_icall_prefix;
-
-       // dialing information
-       if (callerip[0] || dialing[0])
-       {
-               SCPY(dialinginfo->number, (char *)dialing);
-               dialinginfo->ntype = INFO_NTYPE_UNKNOWN;
-       }
-
-       memcpy(&message->param.setup.callerinfo, callerinfo, sizeof(struct caller_info));
-       memcpy(&message->param.setup.dialinginfo, dialinginfo, sizeof(struct dialing_info));
-       memcpy(&message->param.setup.redirinfo, redirinfo, sizeof(struct redir_info));
-       memcpy(&message->param.setup.capainfo, capainfo, sizeof(struct capa_info));
-       message->param.setup.dtmf = 1;
-       message_put(message);
-
-       port->p_h323_connect = &(connectPDU.GetQ931());
-
-       mutex_h323.Signal();
-
-       if (!strcasecmp(option, "connect") || !strcasecmp(option, "dtmf"))
-       {
-               port->new_state(PORT_STATE_CONNECT);
-               return AnswerCallNow;
-       } else
-       {
-               return AnswerCallDeferred;
-       }
-}
-
-
-//
-// OnOutgoingCall (outgoing call)
-//
-BOOL H323_con::OnOutgoingCall(const H323SignalPDU &connectPDU)
-{  
-       class H323Port *port;
-       const char *calleraddress;
-       char callerip[32];
-       const unsigned char *token_string = callToken;
-       struct message *message;
-//     H225_Connect_UUIE &connect_uuie = connectPDU.m_h323_uu_pdu.m_h323_message_body;
-
-       const Q931 connect_q931 = connectPDU.GetQ931();
-       PString connect_number;
-       unsigned type = 0, plan = 0, present = 0, screen = 0;
-       struct connect_info *connectinfo;
-
-       PDEBUG(DEBUG_H323, "H323 connection  outgoing call is connected.\n");
-
-       mutex_h323.Wait();
-
-       if (!(port = (class H323Port *)find_port_with_token((char *)token_string)))
-       {
-               PERROR(" cannot find port with token '%s'\n", token_string);
-               mutex_h323.Signal();
-               return FALSE;
-       }
-       connectinfo = &port->p_connectinfo;
-
-       if (port->p_type == PORT_TYPE_H323_IN)
-       {
-               PDEBUG(DEBUG_H323, "H323 endpoint  OnConnectionEstablished() incoming port\n");
-       }
-       if (port->p_type == PORT_TYPE_H323_OUT)
-       {
-               PDEBUG(DEBUG_H323, "H323 endpoint  OnConnectionEstablished() outgoing port\n");
-               if (port->p_state==PORT_STATE_OUT_SETUP
-                || port->p_state==PORT_STATE_OUT_OVERLAP
-                || port->p_state==PORT_STATE_OUT_PROCEEDING
-                || port->p_state==PORT_STATE_OUT_ALERTING)
-               {
-                       // get remote party h323-address information
-                       calleraddress = GetRemotePartyAddress();
-                       callerip[0] = '\0';
-                       if (calleraddress)
-                       {
-                               if (strchr(calleraddress, '$'))
-                               {
-                                       SCPY(callerip, strchr(calleraddress, '$'));
-                                       callerip[sizeof(callerip)-1] = '\0';
-                                       if (strchr(callerip, ':'))
-                                               *strchr(callerip, ':') = '\0';
-                               }
-                               SCPY(connectinfo->voip, (char *)calleraddress);
-                       }
-
-                       // get COLP
-                       memset(connectinfo, 0, sizeof(struct connect_info));
-                       connectinfo->itype = INFO_ITYPE_H323;
-                       if (connect_q931.GetConnectedNumber(connect_number, &plan, &type, &present, &screen))
-                       {
-                               SCPY(connectinfo->id, connect_number.GetPointer());
-                               switch (present)
-                               {
-                                       case 1:
-                                       connectinfo->present = INFO_PRESENT_RESTRICTED;
-                                       break;
-                                       case 2:
-                                       connectinfo->present = INFO_PRESENT_NOTAVAIL;
-                                       break;
-                                       default:
-                                       connectinfo->present = INFO_PRESENT_ALLOWED;
-                               }
-                               switch (type)
-                               {
-                                       case Q931::InternationalType:
-                                       connectinfo->ntype = INFO_NTYPE_INTERNATIONAL;
-                                       break;
-                                       case Q931::NationalType:
-                                       connectinfo->ntype = INFO_NTYPE_NATIONAL;
-                                       break;
-                                       case Q931::SubscriberType:
-                                       connectinfo->ntype = INFO_NTYPE_SUBSCRIBER;
-                                       break;
-                                       default:
-                                       connectinfo->ntype = INFO_NTYPE_UNKNOWN;
-                               }
-                               switch (screen)
-                               {
-                                       case 0:
-                                       connectinfo->screen = INFO_SCREEN_USER;
-                                       break;
-                                       default:
-                                       connectinfo->screen = INFO_SCREEN_NETWORK;
-                               }
-                       }
-                       port->new_state(PORT_STATE_CONNECT);
-                       message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_CONNECT);
-                       memcpy(&message->param.connectinfo, connectinfo, sizeof(struct connect_info));
-                       message_put(message);
-               }
-       }
-
-       mutex_h323.Signal();
-
-       return H323Connection::OnOutgoingCall(connectPDU);
-}
-
-
-//
-// send setup information to the called h323 user
-//
-BOOL H323_con::OnSendSignalSetup(H323SignalPDU &setupPDU)
-{
-       H225_Setup_UUIE &setup = setupPDU.m_h323_uu_pdu.m_h323_message_body;
-       H225_ArrayOf_AliasAddress &adr = setup.m_sourceAddress;
-       H225_AliasAddress new_alias;
-       PString calling_number;
-       PString calling_alias;
-       PString dialing_number;
-       PString redir_number;
-       int type, present, screen, reason;
-       class H323Port *port;
-       const unsigned char *token_string = callToken;
-
-       struct caller_info *callerinfo;
-       struct dialing_info *dialinginfo;
-       struct capa_info *capainfo;
-       struct redir_info *redirinfo;
-
-       mutex_h323.Wait();
-
-       if (!(port = (class H323Port *)find_port_with_token((char *)token_string)))
-       {
-               PERROR(" no port with token '%s'\n", token_string);
-               mutex_h323.Signal();
-               return FALSE;
-       }
-       callerinfo = &port->p_callerinfo;
-       redirinfo = &port->p_redirinfo;
-       capainfo = &port->p_capainfo;
-       dialinginfo = &port->p_dialinginfo;
-
-       PDEBUG(DEBUG_H323, "H323-connection  sending modified setup signal '%s'->'%s'\n", callerinfo->id, dialinginfo->number);
-
-
-       if (callerinfo->present!=INFO_PRESENT_NULL)
-       {
-               calling_alias = numberrize_callerinfo(callerinfo->id, callerinfo->ntype);
-               H323SetAliasAddress(calling_alias, new_alias);
-               adr.SetSize(adr.GetSize()+1);
-               adr[adr.GetSize()-1] = new_alias;
-
-               calling_number = callerinfo->id;
-               switch(callerinfo->ntype)
-               {
-                       case INFO_NTYPE_SUBSCRIBER:
-                       type = Q931::SubscriberType;
-                       break;
-                       case INFO_NTYPE_NATIONAL:
-                       type = Q931::NationalType;
-                       break;
-                       case INFO_NTYPE_INTERNATIONAL:
-                       type = Q931::InternationalType;
-                       break;
-                       default: /* INFO_NTYPE_UNKNOWN */
-                       type = Q931::UnknownType;
-               }
-
-               switch(callerinfo->present)
-               {
-                       case INFO_PRESENT_RESTRICTED:
-                       present = 1;
-                       break;
-                       case INFO_PRESENT_NOTAVAIL:
-                       present = 2;
-                       break;
-                       default: /* INFO_PRESENT_ALLOWED */
-                       present = 0;
-               }
-               switch(callerinfo->screen)
-               {
-                       case INFO_SCREEN_USER:
-                       screen = 0;
-                       break;
-                       default: /* INFO_SCREEN_NETWORK */
-                       screen = 3;
-               }
-
-               Q931 &new_q931 = setupPDU.GetQ931();
-               new_q931.SetCallingPartyNumber(calling_number, Q931::ISDNPlan, type, present, screen);
-       }
-
-       if (redirinfo->present!=INFO_PRESENT_NULL)
-       {
-               if (redirinfo->present==INFO_PRESENT_ALLOWED)
-               {
-                       redir_number = callerinfo->id;
-               } else
-                       redir_number = "";
-
-               switch(redirinfo->ntype)
-               {
-                       case INFO_NTYPE_SUBSCRIBER:
-                       type = Q931::SubscriberType;
-                       break;
-                       case INFO_NTYPE_NATIONAL:
-                       type = Q931::NationalType;
-                       break;
-                       case INFO_NTYPE_INTERNATIONAL:
-                       type = Q931::InternationalType;
-                       break;
-                       default: /* INFO_TYPE_UNKNOWN */
-                       type = Q931::UnknownType;
-               }
-
-               switch(redirinfo->present)
-               {
-                       case INFO_PRESENT_RESTRICTED:
-                       present = 1;
-                       break;
-                       case INFO_PRESENT_NOTAVAIL:
-                       present = 2;
-                       break;
-                       default: /* INFO_PRESENT_ALLOWED */
-                       present = 0;
-               }
-
-               switch(redirinfo->reason)
-               {
-                       case INFO_REDIR_BUSY:
-                       reason = 1;
-                       break;
-                       case INFO_REDIR_NORESPONSE:
-                       reason = 2;
-                       break;
-                       case INFO_REDIR_UNCONDITIONAL:
-                       reason = 15;
-                       break;
-                       case INFO_REDIR_OUTOFORDER:
-                       reason = 9;
-                       break;
-                       case INFO_REDIR_CALLDEFLECT:
-                       reason = 10;
-                       break;
-                       default: /* INFO_REDIR_UNKNOWN */
-                       reason = 0;
-               }
-
-               Q931 &new_q931 = setupPDU.GetQ931();
-               new_q931.SetRedirectingNumber(redir_number, Q931::ISDNPlan, type, present, screen, reason);
-       }
-
-       if (dialinginfo->number[0])
-       {
-               dialing_number = dialinginfo->number;
-
-               Q931 &new_q931 = setupPDU.GetQ931();
-               new_q931.SetCalledPartyNumber(dialing_number);
-       }
-       
-       mutex_h323.Signal();
-
-       return H323Connection::OnSendSignalSetup(setupPDU);
-}
-
-
-//
-// callback for start of channel
-//
-BOOL H323_con::OnStartLogicalChannel(H323Channel &channel)
-{
-       if (!H323Connection::OnStartLogicalChannel(channel))
-       {
-               PERROR("starting logical channel failed!\n");
-               return FALSE;
-       }
-
-       PDEBUG(DEBUG_H323, "H323 connection  starting logical channel using \"%s\" codec %s :%s\n",
-                channel.GetCapability().GetFormatName().GetPointer(),
-                (channel.GetDirection()==H323Channel::IsTransmitter)?"transmit":"receive",
-                callToken.GetPointer());
-
-       return H323Connection::OnStartLogicalChannel(channel);
-}
-
-
-//
-// user input received
-//
-void H323_con::OnUserInputString (const PString &value)
-{
-       class H323Port *port;
-       const unsigned char *token_string = callToken;
-       const unsigned char *value_string = value;
-       struct message *message;
-
-       PDEBUG(DEBUG_H323, "H323-connection  received user input'%s'\n", value_string);
-
-       mutex_h323.Wait();
-
-       if (!(port = (class H323Port *)find_port_with_token((char *)token_string)))
-       {
-               PERROR("no port with token '%s'\n", token_string);
-       } else
-       {
-               while(*value_string)
-               {
-                       message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_DTMF);
-                       message->param.dtmf = *value_string++;
-                       message_put(message);
-               }
-#if 0
-               message = message_create(port->p_serial, ACTIVE_EPOINT(port->p_epointlist), PORT_TO_EPOINT, MESSAGE_INFORMATION);
-               SCPY(message->param.information.number, (char *)value_string);
-               message_put(message);
-#endif
-       }
-
-       mutex_h323.Signal();
-}
-