📄 sipprocessor.cpp
字号:
#include "SipProcessor.h"#include "Database.h"#include "time.h"#include <sstream>using namespace std;// Init static membersconst string SipProcessor::INVITE = "INVITE";const string SipProcessor::REGISTER = "REGISTER";const string SipProcessor::ACK = "ACK";const string SipProcessor::SIP_HEADER_OK = "SIP/2.0 200 OK";const string SipProcessor::SIP_HEADER_TRYING = "SIP/2.0 100 Trying";const string SipProcessor::SIP_HEADER_MOVED_TEMPORARILY = "SIP/2.0 302 Moved Temporarily";//const string SipProcessor::SIP_HEADER_MOVED_TEMPORARILY = "SIP/2.0 305 Use Proxy";// ConstructorSipProcessor::SipProcessor(UDPServerSocket* sSocket, IPAddress* callerIP, int cPort) { log = new Logger("SipProcessor"); serverSocket = sSocket; callerIPSource = callerIP; callerPort = cPort;}// DestructorSipProcessor::~SipProcessor() {}// Processes a SIP request.void SipProcessor::processRequest(const string& request) { originalRequest = request; log->debug("Request received."); istringstream is; is.str(request); string line; getline(is, line); if (line.find(REGISTER) == 0) { processRegister(); } else if (line.find(INVITE) == 0) { processInvite(); } else if (line.find(ACK) == 0) { processAck(); } else { sendRequestNotSupported(); }}// Private methodsvoid SipProcessor::processRegister() { log->debug("Entering processRegister..."); istringstream is(originalRequest); ostringstream responseStream; string line; responseStream << SIP_HEADER_OK << endl; string contactLine; // Copy needed lines from request to response for (getline(is, line); line != ""; getline(is, line)) { if (line.find("Via:") == 0) { responseStream << line << endl; } else if (line.find("To:") == 0) { responseStream << line << endl; } else if (line.find("From:") == 0) { responseStream << line << endl; } else if (line.find("Call-ID:") == 0) { responseStream << line << endl; } else if (line.find("CSeq:") == 0) { responseStream << line << endl; responseStream << "Date: " << getDateAndTime() << endl; } else if (line.find("Contact:") == 0) { responseStream << line << endl; contactLine = line; } else if (line.find("Content-Length:") == 0) { responseStream << line << endl << endl; } } // Prepare contact data, will be needed by SipServer if (!splitContactData(contactLine)) { log->debug("Eror reading contact data from: " + contactLine); sendServerError(); return; } // Everything ok -> send response to requestor string response = responseStream.str(); log->debug("Sending REGISTER ok to requestor: + " + response); int bytesTransferred = serverSocket->SendDatagram(response.c_str(), response.size(), *callerIPSource, callerPort); log->debug(" - sent bytes: " , bytesTransferred); // Publish the values in the kademlia network log->debug("Publishing the user data in kademlia..."); Database* db = Database::getInstance(); string name = responseContact[0]; string data = name + "@" + responseContact[1]; if (responseContact[2] != "") { data += ":" + responseContact[2]; // if port is not default } int countPublished = db->put(name, data); if (countPublished < 1) { log->debug("ERROR: Could not publish: " + data); } log->debug("Processing REGISTER ok :)");}void SipProcessor::processInvite() { log->debug("Entering processInvite..."); int bytesTransferred = 0; // First send trying string tryingMessage = createTryingMessage(); log->debug("Sending TRYING to caller..."); log->debug("Trying message:\n" + tryingMessage); bytesTransferred = serverSocket->SendDatagram(tryingMessage.c_str(), tryingMessage.size(), *callerIPSource, callerPort); log->debug(" - sent bytes: " , bytesTransferred); // Prepare invite request with data from kademlia string inviteRequest = prepareInvite(); if (inviteRequest == "") { // "" indicates error // Error processing is done in prepareInvite() so we just return. return; } // Get the destination where to forward the message string name = responseContact[0]; string ip = responseContact[1]; string port = responseContact[2]; if (port == "") { port = "5060"; // Def SIP port } int remotePort = atoi(port.c_str()); // Create the socket to callee calleeSocket = new UDPConnectedSocket (false); calleeIPSource = ip.c_str(); log->debug("Creating socket to callee, IP=" + ip + ", port=", remotePort); calleeSocket->Connect(calleeIPSource, remotePort); // Forward INVITE to callee string tempIP(calleeSocket->RemoteIPAddress().GetAddressString()); log->debug("Forwarding INVITE Message to: IP = " + tempIP + ", port = ", calleeSocket->RemotePortNumber()); bytesTransferred = calleeSocket->SendDatagram(inviteRequest.c_str(), inviteRequest.size()); log->debug(" - sent bytes: ", bytesTransferred); char response[BUFFER_SIZE]; response[0] = 0; // Wait for TRYING log->debug("Waiting for TRYING message"); bytesTransferred = calleeSocket->ReceiveDatagram(response, BUFFER_SIZE); log->debug(" - received bytes: ", bytesTransferred); string returnResponse(response); log->debug("Response:\n" + returnResponse); // Forward TRYING to original requestor //bytesTransferred = serverSocket->SendDatagram(returnResponse.c_str(), returnResponse.size(), *callerIPSource, callerPort); //log->debug("TRYING forwarded..."); //log->debug(" - sent bytes: " , bytesTransferred); // Wait for RINGING log->debug("Waiting for RINGING message..."); bytesTransferred = calleeSocket->ReceiveDatagram(response, BUFFER_SIZE); log->debug(" - received bytes: ", bytesTransferred); returnResponse = response; log->debug("Response:\n" + returnResponse); // Forward the RINGING to original requestor bytesTransferred = serverSocket->SendDatagram(returnResponse.c_str(), returnResponse.size(), *callerIPSource, callerPort); log->debug("RINGING forwarded..."); log->debug(" - sent bytes: " , bytesTransferred); // Wait for OK log->debug("Waiting for OK message..."); bytesTransferred = calleeSocket->ReceiveDatagram(response, BUFFER_SIZE); log->debug(" - received bytes: ", bytesTransferred); returnResponse = response; log->debug("Response:\n" + returnResponse); // FOrward the OK to original requestor bytesTransferred = serverSocket->SendDatagram(returnResponse.c_str(), returnResponse.size(), *callerIPSource, callerPort); log->debug("OK forwarded..."); log->debug(" - sent bytes: " , bytesTransferred); /* // Wait for ACK from original requesor log->debug("Waiting for ACK message..."); bytesTransferred = serverSocket->ReceiveDatagram(response, BUFFER_SIZE, *callerIPSource, callerPort); log->debug(" - received bytes: ", bytesTransferred); returnResponse = response; log->debug("Response:\n" + returnResponse); // Forward ACK to callee bytesTransferred = calleeSocket->SendDatagram(response, returnResponse.size()); log->debug("ACK"); log->debug(" - sent bytes: ", bytesTransferred); */ // Disconnect and release memory calleeSocket->DisConnect(); delete calleeSocket; log->debug("Processing INVITE ok :))");}void SipProcessor::processAck() { log->debug("Entering processAck..."); /* int bytesTransferred; istringstream is(originalRequest); string line; string contactLine; // Copy needed lines from request to response for (getline(is, line); line != ""; getline(is, line)) { if (line.find("To:") == 0) { if (!splitContactData(line)) { log->debug("Eror reading contact data from: " + contactLine); sendServerError(); return; } } } // Forward the ACK to the found address // Get the destination where to forward the message string name = responseContact[0]; string ip = responseContact[1]; string port = responseContact[2]; if (port == "") { port = "5060"; // Def SIP port } int remotePort = atoi(port.c_str()); // Create the socket to callee calleeSocket = new UDPConnectedSocket (false); calleeIPSource = ip.c_str(); log->debug("Creating socket to callee, IP=" + ip + ", port=", remotePort); calleeSocket->Connect(calleeIPSource, remotePort);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -