Openfire集成Sip服务器

来源:互联网 发布:淘宝实拍保护怎么申请 编辑:程序博客网 时间:2024/06/13 22:49

一、OpenfireSip插件

Openfire的插件里面,有一个Sip插件,但是该Sip插件不是一个Sip服务器,只是一个Sip客户端,下面主要介绍如何在Openfire上集成一个简单的Sip服务器插件。

 

二、该简单的Sip服务器有如下功能

1、遵守Sip标准协议

2、标准Sip客户端能够注册该Sip服务器

3、能够完成一次完整的呼叫流程和挂断流程

4、能够对用户进行管理以及用户的在线状态进行管理(未呈现,用心跳检测和线程处理)

5、基于SipJava开发包(JainSipApi.jarJainSipRi.jarconcurrent.jarlog4j.jar

 

三、注册、呼叫、挂断流程


注册信息 = REGISTER sip:SIPServer@172.16.7.85:8888 SIP/2.0

Via: SIP/2.0/UDP 172.16.10.51:5060;rport=5060;branch=z9hG4bK-524287-1---4c518269a1efa15b;received=172.16.10.51

Max-Forwards: 70

Contact: <sip:test@172.16.10.51:5060;rinstance=d683c6b6819cc373>

To: <sip:test@172.16.10.51>

From: <sip:test@172.16.10.51>;tag=59501018

Call-ID: KcEz2oIKiX7gTRccriDi5w..

CSeq: 1 REGISTER

Expires: 3600

Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,UPDATE,REGISTER,INFO,MESSAGE,SUBSCRIBE,NOTIFY,PUBLISH,REFER

Supported: resource-priority,timer

User-Agent: xt_sip/1.0

Channel: type=satellite/fixed;delay=100;packetloss=5;mtu=1500;bandwidth=2048

Content-Length: 0

 

回复200OK : SIP/2.0 200 OK

Via: SIP/2.0/UDP 172.16.10.51:5060;rport=5060;branch=z9hG4bK-524287-1---55994f7fd27ea93b;received=172.16.10.51

To: <sip:test@172.16.10.51>

From: <sip:test@172.16.10.51>;tag=59501018

Call-ID: KcEz2oIKiX7gTRccriDi5w..

CSeq: 32 REGISTER

Content-Length: 0



收到呼叫请求

收到的呼叫请求:INVITE sip:YPSQ06720040@172.16.7.85:8888 SIP/2.0

Via: SIP/2.0/UDP 172.16.10.51:5060;rport=5060;branch=z9hG4bK-524287-1---b92653756e52b813;received=172.16.10.51

Max-Forwards: 70

Contact: <sip:test@172.16.10.51:5060>

To: <sip:YPSQ06720040@172.16.7.85:8888>

From: <sip:test@172.16.10.51>;tag=4862ae20

Call-ID: Gd_5NlNEurlhgtCXTweqAA..

CSeq: 1 INVITE

Session-Expires: 1800

Min-SE: 90

Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,UPDATE,REGISTER,INFO,MESSAGE,SUBSCRIBE,NOTIFY,PUBLISH,REFER

Content-Type: application/sdp

Supported: resource-priority,timer

User-Agent: xt_sip/1.0

Content-Length: 368

 

v=0

o=userName 1 1 IN IP4 172.16.10.51

s=Play

i=2?videoCodecType=H.264

c=IN IP4 172.16.10.51

b=AS:1024

t=0 0

m=video 40000 RTP/AVP 96 97

c=IN IP4 172.16.10.51

a=rtpmap:96 H264/90000

a=rtpmap:97 H265/90000

a=control:track1

a=recvonly

m=audio 40002 RTP/AVP 100 100

c=IN IP4 172.16.10.51

a=rtpmap:100 MPEG4-GENERIC/8000

a=rtpmap:100 PCMA/8000

a=control:track2

a=recvonly

 

contact = sip:YPSQ06720040@172.16.10.190:5060;rinstance=41b242381416fe37

转发呼叫请求:INVITE sip:YPSQ06720040@172.16.10.190:5060;rinstance=41b242381416fe37 SIP/2.0

Max-Forwards: 70

To: <sip:YPSQ06720040@172.16.7.85:8888>

From: <sip:test@172.16.10.51>;tag=4862ae20

Call-ID: Gd_5NlNEurlhgtCXTweqAA..

CSeq: 1 INVITE

Session-Expires: 1800

Min-SE: 90

Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,UPDATE,REGISTER,INFO,MESSAGE,SUBSCRIBE,NOTIFY,PUBLISH,REFER

Content-Type: application/sdp

Supported: resource-priority,timer

User-Agent: xt_sip/1.0

Via: SIP/2.0/UDP 172.16.7.85:8888;branch=z9hG4bK-524287-1---b92653756e52b813sipphone

Contact: <sip:sipsoft@172.16.7.85:8888>;expires=3600

Content-Length: 368

 

v=0

o=userName 1 1 IN IP4 172.16.10.51

s=Play

i=2?videoCodecType=H.264

c=IN IP4 172.16.10.51

b=AS:1024

t=0 0

m=video 40000 RTP/AVP 96 97

c=IN IP4 172.16.10.51

a=rtpmap:96 H264/90000

a=rtpmap:97 H265/90000

a=control:track1

a=recvonly

m=audio 40002 RTP/AVP 100 100

c=IN IP4 172.16.10.51

a=rtpmap:100 MPEG4-GENERIC/8000

a=rtpmap:100 PCMA/8000

a=control:track2

a=recvonly

 

收到Ringing

收到的ring:SIP/2.0 180 Ringing

Via: SIP/2.0/UDP 172.16.7.85:8888;branch=z9hG4bK-524287-1---b92653756e52b813sipphone

Contact: <sip:YPSQ06720040@172.16.10.190:5060>

To: <sip:YPSQ06720040@172.16.7.85:8888>;tag=920bce1e

From: <sip:test@172.16.10.51>;tag=4862ae20

Call-ID: Gd_5NlNEurlhgtCXTweqAA..

CSeq: 1 INVITE

User-Agent: xt_sip/1.0

Content-Length: 0

 

 

sdp is null.

 

发送回复ring : SIP/2.0 180 Ringing

Via: SIP/2.0/UDP 172.16.10.51:5060;rport=5060;branch=z9hG4bK-524287-1---b92653756e52b813;received=172.16.10.51

From: <sip:test@172.16.10.51>;tag=4862ae20

Call-ID: Gd_5NlNEurlhgtCXTweqAA..

CSeq: 1 INVITE

Contact: <sip:sipsoft@172.16.7.85:8888>;expires=3600

To: <sip:YPSQ06720040@172.16.7.85:8888>;tag=920bce1e

Content-Length: 0

 

收到200OK

收到的200OK:SIP/2.0 200 OK

Via: SIP/2.0/UDP 172.16.7.85:8888;branch=z9hG4bK-524287-1---b92653756e52b813sipphone

Require: timer

Contact: <sip:YPSQ06720040@172.16.10.190:5060>

To: <sip:YPSQ06720040@172.16.7.85:8888>;tag=920bce1e

From: <sip:test@172.16.10.51>;tag=4862ae20

Call-ID: Gd_5NlNEurlhgtCXTweqAA..

CSeq: 1 INVITE

Session-Expires: 1800;refresher=uas

Min-SE: 90

Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,UPDATE,REGISTER,INFO,MESSAGE

Content-Type: application/sdp

Supported: resource-priority,timer

User-Agent: xt_sip/1.0

Content-Length: 580

 

v=0

o=YPSQ06720040 2400244997 1 IN IP4 172.16.10.190

s=-

i=stream

c=IN IP4 172.16.10.190

t=0 0

a=tool:XTXK Stream Server V2015.5.14

a=control:*

a=range:npt=0-

a=x-qt-text-nam:-

a=x-qt-text-inf:stream

m=video 6982 RTP/AVP 96

c=IN IP4 172.16.10.190

a=control:track1

a=rtcp-fb:* fir

a=sendonly

a=rtpmap:96 H264/90000

a=fmtp:96 packetization-mode=1;profile-level-id=42000a;sprop-parameter-sets=Z00ACpWosTpuAgICBA==,aO48gA==

m=audio 40002 RTP/AVP 100 100

c=IN IP4 172.16.10.190

a=rtpmap:100 MPEG4-GENERIC/8000

a=rtpmap:100 PCMA/8000

a=control:track2

a=inactive

 

the sdp contenttype is Content-Type: application/sdp

 

发送回复200OK :SIP/2.0 200 OK

Via: SIP/2.0/UDP 172.16.10.51:5060;rport=5060;branch=z9hG4bK-524287-1---b92653756e52b813;received=172.16.10.51

From: <sip:test@172.16.10.51>;tag=4862ae20

Call-ID: Gd_5NlNEurlhgtCXTweqAA..

CSeq: 1 INVITE

Contact: <sip:sipsoft@172.16.7.85:8888>;expires=3600

To: <sip:YPSQ06720040@172.16.7.85:8888>;tag=920bce1e

Content-Type: application/sdp

Content-Length: 580

 

v=0

o=YPSQ06720040 2400244997 1 IN IP4 172.16.10.190

s=-

i=stream

c=IN IP4 172.16.10.190

t=0 0

a=tool:XTXK Stream Server V2015.5.14

a=control:*

a=range:npt=0-

a=x-qt-text-nam:-

a=x-qt-text-inf:stream

m=video 6982 RTP/AVP 96

c=IN IP4 172.16.10.190

a=control:track1

a=rtcp-fb:* fir

a=sendonly

a=rtpmap:96 H264/90000

a=fmtp:96 packetization-mode=1;profile-level-id=42000a;sprop-parameter-sets=Z00ACpWosTpuAgICBA==,aO48gA==

m=audio 40002 RTP/AVP 100 100

c=IN IP4 172.16.10.190

a=rtpmap:100 MPEG4-GENERIC/8000

a=rtpmap:100 PCMA/8000

a=control:track2

a=inactive

 

ACK请求

收到的ACK:ACK sip:sipsoft@172.16.7.85:8888 SIP/2.0

Via: SIP/2.0/UDP 172.16.10.51:5060;rport=5060;branch=z9hG4bK-524287-1---f9c3fe0d0d945038;received=172.16.10.51

Max-Forwards: 70

Contact: <sip:test@172.16.10.51:5060>

To: <sip:YPSQ06720040@172.16.7.85:8888>;tag=920bce1e

From: <sip:test@172.16.10.51>;tag=4862ae20

Call-ID: Gd_5NlNEurlhgtCXTweqAA..

CSeq: 1 ACK

User-Agent: xt_sip/1.0

Content-Length: 0

 

 

回复ACK:ACK sip:YPSQ06720040@172.16.10.190:5060 SIP/2.0

Via: SIP/2.0/UDP 172.16.7.85:8888;branch=z9hG4bK15888b8cae76785dffea07618fb89591

CSeq: 1 ACK

To: <sip:YPSQ06720040@172.16.7.85:8888>;tag=920bce1e

From: <sip:test@172.16.10.51>;tag=4862ae20

Call-ID: Gd_5NlNEurlhgtCXTweqAA..

Session-Expires: 1800;refresher=uas

Min-SE: 90

Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,UPDATE,REGISTER,INFO,MESSAGE

Supported: resource-priority,timer

User-Agent: xt_sip/1.0

Max-Forwards: 70

Content-Length: 0




Bye请求

收到bye:BYE sip:sipsoft@172.16.7.85:8888 SIP/2.0

Via: SIP/2.0/UDP 172.16.10.51:5060;rport=5060;branch=z9hG4bK-524287-1---e74c8841515e606c;received=172.16.10.51

Max-Forwards: 70

Contact: <sip:test@172.16.10.51:5060>

To: <sip:YPSQ06720040@172.16.7.85:8888>;tag=d94e4440

From: <sip:test@172.16.10.51>;tag=61880555

Call-ID: d1FfqZ_j708LZiRjUJ1UmQ..

CSeq: 2 BYE

User-Agent: xt_sip/1.0

Content-Length: 0

 

转发bye:BYE sip:YPSQ06720040@172.16.10.190:5060 SIP/2.0

Via: SIP/2.0/UDP 172.16.7.85:8888;branch=z9hG4bKe1d85d1b6a6f94dc79e959145437ad8f

CSeq: 2 BYE

To: <sip:YPSQ06720040@172.16.7.85:8888>;tag=d94e4440

From: <sip:test@172.16.10.51>;tag=61880555

Call-ID: d1FfqZ_j708LZiRjUJ1UmQ..

Session-Expires: 1800;refresher=uas

Min-SE: 90

Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,UPDATE,REGISTER,INFO,MESSAGE

Supported: resource-priority,timer

User-Agent: xt_sip/1.0

Max-Forwards: 70

Content-Length: 0

 

 

收到200OK

收到的200OK:SIP/2.0 200 OK

Via: SIP/2.0/UDP 172.16.7.85:8888;branch=z9hG4bKe1d85d1b6a6f94dc79e959145437ad8f

Contact: <sip:YPSQ06720040@172.16.10.190:5060>

To: <sip:YPSQ06720040@172.16.7.85:8888>;tag=d94e4440

From: <sip:test@172.16.10.51>;tag=61880555

Call-ID: d1FfqZ_j708LZiRjUJ1UmQ..

CSeq: 2 BYE

User-Agent: xt_sip/1.0

Content-Length: 0

 

发送回复200OK :SIP/2.0 200 OK

Via: SIP/2.0/UDP 172.16.10.51:5060;rport=5060;branch=z9hG4bK-524287-1---a2b8d8182899f615;received=172.16.10.51

From: <sip:test@172.16.10.51>;tag=61880555

Call-ID: d1FfqZ_j708LZiRjUJ1UmQ..

CSeq: 1 INVITE

Contact: <sip:sipsoft@172.16.7.85:8888>;expires=3600

To: <sip:YPSQ06720040@172.16.7.85:8888>;tag=d94e4440

Content-Length: 0


四、Sip服务端主程序

实现SipListener接口,主要有processRequestprocessResponse需要实现,processRequest主要处理的是Request请求,processResponse主要处理的是Response请求,init主要对Sip进行初始化

package org.jivesoftware.openfire.sip;

 

import java.util.Hashtable;

import java.util.Properties;

import javax.sip.*;

import javax.sip.address.AddressFactory;

import javax.sip.address.URI;

import javax.sip.header.HeaderFactory;

import javax.sip.message.MessageFactory;

import javax.sip.message.Request;

import javax.sip.message.Response;

 

public class SipManagerimplements SipListener {

 

public static Hashtable<String, URI>allUsers = new Hashtable<String, URI>();

public static StringipAddr = "172.16.7.85";

public static int port = 8888;

 

public static SipStacksipStack = null;

 

public static AddressFactoryaddressFactory = null;

 

public static MessageFactorymsgFactory = null;

 

public static HeaderFactoryheaderFactory = null;

 

public static SipProvidersipProvider = null;

 

//以下三个变量需要根据Call-ID进行统一匹配管理

public static ServerTransactionserverTransactionId = null;

public static DialogcallerDialog = null;

public static DialogcalleeDialog = null;

 

private void init() {

SipFactory sipFactory = null;

sipFactory = SipFactory.getInstance();

if (null == sipFactory) {

System.out.println("init sipFactory is null.");

return;

}

sipFactory.setPathName("gov.nist");

Properties properties = new Properties();

properties.setProperty("javax.sip.STACK_NAME","sipphone");

properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL","32");

properties.setProperty("gov.nist.javax.sip.DEBUG_LOG",

"sipphonedebug.txt");

properties.setProperty("gov.nist.javax.sip.SERVER_LOG",

"sipphonelog.txt");

try {

sipStack = sipFactory.createSipStack(properties);

} catch (PeerUnavailableException e) {

// TODO Auto-generated catch block

e.printStackTrace();

return;

}

try {

headerFactory = sipFactory.createHeaderFactory();

addressFactory = sipFactory.createAddressFactory();

msgFactory = sipFactory.createMessageFactory();

ListeningPoint udp = sipStack.createListeningPoint(ipAddr,

port, "udp");

//ListeningPoint tcp = sipStack.createListeningPoint(ipAddr,

//port, "tcp");

SipManager listener = this;

 

sipProvider = sipStack.createSipProvider(udp);

System.out.println("udp provider " +sipProvider.toString());

sipProvider.addSipListener(listener);

//sipProvider = sipStack.createSipProvider(tcp);

//System.out.println("tcp provider " + sipProvider.toString());

sipProvider.addSipListener(listener);

//

} catch (Exception ex) {

ex.printStackTrace();

return;

}

 

}

public static void main(String[] args) {

new SipManager().init();

}

@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

Request request = arg0.getRequest();

if (null == request) {

System.out.println("processRequest request is null.");

return;

}

 

if (Request.INVITE.equals(request.getMethod())) {

System.out.println("收到呼叫请求");

SipInvite.invite(request, arg0);

} else if (Request.REGISTER.equals(request.getMethod())) {

System.out.println("注册请求");

SipRegister.register(request, arg0);

} else if (Request.SUBSCRIBE.equals(request.getMethod())) {

} else if (Request.ACK.equalsIgnoreCase(request.getMethod())) {

System.out.println("ACK请求");

SipAck.ack(request, arg0);

} else if (Request.BYE.equalsIgnoreCase(request.getMethod())) {

System.out.println("Bye请求");

SipBye.bye(request, arg0);

} else if (Request.CANCEL.equalsIgnoreCase(request.getMethod())) {

} else if (Request.OPTIONS.equalsIgnoreCase(request.getMethod())) {

System.out.println("收到心跳检测");

SipOption.option(request, arg0);

} else if (Request.SUBSCRIBE.equalsIgnoreCase(request.getMethod())) {

System.out.println("收到订阅信息");

} else {

System.out.println("no support the method!");

}

}

@Override

public void processResponse(ResponseEvent arg0) {

// TODO Auto-generated method stub

Response response = arg0.getResponse();

if (response.getStatusCode() == Response.RINGING) {

System.out.println("收到Ringing");

SipResponseRing.ring(response, arg0);

} else if (response.getStatusCode() == Response.OK) {

System.out.println("收到200OK");

SipResponseOK.ok(response, arg0);

}

}

@Override

public void processTimeout(TimeoutEvent arg0) {

// TODO Auto-generated method stub

}

@Override

public void processTransactionTerminated(TransactionTerminatedEvent arg0) {

// TODO Auto-generated method stub

}

 

}

 

五、Sip服务端register处理程序

Register功能主要是将Sip客户端的信息进行统一管理,在该代码实现处则是将用户的唯一标识与URI进映射,同时对于注册的用户都回复200OK

package org.jivesoftware.openfire.sip;

 

import java.text.ParseException;

 

import javax.sip.InvalidArgumentException;

import javax.sip.RequestEvent;

import javax.sip.ServerTransaction;

import javax.sip.SipException;

import javax.sip.address.Address;

import javax.sip.address.URI;

import javax.sip.header.ContactHeader;

import javax.sip.header.ToHeader;

import javax.sip.message.Request;

import javax.sip.message.Response;

 

public class SipRegister

{

 

public static void register(Request request, RequestEvent requestEvent)

{

if (null == request) {

System.out.println("processInvite request is null.");

return;

}

System.out.println("注册信息 = " + request.toString());

ServerTransaction serverTransactionId = requestEvent

.getServerTransaction();

try {

Response response = null;

ToHeader head = (ToHeader) request.getHeader(ToHeader.NAME);

Address toAddress = head.getAddress();

URI toURI = toAddress.getURI();

ContactHeader contactHeader = (ContactHeader) request

.getHeader("Contact");

Address contactAddr = contactHeader.getAddress();

URI contactURI = contactAddr.getURI();

int expires = request.getExpires().getExpires();

// ���expires������0,��Ϊע�����Ϊע��

System.out.println("-------contactURI------" + contactURI);

String contact = Util.getContact(contactURI);

if (expires != 0 || contactHeader.getExpires() != 0) {

if (contact != null && contact.length() > 0) {

System.out.println("注册 成功" + contact);

SipManager.allUsers.put(contact, contactURI);

}

} else {

if (contact != null && contact.length() > 0) {

System.out.println("注销 成功" + contact);

SipManager.allUsers.remove(toURI);

}

}

response = SipManager.msgFactory.createResponse(200, request);

System.out.println("回复200OK  : " + response.toString());

 

if (serverTransactionId == null) {

serverTransactionId = SipManager.sipProvider

.getNewServerTransaction(request);

serverTransactionId.sendResponse(response);

 

} else {

System.out

.println("processRequest serverTransactionId is null.");

}

 

} catch (ParseException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (SipException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvalidArgumentException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

 

六、Sip服务端invite处理程序

package org.jivesoftware.openfire.sip;

 

import gov.nist.javax.sip.header.Via;

 

import java.text.ParseException;

 

import javax.sip.ClientTransaction;

import javax.sip.RequestEvent;

import javax.sip.SipException;

import javax.sip.TransactionUnavailableException;

import javax.sip.address.Address;

import javax.sip.address.URI;

import javax.sip.header.ContactHeader;

import javax.sip.message.Request;

import javax.sip.message.Response;

 

public class SipInvite

{

 

public static void invite(Request request, RequestEvent requestEvent)

{

System.out.println("收到的呼叫请求:" + request.toString());

ClientTransaction clientTransactionId = null;

if (null == request) {

System.out.println("processInvite request is null.");

return;

}

try {

SipManager.serverTransactionId = requestEvent.getServerTransaction();

if (SipManager.serverTransactionId ==null) {

SipManager.serverTransactionId = SipManager.sipProvider

.getNewServerTransaction(request);

SipManager.callerDialog = SipManager.serverTransactionId.getDialog();

Response response = SipManager.msgFactory.createResponse(Response.TRYING,

request);

SipManager.serverTransactionId.sendResponse(response);

}

 

URI contactURI = request.getRequestURI();

String contact = Util.getContact(contactURI);

if (contact == null) {

return ;

}

contactURI = SipManager.allUsers.get(contact);

System.out.println("contact = " + contactURI);

 

Request cliReq = SipManager.msgFactory.createRequest(request.toString());

cliReq.setRequestURI(contactURI);

 

Via callerVia = (Via) request.getHeader(Via.NAME);

Via via = (Via) SipManager.headerFactory.createViaHeader(SipManager.ipAddr, SipManager.port,"UDP",

callerVia.getBranch() + "sipphone");

cliReq.removeHeader(Via.NAME);

cliReq.addHeader(via);

 

// ����contact�ĵ�ַ

ContactHeader contactHeader = SipManager.headerFactory.createContactHeader();

Address address = SipManager.addressFactory.createAddress("sip:sipsoft@"

+ SipManager.ipAddr + ":" + SipManager.port);

contactHeader.setAddress(address);

contactHeader.setExpires(3600);

cliReq.setHeader(contactHeader);

 

clientTransactionId = SipManager.sipProvider.getNewClientTransaction(cliReq);

clientTransactionId.sendRequest();

 

System.out.println("转发呼叫请求:" + cliReq);

} catch (TransactionUnavailableException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

} catch (SipException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (ParseException e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

}

}

}

 

七、Sip服务端ring处理程序

package org.jivesoftware.openfire.sip;

 

import gov.nist.javax.sip.header.ContentLength;

import gov.nist.javax.sip.header.ContentType;

 

import java.text.ParseException;

 

import javax.sip.ClientTransaction;

import javax.sip.InvalidArgumentException;

import javax.sip.ResponseEvent;

import javax.sip.SipException;

import javax.sip.address.Address;

import javax.sip.header.ContactHeader;

import javax.sip.header.ToHeader;

import javax.sip.message.Request;

import javax.sip.message.Response;

 

public class SipResponseRing {

 

public static void ring(Response response, ResponseEvent arg0) {

System.out.println("收到的ring:" + response.toString());

try {

ClientTransaction clientTran = (ClientTransaction) arg0

.getClientTransaction();

 

if (Request.INVITE.equalsIgnoreCase(clientTran.getRequest()

.getMethod())) {

int statusCode = response.getStatusCode();

Response callerResp = null;

 

callerResp = SipManager.msgFactory.createResponse(statusCode,

SipManager.serverTransactionId.getRequest());

 

// 更新contact头域值,因为后面的消息是根据该URI来路由的

ContactHeader contactHeader = SipManager.headerFactory

.createContactHeader();

Address address = SipManager.addressFactory.createAddress("sip:sipsoft@"

+ SipManager.ipAddr + ":" + SipManager.port);

contactHeader.setAddress(address);

contactHeader.setExpires(3600);

callerResp.addHeader(contactHeader);

 

// 拷贝to头域

ToHeader toHeader = (ToHeader) response

.getHeader(ToHeader.NAME);

callerResp.setHeader(toHeader);

 

// 拷贝相应的消息体

ContentLength contentLen = (ContentLength) response

.getContentLength();

if (contentLen != null && contentLen.getContentLength() != 0) {

ContentType contentType = (ContentType) response

.getHeader(ContentType.NAME);

System.out.println("the sdp contenttype is " + contentType);

 

callerResp.setContentLength(contentLen);

// callerResp.addHeader(contentType);

callerResp.setContent(response.getContent(), contentType);

} else {

System.out.println("sdp is null.");

}

if (SipManager.serverTransactionId != null) {

SipManager.callerDialog = SipManager.serverTransactionId.getDialog();

SipManager.calleeDialog = clientTran.getDialog();

SipManager.serverTransactionId.sendResponse(callerResp);

} else {

System.out.println("serverTransactionId is null.");

}

 

System.out.println("发送回复ring : " + callerResp.toString());

}

 

} catch (ParseException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (SipException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvalidArgumentException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (Exception ex) {

ex.printStackTrace();

}

}

}

 

八、Sip服务端200OK处理程序

package org.jivesoftware.openfire.sip;

 

import gov.nist.javax.sip.header.ContentLength;

import gov.nist.javax.sip.header.ContentType;

 

import java.text.ParseException;

 

import javax.sip.ClientTransaction;

import javax.sip.InvalidArgumentException;

import javax.sip.ResponseEvent;

import javax.sip.SipException;

import javax.sip.address.Address;

import javax.sip.header.ContactHeader;

import javax.sip.header.ToHeader;

import javax.sip.message.Request;

import javax.sip.message.Response;

 

public class SipResponseOK {

 

public static void ok(Response response, ResponseEvent arg0) {

try {

System.out.println("收到的200OK:" + response.toString());

ClientTransaction clientTran = (ClientTransaction) arg0

.getClientTransaction();

 

if (Request.INVITE.equalsIgnoreCase(clientTran.getRequest()

.getMethod()) ||Request.BYE.equalsIgnoreCase(clientTran.getRequest()

.getMethod()) ) {

int statusCode = response.getStatusCode();

Response callerResp = null;

 

callerResp = SipManager.msgFactory.createResponse(statusCode,

SipManager.serverTransactionId.getRequest());

 

// 更新contact头域值,因为后面的消息是根据该URI来路由的

ContactHeader contactHeader = SipManager.headerFactory

.createContactHeader();

Address address = SipManager.addressFactory.createAddress("sip:sipsoft@"

+ SipManager.ipAddr + ":" + SipManager.port);

contactHeader.setAddress(address);

contactHeader.setExpires(3600);

callerResp.addHeader(contactHeader);

 

// 拷贝to头域

ToHeader toHeader = (ToHeader) response

.getHeader(ToHeader.NAME);

callerResp.setHeader(toHeader);

 

// 拷贝相应的消息体

ContentLength contentLen = (ContentLength) response

.getContentLength();

if (contentLen != null && contentLen.getContentLength() != 0) {

ContentType contentType = (ContentType) response

.getHeader(ContentType.NAME);

System.out.println("the sdp contenttype is " + contentType);

 

callerResp.setContentLength(contentLen);

// callerResp.addHeader(contentType);

callerResp.setContent(response.getContent(), contentType);

} else {

System.out.println("sdp is null.");

}

if (SipManager.serverTransactionId != null) {

SipManager.callerDialog = SipManager.serverTransactionId.getDialog();

SipManager.calleeDialog = clientTran.getDialog();

SipManager.serverTransactionId.sendResponse(callerResp);

} else {

System.out.println("serverTransactionId is null.");

}

System.out.println("发送回复200OK : " + callerResp.toString());

}

 

} catch (ParseException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (SipException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvalidArgumentException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (Exception ex) {

ex.printStackTrace();

}

}

}

 

九、Sip服务端ACK处理程序

package org.jivesoftware.openfire.sip;

 

import gov.nist.javax.sip.header.CSeq;

 

import javax.sip.InvalidArgumentException;

import javax.sip.RequestEvent;

import javax.sip.SipException;

import javax.sip.message.Request;

 

public class SipAck {

 

public static void ack(Request request, RequestEvent requestEvent) {

if (null == request) {

System.out.println("processAck request is null.");

return;

}

System.out.println("收到的ACK:" + request.toString());

try {

Request ackRequest = null;

CSeq csReq = (CSeq) request.getHeader(CSeq.NAME);

ackRequest = SipManager.calleeDialog.createAck(csReq.getSeqNumber());

SipManager.calleeDialog.sendAck(ackRequest);

System.out.println("回复ACK:" + ackRequest.toString());

} catch (SipException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvalidArgumentException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

 

}

}

 

十、Sip服务端option心跳处理程序

package org.jivesoftware.openfire.sip;

 

import java.text.ParseException;

 

import javax.sip.InvalidArgumentException;

import javax.sip.RequestEvent;

import javax.sip.ServerTransaction;

import javax.sip.SipException;

import javax.sip.address.Address;

import javax.sip.header.ContactHeader;

import javax.sip.message.Request;

import javax.sip.message.Response;

 

public class SipOption

{

 

public static void option(Request request, RequestEvent requestEvent)

{

if (null == request) {

System.out.println("processInvite request is null.");

return;

}

System.out.println("心跳信息 = " + request.toString());

ServerTransaction serverTransactionId = requestEvent

.getServerTransaction();

System.out.println("serverTransactionId = " + serverTransactionId);

try {

Response response = null;

response = SipManager.msgFactory.createResponse(200, request);

ContactHeader contactHeader = SipManager.headerFactory.createContactHeader();

Address address = SipManager.addressFactory.createAddress("sip:sipsoft@"

+ SipManager.ipAddr + ":" + SipManager.port);

contactHeader.setAddress(address);

response.setHeader(contactHeader);

if (serverTransactionId == null) {

serverTransactionId = SipManager.sipProvider

.getNewServerTransaction(request);

serverTransactionId.sendResponse(response);

 

} else {

System.out

.println("processRequest serverTransactionId is null.");

}

System.out.println("回复Option200OK  : " + response.toString());

} catch (ParseException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (SipException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (InvalidArgumentException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

 

十一、Sip服务端bye处理程序

package org.jivesoftware.openfire.sip;

 

import javax.sip.ClientTransaction;

import javax.sip.Dialog;

import javax.sip.RequestEvent;

import javax.sip.SipException;

import javax.sip.message.Request;

 

public class SipBye

{

 

public static void bye(Request request, RequestEvent requestEvent) {

if (null == request ||null == requestEvent) {

System.out.println("processBye request is null.");

return;

}

System.out.println("收到bye:" + request.toString());

Request byeReq = null;

Dialog dialog = requestEvent.getDialog();

System.out.println("calleeDialog : " + SipManager.calleeDialog);

System.out.println("callerDialog : " + SipManager.callerDialog);

try {

if (dialog.equals(SipManager.calleeDialog)) {

byeReq = SipManager.callerDialog.createRequest(request.getMethod());

ClientTransaction clientTran = SipManager.sipProvider

.getNewClientTransaction(byeReq);

SipManager.callerDialog.sendRequest(clientTran);

SipManager.calleeDialog.setApplicationData(requestEvent

.getServerTransaction());

} else if (dialog.equals(SipManager.callerDialog)) {

byeReq = SipManager.calleeDialog.createRequest(request.getMethod());

ClientTransaction clientTran = SipManager.sipProvider

.getNewClientTransaction(byeReq);

SipManager.calleeDialog.sendRequest(clientTran);

SipManager.callerDialog.setApplicationData(requestEvent

.getServerTransaction());

} else {

System.out.println("");

}

 

System.out.println("转发bye:" +byeReq.toString());

} catch (SipException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

 

}

}

 

十二、Util

package org.jivesoftware.openfire.sip;

 

import javax.sip.address.URI;

 

public class Util {

 

public static String getContact(URI uri) {

if (uri != null) {

String contact = uri.toString().split(":")[1].split("@")[0];

if (contact != null && contact.length() > 0) {

return contact;

}

return null;

}

return null;

}

}

 

十三、Openfire插件

Openfire插件编写过程可以按照本人之前博客介绍





0 0
原创粉丝点击