我正在Eclipse中开发sip客户端应用程序。我可以注册并生成呼叫。 使用INVITE请求生成呼叫。我正在使用linphone接听电话。但是当我接到电话时,没有声音。在Asterisk服务器中,我可以看到RTP数据包。当我通过linphone应答时,我从服务器获取以下信息:
v=0
o=root 1674073465 1674073465 IN IP4 xx.xx.xx.xx
s=Asterisk PBX 16.7.0
c=IN IP4 xx.xx.xx.xx
b=CT:384
t=0 0
m=audio 13472 RTP/AVP 0 8 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=maxptime:150
a=sendrecv
m=video 16180 RTP/AVP 34 103 100 108
a=rtpmap:34 H263/90000
a=rtpmap:103 h263-1998/90000
a=rtpmap:100 VP8/90000
a=rtcp-fb:* ccm fir
a=rtpmap:108 VP9/90000
a=sendrecv
我的代码如下:
public class SipInit implements SipListener {
private String ip;
private SipFactory sipFactory;
private Properties properties;
private SipStack sipStack;
@SuppressWarnings("unused")
private MessageFactory messageFactory;
private HeaderFactory headerFactory;
private AddressFactory addressFactory;
private ListeningPoint listeningPoint;
private int port;
private String protocol;
private SipProvider sipProvider;
private String username1;
private String username2;
private Address contactAddress;
@SuppressWarnings("unused")
private ContactHeader contactHeader;
private String server;
private char[] tag;
private Request request;
private String password;
private ClientTransaction inviteTid;
private Dialog dialog;
private Response resp;
private final String Tag="abcd";
private ResponseEvent event;
private SipStackExt sipStackExt;
private int callCtr=0;
private Request rqst;
//private SipProvider udp;
int cseq = 0;
public void init() throws ParseException {
try {
// Get the local IP address.
this.ip = "192.168.0.2";//InetAddress.getLocalHost().getHostAddress();
//this.tag=" ".toCharArray();
// Create the SIP factory and set the path name.
this.sipFactory = SipFactory.getInstance();
this.port=5060;
this.protocol="udp";
this.server="xx.xx.xx.xx";
this.username1="Santanu";
this.username2="Arijit";
this.password="voip123";
this.sipFactory.setPathName("gov.nist");
// Create and set the SIP stack properties.
this.properties = new Properties();
this.properties.setProperty("javax.sip.STACK_NAME", "stack");
this.properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32");
this.properties.setProperty(
"gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true");
this.properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",
"mss-jsip-debuglog.txt");
this.properties.setProperty("gov.nist.javax.sip.SERVER_LOG",
"mss-jsip-messages.xml");
// Create the SIP stack.
this.sipStack = this.sipFactory.createSipStack(this.properties);
// Create the SIP message factory.
this.sipStackExt = (SipStackExt) this.sipFactory.createSipStack(properties);
this.messageFactory = this.sipFactory.createMessageFactory();
// Create the SIP header factory.
this.headerFactory = this.sipFactory.createHeaderFactory();
// Create the SIP address factory.
this.addressFactory = this.sipFactory.createAddressFactory();
// Create the SIP listening point and bind it to the local IP
// address, port and protocol.
this.listeningPoint = this.sipStack.createListeningPoint(this.ip,
6666, this.protocol);
// Create the SIP provider.
this.sipProvider = this.sipStack
.createSipProvider(this.listeningPoint);
// Add our application as a SIP listener.
this.sipProvider.addSipListener(this);
// Create the contact address used for all SIP messages.
this.contactAddress = this.addressFactory.createAddress("sip:" + this.username1 + "@"
+ this.ip + ":6666;transport=udp");
// Create the contact header used for all SIP messages.
this.contactHeader = this.headerFactory
.createContactHeader(contactAddress);
// Display the local IP address and port in the text area.
} catch (Exception e) {
e.printStackTrace();
// If an error occurs, display an error message box and exit.
System.exit(-1);
}
//r.setStatusCode(200);
register();
}
public void register() throws NullPointerException{
Object logger;
try {
cseq++;
if(resp == null) {
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
ViaHeader viaHeader = this.headerFactory.createViaHeader(this.ip,
this.port, "udp", "abcd");
viaHeaders.add(viaHeader);
AllowHeader allow=this.headerFactory.createAllowHeader("INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH,MESSAGE");
// The "Max-Forwards" header.
MaxForwardsHeader maxForwardsHeader = this.headerFactory
.createMaxForwardsHeader(70);
// The "Call-Id" header.
CallIdHeader callIdHeader = this.sipProvider.getNewCallId();
// The "CSeq" header.
@SuppressWarnings("deprecation")
CSeqHeader cSeqHeader = this.headerFactory.createCSeqHeader(cseq,
"REGISTER");
Address fromAddress = addressFactory.createAddress("sip:"
+ username1 + '@' + server);
FromHeader fromHeader = this.headerFactory.createFromHeader(
fromAddress, "textClient");//String.valueOf(this.tag)//Integer.toString(hashCode())
Address toAddress = addressFactory.createAddress("sip:"
+ username1 + '@' + server);
// The "To" header.
ToHeader toHeader = this.headerFactory.createToHeader(
toAddress, null);
//ToHeader toHeader = this.headerFactory.createToHeader(fromAddress,
//null);
// this.contactHeader = this.headerFactory
// .createContactHeader(contactAddress);
/*ContentLengthHeader contentLength = this.headerFactory.createContentLengthHeader(300);
ContentTypeHeader contentType = this.headerFactory.createContentTypeHeader("application", "sdp");
String sdpData = "v=0\n" +
"o=user1 392867480 292042336 IN IP4 xx.xx.xx.xx\n" +
"s=-\n" +
"c=IN IP4 xx.xx.xx.xx\n" +
"t=0 0\n" +
"m=audio 8000 RTP/AVP 0 8 101\n" +
"a=rtpmap:0 PCMU/8000\n" +
"a=rtpmap:8 PCMA/8000\n" +
"a=rtpmap:101 telephone-event/8000\n" +
"a=sendrecv";
byte[] contents = sdpData.getBytes();
this.contactHeader = this.headerFactory.createContactHeader(contactAddress);*/
request = this.messageFactory.createRequest("REGISTER sip:"
+ server + " SIP/2.0\r\n\r\n");
request.addHeader(viaHeader);
request.addHeader(maxForwardsHeader);
request.addHeader(fromHeader);
request.addHeader(toHeader);
request.addHeader(callIdHeader);
request.addHeader(cSeqHeader);
request.addHeader(allow);
request.addHeader(contactHeader);
/*URI requestURI = addressFactory.createURI("sip:" + server);
Request request = messageFactory.createRequest(requestURI,
Request.REGISTER, callIdHeader, cSeqHeader, fromHeader,
toHeader, viaHeaders, maxForwardsHeader);
request.addHeader(contactHeader);*/
/*Request request = messageFactory.createRequest(requestURI,
Request.REGISTER, callIdHeader, cSeqHeader, fromHeader,
toHeader, viaHeaders, maxForwardsHeader);*/
//Response response=this.messageFactory.createResponse(200, request);
HeaderFactory header=this.sipFactory.createHeaderFactory();
ExpiresHeader eh = header.createExpiresHeader(3060);
request.addHeader(eh);
}
if (resp != null) {
boolean retry = true;
request = this.messageFactory.createRequest("REGISTER sip:"
+ server + " SIP/2.0\r\n\r\n");
CSeqHeader cSeqHeader = this.headerFactory.createCSeqHeader(cseq,
"REGISTER");
Address toAddress = addressFactory.createAddress("sip:"
+ username1 + '@' + server);
ToHeader toHeader = this.headerFactory.createToHeader(
toAddress, null);
CallIdHeader callIdHeader = this.sipProvider.getNewCallId();
Address fromAddress = addressFactory.createAddress("sip:"
+ username1 + '@' + server);
FromHeader fromHeader = this.headerFactory.createFromHeader(
fromAddress, "textClient");
MaxForwardsHeader maxForwardsHeader = this.headerFactory
.createMaxForwardsHeader(70);
request.addHeader(cSeqHeader);
request.addHeader(toHeader);
request.addHeader(callIdHeader);
request.addHeader(fromHeader);
request.addHeader(maxForwardsHeader);
ClientTransaction tid = event.getClientTransaction();
AccountManagerImpl manager = new AccountManagerImpl();
HeaderFactory header=this.headerFactory;
AuthenticationHelper helper = sipStackExt.getAuthenticationHelper(manager, header);
ClientTransaction transaction = helper.handleChallenge(resp, tid, this.sipProvider, 5);
transaction.sendRequest();
System.out.println(""+ request);
//AuthorizationHeader authHeader = makeAuthHeader(headerFactory, resp,
//request, username1, password);
//request.addHeader(authHeader);
}
if(resp==null) {
System.out.println(""+ request);
inviteTid = sipProvider.getNewClientTransaction(request);
// send the request out.
inviteTid.sendRequest();
this.dialog = inviteTid.getDialog();
}
// Send the request statelessly through the SIP provider.
// this.sipProvider.sendRequest(请求);
// Display the message in the text area.
//debug("Request sent:\n" + request.toString() + "\n\n");
} catch (Exception e) {
// If an error occurred, display the error.
e.printStackTrace();
//debug("Request sent failed: " + e.getMessage() + "\n");
}
}
public void sendMessage()
{
try
{
cseq++;
callCtr++;
if(callCtr==1) {
sendACK();
request = this.messageFactory.createRequest("INVITE sip:852@"
+ server + " SIP/2.0\r\n\r\n");
CSeqHeader cSeqHeader = this.headerFactory.createCSeqHeader(cseq,
"INVITE");
Address toAddress = addressFactory.createAddress("sip:"
+ username2 + '@' + server);
ToHeader toHeader = this.headerFactory.createToHeader(
toAddress, null);
CallIdHeader callIdHeader = this.sipProvider.getNewCallId();
Address fromAddress = addressFactory.createAddress("sip:"
+ username1 + '@' + server);
FromHeader fromHeader = this.headerFactory.createFromHeader(
fromAddress, "textClient");
MaxForwardsHeader maxForwardsHeader = this.headerFactory
.createMaxForwardsHeader(70);
request.addHeader(cSeqHeader);
request.addHeader(toHeader);
request.addHeader(callIdHeader);
request.addHeader(fromHeader);
request.addHeader(maxForwardsHeader);
request.addHeader(contactHeader);
inviteTid = sipProvider.getNewClientTransaction(request);
// send the request out.
inviteTid.sendRequest();
}
}catch(Exception ex)
{
ex.printStackTrace();
}
}
@Override
public void processDialogTerminated(DialogTerminatedEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void processIOException(IOExceptionEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void processRequest(RequestEvent arg0) {
// TODO Auto-generated method stub
System.out.println(""+ arg0.getRequest());
//sendMessage();
//register();
rqst=arg0.getRequest();
Response myResponse=resp;
String method=rqst.getMethod();
try {
if(method.equals("OPTIONS")) {
ServerTransaction myServerTransaction = this.sipProvider.getNewServerTransaction(rqst);
myResponse=this.messageFactory.createResponse(200,rqst);
myResponse.addHeader(this.contactHeader);
myServerTransaction.sendResponse(myResponse);
sendMessage();
}
}catch(Exception ex) {
ex.printStackTrace();
}
}
public void sendACK()
{
try
{
ServerTransaction myServerTransaction = this.sipProvider.getNewServerTransaction(rqst);
resp=this.messageFactory.createResponse(200,rqst);
resp.addHeader(this.contactHeader);
myServerTransaction.sendResponse(resp);
}
catch(Exception ex)
{
}
}
@Override
public void processResponse(ResponseEvent arg0) {
// TODO Auto-generated method stub
event=arg0;
resp=arg0.getResponse();
//CSeqHeader cseq = (CSeqHeader) resp.getHeader(CSeqHeader.NAME);
if(resp.getStatusCode()==401)
{
ClientTransaction tid = event.getClientTransaction();
AccountManagerImpl manager = new AccountManagerImpl();
HeaderFactory header=this.headerFactory;
AuthenticationHelper helper = sipStackExt.getAuthenticationHelper(manager, header);
ClientTransaction transaction=null;
try {
transaction = helper.handleChallenge(resp, tid, this.sipProvider, 5);
} catch (NullPointerException | SipException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
transaction.sendRequest();
} catch (SipException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(""+ request);
}
else
System.out.println(resp);
}
@Override
public void processTimeout(TimeoutEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void processTransactionTerminated(TransactionTerminatedEvent arg0) {
// TODO Auto-generated method stub
}
private AuthorizationHeader makeAuthHeader(HeaderFactory headerFactory2, Response response, Request request, String username2,
String password2) throws ParseException {
// TODO Auto-generated method stub
// Authenticate header with challenge we need to reply to
WWWAuthenticateHeader ah_c = (WWWAuthenticateHeader)response.getHeader(WWWAuthenticateHeader.NAME);
// Authorization header we will build with response to challenge
AuthorizationHeader ah_r = headerFactory.createAuthorizationHeader(ah_c.getScheme());
// assemble data we need to create response string
URI request_uri = request.getRequestURI();
String request_method = request.getMethod();
String nonce = ah_c.getNonce();
String algrm = ah_c.getAlgorithm();
String realm = ah_c.getRealm();
MessageDigest mdigest;
try {
mdigest = MessageDigest.getInstance(algrm);
// A1
String A1 = username2 + ":" + realm + ":" + password2;//
String HA1 = toHexString(mdigest.digest(A1.getBytes()));
// A2
String A2 = request_method.toUpperCase() + ":" + request_uri ;
String HA2 = toHexString(mdigest.digest(A2.getBytes()));
// KD
String KD = HA1 + ":" + nonce + ":" + HA2;
String responsenew = toHexString(mdigest.digest(KD.getBytes()));
ah_r.setUsername(username2);
ah_r.setRealm(realm);
ah_r.setNonce(nonce);
ah_r.setURI(request_uri);
ah_r.setAlgorithm(algrm);
ah_r.setResponse(responsenew);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return ah_r;
}
private static final char[] toHex = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
static String toHexString(byte b[]) {
int pos = 0;
char[] c = new char[b.length * 2];
for (int i = 0; i < b.length; i++) {
c[pos++] = toHex[(b[i] >> 4) & 0x0F];
c[pos++] = toHex[b[i] & 0x0f];
}
return new String(c);
}
private class AccountManagerImpl implements AccountManager {
@Override
public UserCredentials getCredentials(ClientTransaction clientTransaction, String s) {
return new UserCredentials() {
@Override
public String getUserName() { return username1; }
@Override
public String getPassword() { return password; }
@Override
public String getSipDomain() { return "asterisk"; }
};
}
}
}
我做错什么了吗?请指教。