📄 sipclient.cpp
字号:
} return; } found = true; } if( callid == curcall->getCallId() && curcall->getCallType() == SipCall::inSubscribeCall_2 ) { curcall->incomingMessage( curmessage ); found = true; } if( found ) { return; } } if( touri.hasTag() ) { sendQuickResponse( curmessage, SipStatus( 481 ) ); delete curmessage; return; } SipCall *newcall; SipCallMember *member; bool sendSubscribe = true; if( touri == user->getUri() ) { newcall = new SipCall( user, curmessage->getHeaderData( SipHeader::Call_ID ), SipCall::inSubscribeCall ); member = newcall->incomingMessage( curmessage ); } else { newcall = new SipCall( user, curmessage->getHeaderData( SipHeader::Call_ID ), SipCall::inSubscribeCall_2 ); newcall->incomingMessage( curmessage ); delete newcall; return; } SipUri remoteuri( curmessage->getHeaderData( SipHeader::From ) ); if( curmessage->getHeaderData( SipHeader::Expires ) == "0" || remoteuri.reqUri() == user->getMyUri()->reqUri() ) { delete newcall; } else { for( SipCall *curcall = calls.first(); curcall != 0; curcall = calls.next() ) { if( curcall->getCallType() == SipCall::outSubscribeCall ) { if( curcall->getMember( remoteuri ) ) { if( curcall->getCallStatus() == SipCall::callInProgress ) { sendSubscribe = false; } } } } member->setContactUri( curmessage->getContactList().getHead() ); member->setUri( remoteuri ); if( curmessage->getHeaderData( SipHeader::Expires).toInt() > 0 ) { member->timerStart( curmessage->getHeaderData( SipHeader::Expires).toInt() * 1000 ); } connect( member, SIGNAL( statusUpdated( SipCallMember * ) ), this, SLOT( callMemberUpdated() ) ); member->getCall()->setCallStatus( SipCall::callInProgress ); incomingSubscribe( member, sendSubscribe ); } return; } // If the CallId exists already, pass the message to that call for( SipCall *curcall = calls.first(); curcall != 0; curcall = calls.next() ) { if( callid == curcall->getCallId() ) { // Check cseq because SUBSCRIBE and NOTIFY call have same CallID QString cseq = curmessage->getHeaderData( SipHeader::CSeq ); if( cseq.contains( "NOTIFY" ) && curmessage->getMethod() != Sip::NOTIFY ) { if( curcall->getCallType() == SipCall::inSubscribeCall ) { curcall->incomingMessage( curmessage ); return; } } else { if( curmessage->getType() == SipMessage::Request && touri.hasTag() && curmessage->getMethod() != Sip::REFER ) { if( touri.getTag() != curcall->localAddress().getTag() ) { if( curmessage->getMethod() != Sip::ACK && curmessage->getMethod() != Sip::CANCEL ) { sendQuickResponse( curmessage, SipStatus( 481 ) ); } else { printf( "SipClient: Dropping ACK/CANCEL which deserved a 481\n" ); } delete curmessage; return; } } curcall->incomingMessage( curmessage ); return; } } } // Check message type if( curmessage->getType() != SipMessage::Request ) { printf( "SipClient: No call found for incoming response. Dropping.\n" ); delete curmessage; return; } // Check method if( curmessage->getMethod() == Sip::ACK ) { printf( "SipClient: ACK received, but nobody was listening. Dropping.\n" ); delete curmessage; return; } if( curmessage->getMethod() == Sip::CANCEL ) { printf( "SipClient: No listener for this CANCEL, returning a 481.\n" ); sendQuickResponse( curmessage, SipStatus( 481 ) ); delete curmessage; return; } if( touri.hasTag() ) { sendQuickResponse( curmessage, SipStatus( 481 ) ); delete curmessage; return; } if( fwmode ) { printf( "SipClient: Forwarding call.\n" ); if( fwbody != QString::null ) { sendQuickResponse( curmessage, SipStatus( 302 ), fwbody, MimeContentType( "text/plain" ) ); } else { sendQuickResponse( curmessage, SipStatus( 302 ) ); } delete curmessage; return; } if( busymode ) { printf( "SipClient: We're busy.\n" ); if( busybody != QString::null ) { sendQuickResponse( curmessage, SipStatus( 486 ), busybody, MimeContentType( "text/plain" ) ); } else { sendQuickResponse( curmessage, SipStatus( 486 ) ); } delete curmessage; return; } if( curmessage->getMethod() == Sip::REGISTER ) { printf( "SipClient:Not Implemented, Returning a 501.\n" ); sendQuickResponse( curmessage, SipStatus( 501 ) ); delete curmessage; return; } if( curmessage->getMethod() == Sip::BadMethod ) { printf( "SipClient: I don't recognize that method... Returning a 501.\n" ); sendQuickResponse( curmessage, SipStatus( 501 ) ); delete curmessage; return; } if( curmessage->hasHeader( SipHeader::Accept ) ) { if( curmessage->getMethod() == Sip::INVITE ) { if( !curmessage->getHeaderData( SipHeader::Accept ).lower().contains( "application/sdp" ) ) { sendQuickResponse( curmessage, SipStatus( 406 ) ); delete curmessage; return; } } else if( curmessage->getMethod() == Sip::SUBSCRIBE ) { if( !curmessage->getHeaderData( SipHeader::Accept ).lower().contains( "application/xpidf+xml" ) ) { sendQuickResponse( curmessage, SipStatus( 406 ) ); delete curmessage; return; } } } if( curmessage->hasHeader( SipHeader::Require ) && curmessage->getHeaderData( SipHeader::Require ) != QString::null ) { printf( "SipClient: This messages says it requires '%s', returning 420.\n", curmessage->getHeaderData( SipHeader::Require ).latin1() ); sendQuickResponse( curmessage, SipStatus( 420 ) ); delete curmessage; return; } // Create a new call and pass it the message printf( "SipClient: Searching for a user\n" ); if( curmessage->getMethod() == Sip::OPTIONS ) { SipCall *newcall = new SipCall( user, curmessage->getHeaderData( SipHeader::Call_ID ) ); newcall->incomingMessage( curmessage ); return; } printf( "SipClient: Creating new call for user %s\n", user->getUri().nameAddr().ascii() ); SipCall *newcall = new SipCall( user, curmessage->getHeaderData( SipHeader::Call_ID ) ); SipCallMember *member = newcall->incomingMessage( curmessage ); if( member == 0 ) { return; } // Signal that we have an incoming call if( curmessage->getMethod() == Sip::INVITE ) { QString body = curmessage->messageBody(); if( body.contains( "m=video" ) ) { newcall->setCallType( SipCall::videoCall ); } incomingCall( newcall, body ); } else { delete curmessage; }}bool SipClient::sendRequest( SipMessage *msg, bool contact, const SipUri ®Proxy, const QString &branch ){ if( regProxy != SipUri::null ) { sipProxy = regProxy; } // Create a Via tag and add it to the message at the top of the list SipVia regvia; if( isTcpSocket() ) { regvia.setTransport( SipVia::TCP ); } else { regvia.setTransport( SipVia::UDP ); } if (symmetricmode) { regvia.setRportParam( QString::null ); } regvia.setHostname( Sip::getLocalAddress() ); if( isTcpSocket() ) { regvia.setPortNumber( TCP_listener.getPortNumber() ); } else { regvia.setPortNumber( listener.getPortNumber() ); } if( branch != QString::null ) { regvia.setBranchParam( branch ); } else { regvia.generateBranchParam(); } msg->getViaList().insertTopmostVia( regvia ); // Calculate content length msg->insertHeader( SipHeader::Content_Length, QString::number( msg->messageBody().utf8().length() ) ); // Advertise shamelessly msg->insertHeader( SipHeader::User_Agent, getUserAgent() ); if( msg->getMethod() == Sip::REGISTER ) { msg->insertHeader( SipHeader::Event, "registration" ); msg->insertHeader( SipHeader::Allow_Events, "presence" ); } if( msg->getMethod() == Sip::SUBSCRIBE ) { msg->insertHeader( SipHeader::Event, "presence" ); msg->insertHeader( SipHeader::Accept, "application/xpidf+xml" ); } if( msg->getMethod() == Sip::NOTIFY ) { msg->insertHeader( SipHeader::Event, "presence" ); } // Set max-forwards if( maxforwards != 0 ) { msg->insertHeader( SipHeader::Max_Forwards, QString::number( maxforwards ) ); } // Via hiding mode if( hidemode != DontHideVia ) { if( hidemode == HideHop ) msg->insertHeader( SipHeader::Hide, "hop" ); else msg->insertHeader( SipHeader::Hide, "route" ); } // If this request requires the contact header, add it if( contact ) { msg->getContactList().addToHead( contacturi ); } // Retransmission timestamp msg->setTimestamp(); if( msg->getMethod() == Sip::REGISTER || msg->getMethod() == Sip::MESSAGE ) { msg->setTimeTick( 4000 ); } else { msg->setTimeTick( 500 ); // T1 } msg->incrSendCount(); // Error in reguest uri if( msg->getRequestUri().reqUri().contains( ' ' ) ) { QString s = msg->getRequestUri().reqUri(); while( s.contains( ' ' ) ) { s.remove( s.find( ' ' ), 1 ); } msg->setRequestUri( SipUri( s ) ); printf( "\nSipClient: Spaces removed from Request Uri\n" ); } // Announce that we're sending a message if( traceMessageSending ) { printf( "\nSipClient: Sending: %s.%03d\n--------------------------------\n%s\n", QTime::currentTime().toString().latin1(), QTime::currentTime().msec(), msg->message().data() ); } // Send the message TCPMessageSocket *tcpSocket = 0; if( isTcpSocket() ) { bool createTcpSocket = true; TCPMessageSocketIterator it( getTcpSocketList() ); if( useExplicitProxy ) { for (it.toFirst(); it.current(); ++it) { tcpSocket = it.current(); if( tcpSocket->cmpSocket( proxy, proxyport ) ) { createTcpSocket = false; break; } } if( createTcpSocket ) { tcpSocket = new TCPMessageSocket; if( !tcpSocket->setHostnamePort( proxy, proxyport ) ) { return false; } if( tcpSocket->connect( proxyport ) == -1 ) { delete tcpSocket; tcpSocket = 0; } else { if( traceMessageSending ) { printf( "SipClient: Sending to '%s:%d' (TCP)\n", proxy.latin1(), proxyport ); } tcpSockets.append( tcpSocket ); } } } else { // send to the host/port in the request uri QString sendtoaddr; if( msg->getRequestUri().hasMaddrParam() ) { sendtoaddr = msg->getRequestUri().getMaddrParam(); } else { sendtoaddr = msg->getRequestUri().getHostname(); } sendtoaddr = getSipProxySrv( sendtoaddr ); if( sendtoaddr.contains( ':' ) ) { unsigned int port = sendtoaddr.mid( sendtoaddr.find( ':' ) + 1 ).toUInt(); msg->getRequestUri().setPortNumber( port ); sendtoaddr = sendtoaddr.left( sendtoaddr.find( ':' ) ); } if( traceMessageSending ) { printf( "SipClient: Sending to '%s:%d' (TCP)\n", sendtoaddr.latin1(), msg->getRequestUri().getPortNumber() ); } for (it.toFirst(); it.current(); ++it) { tcpSocket = it.current(); if( tcpSocket->cmpSocket( sendtoaddr, msg->getRequestUri().getPortNumber() ) ) { createTcpSocket = false; break; } } if( createTcpSocket ) { tcpSocket = new TCPMessageSocket; if( !tcpSocket->setHostnamePort( sendtoaddr, msg->getRequestUri().getPortNumber() ) ) { return false; } if( tcpSocket->connect( msg->getRequestUri().getPortNumber() ) == -1 ) { delete tcpSocket; tcpSocket = 0; } else { tcpSockets.append( tcpSocket ); } } } if( tcpSocket != 0 ) { if( tcpSocket->send( msg->message().utf8().data(), msg->message().utf8().length() ) == -1 ) { tcpSockets.remove( tcpSocket ); tcpSocket = 0; } } } if( tcpSocket == 0 ) { UDPMessageSocket* s; UDPMessageSocket sendsocket; if (symmetricmode) { s = &listener; } else { s = &sendsocket; } // Choose destination if( useExplicitProxy ) { if( !s->setHostname( proxy ) ) { return false; } if( traceMessageSending ) { printf( "SipClient: Sending to '%s:%d'\n", proxy.latin1(), proxyport ); } s->connect( proxyport ); } else { // send to the host/port in the request uri QString sendtoaddr; unsigned int sendtoport = msg->getRequestUri().getPortNumber(); if( msg->getRequestUri().hasMaddrParam() ) { sendtoaddr = msg->getRequestUri().getMaddrParam(); } else { SipUri route( msg->getHeaderData( SipHeader::Route ) ); if( route.uri().contains( ";lr" ) ) { sendtoaddr = route.getHostname(); sendtoport = route.getPortNumber(); } else { sendtoaddr = msg->getRequestUri().getHostname(); sendtoaddr = getSipProxySrv( sendtoaddr ); if( sendtoaddr.contains( ':' ) ) { unsigned int port = sendtoaddr.mid( sendtoaddr.find( ':' ) + 1 ).toUInt(); msg->getRequestUri().setPortNumber( port ); sendtoaddr = sendtoaddr.left( sendtoaddr.find( ':' ) ); } sendtoport = msg->getRequestUri().getPortNumber(); } } if( traceMessageSending ) { printf( "SipClient: Sending to '%s:%d'\n", sendtoaddr.latin1(), sendtoport ); } if( !s->setHostname( sendtoaddr ) ) { return false; } s->connect( sendtoport ); } s->send( msg->message().utf8().data(), msg->message().utf8().length() ); } return true;}void SipClient::setSymmetricMode( bool newmode){ symmetricmode = newmode;}void SipClient::sendResponse( SipMessage *msg, bool contact ){ MessageSocket *outsocket = 0; SipVia topvia; QString sendaddr; // Calculate content length msg->insertHeader( SipHeader::Content_Length, QString::number( msg->messageBody().utf8().length() ) ); // Advertise shamelesslysipvialist msg->insertHeader( SipHeader::User_Agent, getUserAgent() ); // If this rquest requires the contact header, add it if( contact ) { msg->getContactList().addToHead( contacturi ); } // Indicate what methods we allow if this is an answer to an OPTIONS if( msg->getHeaderData( SipHeader::CSeq ).contains( "OPTIONS" ) ) { msg->insertHeader( SipHeader::Allow, "INVITE, OPTIONS, ACK, BYE, MSG, CANCEL, MESSAGE, SUBSCRIBE, NOTIFY, INFO, REFER" ); } // Use via to tell us where to send it and how topvia = msg->getViaList().getTopmostVia(); switch( topvia.getTransport() ) { case SipVia::UDP: printf( "SipClient: Sending UDP Response\n" ); if (symmetricmode) { outsocket = &listener; } else { outsocket = new UDPMessageSocket; } break; case SipVia::TCP: printf( "SipClient: Sending TCP Response\n" ); outsocket = new TCPMessageSocket; break; case SipVia::TLS: printf( "SipClient: TLS in top via, not supported (full TLS support not implemented)\n" ); break; case SipVia::BadTransport: printf( "SipClient: Bad transport on incoming Via\n" ); break; } // If transport was bad, no use sending if( !outsocket ) return; // maddr, received, sentby if( topvia.hasMaddrParam() ) { printf( "SipClient: Using address from maddr via parameter\n" ); sendaddr = topvia.getMaddrParam(); } else if( topvia.hasReceivedParam() ) { printf( "SipClient: Using address from received via parameter\n" ); sendaddr = topvia.getReceivedParam(); } else { sendaddr = topvia.getHostname(); } // Announce where we're sending if( traceMessageSending ) { printf( "SipClient: Sending to '%s' port %d\n", sendaddr.utf8().data(), topvia.getPortNumber() ); } if( !outsocket->setHostname( sendaddr.utf8().data() ) ) { if (outsocket != &listener) { delete outsocket; } return; } outsocket->connect( topvia.getPortNumber() ); // Announce what we're sending if( traceMessageSending ) { printf( "\nSipClient: Sending: %s.%03d\n--------------------------------\n%s\n", QTime::currentTime().toString().latin1(), QTime::currentTime().msec(), msg->message().data() ); } // Send it outsocket->send( msg->message().utf8().data(), msg->message().utf8().length() ); if (outsocket != &listener) { delete outsocket; }}void SipClient::sendRaw( SipMessage *msg ){ if( isTcpSocket() ) { return; } // Announce that we're sending if( traceMessageSending ) { printf( "\nSipClient: Sending: %s.%03d\n--------------------------------\n%s\n", QTime::currentTime().toString().latin1(), QTime::currentTime().msec(), msg->message().data() ); } UDPMessageSocket *sendsocket; if (symmetricmode) { sendsocket = &listener; } else { sendsocket = new UDPMessageSocket; } // Choose destination if( ( msg->getType() != SipMessage::Response ) && useExplicitProxy ) { if( !sendsocket->setHostname( proxy ) ) { if (sendsocket != &listener) { delete sendsocket; } return; } sendsocket->connect( proxyport ); } else { // Send to whatever is in the request uri QString sendtoaddr; if( msg->getRequestUri().hasMaddrParam() ) { sendtoaddr = msg->getRequestUri().getMaddrParam(); } else { sendtoaddr = msg->getRequestUri().getHostname(); } if( !sendsocket->setHostname( sendtoaddr ) ) { if (sendsocket != &listener) { delete sendsocket; } return; } sendsocket->connect( msg->getRequestUri().getPortNumber() ); } sendsocket->send( msg->message().utf8().data(), msg->message().utf8().length() ); if (sendsocket != &listener) { delete sendsocket;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -