ast_h323.cpp
来自「一个非常美妙的proxy。功能强大。基于sip的协议。如果还要的话」· C++ 代码 · 共 1,533 行 · 第 1/3 页
CPP
1,533 行
H323_G711Capability *g711aCap; lastcap = localCapabilities.SetCapability(0, 0, g711aCap = new H323_G711Capability(H323_G711Capability::ALaw)); g711aCap->SetTxFramesInPacket(g711Frames); } lastcap++; lastcap = localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::HookFlashH245)); lastcap++; mode = dtmfMode; if (dtmfMode == H323_DTMF_INBAND) { localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneH245)); sendUserInputMode = SendUserInputAsTone; } else { localCapabilities.SetCapability(0, lastcap, new H323_UserInputCapability(H323_UserInputCapability::SignalToneRFC2833)); sendUserInputMode = SendUserInputAsInlineRFC2833; } if (h323debug) { cout << "Allowed Codecs:\n\t" << setprecision(2) << localCapabilities << endl; }}/* MyH323_ExternalRTPChannel */MyH323_ExternalRTPChannel::MyH323_ExternalRTPChannel(MyH323Connection & connection, const H323Capability & capability, Directions direction, unsigned id) : H323_ExternalRTPChannel::H323_ExternalRTPChannel(connection, capability, direction, id){ struct rtp_info *info; /* Determine the Local (A side) IP Address and port */ info = on_external_rtp_create(connection.GetCallReference(), (const char *)connection.GetCallToken()); if (!info) { cout << "\tERROR: on_external_rtp_create failure" << endl; return; } else { localIpAddr = info->addr; localPort = info->port; /* tell the H.323 stack */ SetExternalAddress(H323TransportAddress(localIpAddr, localPort), H323TransportAddress(localIpAddr, localPort + 1)); /* clean up allocated memory */ free(info); } /* Get the payload code */ OpalMediaFormat format(capability.GetFormatName(), FALSE); payloadCode = format.GetPayloadType();} MyH323_ExternalRTPChannel::~MyH323_ExternalRTPChannel() { if (h323debug) { cout << "\tExternalRTPChannel Destroyed" << endl; }}BOOL MyH323_ExternalRTPChannel::Start(void){ /* Call ancestor first */ if (!H323_ExternalRTPChannel::Start()) { return FALSE; } if (h323debug) { cout << "\t\tExternal RTP Session Starting" << endl; cout << "\t\tRTP channel id " << sessionID << " parameters:" << endl; } /* Collect the remote information */ H323_ExternalRTPChannel::GetRemoteAddress(remoteIpAddr, remotePort); if (h323debug) { cout << "\t\t-- remoteIpAddress: " << remoteIpAddr << endl; cout << "\t\t-- remotePort: " << remotePort << endl; cout << "\t\t-- ExternalIpAddress: " << localIpAddr << endl; cout << "\t\t-- ExternalPort: " << localPort << endl; } /* Notify Asterisk of remote RTP information */ on_start_rtp_channel(connection.GetCallReference(), (const char *)remoteIpAddr.AsString(), remotePort, (const char *)connection.GetCallToken(), (int)payloadCode); return TRUE;}BOOL MyH323_ExternalRTPChannel::OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param){ PIPSocket::Address remoteIpAddress; WORD remotePort; if (h323debug) { cout << " MyH323_ExternalRTPChannel::OnReceivedAckPDU" << endl; } if (H323_ExternalRTPChannel::OnReceivedAckPDU(param)) { GetRemoteAddress(remoteIpAddress, remotePort); if (h323debug) { cout << " -- remoteIpAddress: " << remoteIpAddress << endl; cout << " -- remotePort: " << remotePort << endl; } on_start_rtp_channel(connection.GetCallReference(), (const char *)remoteIpAddress.AsString(), remotePort, (const char *)connection.GetCallToken(), (int)payloadCode); return TRUE; } return FALSE;}/** IMPLEMENTATION OF C FUNCTIONS *//** * The extern "C" directive takes care for * the ANSI-C representation of linkable symbols */extern "C" {int h323_end_point_exist(void){ if (!endPoint) { return 0; } return 1;} void h323_end_point_create(void){ channelsOpen = 0; logstream = new PAsteriskLog(); localProcess = new MyProcess(); localProcess->Main();}void h323_gk_urq(void){ if (!h323_end_point_exist()) { cout << " ERROR: [h323_gk_urq] No Endpoint, this is bad" << endl; return; } endPoint->RemoveGatekeeper();}void h323_debug(int flag, unsigned level){ if (flag) { PTrace:: SetLevel(level); } else { PTrace:: SetLevel(0); }} /** Installs the callback functions on behalf of the PBX application */void h323_callback_register(setup_incoming_cb ifunc, setup_outbound_cb sfunc, on_rtp_cb rtpfunc, start_rtp_cb lfunc, clear_con_cb clfunc, chan_ringing_cb rfunc, con_established_cb efunc, send_digit_cb dfunc, answer_call_cb acfunc, progress_cb pgfunc, rfc2833_cb dtmffunc, hangup_cb hangupfunc, setcapabilities_cb capabilityfunc){ on_incoming_call = ifunc; on_outgoing_call = sfunc; on_external_rtp_create = rtpfunc; on_start_rtp_channel = lfunc; on_connection_cleared = clfunc; on_chan_ringing = rfunc; on_connection_established = efunc; on_send_digit = dfunc; on_answer_call = acfunc; on_progress = pgfunc; on_set_rfc2833_payload = dtmffunc; on_hangup = hangupfunc; on_setcapabilities = capabilityfunc;}/** * Add capability to the capability table of the end point. */int h323_set_capabilities(const char *token, int cap, int dtmfMode){ MyH323Connection *conn; if (!h323_end_point_exist()) { cout << " ERROR: [h323_set_capablities] No Endpoint, this is bad" << endl; return 1; } if (!token || !*token) { cout << " ERROR: [h323_set_capabilities] Invalid call token specified." << endl; return 1; } PString myToken(token); conn = (MyH323Connection *)endPoint->FindConnectionWithLock(myToken); if (!conn) { cout << " ERROR: [h323_set_capabilities] Unable to find connection " << token << endl; return 1; } conn->SetCapabilities(cap, dtmfMode); conn->Unlock(); return 0;}/** Start the H.323 listener */int h323_start_listener(int listenPort, struct sockaddr_in bindaddr){ if (!h323_end_point_exist()) { cout << "ERROR: [h323_start_listener] No Endpoint, this is bad!" << endl; return 1; } PIPSocket::Address interfaceAddress(bindaddr.sin_addr); if (!listenPort) { listenPort = 1720; } /** H.323 listener */ H323ListenerTCP *tcpListener; tcpListener = new H323ListenerTCP(*endPoint, interfaceAddress, (WORD)listenPort); if (!endPoint->StartListener(tcpListener)) { cout << "ERROR: Could not open H.323 listener port on " << ((H323ListenerTCP *) tcpListener)->GetListenerPort() << endl; delete tcpListener; return 1; } cout << " == H.323 listener started" << endl; return 0;}; int h323_set_alias(struct oh323_alias *alias){ char *p; char *num; PString h323id(alias->name); PString e164(alias->e164); char *prefix; if (!h323_end_point_exist()) { cout << "ERROR: [h323_set_alias] No Endpoint, this is bad!" << endl; return 1; } cout << "== Adding alias \"" << h323id << "\" to endpoint" << endl; endPoint->AddAliasName(h323id); endPoint->RemoveAliasName(localProcess->GetUserName()); if (!e164.IsEmpty()) { cout << "== Adding E.164 \"" << e164 << "\" to endpoint" << endl; endPoint->AddAliasName(e164); } if (strlen(alias->prefix)) { p = prefix = strdup(alias->prefix); while((num = strsep(&p, ",")) != (char *)NULL) { cout << "== Adding Prefix \"" << num << "\" to endpoint" << endl; endPoint->SupportedPrefixes += PString(num); endPoint->SetGateway(); } if (prefix) free(prefix); } return 0;}void h323_set_id(char *id){ PString h323id(id); if (h323debug) { cout << " == Using '" << h323id << "' as our H.323ID for this call" << endl; } /* EVIL HACK */ endPoint->SetLocalUserName(h323id);}void h323_show_tokens(void){ cout << "Current call tokens: " << setprecision(2) << endPoint->GetAllConnections() << endl;}/** Establish Gatekeeper communiations, if so configured, * register aliases for the H.323 endpoint to respond to. */int h323_set_gk(int gatekeeper_discover, char *gatekeeper, char *secret){ PString gkName = PString(gatekeeper); PString pass = PString(secret); H323TransportUDP *rasChannel; if (!h323_end_point_exist()) { cout << "ERROR: [h323_set_gk] No Endpoint, this is bad!" << endl; return 1; } if (!gatekeeper) { cout << "Error: Gatekeeper cannot be NULL" << endl; return 1; } if (strlen(secret)) { endPoint->SetGatekeeperPassword(pass); } if (gatekeeper_discover) { /* discover the gk using multicast */ if (endPoint->DiscoverGatekeeper(new H323TransportUDP(*endPoint))) { cout << "== Using " << (endPoint->GetGatekeeper())->GetName() << " as our Gatekeeper." << endl; } else { cout << "Warning: Could not find a gatekeeper." << endl; return 1; } } else { rasChannel = new H323TransportUDP(*endPoint); if (!rasChannel) { cout << "Error: No RAS Channel, this is bad" << endl; return 1; } if (endPoint->SetGatekeeper(gkName, rasChannel)) { cout << "== Using " << (endPoint->GetGatekeeper())->GetName() << " as our Gatekeeper." << endl; } else { cout << "Error registering with gatekeeper \"" << gkName << "\". " << endl; /* XXX Maybe we should fire a new thread to attempt to re-register later and not kill asterisk here? */ return 1; } } return 0;}/** Send a DTMF tone over the H323Connection with the * specified token. */void h323_send_tone(const char *call_token, char tone){ if (!h323_end_point_exist()) { cout << "ERROR: [h323_send_tone] No Endpoint, this is bad!" << endl; return; } PString token = PString(call_token); endPoint->SendUserTone(token, tone);}/** Make a call to the remote endpoint. */int h323_make_call(char *dest, call_details_t *cd, call_options_t *call_options){ int res; PString token; PString host(dest); if (!h323_end_point_exist()) { return 1; } res = endPoint->MakeCall(host, token, &cd->call_reference, call_options); memcpy((char *)(cd->call_token), (const unsigned char *)token, token.GetLength()); return res;};int h323_clear_call(const char *call_token, int cause){ H225_ReleaseCompleteReason dummy; H323Connection::CallEndReason r = H323Connection::EndedByLocalUser; MyH323Connection *connection; const PString currentToken(call_token); if (!h323_end_point_exist()) { return 1; } if (cause) { r = H323TranslateToCallEndReason((Q931::CauseValues)(cause), dummy); } connection = (MyH323Connection *)endPoint->FindConnectionWithLock(currentToken); if (connection) { connection->SetCause(cause); connection->SetCallEndReason(r); connection->Unlock(); } endPoint->ClearCall(currentToken, r); return 0;};/* Send Alerting PDU to H.323 caller */int h323_send_alerting(const char *token){ const PString currentToken(token); H323Connection * connection; if (h323debug) { cout << "\tSending alerting\n" << endl; } connection = endPoint->FindConnectionWithLock(currentToken); if (!connection) { cout << "No connection found for " << token << endl; return -1; } connection->AnsweringCall(H323Connection::AnswerCallPending); connection->Unlock(); return 0; }/* Send Progress PDU to H.323 caller */int h323_send_progress(const char *token){ const PString currentToken(token); H323Connection * connection; connection = endPoint->FindConnectionWithLock(currentToken); if (!connection) { cout << "No connection found for " << token << endl; return -1; } connection->AnsweringCall(H323Connection::AnswerCallDeferredWithMedia); connection->Unlock(); return 0; }/** This function tells the h.323 stack to either answer or deny an incoming call */int h323_answering_call(const char *token, int busy) { const PString currentToken(token); H323Connection * connection; connection = endPoint->FindConnectionWithLock(currentToken); if (!connection) { cout << "No connection found for " << token << endl; return -1; } if (!busy) { if (h323debug) { cout << "\tAnswering call " << token << endl; } connection->AnsweringCall(H323Connection::AnswerCallNow); } else { if (h323debug) { cout << "\tdenying call " << token << endl; } connection->AnsweringCall(H323Connection::AnswerCallDenied); } connection->Unlock(); return 0;}int h323_show_codec(int fd, int argc, char *argv[]){ cout << "Allowed Codecs:\n\t" << setprecision(2) << endPoint->GetCapabilities() << endl; return 0;}int h323_soft_hangup(const char *data){ PString token(data); BOOL result; cout << "Soft hangup" << endl; result = endPoint->ClearCall(token); return result;}/* alas, this doesn't work :( */void h323_native_bridge(const char *token, const char *them, char *capability){ H323Channel *channel; MyH323Connection *connection = (MyH323Connection *)endPoint->FindConnectionWithLock(token); if (!connection) { cout << "ERROR: No connection found, this is bad\n"; return; } cout << "Native Bridge: them [" << them << "]" << endl; channel = connection->FindChannel(connection->sessionId, TRUE); connection->bridging = TRUE; connection->CloseLogicalChannelNumber(channel->GetNumber()); connection->Unlock(); return;}#undef coutvoid h323_end_process(void){ if (endPoint) { endPoint->ClearAllCalls(); endPoint->RemoveListener(NULL); delete endPoint; endPoint = NULL; } if (localProcess) { delete localProcess; localProcess = NULL; } PTrace::SetLevel(0); PTrace::SetStream(&cout); if (logstream) { delete logstream; logstream = NULL; }}} /* extern "C" */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?