call.cpp
资源名称:h323.zip [点击查看]
上传用户:hnnddl
上传日期:2007-01-06
资源大小:3580k
文件大小:56k
源码类别:
IP电话/视频会议
开发平台:
WINDOWS
- /*
- * $Revision: 1.26 $
- * $Date: 1999/03/17 18:05:31 $
- */
- ////////////////////////////////////////////////////////////////
- // Copyright (c) 1996-98 Lucent Technologies //
- // All Rights Reserved //
- // //
- // THIS IS UNPUBLISHED //
- // PROPRIETARY SOURCE //
- // CODE OF Lucent Technologies //
- // AND elemedia //
- // //
- ////////////////////////////////////////////////////////////////
- //
- ////////////////////////////////////////////////////////////////
- // Example programs are provided soley to demonstrate one //
- // possible use of the stack libraries and are included for //
- // instructional purposes only. You are free to use, modify //
- // and/or redistribute any portion of code in the example //
- // programs. However, such examples are not intended to //
- // represent production quality code. //
- // //
- // THE COPYRIGHT HOLDERS PROVIDE THESE EXAMPLE PROGRAMS //
- // "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED //
- // OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED //
- // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A //
- // PARTICULAR PURPOSE. //
- ////////////////////////////////////////////////////////////////
- #include "exchange.h"
- #include "call.h"
- #include "msg.h"
- #include "api/h225ie.h"
- #include <assert.h>
- #if (defined(WIN32))
- #include <winsock.h>
- #elif defined(VXWORKS)
- #else
- // Include the following line in uw2.1.0
- #if defined(sun)
- extern "C" int gethostname(char *name, int len);
- #endif
- #if defined(__hpux)
- #include <wchar.h>
- #else
- #include <wctype.h>
- #endif
- #endif
- #if (defined(ENABLE_BENCHMARKS))
- #include "perf.h"
- #endif
- #ifdef USE_RAS
- extern int seqno;
- #endif
- /*ARGSUSED*/
- H323Call::H323Call(Exchange* ex,int h225_id, int h245_id,
- H225CSEndpointType& ep, int tt, char *display, int outgoing_call,
- ProtReturnCode& result) :
- H225CSProtocol(h225_id,ep,result,display),
- H245Protocol(h245_id,tt,result),
- MessageQueue(0,0,0)
- {
- LOG("H323Call::H323Calln");
- LOG("terminal_type = %dn",tt);
- if (!PROT_IS_SUCCESS(result))
- {
- LOG("Constructor failed result = 0x%xn", result);
- return;
- }
- cap_done = 0;
- olc_done = 0;
- msd_done = 0;
- audio_session = NULL;
- exchange = ex;
- endsession_sent = 0;
- call_dropped = 0;
- faststart_state = FAST_START_STATE_DISABLED;
- do_faststart = ex->use_faststart;
- do_tunneling = ex->use_tunneling;
- do_overlapsend = ex->use_overlapsend;
- do_alerting = ex->use_alerting;
- do_proceeding = ex->use_callproc;
- remote_name[0] = ' ';
- phone[0] = ' ';
- src_phone[0] = ' ';
- // transfer related
- transfer_flag = FALSE;
- transfer_invoke_id = -1;
- transfer_call_id[0] = ' ';
- transfer_parent_index = -1;
- #if !defined(VXWORKS)
- char hostname[256];
- struct hostent *hent_p;
- gethostname(hostname,sizeof(hostname));
- hent_p = gethostbyname(hostname);
- if(hent_p == NULL)
- {
- LOG("gethostbyname failed on %s error %dn", hostname,errno);
- return;
- }
- #endif
- if (strlen(display))
- {
- display_str = new char[strlen(display) + 1];
- strcpy(display_str, display);
- }
- else
- {
- display_str = NULL;
- }
- #if defined(VXWORKS)
- {
- char hostname[256];
- sprintf(hostname,"vxworks%d",sysProcNumGet());
- if_ip_addr = hostGetByName(hostname);
- //if_ip_addr = inet_addr("127.0.1.2");
- }
- #else
- int i = 0;
- while(hent_p->h_addr_list[i])
- {
- LOG("Interface %d, ip = 0x%xn",
- i,*(unsigned long *)(hent_p->h_addr_list[i]));
- ++i;
- }
- if_ip_addr = *(unsigned long *)(hent_p->h_addr_list[0]);
- #endif
- is_outgoing_call = outgoing_call;
- if (outgoing_call)
- {
- // Set the conference ID and the Call ID.
- // IP and index just for demonstration purposes.
- sprintf(confid, "%00000008x%0004d",
- exchange->confid_prefix, h225_id);
- callid.SetCallID((unsigned char *)confid,16);
- H225CSProtocol::SetCallID(callid);
- H225CSProtocol::SetConfID((unsigned char *)confid,16);
- }
- #if defined(ENABLE_BENCHMARKS)
- get_current_time(st_sec,st_msec);
- end_sec = end_msec = 0;
- max_stack_size = cur_stack_size = 0;
- #endif
- audio_session_flag = 0;
- memset(&remote_lc0_addr, 0, sizeof(remote_lc0_addr));
- memset(&local_lc0_addr, 0, sizeof(local_lc0_addr));
- LOG("Defaulting to interface ip address 0x%xn", if_ip_addr);
- if (do_faststart)
- {
- if (CreateRtpSession())
- {
- result = (unsigned int)-1;
- }
- }
- }
- H323Call::~H323Call()
- {
- LOG("H323Call::~H323Calln");
- if (audio_session)
- {
- delete audio_session;
- }
- delete display_str;
- }
- void
- H323Call::NotifyMessage(USER_MESSAGE& msg)
- {
- LOG("H323Call::NotifyMessagen");
- ProtReturnCode ret;
- void *data = (void*)(msg.lParam);
- if (call_dropped)
- {
- if (data)
- {
- delete (CBData*)data;
- }
- return;
- }
- int myindex = ((H225CSProtocol *)this)->GetIdentifier() - ID_H225;
- if (msg.message == PROT_CALL_MSG)
- {
- switch(msg.wParam)
- {
- case CB_Q931_EVENT:
- {
- Q931Evt *info = (Q931Evt *)data;
- LOG("CB_Q931_EVENT, event type = %dn", info->event_type);
- Q931Message *q931msg = NULL;
- int type = 0;
- if (info->event_type == Q931EVENT_ERROR)
- {
- LOG("Got Error from Q931Engine, STATE_NULL,"
- " error = 0x%xn",
- info->err->GetError());
- // Check if the H.245 is listening
- if(GetCallDirection() == DIR_INCOMING &&
- (!((H245Protocol *)this)->IsConnectionReady()))
- {
- exchange->StopListening(
- ((H245Protocol *)this)->GetIdentifier());
- }
- DropQ931(RCR_UNDEFINED);
- goto end_call;
- }
- if (info->event_type == Q931EVENT_MESSAGE)
- {
- q931msg = info->message;
- if (q931msg)
- {
- q931msg->GetType(type);
- LOG("Q931msg = 0x%xn", type);
- }
- }
- if (info->event_type == Q931EVENT_MESSAGE &&
- q931msg && type == MESSAGE_Q932_FACILITY)
- {
- H225CSFacilityUUIE *f = (H225CSFacilityUUIE*)info->ie;
- LOG("In call.cpp received FACILITYn");
- // Now check for supp services
- H4501SuppService *ss;
- // ProtReturnCode ret;
- int sscount;
- ret = f->GetNumH450SupplementaryServices(sscount);
- if(!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed in GetNumH450SupplementaryServices - "
- "getting num supp services ret=%dn", ret);
- }
- if(sscount != 0)
- {
- ss = new H4501SuppService[sscount];
- ret = f->GetH450SupplementaryServices(ss, sscount);
- if(!PROT_IS_SUCCESS(ret))
- {
- printf("Failed in GetH450SupplementaryServices - "
- "getting supplementary services ret=0x%xn", ret);
- //return
- }
- else
- {
- int isII;
- unsigned int ip_addr;
- isII = isInitiateInvoke(ss, transfer_invoke_id,
- transfer_call_id, ip_addr, phone);
- if(isII == 1) {
- LOG("Placing a call to transferredTon");
- exchange->PlaceTransferedToCall(myindex, ip_addr,
- phone, transfer_invoke_id, transfer_call_id);
- } else if(isII == -1) {
- break;
- }
- }
- delete [] ss;
- }
- }
- switch(info->new_state)
- {
- // TODO: FASTSTART FALLBACK incase we recv a facility message
- case STATE_NULL:
- {
- LOG("Got ReleaseComplete,STATE_NULLn");
- if (((H245Protocol *)this)->IsConnectionReady())
- {
- if ( endsession_sent == 0)
- {
- LOG("ERROR..Deleting call before "
- " end sessionn");
- }
- }
- else
- {
- // Check if the H.245 is listening
- if(GetCallDirection() == DIR_INCOMING &&
- (!((H245Protocol *)this)->IsConnectionReady()))
- {
- exchange->StopListening(
- ((H245Protocol *)this)->GetIdentifier());
- }
- }
- goto end_call;
- /*NOTREACHED*/
- }
- break;
- case STATE_CALL_PRESENT:
- {
- assert(info->event_type == Q931EVENT_MESSAGE);
- assert(q931msg != NULL);
- if (q931msg && type == MESSAGE_SETUP)
- {
- LOG("Line <%d> STATE_CALL_PRESENTn", myindex);
- LOG("MESSAGE_SETUPn");
- H225CSSetupUUIE *s = (H225CSSetupUUIE*)info->ie;
- struct sockaddr_in saddr;
- int alias_count = 0;
- if (s->GetH245Transport((struct sockaddr *)&saddr)
- == H225CS_SUCCESS)
- {
- LOG("H245Transport Address 0x%x, %dn",
- saddr.sin_addr.s_addr,
- ntohs(saddr.sin_port));
- }
- // V2
- // Set the call id if the remote end is version 1.
- int remote_version = H225_VERSION_INVALID;
- s->GetProtocolID(remote_version);
- LOG("remote end is a Version %d endpointn",
- remote_version);
- #if defined(GK19980320) // this is internal test, do not define it
- // Set the Call ID.
- char tmp[80];
- sprintf(tmp, "%00000008x%00000008d",
- exchange->confid_prefix, myindex);
- callid.SetCallID((unsigned char *)tmp,16);
- // Set the callid in the protocol object..
- // This dummy callid will be used for all
- // q931 messages we send out.
- SetCallID(callid);
- #else
- if (remote_version == H225_VERSION_1)
- {
- // Set the Call ID.
- char tmp[80];
- sprintf(tmp, "%00000008x%00000008d",
- exchange->confid_prefix, myindex);
- callid.SetCallID((unsigned char *)tmp,16);
- // Set the callid in the protocol object..
- // This dummy callid will be used for all
- // q931 messages we send out.
- SetCallID(callid);
- }
- else
- {
- // Get the call id from setup message and
- // fill it in.
- if (!PROT_IS_SUCCESS(s->GetCallID(callid)))
- {
- LOG("Unable to retrieve call id n");
- LocalHangup();
- goto end_call;
- }
- }
- #endif
- // Get and print the Display information element.
- Q931IE *ie_display;
- if (PROT_IS_SUCCESS(q931msg->GetIE(IE_DISPLAY,
- ie_display)))
- {
- int len = sizeof(remote_name);
- if (PROT_IS_SUCCESS(((Q931DisplayIE *)ie_display)->
- GetDisplayString(remote_name, len)))
- {
- remote_name[len] = 0;
- }
- }
- LOG("Remote Ends DISPLAY is %s.n", remote_name);
- // Get and print the Bearer capability element.
- Q931IE *ie_bc;
- if (PROT_IS_SUCCESS(q931msg->GetIE(IE_BEARER_CAPABILITY,
- ie_bc)))
- {
- H225CSBearerCapabilityIE *_ie_bc =
- (H225CSBearerCapabilityIE *)ie_bc;
- int cap = 0, rate = 0, value = 0;
- LOG("Got bearer capsn");
- _ie_bc->GetInfoTransferCap(cap);
- LOG("tinfo transfer cap = %dn", cap);
- _ie_bc->GetInfoTransferRate(rate);
- LOG("tinfo transfer rate = %dn", rate);
- if (rate == BC_ITR_MULTIRATE)
- {
- _ie_bc->GetRateMultiplier(value);
- LOG("trate multiplier = %dn", value);
- }
- _ie_bc->GetLayer1Prot(value);
- LOG("tlayer 1 protocol = %dn", value);
- _ie_bc->GetCodingStd(value);
- LOG("tCoding Standard = %dn", value);
- }
- else
- {
- LOG("Bearer capability not set !!!n");
- }
- // Get and print the remote endpoint type
- H225CSEndpointType ep;
- if (PROT_IS_SUCCESS(s->GetSrcInfo(ep)))
- {
- if (PROT_IS_SUCCESS(ep.IsGatekeeperSet()))
- {
- LOG("Remote end is a Gatekeepern");
- }
- if (PROT_IS_SUCCESS(ep.IsTerminalSet()))
- {
- LOG("Remote end is a Terminaln");
- }
- if (PROT_IS_SUCCESS(ep.IsGatewaySet()))
- {
- LOG("Remote end is a Gatewayn");
- }
- if (PROT_IS_SUCCESS(ep.IsMCUSet()))
- {
- LOG("Remote end is an MCUn");
- }
- }
- // get and print the source aliases
- if (PROT_IS_SUCCESS(s->GetNumSrcAddrs(alias_count)) &&
- alias_count > 0)
- {
- LOG("Got %d source alias addressesn", alias_count);
- int count = alias_count;
- H225CSAliasAddress *a =
- new H225CSAliasAddress[count];
- ret = s->GetSrcAddrs(a, count);
- assert(count == alias_count);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Unable to extract source address"
- " 0x%xn", ret);
- }
- else
- {
- unsigned short *id;
- unsigned short len;
- int j = 0;
- while (j < alias_count)
- {
- ProtReturnCode ret;
- if (a[j].GetType() == AAT_H323_ID)
- {
- if ((ret = a[j].GetH323ID(id, len)) !=
- H225CS_SUCCESS)
- {
- LOG("Unable to extract the H323ID"
- " 0x%xn", ret);
- }
- else
- {
- char string[512];
- int string_length = 512;
- char q = '?';
- int ret_length;
- #if (defined(WIN32))
- if ((ret_length = WideCharToMultiByte(
- CP_ACP,
- 0,
- id,
- len,
- string,
- string_length,
- &q,
- NULL)) == FALSE)
- {
- LOG("WideChartoMultiByte"
- " conversion failed %dn",
- GetLastError());
- }
- else
- {
- string[ret_length] = ' ';
- LOG("source H323ID = %sn",
- string);
- printf("%sn",string);
- strncpy(remote_name, string,
- sizeof(remote_name) -1);
- }
- #elif defined(VXWORKS)
- #else
- int i;
- for (i = 0; i < len; i++)
- {
- #if defined(__hpux)
- if (iswalnum(id[i]))
- #else
- if (iswascii(id[i]))
- #endif
- {
- string[i] = (char) id[i];
- }
- else
- {
- break;
- }
- }
- string[i] = ' ';
- LOG("source H323ID = %sn", string);
- printf("%sn",string);
- strncpy(remote_name, string,
- sizeof(remote_name) -1);
- #endif
- }
- }
- else if (a[j].GetType() == AAT_E164)
- {
- char *tmp_phone;
- if ((ret = a[j].GetE164(tmp_phone, len)) !=
- H225CS_SUCCESS)
- {
- LOG("Unable to extract the E164 alias"
- " 0x%xn", ret);
- }
- else
- {
- tmp_phone[len] = ' ';
- SetSrcPhoneNumber(tmp_phone);
- LOG("src phone = %sn",
- src_phone);
- }
- }
- ++j;
- }
- }
- delete [] a;
- }
- // get and print the destination aliases
- if (PROT_IS_SUCCESS(s->GetNumDstAddrs(alias_count)) &&
- alias_count > 0)
- {
- LOG("Got %d dest alias addressesn", alias_count);
- int count = alias_count;
- H225CSAliasAddress *a =
- new H225CSAliasAddress[count];
- ret = s->GetDstAddrs(a, count);
- assert(count == alias_count);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Unable to extract destination address"
- " 0x%xn", ret);
- }
- else
- {
- unsigned short *id;
- unsigned short len;
- int j = 0;
- while (j < alias_count)
- {
- ProtReturnCode ret;
- if (a[j].GetType() == AAT_H323_ID)
- {
- if ((ret = a[j].GetH323ID(id, len)) !=
- H225CS_SUCCESS)
- {
- LOG("Unable to extract the destination H323ID"
- " 0x%xn", ret);
- }
- else
- {
- char string[512];
- int string_length = 512;
- char q = '?';
- int ret_length;
- #if (defined(WIN32))
- if ((ret_length = WideCharToMultiByte(
- CP_ACP,
- 0,
- id,
- len,
- string,
- string_length,
- &q,
- NULL)) == FALSE)
- {
- LOG("WideChartoMultiByte"
- " conversion failed %dn",
- GetLastError());
- }
- else
- {
- string[ret_length] = ' ';
- LOG("destination end H323ID = %sn",
- string);
- printf("%sn",string);
- //strncpy(remote_name, string,
- // sizeof(remote_name) -1);
- }
- #elif defined(VXWORKS)
- #else
- int i;
- for (i = 0; i < len; i++)
- {
- #if defined(__hpux)
- if (iswalnum(id[i]))
- #else
- if (iswascii(id[i]))
- #endif
- {
- string[i] = (char) id[i];
- }
- else
- {
- break;
- }
- }
- string[i] = ' ';
- LOG("destination end H323ID = %sn", string);
- //strncpy(remote_name, string,
- // sizeof(remote_name) -1);
- #endif
- }
- }
- else if (a[j].GetType() == AAT_E164)
- {
- char *tmp_phone;
- if ((ret = a[j].GetE164(tmp_phone, len)) !=
- H225CS_SUCCESS)
- {
- LOG("Unable to extract the E164 destination alias"
- " 0x%xn", ret);
- }
- else
- {
- tmp_phone[len] = ' ';
- SetPhoneNumber(tmp_phone);
- LOG("dest phone = %sn",
- phone);
- }
- }
- ++j;
- }
- }
- delete [] a;
- }
- // Set the conference identifier to be
- // the same as the incoming call's cid.
- unsigned char *cid_p;
- int cid_len;
- s->GetConfID(cid_p, cid_len);
- SetConfID(cid_p, cid_len);
- // check if this a call coming from transferred (B endpoint)
- H4501SuppService *ss;
- ProtReturnCode ret;
- int sscount;
- ret = s->GetNumH450SupplementaryServices(sscount);
- if(!PROT_IS_SUCCESS(ret))
- {
- printf("Failed in GetH450SupplementaryServices - "
- "getting supplementary services ret=0x%xn", ret);
- }
- else if(sscount != 0)
- {
- ss = new H4501SuppService[sscount];
- ret = s->GetH450SupplementaryServices(ss, sscount);
- if(!PROT_IS_SUCCESS(ret))
- {
- printf("Failed in GetH450SupplementaryServices - "
- "getting supplementary services ret=0x%xn", ret);
- printf("%s: line %dn",__FILE__,__LINE__);
- }
- else
- {
- LOG("Got %d Supplementary Servicesn",sscount);
- LOG("=============================n");
- LOG("Extract Supplementary Services msgn");
- extractedSS *extSS = new extractedSS;
- extSS->tH4501SuppService(&ss[0]);
- if (extSS->ssNumROSs > 0)
- {
- if (extSS->ssROS[0].type == ROS_INVOKE)
- {
- if (extSS->ssROS[0].code == CTOT_SETUP)
- {
- transfer_invoke_id = extSS->ssROS[0].InvokeId;
- strncpy(transfer_call_id, extSS->ssROS[0].Arg.CallID, 5);
- SetTransferFlag(TRUE);
- }
- }
- }
- delete extSS;
- }
- delete [] ss;
- }
- else
- {
- LOG("There are no Supplementary Services in this SETUPn");
- }
- #if defined(USE_RAS)
- if (exchange->IsGKRegistered())
- {
- SendARQdata *arq_data = new SendARQdata;
- if (src_phone[0])
- strcpy(arq_data->e164src, src_phone);
- else // ARQ needs the srcInfo field anyway, so fill it up
- strcpy(arq_data->e164src, "999999");
- strcpy(arq_data->e164dst, phone);
- arq_data->index = GetApplicationPrivate();
- // ask the RAS protocol handler to send ARQ for this call
- exchange->SendToExchange(PROT_CALL_MSG, CB_SEND_ARQ,
- (unsigned long)arq_data);
- }
- // not registered, sent ALERTING
- else if (do_alerting && (Q931SendAlerting() < 0))
- goto end_call;
- else
- {
- if (Q931SendConnect() < 0)
- goto end_call;
- else
- printf("Connected to %sn", remote_name);
- }
- #else // defined(USE_RAS)
- if (do_overlapsend)
- {
- // We have to send back a setupack.
- if (Q931SendSetupAck() < 0)
- goto end_call;
- }
- else
- {
- if (do_alerting)
- {
- if (Q931SendAlerting() < 0)
- goto end_call;
- }
- else
- {
- if (Q931SendConnect() < 0)
- goto end_call;
- else
- printf("Connected to %sn", remote_name);
- }
- }
- #endif //defined(USE_RAS)
- }
- }
- break;
- case STATE_INCOMING_CALL_PROCEEDING:
- {
- LOG("Line <%d> STATE_INCOMING_CALL_PROCEEDINGn", myindex);
- }
- break;
- case STATE_OUTGOING_CALL_PROCEEDING:
- {
- LOG("Line <%d> STATE_OUTGOING_CALL_PROCEEDINGn", myindex);
- }
- break;
- case STATE_CALL_RECEIVED:
- {
- #if 1
- LOG("Line <%d> STATE_CALL_RECEIVEDn", myindex);
- if (Q931SendConnect() < 0)
- goto end_call;
- else
- printf("Connected to %sn", remote_name);
- #endif
- }
- break;
- case STATE_CALL_INITIATED:
- {
- LOG("Line <%d> STATE_CALL_INITIATEDn", myindex);
- }
- break;
- case STATE_OVERLAP_SENDING:
- {
- LOG("Line <%d> STATE_OVERLAP_SENDINGn", myindex);
- if (Q931SendInformation("12345#") < 0)
- goto end_call;
- }
- break;
- case STATE_OVERLAP_RECEIVING:
- {
- LOG("Line <%d> STATE_OVERLAP_RECEIVINGn", myindex);
- if (q931msg && type == MESSAGE_INFORMATION)
- {
- LOG("Got Information messagen");
- // Fetch the keypad facility ie.
- LOG("Fetching keytpad facility ien");
- Q931IE *ie_keypad_fac;
- if (PROT_IS_SUCCESS(q931msg->GetIE(
- IE_KEYPAD_FACILITY,ie_keypad_fac)))
- {
- Q931KeypadFacilityIE *ie_kp =
- (Q931KeypadFacilityIE*)ie_keypad_fac;
- char info[256];
- int length = sizeof(info) - 1;
- if (PROT_IS_SUCCESS(ie_kp->GetKeypadInfo(
- info,length)))
- {
- info[length] = 0;
- LOG("Keypad fac[%s]n",info);
- }
- }
- else
- {
- LOG("keytpad facility ie fetch failedn");
- }
- Q931IE *ie_snd_comp;
- if (PROT_IS_SUCCESS(q931msg->GetIE(
- IE_SENDING_COMPLETE,ie_snd_comp)))
- {
- printf("Got sending_complete...!n");
- if (Q931SendConnect() < 0)
- goto end_call;
- }
- }
- }
- break;
- case STATE_CALL_DELIVERED:
- {
- LOG("Line <%d> STATE_CALL_DELIVEREDn", myindex);
- }
- break;
- case STATE_CALL_ACTIVE:
- {
- LOG("Line <%d> STATE_CALL_ACTIVEn", myindex);
- // Q.931 negotiations succeeded.
- // Q.931 Call is active, but faststart is still
- // pending.. disable it, something went wrong..
- if (do_faststart &&
- faststart_state == FAST_START_STATE_PENDING)
- {
- faststart_state = FAST_START_STATE_DISABLED;
- }
- if (GetCallDirection() == DIR_OUTGOING &&
- info->new_state != info->old_state)
- {
- assert (type == MESSAGE_CONNECT);
- assert(q931msg != NULL);
- // Connect message from the remote end...
- // Get the H245 address and open a logical channel.
- H225CSConnectUUIE *c =
- (H225CSConnectUUIE*)info->ie;
- assert(c != NULL);
- struct sockaddr_in saddr;
- if (c->GetH245Transport(
- (struct sockaddr *)&saddr) == H225CS_SUCCESS)
- {
- LOG("H245Transport Address 0x%x, %dn",
- saddr.sin_addr.s_addr,
- ntohs(saddr.sin_port));
- remote_lc0_addr = saddr;
- // Connect only if no faststart or faststart
- // failed.
- if (!do_faststart ||
- (do_faststart && faststart_state ==
- FAST_START_STATE_DISABLED))
- {
- ret = exchange->Connect(
- (sockaddr *)&remote_lc0_addr,
- (H245Protocol *)this);
- if (!PROT_IS_PENDING(ret))
- {
- exchange->NotifyConnectionStatus(
- (H245Protocol*)this,ret);
- }
- }
- }
- // Get the Display Information element..
- Q931IE *ie_display;
- if (PROT_IS_SUCCESS(q931msg->GetIE(IE_DISPLAY,
- ie_display)))
- {
- int len = sizeof(remote_name);
- if (PROT_IS_SUCCESS(ie_display->
- GetContent(remote_name, len)))
- {
- remote_name[len] = 0;
- }
- }
- LOG("Remote Ends DISPLAY is %s.n", remote_name);
- printf("Connected to %sn",remote_name);
- // now check if this is a call that was transferred successfully
- if (transfer_flag)
- {
- H4501SuppService *ss;
- ProtReturnCode ret;
- int sscount;
- ret = c->GetNumH450SupplementaryServices(sscount);
- if(!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed in GetNumH450SupplementaryServices - "
- "getting num supp services ret=%dn", ret);
- break;
- }
- if(sscount != 0)
- {
- ss = new H4501SuppService[sscount];
- ret = c->GetH450SupplementaryServices(ss, sscount);
- if(!PROT_IS_SUCCESS(ret))
- {
- printf("Failed in GetH450SupplementaryServices - "
- "getting supplementary services ret=0x%xn", ret);
- //return
- }
- else
- {
- LOG("Got %d Supplementary Servicesn",sscount);
- LOG("=============================n");
- LOG("Extract Supplementary Services msgn");
- extractedSS *extSS = new extractedSS;
- extSS->tH4501SuppService(&ss[0]);
- if (extSS->ssNumROSs > 0)
- {
- if (extSS->ssROS[0].type == ROS_RETURN_RESULT)
- {
- if (extSS->ssROS[0].code == CTOT_SETUP)
- {
- // transfer_invoke_id = extSS->ssROS[0].InvokeId;
- // strncpy(transfer_call_id, extSS->ssROS[0].Arg.CallID, 5);
- // LOG("Dropping the transferring calln");
- exchange->DropTranferringCall(transfer_parent_index);
- }
- }
- }
- delete extSS;
- }
- delete [] ss;
- }
- else
- {
- LOG("There are no Supplementary Services in this SETUPn");
- }
- }
- }
- }
- break;
- }
- }
- break;
- case CB_CONNECTION_CLOSED:
- {
- LOG("CB_CONNECTION_CLOSEDn");
- XchgConnectionClosed *info = (XchgConnectionClosed *)data;
- if (info->conn->GetIdentifier() ==
- ((H225CSProtocol *)this)->GetIdentifier())
- {
- // check for the h.245 connection closure here...
- if (((H245Protocol *)this)->IsConnectionReady())
- {
- if (endsession_sent != 0)
- {
- H245SigCommand *cmd ;
- H245SigCommand::Factory(cmd, CMDT_END_SESSION);
- ((H245SigEndSessionCommand *)cmd)->SetType(ESTY_DISCONNECT);
- SendCommand(*cmd);
- delete cmd;
- endsession_sent = 1;
- }
- }
- else
- {
- // Check if the H.245 is listening
- if(GetCallDirection() == DIR_INCOMING &&
- (!((H245Protocol *)this)->IsConnectionReady()))
- {
- exchange->StopListening(
- ((H245Protocol *)this)->GetIdentifier());
- }
- }
- LOG("H.225 Connection closedn");
- goto end_call;
- }
- else
- {
- assert(info->conn->GetIdentifier() ==
- ((H245Protocol *)this)->GetIdentifier());
- LOG("H.245 Connection closedn");
- }
- }
- break;
- // Exchange indicates the state of the H.245 logical channel 0
- // tcp connection.
- case CB_CONNECTION_STATUS:
- {
- LOG("CB_CONNECTION_STATUSn");
- XchgConnectionStatus *info = (XchgConnectionStatus *)data;
- if (info->conn->GetIdentifier() == // is this a H.225 connection?
- ((H225CSProtocol *)this)->GetIdentifier())
- {
- // either something went wrong with the connection
- if (PROT_IS_ERROR(info->status))
- {
- LOG("H225 Connect Failedn");
- goto end_call;
- }
- else // or the nonblocking connection succeeded.
- {
- LOG("H225 Connect Succeededn");
- // Create the bearer capability information element..
- Q931Message q931msg(MESSAGE_SETUP);
- H225CSBearerCapabilityIE bc;
- bc.SetInfoTransferCap(BC_ITC_SPEECH);
- bc.SetInfoTransferRate(BC_ITR_PACKET);
- bc.SetLayer1Prot(BC_L1P_ULAW);
- bc.SetCodingStd(BC_CS_ISO);
- q931msg.SetIE(bc);
- H225CSSetupUUIE setup_uuie(*(H225CSProtocol *)this);
- // Plug in the destination Address in the setup uuie.
- // If the phone number field is set.. then set
- // the destinationAddress.
- if (phone[0] != ' ')
- {
- Q931CalledPartyNumberIE cpn;
- cpn.SetNumberParams(NUMBERTYPE_UNKNOWN,
- NUMBERINGPLAN_ISDN);
- cpn.SetDigits((char *)phone, strlen(phone));
- q931msg.SetIE(cpn);
- H225CSAliasAddress e164;
- LOG("Phone number set in Setup message(%s)n",
- phone);
- e164.SetE164(phone,(unsigned short)strlen(phone));
- setup_uuie.AddDstAddr(e164);
- }
- if (config->e164src[0] != ' ')
- {
- Q931CallingPartyNumberIE cpn;
- // here we generate the originator phone number
- // in real life you should get that from the callerID (e.g. PSTN)
- // and pass it here
- char tmp_phone[256];
- sprintf(tmp_phone, "%s%0004d", config->e164src,
- GetApplicationPrivate());
- SetSrcPhoneNumber(tmp_phone);
- cpn.SetNumberParams(NUMBERTYPE_UNKNOWN,
- NUMBERINGPLAN_ISDN);
- cpn.SetDigits((char *)src_phone, strlen(src_phone));
- q931msg.SetIE(cpn);
- H225CSAliasAddress e164;
- LOG("Originator Phone number set in Setup message(%s)n",
- src_phone);
- e164.SetE164(src_phone,(unsigned short)strlen(src_phone));
- setup_uuie.AddSrcAddr(e164);
- }
- struct sockaddr_in dst_ip_addr;
- struct sockaddr_in src_ip_addr;
- // Warning! Unixware libnsl is buggy, the following call
- // can block indefinitely.
- ((H225CSProtocol *)this)->GetConnectionAddrs(
- (struct sockaddr*)&src_ip_addr,
- (struct sockaddr*)&dst_ip_addr);
- char *src_addr_str = inet_ntoa(src_ip_addr.sin_addr);
- LOG("source IP set in Setup mesg <%s>:<%u>n",
- src_addr_str, ntohs(src_ip_addr.sin_port));
- char *rem_addr_str = inet_ntoa(dst_ip_addr.sin_addr);
- LOG("dest IP set in Setup msg <%s>:<%u>n",
- rem_addr_str, ntohs(dst_ip_addr.sin_port));
- // d.sin_family = AF_INET;
- // d.sin_port = htons(1720);
- #if (!defined(BUGGY_NSL)) // returns 0 in remote address...
- setup_uuie.SetDstCallSig((sockaddr*)&dst_ip_addr);
- #endif
- setup_uuie.SetSrcCallSig((sockaddr*)&src_ip_addr);
- if (transfer_flag)
- {
- // Set the H4501 Supplimentary Services in setup_uuie
- H4501SuppService *pss;
- pss = ctSetupInvoke(transfer_invoke_id, &transfer_call_id[0]);
- //pss = ctSetupInvoke(transfer_invoke_id, &transfer_call_id[0]);
- ret = setup_uuie.AddH450SupplementaryService(*pss);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to set setup request ");
- LOG("AddH450SupplementaryService, error = 0x%xn", ret);
- }
- delete pss;
- }
- // Check if we are to attempt fast start. If so,
- // then create the list of OLCs and send it in
- // the setup message.
- if (do_faststart)
- {
- if (InitFastStartProposal(&setup_uuie) == 0)
- {
- faststart_state = FAST_START_STATE_PENDING;
- }
- }
- // Send the setup request..
- ret = InvokeCCPrim(CCP_SETUP_REQUEST, &q931msg,
- setup_uuie);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to send setup messagen");
- goto end_call;
- }
- }
- }
- else // it is not a H.225 TCP connection. It must be H.245 TCP connection
- {
- assert(info->conn->GetIdentifier() ==
- ((H245Protocol *)this)->GetIdentifier());
- // either something went wrong with the previous
- // outgoing H.245 LC0 connection
- if (PROT_IS_ERROR(info->status))
- {
- LOG("H245 Connect Failedn");
- if (((H225CSProtocol *)this)->IsConnectionReady())
- {
- DropQ931(RCR_UNDEFINED);
- goto end_call;
- }
- }
- else // or the connection succeeded.
- {
- LOG("H245 Connect succeeded (LC0 Connected)n");
- // TODO: FASTSTART FALLBACK....
- // pick interface ip address.
- sockaddr_in local_addr;
- #if (!defined(BUGGY_NSL)) // unixware nsl is buggy, alas! no multihomed hosts...
- if (PROT_IS_SUCCESS(
- ((H245Protocol *)this)->GetConnectionAddrs
- ((sockaddr*)&local_addr,NULL)))
- {
- if_ip_addr = local_addr.sin_addr.s_addr;
- LOG("Using i/f 0x%x for this calln", if_ip_addr);
- }
- #endif
- // Initiate capability exchange proceedures.
- H245SigH225Cap mc;
- H245SigCapTable ct;
- H245SigCapDescs cd;
- InitCapTable(ct);
- InitCapDescs(cd);
- InitMuxCap(mc);
- ret = SendTermCaps(&mc, &ct, &cd);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("SendTermCaps failed..n");
- LocalHangup();
- goto end_call;
- }
- }
- }
- }
- break;
- case CB_NEW_CONNECTION:
- {
- LOG("LC0_CONNECTEDn");
- XchgNewConnection *info = (XchgNewConnection *)data;
- // We will get only H.245 new connections here...
- remote_lc0_addr = info->new_addr;
- // First accept the connection from the remote end.
- ret = exchange->AcceptConnection(
- info->conn_ref,(H245Protocol *)this);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("H245 accept connection failed..n");
- LocalHangup();
- goto end_call;
- }
- // Initiate capability exchange proceedures.
- H245SigH225Cap mc;
- H245SigCapTable ct;
- H245SigCapDescs cd;
- InitCapTable(ct);
- InitCapDescs(cd);
- InitMuxCap(mc);
- ret = SendTermCaps(&mc, &ct, &cd);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("SendTermCaps failed.. after H245Accept connn");
- LocalHangup();
- goto end_call;
- }
- }
- break;
- case CB_REMOTE_TERM_CAPS:
- {
- LOG("CB_REMOTE_TERM_CAPSn");
- // Just acknowledge the remote terminals capabilities.
- // TODO: parse them and see if they are acceptable.
- RemoteTermCaps *info = (RemoteTermCaps *)data;
- PrintCaps(*info->cap_table);
- ret = AckTermCaps();
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to ack remote caps, error = 0x%xn",
- ret);
- LocalHangup();
- goto end_call;
- }
- // both ends have exchanged caps successfully.
- if (++cap_done == 2)
- {
- ret = DetermineMS();
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to ack remote caps,"
- " error = 0x%xn", ret);
- LocalHangup();
- goto end_call;
- }
- }
- }
- break;
- case CB_TERM_CAPS_ACK:
- {
- LOG("CB_TERM_CAPS_ACKn");
- // Remote end has accepted our terminal capabilities.
- // both ends have exchanged caps successfully.
- if (++cap_done == 2)
- {
- ret = DetermineMS();
- if (!PROT_IS_SUCCESS(ret) && !PROT_IS_PENDING(ret))
- {
- LOG("Failure in DetermineMS,"
- " error = 0x%xn", ret);
- LocalHangup();
- goto end_call;
- }
- }
- }
- break;
- case CB_TERM_CAPS_REJECT:
- {
- LOG("CB_TERM_CAPS_REJECTn");
- TermCapsReject *info = (TermCapsReject *)data;
- LOG("Remote end rejected our terminal capabilities"
- " cause = %d, direction = %dn", info->cause, info->direction);
- LocalHangup();
- goto end_call;
- }
- /*NOTREACHED*/
- break;
- case CB_OUT_LC_ERROR:
- {
- LOG("CB_OUT_LC_ERRORn");
- }
- break;
- case CB_MSD_ERROR:
- {
- LOG("CB_MSD_ERRORn");
- MSDError *info = (MSDError *)data;
- LOG("Master slave determination failed,"
- "error = 0x%lxn", info->error);
- LocalHangup();
- goto end_call;
- }
- /*NOTREACHED*/
- break;
- case CB_MSD_CONFIRM:
- {
- LOG("CB_MSD_CONFIRMn");
- MSDConfirm *info = (MSDConfirm *)data;
- if(msd_done)
- {
- break;
- }
- msd_done++;
- LOG("Master slave determine succeeded,"
- "decision = %sn",
- (info->decision == MSDRES_MASTER) ?
- "MASTER" : "SLAVE");
- // Open a logical channel with the remote end
- // do to G.723 audio.
- // First get the capability table entry corresponding
- // to G723.1 from the capability table.
- H245SigCapTable *ct= new H245SigCapTable;
- ret = GetCapTable(*ct);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Could not retrieve the cap table"
- ", error = 0x%lxn", ret);
- LocalHangup();
- goto end_call;
- }
- H245SigCap *c = NULL;
- H245SigCap::Factory(c,CAP_AUDIO,AUD_G7231);
- assert(c != NULL);
- ret = ct->GetCap(*c, G7231_INDEX);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Could not get G.723 audio capability"
- "from cap table, error = 0x%lxn", ret);
- delete c;
- LocalHangup();
- goto end_call;
- }
- // Prepare the Data type to use with the out_lc_num
- H245SigAudDataType *d = new H245SigAudDataType;
- ret = d->Set(*(H245SigAudCap *)c);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Could not set G.723 audio capability"
- "in audio data type, error = 0x%lxn", ret);
- delete c;
- LocalHangup();
- goto end_call;
- }
- delete c;
- delete ct;
- // Prepare the mux params to use with the out_lc_num.
- H245SigH225Params m;
- // Create an audio session if not already created
- // and generate the local ends RTP/RTCP addresses.
- if (!audio_session)
- {
- int status;
- audio_session = new H245RTPSession("RTP:ELEMEDIA",
- G7231_RTP_PAYLOAD_TYPE,G7231_AUDIO_SAMPLING_RATE,status);
- if (status)
- {
- LOG("new H245RTPSession failedd. status = 0x%xn",
- status);
- delete d;
- LocalHangup();
- goto end_call;
- }
- unsigned short rtp_port = 0, rtcp_port = 0;
- audio_session->SetLocalPorts(if_ip_addr,
- rtp_port, rtcp_port);
- rtcp_addr.sin_family = AF_INET;
- rtcp_addr.sin_addr.s_addr = if_ip_addr;
- rtcp_addr.sin_port = rtcp_port;
- rtp_addr.sin_family = AF_INET;
- rtp_addr.sin_addr.s_addr = if_ip_addr;
- rtp_addr.sin_port = rtp_port;
- audio_session->SetLocalPayloadType(
- G7231_RTP_PAYLOAD_TYPE);
- }
- m.SetSessionID(PRI_SSID_AUDIO);
- m.SetDynamicRTPPayloadType(G7231_RTP_PAYLOAD_TYPE);
- m.SetSilenceSupp(FALSE);
- m.SetMediaCtrlChan((struct sockaddr *)&rtcp_addr);
- out_lc_num = 1;
- ret = OpenLC(out_lc_num, 0, *d, m);
- if (!PROT_IS_PENDING(ret) && PROT_IS_ERROR(ret))
- {
- LOG("Open LC failed, lcnum = %d"
- " error = 0x%lxn", out_lc_num,ret);
- }
- delete d;
- }
- break;
- case CB_IN_LC_ERROR:
- {
- LOG("CB_IN_LC_ERRORn");
- LCError *info = (LCError *)data;
- LOG("Error in ILCSE signalling entity,"
- " lc = %d, error = %dn", info->lc_num, info->error);
- LocalHangup();
- goto end_call;
- }
- /*NOTREACHED*/
- break;
- case CB_OLC_REQUEST:
- {
- OLCReq *info = (OLCReq *)data;
- int dtype;
- int cap_type;
- int cap_sub_type;
- H245SigH225Params *mux;
- int dynamic_rtp_pt = 0;
- sockaddr_in remote_rtcp_addr;
- H245SigG7231Cap *g7231;
- H245SigCap *gen_cap;
- LOG("CB_OLC_REQUESTn");
- in_lc_num = info->lc_num;
- assert(info->mux_params);
- assert(info->data_type);
- info->data_type->GetType(dtype,cap_type,cap_sub_type);
- if ((dtype != DT_AUDIO) || (cap_type != CAP_AUDIO) ||
- cap_sub_type != AUD_G7231)
- {
- LOG("Remote end request data type that we don't supportn");
- // Send OLC reject here...
- RejectOpenLCReq(info->lc_num,
- OLCRR_DATATYPE_NOT_SUPPORTED);
- LocalHangup();
- goto end_call;
- }
- H245SigCap::Factory(gen_cap,cap_type, cap_sub_type);
- g7231 = (H245SigG7231Cap*)gen_cap;
- assert(g7231 != NULL);
- ((H245SigAudDataType *)info->data_type)->Get(*g7231);
- mux = (H245SigH225Params*)info->mux_params;
- ret = mux->GetDynamicRTPPayloadType(dynamic_rtp_pt);
- if (mux->GetMediaCtrlChan((sockaddr*)&remote_rtcp_addr) !=
- H245SIG_SUCCESS)
- {
- LOG("Remote has not supplied RTCP address");
- RejectOpenLCReq(info->lc_num,OLCRR_UNSPECIFIED);
- delete g7231;
- LocalHangup();
- goto end_call;
- }
- // Create an audio session if not already created
- // and generate the local ends RTP/RTCP addresses.
- if (!audio_session)
- {
- unsigned short rtp_port = 0, rtcp_port = 0;
- int status;
- audio_session = new H245RTPSession("RTP:ELEMEDIA",
- G7231_RTP_PAYLOAD_TYPE,G7231_AUDIO_SAMPLING_RATE,status);
- if (status)
- {
- LOG("new H245RTPSession failedd. status = 0x%xn",
- status);
- delete g7231;
- LocalHangup();
- goto end_call;
- }
- audio_session->SetLocalPorts(if_ip_addr,
- rtp_port, rtcp_port);
- rtcp_addr.sin_family = AF_INET;
- rtcp_addr.sin_addr.s_addr = if_ip_addr;
- rtcp_addr.sin_port = rtcp_port;
- rtp_addr.sin_family = AF_INET;
- rtp_addr.sin_addr.s_addr = if_ip_addr;
- rtp_addr.sin_port = rtp_port;
- }
- audio_session->SetRemotePayloadType(dynamic_rtp_pt);
- audio_session->SetRemotePorts(
- remote_rtcp_addr.sin_addr.s_addr,
- 0,remote_rtcp_addr.sin_port);
- H245SigH225AckParams ack;
- ack.SetSessionID(PRI_SSID_AUDIO);
- ack.SetMediaChan((sockaddr*)&rtp_addr);
- ack.SetMediaCtrlChan((sockaddr*)&rtcp_addr);
- LOG("calling AckOpenLCReqn");
- AckOpenLCReq(in_lc_num, &ack);
- if (++olc_done == 2)
- {
- audio_session_flag = 1;
- #if defined (ENABLE_BENCHMARKS)
- get_current_time(end_sec,end_msec);
- #endif
- StartAudio();
- }
- delete g7231;
- }
- break;
- case CB_OLC_REJECT:
- {
- LOG("CB_OLC_REJECTn");
- OLCReject *info = (OLCReject *)data;
- LOG("Remote end rejected our open channel request"
- " lc = %d, reason = %dn", info->lc_num, info->reason);
- LocalHangup();
- goto end_call;
- }
- /*NOTREACHED*/
- break;
- case CB_OLC_ACK:
- {
- LOG("CB_OLC_ACKn");
- OLCAck *info = (OLCAck *)data;
- LOG("Open logical channel ack, lc = %dn",
- info->lc_num);
- H245SigH225AckParams *ap = info->ack_params;
- struct sockaddr_in rrtp_addr;
- struct sockaddr_in rrtcp_addr;
- ret = ap->GetMediaChan((sockaddr*)&rrtp_addr);
- ret = ap->GetMediaCtrlChan((sockaddr*)&rrtcp_addr);
- assert(audio_session != NULL);
- audio_session->SetRemotePorts(rrtp_addr.sin_addr.s_addr,
- rrtp_addr.sin_port,rrtcp_addr.sin_port);
- if (++olc_done == 2)
- {
- audio_session_flag = 1;
- #if defined (ENABLE_BENCHMARKS)
- get_current_time(end_sec,end_msec);
- #endif
- StartAudio();
- }
- }
- break;
- case CB_CLOSE_OUT_LC_REQUEST:
- {
- LOG("CB_CLOSE_OUT_LC_REQUESTn");
- }
- break;
- case CB_CLOSE_OUT_LC_ACK:
- {
- LOG("CB_CLOSE_OUT_LC_ACKn");
- CloseXXX *info = (CloseXXX *)data;
- LOG("Remote end acked close lc, lc = %dn",
- info->lc_num);
- }
- break;
- case CB_CLOSE_IN_LC:
- {
- LOG("CB_CLOSE_IN_LCn");
- // remote end decided to close its lc,
- // we will close ours too...
- CloseOutLC(out_lc_num);
- }
- break;
- case CB_CLOSE_IN_LC_ACK:
- {
- LOG("CB_CLOSE_IN_LC_ACKn");
- }
- break;
- case CB_CLOSE_IN_LC_REJECT:
- {
- LOG("CB_CLOSE_IN_LC_REJECTn");
- }
- break;
- case CB_NOTIFY_CMD:
- {
- LOG("CB_NOTIFY_CMDn");
- // check if an end session was generated from the remote end.
- H245CMD *info = (H245CMD *)data;
- int type = 0;
- info->cmd->GetCommandType(type);
- LOG("command type = %dn", type);
- if (type == CMDT_END_SESSION)
- {
- LOG("CMDT_END_SESSIONn");
- // send an end session.
- H245SigCommand *cmd ;
- H245SigCommand::Factory(cmd, CMDT_END_SESSION);
- ((H245SigEndSessionCommand *)cmd)->SetType(
- ESTY_DISCONNECT);
- SendCommand(*cmd);
- delete cmd;
- endsession_sent = 1;
- }
- }
- break;
- case CB_NOTIFY_IND:
- {
- LOG("CB_NOTIFY_INDn");
- }
- break;
- }
- }
- else if (msg.message == PROT_UI_MSG)
- {
- if ((msg.wParam == UI_CMD_EXIT) ||
- (msg.wParam == UI_CMD_HANGUP))
- {
- if (msg.wParam == UI_CMD_HANGUP)
- {
- LocalHangup();
- }
- goto end_call;
- } else if (msg.wParam == UI_CMD_FACILITY) {
- UICmdFacility *info = (UICmdFacility *)data;
- SendFacility(info->suppsvcs);
- }
- else if (msg.wParam == UI_CMD_CTRL)
- {
- }
- }
- if (data)
- {
- delete (CBData*)data;
- }
- return;
- end_call:
- call_dropped = 1;
- exchange->SendToExchange(PROT_EXCH_MSG, XC_CALL_DROPPED,
- (unsigned long)this);
- if (data)
- {
- delete (CBData*)data;
- }
- return;
- }
- int
- H323Call::LocalHangup()
- {
- // Request from the user to drop the call.
- if (((H245Protocol *)this)->IsConnectionReady())
- {
- H245SigCommand *cmd ;
- H245SigCommand::Factory(cmd, CMDT_END_SESSION);
- ((H245SigEndSessionCommand *)cmd)->SetType(ESTY_DISCONNECT);
- LOG("Sending END_SESSIONn");
- SendCommand(*cmd);
- delete cmd;
- endsession_sent = 1;
- }
- else
- {
- if(GetCallDirection() == DIR_INCOMING)
- {
- exchange->StopListening(
- ((H245Protocol *)this)->GetIdentifier());
- }
- }
- if(((H225CSProtocol *)this)->IsConnectionReady())
- {
- LOG("Sending Release completen");
- DropQ931(RCR_UNDEFINED);
- return(-1);
- }
- return -1;
- }
- void
- H323Call::DropQ931(int rc_reason)
- {
- LOG("H323Call::DropQ931n");
- LOG("rc_reason = %dn", rc_reason);
- ProtReturnCode ret;
- H225CSReleaseCompleteUUIE ie(*this);
- ret = ie.SetReason(rc_reason);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to set release complete reason, error = 0x%xn",
- ret);
- }
- if (transfer_flag)
- {
- // Set the H4501 Supplimentary Services in setup_uuie
- H4501SuppService *pss;
- // invokeID is 0 for now until OSS fixes the bug
- pss = ctInitiateReturnResult(transfer_invoke_id);
- ret = ie.AddH450SupplementaryService(*pss);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to set setup request ");
- LOG("AddH450SupplementaryService, error = 0x%xn", ret);
- }
- delete pss;
- }
- ret = InvokeCCPrim(CCP_RELEASE_REQUEST, NULL, ie);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to send release complete, error = 0x%xn", ret);
- }
- }
- int
- H323Call::Q931SendAlerting()
- {
- ProtReturnCode ret;
- // send connect
- assert(GetCallDirection() == DIR_INCOMING);
- LOG("DIR_INCOMING, sending alertingn");
- // Send the alerting message.
- H225CSAlertingUUIE ie(*this);
- if (do_faststart && faststart_state == FAST_START_STATE_PENDING)
- {
- if ((ie.AddOLC(fs_channels[FS_CHANNEL_OUTGOING]) != H245SIG_SUCCESS) ||
- (ie.AddOLC(fs_channels[FS_CHANNEL_INCOMING]) != H245SIG_SUCCESS))
- {
- LOG("ERROR: Failed to add the fast start OLCs.n");
- faststart_state = FAST_START_STATE_DISABLED;
- return LocalHangup();
- }
- faststart_state = FAST_START_STATE_ENABLED;
- }
- ret = InvokeCCPrim(CCP_ALERTING_REQUEST, NULL, ie);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to send alerting, error = 0x%xn", ret);
- return LocalHangup();
- }
- else
- {
- if (do_faststart && audio_session_flag == 0 &&
- faststart_state == FAST_START_STATE_ENABLED)
- {
- audio_session_flag = 1;
- #if defined (ENABLE_BENCHMARKS)
- get_current_time(end_sec,end_msec);
- #endif
- StartAudio();
- }
- }
- return 1;
- }
- int
- H323Call::Q931SendSetupAck()
- {
- ProtReturnCode ret;
- assert(GetCallDirection() == DIR_INCOMING);
- LOG("DIR_INCOMING, sending setup_ackn");
- ret = InvokeCCPrim(CCP_MORE_INFO_REQUEST, NULL);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to send setup_ack, error = 0x%xn", ret);
- return LocalHangup();
- }
- return 1;
- }
- int
- H323Call::Q931SendInformation(char *info)
- {
- ProtReturnCode ret;
- Q931Message q931msg(MESSAGE_INFORMATION);
- Q931KeypadFacilityIE ie_kp;
- Q931IE snd_comp;
- H225CSInformationUUIE info_uuie(*(H225CSProtocol *)this);
- ie_kp.SetKeypadInfo(info,strlen(info));
- // Sending Complete is a fixed length ie.
- snd_comp.SetContent(IE_SENDING_COMPLETE,NULL,0);
- if (!PROT_IS_SUCCESS(q931msg.SetIE(ie_kp)))
- {
- LOG("Error inserting keypad facility ie!n");
- }
- if (!PROT_IS_SUCCESS(q931msg.SetIE(snd_comp)))
- {
- LOG("Error inserting sending complete ie!n");
- }
- ret = InvokeCCPrim(CCP_INFO_REQUEST, &q931msg,info_uuie);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to send information, error = 0x%xn", ret);
- return LocalHangup();
- }
- return 1;
- }
- int
- H323Call::Q931SendProceeding()
- {
- ProtReturnCode ret;
- // send proceeding
- assert(GetCallDirection() == DIR_INCOMING);
- LOG("DIR_INCOMING, sending proceedingn");
- // Send the proceeding message.
- H225CSCallProceedingUUIE ie(*this);
- if (do_faststart && faststart_state == FAST_START_STATE_PENDING)
- {
- if ((ie.AddOLC(fs_channels[FS_CHANNEL_OUTGOING]) != H245SIG_SUCCESS) ||
- (ie.AddOLC(fs_channels[FS_CHANNEL_INCOMING]) != H245SIG_SUCCESS))
- {
- LOG("ERROR: Failed to add the fast start OLCs.n");
- faststart_state = FAST_START_STATE_DISABLED;
- return LocalHangup();
- }
- faststart_state = FAST_START_STATE_ENABLED;
- }
- ret = InvokeCCPrim(CCP_PROCEEDING_REQUEST, NULL, ie);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to send proceeding,"
- " error = 0x%xn", ret);
- return LocalHangup();
- }
- else
- {
- if (do_faststart && audio_session_flag == 0 &&
- faststart_state == FAST_START_STATE_ENABLED)
- {
- audio_session_flag = 1;
- #if defined (ENABLE_BENCHMARKS)
- get_current_time(end_sec,end_msec);
- #endif
- StartAudio();
- }
- }
- return 1;
- }
- int
- H323Call::Q931SendConnect()
- {
- ProtReturnCode ret;
- assert(GetCallDirection() == DIR_INCOMING);
- LOG("DIR_INCOMING, sending connectn");
- // Send the connect message.
- H225CSConnectUUIE ie(*this);
- if (do_faststart && faststart_state == FAST_START_STATE_PENDING)
- {
- if ((ie.AddOLC(fs_channels[FS_CHANNEL_OUTGOING]) != H245SIG_SUCCESS) ||
- (ie.AddOLC(fs_channels[FS_CHANNEL_INCOMING]) != H245SIG_SUCCESS))
- {
- LOG("ERROR: Failed to add the fast start OLCs.n");
- faststart_state = FAST_START_STATE_DISABLED;
- return LocalHangup();
- }
- faststart_state = FAST_START_STATE_ENABLED;
- }
- //send the H.245 address if either, faststart is disabled, or
- //if we refused the faststart the remote side sent us.
- if (!do_faststart ||
- do_faststart && faststart_state == FAST_START_STATE_DISABLED)
- {
- // First insert the H245address into the connect
- // user to user information element.
- memset(&local_lc0_addr, 0, sizeof(local_lc0_addr));
- local_lc0_addr.sin_family = AF_INET;
- // 07/01/97 Added support for multi-homed hosts..
- #if (defined(BUGGY_NSL)) // Needed for unixware, alas! no multihomed hosts...
- local_lc0_addr.sin_addr.s_addr = if_ip_addr;
- #else
- if (!PROT_IS_SUCCESS(
- ((H225CSProtocol *)this)->GetConnectionAddrs(
- (struct sockaddr*)&local_lc0_addr,
- NULL)))
- {
- LOG("Can't get i/f ip addressn");
- local_lc0_addr.sin_addr.s_addr = if_ip_addr;
- }
- else
- {
- LOG("Got i/f ip address, 0x%xn",
- local_lc0_addr.sin_addr.s_addr);
- if_ip_addr = local_lc0_addr.sin_addr.s_addr;
- }
- #endif
- // Make the connection manager pick a port for
- // us.
- local_lc0_addr.sin_port = 0;
- ret = exchange->Listen(
- ((H245Protocol *)this)->GetIdentifier(),
- (struct sockaddr *)&local_lc0_addr,
- LT_ONCE);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to create H.245 address error = 0x%xn",ret);
- return LocalHangup();
- }
- ret = ie.SetH245Transport(
- (struct sockaddr *)&local_lc0_addr);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to set H.245 address"
- " in connectUUIE error = 0x%xn",ret);
- return LocalHangup();
- }
- }
- if (transfer_flag)
- {
- // Set the H4501 Supplimentary Services in setup_uuie
- H4501SuppService *pss;
- // invokeID is 0 for now until OSS fixes the bug
- pss = ctSetupReturnResult(transfer_invoke_id);
- ret = ie.AddH450SupplementaryService(*pss);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to set setup response ");
- LOG("AddH450SupplementaryService, error = 0x%xn", ret);
- }
- delete pss;
- }
- ret = InvokeCCPrim(CCP_SETUP_RESPONSE, NULL, ie);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to send connect, error = 0x%xn", ret);
- return LocalHangup();
- }
- else
- {
- if (do_faststart && audio_session_flag == 0 &&
- faststart_state == FAST_START_STATE_ENABLED)
- {
- audio_session_flag = 1;
- #if defined (ENABLE_BENCHMARKS)
- get_current_time(end_sec,end_msec);
- #endif
- StartAudio();
- }
- }
- return 1;
- }
- int
- H323Call::SendFacility(H450SSseq *ssSeq)
- {
- // Request from the user to send Facility message.
- if(((H225CSProtocol *)this)->IsConnectionReady())
- {
- LOG("H323Call::SendFacility() sending (ssSeq=0x%x)t",ssSeq);
- SendQ932Facility(FYR_UNDEFINED, ssSeq);
- return(-1);
- }
- return -1;
- }
- void
- H323Call::SendQ932Facility(int reason, H450SSseq *ssSeq)
- {
- LOG("H323Call::SendQ932Facilityn");
- LOG("Facility reason = %dn", reason);
- ProtReturnCode ret;
- H225CSFacilityUUIE ie(*this);
- Q931Message fmsg(MESSAGE_Q932_FACILITY);
- // Set Reason in H225CSFacilityUUIE
- ret = ie.SetReason(reason);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to set facility reason, error = 0x%xn", ret);
- }
- #ifdef NOTNEEDED
- // {
- // Set AlternativeAliasAddress in H225CSFacilityUUIE
- H225CSAliasAddress e164;
- char dummy[15];
- strcpy(dummy,"12345678901");
- e164.SetE164(dummy,(unsigned short)strlen(dummy));
- ret = ie.AddAlternativeAliasAddr(e164);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to set facility AddAlternativeAliasAddr, error = 0x%xn", ret);
- }
- // Set AlternativeAddress in H225CSFacilityUUIE
- struct sockaddr_in addr;
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = inet_addr("123.45.67.89");
- addr.sin_port = htons(1122);
- ret = ie.SetAlternativeAddr((sockaddr *)&addr);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to set facility SetAlternativeAddr, error = 0x%xn", ret);
- }
- // }
- #endif
- // Set the H4501 Supplimentary Services
- H4501SuppService *pss;
- H450SSseq *p;
- int i = 0;
- p = ssSeq;
- while(p != NULL)
- {
- pss = p->value;
- if(pss != NULL) {
- ret = ie.AddH450SupplementaryService(*pss);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to set facility AddH450SupplementaryService, error = 0x%xn", ret);
- }
- }
- p = p->next;
- i++;
- }
- LOG("Added %d SuppServices to FACILITY_REQUESTn",i);
- ret = InvokeCCPrim(CCP_FACILITY_REQUEST, &fmsg, ie);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to send facility, error = 0x%xn", ret);
- }
- // deleteSSlist(ssSeq);
- }
- // return 0 on success
- int
- H323Call::CreateRtpSession()
- {
- unsigned short rtp_port = 0, rtcp_port = 0;
- int status;
- audio_session =
- new H245RTPSession("RTP:ELEMEDIA",
- G7231_RTP_PAYLOAD_TYPE,
- G7231_AUDIO_SAMPLING_RATE,status);
- if (status)
- {
- LOG("new H245RTPSession failed. "
- "status = 0x%xn", status);
- return status;
- }
- audio_session->SetLocalPorts(if_ip_addr,
- rtp_port, rtcp_port);
- rtcp_addr.sin_family = AF_INET;
- rtcp_addr.sin_addr.s_addr = if_ip_addr;
- rtcp_addr.sin_port = rtcp_port;
- rtp_addr.sin_family = AF_INET;
- rtp_addr.sin_addr.s_addr = if_ip_addr;
- rtp_addr.sin_port = rtp_port;
- return 0;
- }
- // return 0 on success
- int
- H323Call::SwitchToRegularH245()
- {
- // Switch to Regular H.245 proceedures.
- ProtReturnCode ret;
- assert(do_faststart == 1);
- // Check if we already have the remote endpoints H.245 address.
- // If not obtain it by sending out a facility message.
- if (remote_lc0_addr.sin_addr.s_addr != 0)
- {
- // we already have the remote ends H.245 address. Just connect to it.
- ret = exchange->Connect( (sockaddr *)&remote_lc0_addr,
- (H245Protocol *)this);
- faststart_state = H245_FAST_START_STATE_SWITCH_OUT_BEGIN;
- if (!PROT_IS_PENDING(ret))
- {
- exchange->NotifyConnectionStatus(
- (H245Protocol*)this,ret);
- faststart_state = H245_FAST_START_STATE_SWITCHED_OUT;
- }
- }
- else
- {
- // Try to get the remote end to switch to regular H.245
- // procedure by providing our lc0 address.
- H225CSFacilityUUIE ie(*this);
- // Insert our H245address
- local_lc0_addr.sin_family = AF_INET;
- #if (defined(BUGGY_NSL)) // Needed for unixware, alas! no multihomed hosts...
- local_lc0_addr.sin_addr.s_addr = if_ip_addr;
- #else
- if (!PROT_IS_SUCCESS(
- ((H225CSProtocol *)this)->GetConnectionAddrs(
- (struct sockaddr*)&local_lc0_addr,
- NULL)))
- {
- LOG("Can't get i/f ip addressn");
- local_lc0_addr.sin_addr.s_addr = if_ip_addr;
- }
- else
- {
- LOG("Got i/f ip address, 0x%xn",
- local_lc0_addr.sin_addr.s_addr);
- if_ip_addr = local_lc0_addr.sin_addr.s_addr;
- }
- #endif
- // Make the connection manager pick the port.
- local_lc0_addr.sin_port = 0;
- ret = exchange->Listen(
- ((H245Protocol *)this)->GetIdentifier(),
- (struct sockaddr *)&local_lc0_addr,
- LT_ONCE);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to create H.245 address" " error = 0x%xn",ret);
- return -1;
- }
- ret = ie.SetH245Transport((struct sockaddr *)&local_lc0_addr);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to set H.245 address in facilityUUIE error = 0x%xn",
- ret);
- return -1;
- }
- ret = InvokeCCPrim(CCP_FACILITY_REQUEST, NULL, ie);
- if (!PROT_IS_SUCCESS(ret))
- {
- LOG("Failed to send facility, error = 0x%xn", ret);
- return -1;
- }
- faststart_state = H245_FAST_START_STATE_SWITCH_OUT_BEGIN;
- }
- return 0;
- }