⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sipclient.cpp

📁 KphoneSI (kpsi) is a SIP (Session Initiation Protocol) user agent for Linux, with which you can in
💻 CPP
📖 第 1 页 / 共 4 页
字号:
		}					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 &regProxy, 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 + -