ast_h323.cxx
来自「asterisk 是一个很有知名度开源软件」· CXX 代码 · 共 2,064 行 · 第 1/5 页
CXX
2,064 行
}void MyH323Connection::OnUserInputString(const PString &value){ if (h323debug) { cout << "\t-- Received user input string (" << value << ") from remote." << endl; } on_receive_digit(GetCallReference(), value[0], (const char *)GetCallToken(), 0);}void MyH323Connection::OnSendCapabilitySet(H245_TerminalCapabilitySet & pdu){ PINDEX i; H323Connection::OnSendCapabilitySet(pdu); H245_ArrayOf_CapabilityTableEntry & tables = pdu.m_capabilityTable; for(i = 0; i < tables.GetSize(); i++) { H245_CapabilityTableEntry & entry = tables[i]; if (entry.HasOptionalField(H245_CapabilityTableEntry::e_capability)) { H245_Capability & cap = entry.m_capability; if (cap.GetTag() == H245_Capability::e_receiveRTPAudioTelephonyEventCapability) { H245_AudioTelephonyEventCapability & atec = cap; atec.m_dynamicRTPPayloadType = dtmfCodec[0];// on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)dtmfCodec[0]);#ifdef PTRACING if (h323debug) { cout << "\t-- Receiving RFC2833 on payload " << atec.m_dynamicRTPPayloadType << endl; }#endif } } }}void MyH323Connection::OnSetLocalCapabilities(){ if (on_setcapabilities) on_setcapabilities(GetCallReference(), (const char *)callToken);}BOOL MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remoteCaps, const H245_MultiplexCapability * muxCap, H245_TerminalCapabilitySetReject & reject){ struct __codec__ { unsigned int asterisk_codec; unsigned int h245_cap; const char *oid; const char *formatName; }; static const struct __codec__ codecs[] = { { AST_FORMAT_G723_1, H245_AudioCapability::e_g7231 }, { AST_FORMAT_GSM, H245_AudioCapability::e_gsmFullRate }, { AST_FORMAT_ULAW, H245_AudioCapability::e_g711Ulaw64k }, { AST_FORMAT_ALAW, H245_AudioCapability::e_g711Alaw64k }, { AST_FORMAT_G729A, H245_AudioCapability::e_g729AnnexA }, { AST_FORMAT_G729A, H245_AudioCapability::e_g729 }, { AST_FORMAT_G726_AAL2, H245_AudioCapability::e_nonStandard, NULL, CISCO_G726r32 },#ifdef AST_FORMAT_MODEM { AST_FORMAT_MODEM, H245_DataApplicationCapability_application::e_t38fax },#endif { 0 } };#if 0 static const struct __codec__ vcodecs[] = {#ifdef HAVE_H261 { AST_FORMAT_H261, H245_VideoCapability::e_h261VideoCapability },#endif#ifdef HAVE_H263 { AST_FORMAT_H263, H245_VideoCapability::e_h263VideoCapability },#endif#ifdef HAVE_H264 { AST_FORMAT_H264, H245_VideoCapability::e_genericVideoCapability, "0.0.8.241.0.0.1" },#endif { 0 } };#endif struct ast_codec_pref prefs; RTP_DataFrame::PayloadTypes pt; if (!H323Connection::OnReceivedCapabilitySet(remoteCaps, muxCap, reject)) { return FALSE; } memset(&prefs, 0, sizeof(prefs)); int peer_capabilities = 0; for (int i = 0; i < remoteCapabilities.GetSize(); ++i) { unsigned int subType = remoteCapabilities[i].GetSubType(); if (h323debug) { cout << "Peer capability is " << remoteCapabilities[i] << endl; } switch(remoteCapabilities[i].GetMainType()) { case H323Capability::e_Audio: for (int x = 0; codecs[x].asterisk_codec > 0; ++x) { if ((subType == codecs[x].h245_cap) && (!codecs[x].formatName || (!strcmp(codecs[x].formatName, (const char *)remoteCapabilities[i].GetFormatName())))) { int ast_codec = codecs[x].asterisk_codec; int ms = 0; if (!(peer_capabilities & ast_codec)) { struct ast_format_list format; ast_codec_pref_append(&prefs, ast_codec); format = ast_codec_pref_getsize(&prefs, ast_codec); if ((ast_codec == AST_FORMAT_ALAW) || (ast_codec == AST_FORMAT_ULAW)) { ms = remoteCapabilities[i].GetTxFramesInPacket(); if (ms > 60) ms = format.cur_ms; } else ms = remoteCapabilities[i].GetTxFramesInPacket() * format.inc_ms; ast_codec_pref_setsize(&prefs, ast_codec, ms); } if (h323debug) { cout << "Found peer capability " << remoteCapabilities[i] << ", Asterisk code is " << ast_codec << ", frame size (in ms) is " << ms << endl; } peer_capabilities |= ast_codec; } } break; case H323Capability::e_Data: if (!strcmp((const char *)remoteCapabilities[i].GetFormatName(), CISCO_DTMF_RELAY)) { pt = remoteCapabilities[i].GetPayloadType(); if ((dtmfMode & H323_DTMF_CISCO) != 0) { on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)pt, 1);// if (sendUserInputMode == SendUserInputAsTone)// sendUserInputMode = SendUserInputAsInlineRFC2833; }#ifdef PTRACING if (h323debug) { cout << "\t-- Outbound Cisco RTP DTMF on payload " << pt << endl; }#endif } break; case H323Capability::e_UserInput: if (!strcmp((const char *)remoteCapabilities[i].GetFormatName(), H323_UserInputCapability::SubTypeNames[H323_UserInputCapability::SignalToneRFC2833])) { pt = remoteCapabilities[i].GetPayloadType(); if ((dtmfMode & H323_DTMF_RFC2833) != 0) { on_set_rfc2833_payload(GetCallReference(), (const char *)GetCallToken(), (int)pt, 0);// if (sendUserInputMode == SendUserInputAsTone)// sendUserInputMode = SendUserInputAsInlineRFC2833; }#ifdef PTRACING if (h323debug) { cout << "\t-- Outbound RFC2833 on payload " << pt << endl; }#endif } break;#if 0 case H323Capability::e_Video: for (int x = 0; vcodecs[x].asterisk_codec > 0; ++x) { if (subType == vcodecs[x].h245_cap) { H245_CapabilityIdentifier *cap = NULL; H245_GenericCapability y; if (vcodecs[x].oid) { cap = new H245_CapabilityIdentifier(H245_CapabilityIdentifier::e_standard); PASN_ObjectId &object_id = *cap; object_id = vcodecs[x].oid; y.m_capabilityIdentifier = *cap; } if ((subType != H245_VideoCapability::e_genericVideoCapability) || (vcodecs[x].oid && ((const H323GenericVideoCapability &)remoteCapabilities[i]).IsGenericMatch((const H245_GenericCapability)y))) { if (h323debug) { cout << "Found peer video capability " << remoteCapabilities[i] << ", Asterisk code is " << vcodecs[x].asterisk_codec << endl; } peer_capabilities |= vcodecs[x].asterisk_codec; } if (cap) delete(cap); } } break;#endif default: break; } } if (h323debug) { char caps_str[1024], caps2_str[1024]; ast_codec_pref_string(&prefs, caps2_str, sizeof(caps2_str)); cout << "Peer capabilities = " << ast_getformatname_multiple(caps_str, sizeof(caps_str), peer_capabilities) << ", ordered list is " << caps2_str << endl; }#if 0 redir_capabilities &= peer_capabilities;#endif if (on_setpeercapabilities) on_setpeercapabilities(GetCallReference(), (const char *)callToken, peer_capabilities, &prefs); return TRUE;}H323Channel * MyH323Connection::CreateRealTimeLogicalChannel(const H323Capability & capability, H323Channel::Directions dir, unsigned sessionID, const H245_H2250LogicalChannelParameters * /*param*/, RTP_QOS * /*param*/ ){ /* Do not open tx channel when transmitter has been paused by empty TCS */ if ((dir == H323Channel::IsTransmitter) && transmitterSidePaused) return NULL; return new MyH323_ExternalRTPChannel(*this, capability, dir, sessionID);}/** This callback function is invoked once upon creation of each * channel for an H323 session */BOOL MyH323Connection::OnStartLogicalChannel(H323Channel & channel){ /* Increase the count of channels we have open */ channelsOpen++; if (h323debug) { cout << "\t-- Started logical channel: " << ((channel.GetDirection() == H323Channel::IsTransmitter) ? "sending " : ((channel.GetDirection() == H323Channel::IsReceiver) ? "receiving " : " ")) << (const char *)(channel.GetCapability()).GetFormatName() << endl; cout << "\t\t-- channelsOpen = " << channelsOpen << endl; } return connectionState != ShuttingDownConnection;}void MyH323Connection::SetCapabilities(int caps, int dtmf_mode, void *_prefs, int pref_codec){ PINDEX lastcap = -1; /* last common capability index */ int alreadysent = 0; int codec; int x, y; char caps_str[1024]; struct ast_codec_pref *prefs = (struct ast_codec_pref *)_prefs; struct ast_format_list format; int frames_per_packet; int max_frames_per_packet; H323Capability *cap; localCapabilities.RemoveAll(); if (h323debug) { cout << "Setting capabilities to " << ast_getformatname_multiple(caps_str, sizeof(caps_str), caps) << endl; ast_codec_pref_string(prefs, caps_str, sizeof(caps_str)); cout << "Capabilities in preference order is " << caps_str << endl; } /* Add audio codecs in preference order first, then audio codecs without preference as allowed by mask */ for (y = 0, x = -1; x < 32 + 32; ++x) { if (x < 0) codec = pref_codec; else if (y || (!(codec = ast_codec_pref_index(prefs, x)))) { if (!y) y = 1; else y <<= 1; codec = y; } if (!(caps & codec) || (alreadysent & codec) || !(codec & AST_FORMAT_AUDIO_MASK)) continue; alreadysent |= codec; format = ast_codec_pref_getsize(prefs, codec); frames_per_packet = (format.inc_ms ? format.cur_ms / format.inc_ms : format.cur_ms); max_frames_per_packet = (format.inc_ms ? format.max_ms / format.inc_ms : 0); switch(codec) {#if 0 case AST_FORMAT_SPEEX: /* Not real sure if Asterisk acutally supports all of the various different bit rates so add them all and figure it out later*/ lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow2AudioCapability()); lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow3AudioCapability()); lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow4AudioCapability()); lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow5AudioCapability()); lastcap = localCapabilities.SetCapability(0, 0, new SpeexNarrow6AudioCapability()); break;#endif case AST_FORMAT_G729A: AST_G729ACapability *g729aCap; AST_G729Capability *g729Cap; lastcap = localCapabilities.SetCapability(0, 0, g729aCap = new AST_G729ACapability(frames_per_packet)); lastcap = localCapabilities.SetCapability(0, 0, g729Cap = new AST_G729Capability(frames_per_packet)); if (max_frames_per_packet) { g729aCap->SetTxFramesInPacket(max_frames_per_packet); g729Cap->SetTxFramesInPacket(max_frames_per_packet); } break; case AST_FORMAT_G723_1: AST_G7231Capability *g7231Cap; lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, TRUE)); if (max_frames_per_packet) g7231Cap->SetTxFramesInPacket(max_frames_per_packet); lastcap = localCapabilities.SetCapability(0, 0, g7231Cap = new AST_G7231Capability(frames_per_packet, FALSE)); if (max_frames_per_packet) g7231Cap->SetTxFramesInPacket(max_frames_per_packet); break; case AST_FORMAT_GSM: AST_GSM0610Capability *gsmCap; lastcap = localCapabilities.SetCapability(0, 0, gsmCap = new AST_GSM0610Capability(frames_per_packet)); if (max_frames_per_packet) gsmCap->SetTxFramesInPacket(max_frames_per_packet); break; case AST_FORMAT_ULAW: AST_G711Capability *g711uCap; lastcap = localCapabilities.SetCapability(0, 0, g711uCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::muLaw)); if (format.max_ms) g711uCap->SetTxFramesInPacket(format.max_ms); break; case AST_FORMAT_ALAW: AST_G711Capability *g711aCap; lastcap = localCapabilities.SetCapability(0, 0, g711aCap = new AST_G711Capability(format.cur_ms, H323_G711Capability::ALaw)); if (format.max_ms) g711aCap->SetTxFramesInPacket(format.max_ms); break; case AST_FORMAT_G726_AAL2: AST_CiscoG726Capability *g726Cap; lastcap = localCapabilities.SetCapability(0, 0, g726Cap = new AST_CiscoG726Capability(frames_per_packet)); if (max_frames_per_packet) g726Cap->SetTxFramesInPacket(max_frames_per_packet); break; default: alreadysent &= ~codec; break; } } cap = new H323_UserInputCapability(H323_UserInputCapability::HookFlashH245); if (cap && cap->IsUsable(*this)) { lastcap++; lastcap = localCapabilities.SetCapability(0, lastcap, cap); } else if (cap) delete cap; /* Capability is not usable */ dtmfMode = dtmf_mode; if (h323debug) { cout << "DTMF mode is " << (int)dtmfMode << endl; } if (dtmfMode) { lastcap++; if (dtmfMode == H323_DTMF_INBAND) { cap = new H323_UserInputCapability(H323_UserInputCapability::BasicString); if (cap && cap->IsUsable(*this)) { lastcap = localCapabilities.SetCapability(0, lastcap, cap); } else if (cap) delete cap; /* Capability is not usable */ sendUserInputMode = SendUserInputAsString; } else { if ((dtmfMode & H323_DTMF_RFC2833) != 0) { cap = new H323_UserInputCapability(H323_UserInputCapability::SignalToneRFC2833); if (cap && cap->IsUsable(*this)) lastcap = localCapabilities.SetCapability(0, lastcap, cap); else { dtmfMode |= H323_DTMF_SIGNAL; if (cap) delete cap; /* Capability is not usable */ } } if ((dtmfMode & H323_DTMF_CISCO) != 0) { /* Try Cisco's RTP DTMF relay too, but prefer RFC2833 or h245-signal */ cap = new AST_CiscoDtmfCapability(); if (cap && cap->IsUsable(*this)) { lastcap = localCapabilities.SetCapability(0, lastcap, cap); /* We cannot send Cisco RTP DTMFs, use h245-signal instead */ dtmfMode |= H323_DTMF_SIGNAL; } else { dtmfMode |= H323_DTMF_SIGNAL; if (cap) delete cap; /* Capability is not usable */ } } if ((dtmfMode & H323_DTMF_SIGNAL) != 0) { /* Cisco usually sends DTMF correctly only through h245-alphanumeric or h245-signal */ cap = new H323_UserInputCapability(H323_UserInputCapability::SignalToneH245); if (cap && cap->IsUsable(*this)) lastcap = localCapabilities.SetCapability(0, lastcap, cap); else if (cap) delete cap; /* Capability is not usable */ } sendUserInputMode = SendUserInputAsTone; /* RFC2833 transmission handled at Asterisk level */ } } if (h323debug) { cout << "Allowed Codecs for " << GetCallToken() << " (" << GetSignallingChannel()->GetLocalAddress() << "):\n\t" << setprecision(2) << localCapabilities << endl; }}BOOL MyH323Connection::StartControlChannel(const H225_TransportAddress & h245Address){ // Check that it is an IP address, all we support at the moment if (h245Address.GetTag() != H225_TransportAddress::e_ipAddress#if P_HAS_IPV6 && h245Address.GetTag() != H225_TransportAddress::e_ip6Address#endif ) { PTRACE(1, "H225\tConnect of H245 failed: Unsupported transport"); return FALSE; } // Already have the H245 channel up. if (controlChannel != NULL) return TRUE; PIPSocket::Address addr; WORD port; GetSignallingChannel()->GetLocalAddress().GetIpAndPort(addr, port); if (addr) { if (h323debug) cout << "Using " << addr << " for outbound H.245 transport" << endl; controlChannel = new MyH323TransportTCP(endpoint, addr); } else controlChannel = new H323TransportTCP(endpoint); if (!controlChannel->Se
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?