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

📄 sipclient.cpp

📁 kphone-4.2,SHELL协议的VOIP电话
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	}}void SipClient::addCall( SipCall *call ){	if( !calls.contains( call ) ) {		calls.append( call );	}	callListUpdated();}void SipClient::callTypeUpdated( void ){	callListUpdated();}void SipClient::deleteCall( SipCall *call ){	calls.remove( call );	callListUpdated();}void SipClient::setExplicitProxyMode( bool eproxy ){	useExplicitProxy = eproxy;}void SipClient::setExplicitProxyAddress( const QString &newproxy ){	if( newproxy.contains( ':' ) ) {		proxy = newproxy.left( newproxy.find( ':' ) );		proxyport = newproxy.mid( newproxy.find( ':' ) + 1 ).toUInt();	} else {		proxy = newproxy;		proxyport = 5060;	}}QString SipClient::getExplicitProxyAddress( void ){	QString uri = "<sip:" + proxy;	if( proxyport != 5060 ) {		uri += ":" + QString::number( proxyport, 10 );	}	uri += ";lr>";	return uri;}void SipClient::setUser( SipUser *u ){	user = u;}void SipClient::sendQuickResponse( SipMessage *origmessage, const SipStatus &status,	const QString &body, const MimeContentType &bodytype ){	MessageSocket *outsocket = 0;	SipMessage *msg = new SipMessage;	SipVia topvia;	QString sendaddr;	msg->setType( SipMessage::Response );	msg->setStatus( status );	// Copy via list exactly	msg->setViaList( origmessage->getViaList() );	msg->insertHeader( SipHeader::From, origmessage->getHeaderData( SipHeader::From ) );	msg->insertHeader( SipHeader::To, origmessage->getHeaderData( SipHeader::To ) );	msg->insertHeader( SipHeader::CSeq, origmessage->getHeaderData( SipHeader::CSeq ) );	msg->insertHeader( SipHeader::Call_ID, origmessage->getHeaderData( SipHeader::Call_ID ) );	if( origmessage->hasHeader( SipHeader::Require ) ) {		msg->insertHeader( SipHeader::Unsupported, origmessage->getHeaderData( SipHeader::Require ) );	}	if( ( status.getCode() >= 300 ) && ( status.getCode() < 400 ) ) {		msg->getContactList().addToHead( forwarduri );	}	if( status.getCode() == 501 ) {		msg->insertHeader( SipHeader::Allow,			"INVITE, OPTIONS, ACK, BYE, MSG, CANCEL, MESSAGE, SUBSCRIBE, NOTIFY, INFO, REFER" );	}	if( bodytype != MimeContentType::null ) {		msg->insertHeader( SipHeader::Content_Type, bodytype.type() );	}	msg->setBody( body );	// Calculate content length	msg->insertHeader( SipHeader::Content_Length, QString::number( msg->messageBody().utf8().length() ) );	// Advertise shamelessly	msg->insertHeader( SipHeader::User_Agent, getUserAgent() );	// 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 is bad, no use sending	if( !outsocket ) {		delete msg;		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	printf( "SipClient: Sending to '%s' port %d\n",			sendaddr.latin1(), topvia.getPortNumber() );	if( !outsocket->setHostname( sendaddr.utf8().data() ) ) {		delete msg;		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;	}	delete msg;}void SipClient::sendTestMessage( QString sendaddr, unsigned int port, QString msg ){	MessageSocket *outsocket = 0;	if (symmetricmode) {		outsocket = &listener;	} else {		outsocket = new UDPMessageSocket;	}	outsocket->setHostname( sendaddr.utf8().data() );	outsocket->connect( port );	// Announce what we're sending	if( traceMessageSending ) {		printf( "\nSipClient: Sending: %s.%03d\n--------------------------------\n%s\n",			QTime::currentTime().toString().latin1(), QTime::currentTime().msec(),			msg.data() );	}	// Send it	outsocket->send( msg.utf8().data(), msg.utf8().length() );	if (outsocket != &listener) {		delete outsocket;	}}void SipClient::sendAck( SipMessage *origmessage ){	SipMessage *msg = new SipMessage;	msg->setType( SipMessage::Request );	msg->setMethod( Sip::ACK );	QString s = origmessage->getHeaderData( SipHeader::CSeq );	s = s.left( s.find( ' ' ) );	s = s	+ " " + Sip::getMethodString( msg->getMethod() );	msg->insertHeader( SipHeader::CSeq, s );	msg->setRequestUri( SipUri( origmessage->getHeaderData( SipHeader::To ) ) );	msg->insertHeader( SipHeader::From, origmessage->getHeaderData( SipHeader::From ) );	msg->insertHeader( SipHeader::To, origmessage->getHeaderData( SipHeader::To ) );	msg->insertHeader( SipHeader::Call_ID, origmessage->getHeaderData( SipHeader::Call_ID ) );	// We need the correct branch parameter	QString branch = origmessage->getViaList().getBottommostVia().getBranchParam();	sendRequest( msg, true, SipUri::null, branch );	delete msg;}void SipClient::setHideViaMode( HideViaMode newmode ){	hidemode = newmode;}void SipClient::setCallForward( bool onoff ){	fwmode = onoff;}void SipClient::setCallForwardUri( const SipUri &u ){	forwarduri = u;}void SipClient::setCallForwardMessage( const QString &newmessage ){	fwbody = newmessage;}const QString SipClient::getUserAgent( void ){	return "kphone/4.2";}void SipClient::setMaxForwards( int newmax ){	maxforwards = newmax;}void SipClient::setBusy( bool onoff ){	busymode = onoff;}void SipClient::setBusyMessage( const QString &newmessage ){	busybody = newmessage;}SipUser *SipClient::getUser( SipUri uri ){	if( uri == user->getUri() ) {		return user;	} else {		return NULL;	}}void SipClient::updateIdentity( SipUser *u, QString newproxy ){	user = u;	setupContactUri( user );	if( newproxy.isEmpty() || newproxy.lower() == "sip:") {		setExplicitProxyMode( false );	} else {		if( newproxy.left( 4 ).lower() == "sip:" ) {			newproxy.remove( 0, 4 );		}		setExplicitProxyMode( true );		setExplicitProxyAddress( newproxy );	}}void SipClient::sendStunRequest( QString uristr ){	if( !uristr.isEmpty() ) {		useStunProxy = true;		stunProxy = SipUri( uristr );	}	if( useStunProxy ) {		if( !listener.setHostname( stunProxy.getHostname() ) ) { return; }		listener.connect( stunProxy.getPortNumber() );		printf( "SipClient: STUN request\n" );		StunRequestSimple req;		req.msgHdr.msgType = htons(BindRequestMsg);		req.msgHdr.msgLength = htons( sizeof(StunRequestSimple)-sizeof(StunMsgHdr) );		for ( int i=0; i<16; i++ ) {			req.msgHdr.id.octet[i]=0;		}		int id = rand();		req.msgHdr.id.octet[0] = id;		req.msgHdr.id.octet[1] = id>>8;		req.msgHdr.id.octet[2] = id>>16;		req.msgHdr.id.octet[3] = id>>24;		listener.send( (char *)&req, sizeof( req ) );	}}QString SipClient::getSipProxySrv( QString dname ){	if( sipProxyName == dname ) {		return sipProxySrv;	}	QString srv;	QString naptr = getNAPTR( dname );	if( !naptr.isEmpty() ) {		srv = getSRV( naptr );	} else {		srv = getSRV( QString( "_sip._udp." ) + dname );	}	if( !srv.isEmpty() ) {		sipProxyName = dname;		sipProxySrv = srv;		return sipProxySrv;	} else {		return dname;	}}QString SipClient::getResSearch( QString dname, int type, bool UDP ){	unsigned char msg[PACKETSZ],*mptr,*xptr;	int i,j,l,co;	unsigned short *usp,ty;	unsigned int *uip;	res_response *res;	char name[PACKETSZ];	QString tmpName;	QString domainName = "";	u_short priority = 0;	u_short weight = 0;	u_short port = 5060;	if(res_init()==-1){		printf("res_init -error !\n");	}	else if((l=res_search( dname, C_IN, type, msg, sizeof( msg ) ) ) == -1 ) {		printf( "res_search: NO result !\n" );	} else if( l <= 0 ){		printf( "res_search: result is empty !\n" );	} else {		printf( "res_search OK (len=%d)\n", l );		res = (res_response *)msg;		mptr = msg + sizeof( HEADER );		co = ntohs( res->header.qdcount );		for( i=0; i < co; i++ ) {			j = dn_expand( msg, msg + PACKETSZ, mptr, name, MAXDNAME );			if( j < 0 ) {				break;			} else {				mptr += j;				usp = (unsigned short *)mptr;				mptr += sizeof( short );				usp = (unsigned short *)mptr;				mptr += sizeof( short );			}		}		co = ntohs( res->header.ancount );		for( i = 0 ; i < co; i++ ) {			j = dn_expand( msg, msg + PACKETSZ, mptr, name, MAXDNAME );			if( j < 0 ) {				printf( "\t\tname-error\n" );				break;			} else {				mptr += j;				usp = (unsigned short *)mptr;				ty = ntohs( *usp );				mptr += sizeof( short );				usp = (unsigned short *)mptr;				mptr += sizeof(short);				uip = (unsigned int *)mptr;				mptr += sizeof(int);				uip = (unsigned int *)mptr;				j = ntohs( *uip );				mptr += sizeof(short);				xptr = mptr;				mptr += j;				if( ty == T_NAPTR ) {					usp = (unsigned short *)xptr;					xptr += sizeof(short);					usp = (unsigned short *)xptr;					xptr += sizeof(short);					j = (int)(*xptr);					xptr += 1;					while( j > 0 ) {						xptr+=1;						j--;					}					j = (int)(*xptr);					xptr += 1;					while( j > 0 ) {						xptr += 1;						j--;					}					j=(int)(*xptr);					xptr+=1;					while( j > 0 ) {						xptr += 1;						j--;					}					j = dn_expand( msg, msg + PACKETSZ, xptr, name, MAXDNAME );					if( j < 0 ) {						break;					} else {						tmpName = QString( name );						if( UDP ) {							if( tmpName.contains( "_udp" ) ) {								domainName = QString( name );							}						} else {							if( tmpName.contains( "_tcp" ) ) {								domainName = QString( name );							}						}						printf("NAPTR: %s\n",name);						xptr+=j;					}				} else if( ty == T_SRV ) {					u_short pr;					u_short we;					u_short po;					usp = (unsigned short *)xptr;					pr = ntohs( *usp );					xptr += sizeof( short );					usp = (unsigned short *)xptr;					we = ntohs( *usp );					xptr += sizeof( short );					usp = (unsigned short *)xptr;					po = ntohs( *usp );					xptr += sizeof( short );					j = dn_expand( msg, msg + PACKETSZ, xptr, name, MAXDNAME );					if( j < 0 ) {						break;					} else {						if( !priority || pr < priority ||						    (pr == priority && we < weight) ) {							priority = pr;							weight = we;							port = po;							printf("SRV: %d,%d,%d\n",priority,weight,port);							domainName = QString( name ) +								":" + QString::number( port );							printf("SRV: %s\n",name);							xptr+=j;						}					}				} else {				}			}		}		co = ntohs( res->header.nscount );		co = ntohs( res->header.arcount );	}	return domainName;}QString SipClient::getNAPTR( QString strUri ){	return getResSearch( strUri, T_NAPTR, true );}QString SipClient::getSRV( QString naptr ){	return getResSearch( naptr, T_SRV, true );}void SipClient::callMemberUpdated( void ){	callListUpdated();}void SipClient::printStatus(){	for( SipCall *curcall = calls.first(); curcall != 0; curcall = calls.next() ) {		// call type		printf("\nSipClient:printStatus: CallType = ");		switch ( curcall->getCallType()) {			case SipCall::StandardCall:				printf("StandardCall");			break;			case SipCall::videoCall:				printf("videoCall");			break;			case SipCall::OptionsCall:				printf("OptionsCall");			break;			case SipCall::RegisterCall:				printf("RegisterCall");			break;			case SipCall::MsgCall:				printf("MsgCall");			break;			case SipCall::BrokenCall:				printf("BrokenCall");			break;			case SipCall::UnknownCall:				printf("UnknownCall");			break;			case SipCall::outSubscribeCall:				printf("outSubscribeCall");			break;			case SipCall::inSubscribeCall:				printf("inSubscribeCall");			break;			case SipCall::inSubscribeCall_2:				printf("inSubscribeCall_2");			break;			default:				printf("error - undefined call");			break;		}		//call id		printf("\n  CallId = %s", curcall->getCallId().ascii());		//call status		printf("\n  CallStatus = ");		switch ( curcall->getCallStatus()) {			case SipCall::callUnconnected:				printf("callUnconnected");			break;			case SipCall::callInProgress:				printf("callInProgress");			break;			case SipCall::callDead:				printf("callDead");			break;			default:				printf("error - undefined callState");			break;		}		//call members		SipCallMemberIterator it(curcall->getMemberList());		for (it.toFirst(); it.current(); ++it) {			//call member Uri			printf("\n  CallMember: reqUri = %s", it.current()->getUri().reqUri().ascii());			//call member status			printf("\n    CallMemberState = ");			switch ( it.current()->getState()) {				case SipCallMember::state_Idle:					printf(" Idle");				break;				case SipCallMember::state_EarlyDialog:					printf(" EarlyDialog");				break;				case SipCallMember::state_Connected:					printf(" Connected");				break;				case SipCallMember::state_Disconnected:					printf(" Disconnected");				break;				case SipCallMember::state_InviteRequested:					printf(" InviteRequested");				break;				case SipCallMember::state_RequestingInvite:					printf(" RequestingInvite");				break;				case SipCallMember::state_RequestingReInvite:					printf(" RequestingReInvite");				break;				case SipCallMember::state_Redirected:					printf(" Redirected");				break;				case SipCallMember::state_Disconnecting:					printf(" Disconnecting");				break;				case SipCallMember::state_CancelPending:					printf(" CancelPending");				break;				default:					printf("error - undefined callMemberState");				break;			}		}	}	printf("\n");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -