📄 ast_h323.cxx
字号:
cd->transfer_capability = ((unsigned int)capability & 0x1f) | (codingStandard << 5); else cd->transfer_capability = 0x00; /* ITU coding of Speech */ /* Don't show local username as called party name */ SetDisplayName(cd->call_dest_e164); } /* Convert complex strings */ // FIXME: deal more than one source alias sourceAliases = setupPDU.GetSourceAliases(); s1 = strdup((const char *)sourceAliases); if ((s = strchr(s1, ' ')) != NULL) *s = '\0'; if ((s = strchr(s1, '\t')) != NULL) *s = '\0'; cd->call_source_aliases = s1; destAliases = setupPDU.GetDestinationAlias(); s1 = strdup((const char *)destAliases); if ((s = strchr(s1, ' ')) != NULL) *s = '\0'; if ((s = strchr(s1, '\t')) != NULL) *s = '\0'; cd->call_dest_alias = s1;}#ifdef TUNNELLINGstatic BOOL FetchInformationElements(Q931 &q931, const PBYTEArray &data){ PINDEX offset = 0; while (offset < data.GetSize()) { // Get field discriminator int discriminator = data[offset++];#if 0 /* Do not overwrite existing IEs */ if (q931.HasIE((Q931::InformationElementCodes)discriminator)) { if ((discriminatir & 0x80) == 0) offset += data[offset++]; if (offset > data.GetSize()) return FALSE; continue; }#endif PBYTEArray * item = new PBYTEArray; // For discriminator with high bit set there is no data if ((discriminator & 0x80) == 0) { int len = data[offset++];#if 0 // That is not H.225 but regular Q.931 (ISDN) IEs if (discriminator == UserUserIE) { // Special case of User-user field. See 7.2.2.31/H.225.0v4. len <<= 8; len |= data[offset++]; // we also have a protocol discriminator, which we ignore offset++; // before decrementing the length, make sure it is not zero if (len == 0) return FALSE; // adjust for protocol discriminator len--; }#endif if (offset + len > data.GetSize()) { delete item; return FALSE; } memcpy(item->GetPointer(len), (const BYTE *)data+offset, len); offset += len; } q931.SetIE((Q931::InformationElementCodes)discriminator, *item); delete item; } return TRUE;}static BOOL FetchCiscoTunneledInfo(Q931 &q931, const H323SignalPDU &pdu){ BOOL res = FALSE; const H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu; if(uuPDU.HasOptionalField(H225_H323_UU_PDU::e_nonStandardControl)) { for(int i = 0; i < uuPDU.m_nonStandardControl.GetSize(); ++i) { const H225_NonStandardParameter &np = uuPDU.m_nonStandardControl[i]; const H225_NonStandardIdentifier &id = np.m_nonStandardIdentifier; if (id.GetTag() == H225_NonStandardIdentifier::e_h221NonStandard) { const H225_H221NonStandard &ni = id; /* Check for Cisco */ if ((ni.m_t35CountryCode == 181) && (ni.m_t35Extension == 0) && (ni.m_manufacturerCode == 18)) { const PBYTEArray &data = np.m_data; if (h323debug) cout << setprecision(0) << "Received non-standard Cisco extension data " << np.m_data << endl; CISCO_H225_H323_UU_NonStdInfo c; PPER_Stream strm(data); if (c.Decode(strm)) { BOOL haveIEs = FALSE; if (h323debug) cout << setprecision(0) << "H323_UU_NonStdInfo = " << c << endl; if (c.HasOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_protoParam)) { FetchInformationElements(q931, c.m_protoParam.m_qsigNonStdInfo.m_rawMesg); haveIEs = TRUE; } if (c.HasOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_commonParam)) { FetchInformationElements(q931, c.m_commonParam.m_redirectIEinfo.m_redirectIE); haveIEs = TRUE; } if (haveIEs && h323debug) cout << setprecision(0) << "Information elements collected:" << q931 << endl; res = TRUE; } else { cout << "ERROR while decoding non-standard Cisco extension" << endl; return FALSE; } } } } } return res;}static BOOL EmbedCiscoTunneledInfo(H323SignalPDU &pdu){ const static struct { Q931::InformationElementCodes ie; BOOL dontDelete; } codes[] = { { Q931::RedirectingNumberIE, }, { Q931::FacilityIE, },// { Q931::CallingPartyNumberIE, TRUE }, }; BOOL res = FALSE; BOOL notRedirOnly = FALSE; Q931 tmpQ931; Q931 &q931 = pdu.GetQ931(); for(unsigned i = 0; i < ARRAY_LEN(codes); ++i) { if (q931.HasIE(codes[i].ie)) { tmpQ931.SetIE(codes[i].ie, q931.GetIE(codes[i].ie)); if (!codes[i].dontDelete) q931.RemoveIE(codes[i].ie); if (codes[i].ie != Q931::RedirectingNumberIE) notRedirOnly = TRUE; res = TRUE; } } /* Have something to embed */ if (res) { PBYTEArray msg; if (!tmpQ931.Encode(msg)) return FALSE; PBYTEArray ies(msg.GetPointer() + 5, msg.GetSize() - 5); H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu; if(!uuPDU.HasOptionalField(H225_H323_UU_PDU::e_nonStandardControl)) { uuPDU.IncludeOptionalField(H225_H323_UU_PDU::e_nonStandardControl); uuPDU.m_nonStandardControl.SetSize(0); } H225_NonStandardParameter *np = new H225_NonStandardParameter; uuPDU.m_nonStandardControl.Append(np); H225_NonStandardIdentifier &nsi = (*np).m_nonStandardIdentifier; nsi.SetTag(H225_NonStandardIdentifier::e_h221NonStandard); H225_H221NonStandard &ns = nsi; ns.m_t35CountryCode = 181; ns.m_t35Extension = 0; ns.m_manufacturerCode = 18; CISCO_H225_H323_UU_NonStdInfo c; c.IncludeOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_version); c.m_version = 0; if (notRedirOnly) { c.IncludeOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_protoParam); CISCO_H225_QsigNonStdInfo &qsigInfo = c.m_protoParam.m_qsigNonStdInfo; qsigInfo.m_iei = ies[0]; qsigInfo.m_rawMesg = ies; } else { c.IncludeOptionalField(CISCO_H225_H323_UU_NonStdInfo::e_commonParam); c.m_commonParam.m_redirectIEinfo.m_redirectIE = ies; } PPER_Stream stream; c.Encode(stream); stream.CompleteEncoding(); (*np).m_data = stream; } return res;}static const char OID_QSIG[] = "1.3.12.9";static BOOL FetchQSIGTunneledInfo(Q931 &q931, const H323SignalPDU &pdu){ BOOL res = FALSE; const H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu; if (uuPDU.HasOptionalField(H225_H323_UU_PDU::e_tunnelledSignallingMessage)) { const H225_H323_UU_PDU_tunnelledSignallingMessage &sig = uuPDU.m_tunnelledSignallingMessage; const H225_TunnelledProtocol_id &proto = sig.m_tunnelledProtocolID.m_id; if ((proto.GetTag() == H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) && (((const PASN_ObjectId &)proto).AsString() == OID_QSIG)) { const H225_ArrayOf_PASN_OctetString &sigs = sig.m_messageContent; for(int i = 0; i < sigs.GetSize(); ++i) { const PASN_OctetString &msg = sigs[i]; if (h323debug) cout << setprecision(0) << "Q.931 message data is " << msg << endl; if(!q931.Decode((const PBYTEArray &)msg)) { cout << "Error while decoding Q.931 message" << endl; return FALSE; } res = TRUE; if (h323debug) cout << setprecision(0) << "Received QSIG message " << q931 << endl; } } } return res;}static H225_EndpointType *GetEndpointType(H323SignalPDU &pdu){ if (!pdu.GetQ931().HasIE(Q931::UserUserIE)) return NULL; H225_H323_UU_PDU_h323_message_body &body = pdu.m_h323_uu_pdu.m_h323_message_body; switch (body.GetTag()) { case H225_H323_UU_PDU_h323_message_body::e_setup: return &((H225_Setup_UUIE &)body).m_sourceInfo; case H225_H323_UU_PDU_h323_message_body::e_callProceeding: return &((H225_CallProceeding_UUIE &)body).m_destinationInfo; case H225_H323_UU_PDU_h323_message_body::e_connect: return &((H225_Connect_UUIE &)body).m_destinationInfo; case H225_H323_UU_PDU_h323_message_body::e_alerting: return &((H225_Alerting_UUIE &)body).m_destinationInfo; case H225_H323_UU_PDU_h323_message_body::e_facility: return &((H225_Facility_UUIE &)body).m_destinationInfo; case H225_H323_UU_PDU_h323_message_body::e_progress: return &((H225_Progress_UUIE &)body).m_destinationInfo; } return NULL;}static BOOL QSIGTunnelRequested(H323SignalPDU &pdu){ H225_EndpointType *epType = GetEndpointType(pdu); if (epType) { if (!(*epType).HasOptionalField(H225_EndpointType::e_supportedTunnelledProtocols)) { return FALSE; } H225_ArrayOf_TunnelledProtocol &protos = (*epType).m_supportedTunnelledProtocols; for (int i = 0; i < protos.GetSize(); ++i) { if ((protos[i].GetTag() == H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) && (((const PASN_ObjectId &)protos[i]).AsString() == OID_QSIG)) { return TRUE; } } } return FALSE;}static BOOL EmbedQSIGTunneledInfo(H323SignalPDU &pdu){ const static Q931::InformationElementCodes codes[] = { Q931::RedirectingNumberIE, Q931::FacilityIE }; Q931 &q931 = pdu.GetQ931(); PBYTEArray message; q931.Encode(message); /* Remove non-standard IEs */ for(unsigned i = 0; i < ARRAY_LEN(codes); ++i) { if (q931.HasIE(codes[i])) { q931.RemoveIE(codes[i]); } } H225_H323_UU_PDU &uuPDU = pdu.m_h323_uu_pdu; H225_EndpointType *epType = GetEndpointType(pdu); if (epType) { if (!(*epType).HasOptionalField(H225_EndpointType::e_supportedTunnelledProtocols)) { (*epType).IncludeOptionalField(H225_EndpointType::e_supportedTunnelledProtocols); (*epType).m_supportedTunnelledProtocols.SetSize(0); } H225_ArrayOf_TunnelledProtocol &protos = (*epType).m_supportedTunnelledProtocols; BOOL addQSIG = TRUE; for (int i = 0; i < protos.GetSize(); ++i) { if ((protos[i].GetTag() == H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) && (((PASN_ObjectId &)protos[i]).AsString() == OID_QSIG)) { addQSIG = FALSE; break; } } if (addQSIG) { H225_TunnelledProtocol *proto = new H225_TunnelledProtocol; (*proto).m_id.SetTag(H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID); (PASN_ObjectId &)(proto->m_id) = OID_QSIG; protos.Append(proto); } } if (!uuPDU.HasOptionalField(H225_H323_UU_PDU::e_tunnelledSignallingMessage)) uuPDU.IncludeOptionalField(H225_H323_UU_PDU::e_tunnelledSignallingMessage); H225_H323_UU_PDU_tunnelledSignallingMessage &sig = uuPDU.m_tunnelledSignallingMessage; H225_TunnelledProtocol_id &proto = sig.m_tunnelledProtocolID.m_id; if ((proto.GetTag() != H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID) || (((const PASN_ObjectId &)proto).AsString() != OID_QSIG)) { proto.SetTag(H225_TunnelledProtocol_id::e_tunnelledProtocolObjectID); (PASN_ObjectId &)proto = OID_QSIG; sig.m_messageContent.SetSize(0); } PASN_OctetString *msg = new PASN_OctetString; sig.m_messageContent.Append(msg); *msg = message; return TRUE;}BOOL MyH323Connection::EmbedTunneledInfo(H323SignalPDU &pdu){ if ((tunnelOptions & H323_TUNNEL_QSIG) || (remoteTunnelOptions & H323_TUNNEL_QSIG)) EmbedQSIGTunneledInfo(pdu); if ((tunnelOptions & H323_TUNNEL_CISCO) || (remoteTunnelOptions & H323_TUNNEL_CISCO)) EmbedCiscoTunneledInfo(pdu); return TRUE;}/* Handle tunneled messages */BOOL MyH323Connection::HandleSignalPDU(H323SignalPDU &pdu){ if (pdu.GetQ931().HasIE(Q931::UserUserIE)) { Q931 tunneledInfo; const Q931 *q931Info; q931Info = NULL; if (FetchCiscoTunneledInfo(tunneledInfo, pdu)) { q931Info = &tunneledInfo; remoteTunnelOptions |= H323_TUNNEL_CISCO; } if (FetchQSIGTunneledInfo(tunneledInfo, pdu)) { q931Info = &tunneledInfo; remoteTunnelOptions |= H323_TUNNEL_QSIG; } if (!(remoteTunnelOptions & H323_TUNNEL_QSIG) && QSIGTunnelRequested(pdu)) { remoteTunnelOptions |= H323_TUNNEL_QSIG; } if (q931Info) { if (q931Info->HasIE(Q931::RedirectingNumberIE)) { pdu.GetQ931().SetIE(Q931::RedirectingNumberIE, q931Info->GetIE(Q931::RedirectingNumberIE)); if (h323debug) { PString number; unsigned reason; if(q931Info->GetRedirectingNumber(number, NULL, NULL, NULL, NULL, &reason, 0, 0, 0)) cout << "Got redirection from " << number << ", reason " << reason << endl; } } } } return H323Connection::HandleSignalPDU(pdu);}#endifBOOL MyH323Connection::OnReceivedSignalSetup(const H323SignalPDU & setupPDU){ call_details_t cd; if (h323debug) { cout << "\t--Received SETUP message" << endl; } if (connectionState == ShuttingDownConnection) return FALSE; SetCallDetails(&cd, setupPDU, TRUE); /* Notify Asterisk of the request */ call_options_t *res = on_incoming_call(&cd); if (!res) { if (h323debug) { cout << "\t-- Call Failed" << endl; } return FALSE; } SetCallOptions(res, TRUE); /* Disable fastStart if requested by remote side */ if (h245Tunneling && !setupPDU.m_h323_uu_pdu.m_h245Tunneling) { masterSlaveDeterminationProcedure->Stop(); capabilityExchangeProcedure->Stop(); PTRACE(3, "H225\tFast Start DISABLED!"); h245Tunneling = FALSE; } return H323Connection::OnReceivedSignalSetup(setupPDU);}BOOL MyH323Connection::OnSendSignalSetup(H323SignalPDU & setupPDU){ call_details_t cd; if (h323debug) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -