📄 sipclient.cpp
字号:
} if( bytesread < 0 ) { printf("!!!!!SipClient: incoming message read failed\n"); if ((tcpSocket != &TCP_listener) && !closeS) { tcpSockets.remove( tcpSocket ); tcpSocket = 0; } return; } else { fullmessage.append( QString::fromUtf8( inputbuf, bytesread ) ); } // Check if long or short form if( isTcpSocket() ) { if( fullmessage.contains( "Content-Length: " ) > 0 ) { lSearch = "Content-Length: "; //long lLen=16; } else { lSearch = "l: "; // short lLen=3; } } if( isTcpSocket() ) { QString s; if( fullmessage.contains( "\r\n\r\n" ) > 0 ) { if( fullmessage.findRev( lSearch) < fullmessage.findRev( "\r\n\r\n" ) ) { s = fullmessage.mid( fullmessage.findRev( lSearch) + lLen ); s = s.left( s.find( '\r' ) ); if( s.toInt() == 0 ) { if( fullmessage.right( 4 ) == "\r\n\r\n" ) { break; } } else { contentLength = s.toInt(); s = fullmessage.mid( fullmessage.findRev( QString( "\r\n\r\n" ) ) + 4 ); if( s.utf8().length() == contentLength ) { break; } } } else if( fullmessage.right( 4 ) == "\r\n\r\n" ) { break; } } } else { break; } // received nothing / nothingmore if(bytesread==0) break; //unblock the current socket for subsequent reading char fl=1; ioctl(socketfd,FIONBIO,&fl); } //end of for loop //close socket immediately, if it was returned from accept, or nothing was read if(closeS || (bytesread==0) ) ::close( newsockfd ); //Parse message if (isTcpSocket() ) { QString s; while( !fullmessage.isEmpty() ) { contentLength = 0; if( fullmessage.contains( lSearch ) > 0 ) { if( fullmessage.find( lSearch ) < fullmessage.find( QString( "\r\n\r\n" ) ) ) { s = fullmessage.mid( fullmessage.find( lSearch ) + lLen ); s = s.left( s.find( '\r' ) ); contentLength = s.toInt(); } } s = fullmessage.left( fullmessage.find( QString( "\r\n\r\n" ) ) + 4 + contentLength ); parseMessage( s ); fullmessage.remove( 0, s.length() ); } } else { parseMessage( fullmessage ); }}void SipClient::parseMessage( QString fullmessage ){ if(debug >0) printf( "\n=====SipClient >>>>>Received: "); if( ( debug == 1) || (debug >= 3) ) { printf( " %s.%03d len=%d", QTime::currentTime().toString().latin1(), QTime::currentTime().msec(), fullmessage.length()); printf( "\n%s",fullmessage.latin1() ); } if(fullmessage.length() <=4) { //T ONLINE sends such stuff! return; } SipMessage *curmessage = new SipMessage( fullmessage); if( !curmessage->isValid() ) { delete curmessage; if( debug>0 ) printf( "=====SipClient >>>>>this is not valid\n"); return; } QString body = curmessage->messageBody(); if( debug>0 ) printf( "=====SipClient >>>>>this is valid\n"); if( testOn ) { incomingTestMessage(); delete curmessage; return; } QString callid = curmessage->getHeaderData( SipHeader::Call_ID ); // Grab address in To: header SipUri touri( curmessage->getHeaderData( SipHeader::To ) ); // Grab address in From: header SipUri fromuri( curmessage->getHeaderData( SipHeader::From ) ); if( curmessage->getStatus().getCode() == 487 ) { sendAck( curmessage ); delete curmessage; return; } QString cseq = curmessage->getHeaderData( SipHeader::CSeq ); if( curmessage->getMethod() == Sip::MESSAGE ) { if( callid == messageCID && cseq == messageCSeq ) { if(debug>0) printf( "=====SipClient: Received what was likely a retransmission, badly ignoring...\n" ); delete curmessage; return; }// printf( "=====-----------------SipClient: message\n" ); messageCID = callid; messageCSeq = cseq; sendQuickResponse( curmessage, SipStatus( 200 ) ); incomingInstantMessage( curmessage ); delete curmessage; return; } if( curmessage->getMethod() == Sip::INFO ) { sendQuickResponse( curmessage, SipStatus( 200 ) ); } if( curmessage->getMethod() == Sip::SUBSCRIBE ) { if ( fullmessage.contains("Event: presence.winfo") || fullmessage.contains("Event: presence.presencelist") ) { if(debug>0) printf( "=====SipClient: We dont support this\n" ); delete curmessage; return; } if( callid == subscribeCID && cseq == subscribeCSeq ) { if(debug>0) printf( "=====SipClient: Received what was likely a retransmission, badly ignoring...\n" ); delete curmessage; return; } subscribeCID = callid; subscribeCSeq = cseq; bool found = false; for( SipCall *curcall = calls.first(); curcall != 0; curcall = calls.next() ) { if( callid == curcall->getCallId() && curcall->getCallType() == SipCall::inSubscribeCall ) { curcall->incomingMessage( curmessage ); QString expires = curmessage->getHeaderData( SipHeader::Expires ); SipUri incominguri( curmessage->getHeaderData( SipHeader::From ) ); if( curcall->getMember( incominguri ) ) { if( expires == "0" ) { curcall->setCallStatus( SipCall::callUnconnected ); incomingSubscribe( 0, false ); delete curcall; for( SipCall *c = calls.first(); c != 0; c = calls.next() ) { if( c->getCallType() == SipCall::outSubscribeCall ) { if( c->getMember( incominguri ) ) { if( c->getCallStatus() != SipCall::callDead ) { c->setCallStatus( SipCall::callUnconnected ); } } } } } else { curcall->getMember( incominguri )->timerStart( expires.toInt() * 1000 ); curcall->setCallStatus( SipCall::callInProgress ); incomingSubscribe( curcall->getMember( incominguri ), false ); } 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 ) { 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 { if(debug>0) 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 ) { if(debug>0) printf( "=====SipClient: No call found for incoming response. Dropping.\n" ); delete curmessage; return; } // Check method if( curmessage->getMethod() == Sip::ACK ) { if(debug>0) printf( "=====SipClient: ACK received, but nobody was listening. Dropping.\n" ); delete curmessage; return; } if( curmessage->getMethod() == Sip::CANCEL ) { if(debug>0) 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 ) { if(debug>0) 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 ) { if(debug>0) 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 ) { if(debug>0) printf( "=====SipClient:Not Implemented, Returning a 501.\n" ); sendQuickResponse( curmessage, SipStatus( 501 ) ); delete curmessage; return; } if( curmessage->getMethod() == Sip::PUBLISH ) { if(debug>0) printf( "=====SipClient:Not Implemented, Returning a 501.\n" ); sendQuickResponse( curmessage, SipStatus( 501 ) ); delete curmessage; return; } if( curmessage->getMethod() == Sip::BadMethod ) { if(debug>0) 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 ) { QString app = curmessage->getHeaderData( SipHeader::Accept ).lower(); if( !(app.contains( "application/xpidf+xml" ) || app.contains( "application/pidf+xml") ) ) { sendQuickResponse( curmessage, SipStatus( 406 ) ); delete curmessage; return; } } } if( curmessage->hasHeader( SipHeader::Require ) && curmessage->getHeaderData( SipHeader::Require ) != QString::null ) { if(debug>0) 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 if( curmessage->getMethod() == Sip::OPTIONS ) { SipCall *newcall = new SipCall( user, curmessage->getHeaderData( SipHeader::Call_ID ) ); newcall->incomingMessage( curmessage ); return; } if(debug>0) 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(); newcall->setRemoteStart(false); //Remotestart will be detected later if( body.contains( "m=audio" ) ) { newcall->setCallType( SipCall::StandardCall ); if( body.contains( "m=video" ) ) { newcall->setCallType( SipCall::auviCall ); } } else if( body.contains( "m=video" ) ) { newcall->setCallType( SipCall::videoCall ); } else if( body.contains( "m=application" ) ) { newcall->setCallType( SipCall::GarKeinCall );//preliminary, will be correctet in KCallWidget:switchCalls } 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/pidf+xml" ); } if( msg->getMethod() == Sip::NOTIFY ) { msg->insertHeader( SipHeader::Event, "presence" ); } // NOTIFY for REFER triggered actions if( msg->getMethod() == Sip::RNOTIFY ) { msg->insertHeader( SipHeader::Event, "refer" ); } // 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 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -