📄 sipclient.cpp
字号:
}}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 + -