- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在 eclipse 环境中使用 JAIN SIP 库开发 SIP 客户端。
我在获得授权时遇到问题。我还实现了 MD5 质询并将授权添加到第二个注册函数。
授权凭据也是正确的,因为我使用可用的 SIP 应用程序检查了它们。我可以用它注册和打电话。
这是初始化和注册的代码
String username = "username";
String server = "10.99.00.00";
String password = "password";
String realm = null ;
private String nonce = null;
// Objects used to communicate to the JAIN SIP API.
SipFactory sipFactory; // Used to access the SIP API.
SipStack sipStack; // The SIP stack.
SipProvider sipProvider; // Used to send SIP messages.
MessageFactory messageFactory; // Used to create SIP message factory.
HeaderFactory headerFactory; // Used to create SIP headers.
AddressFactory addressFactory; // Used to create SIP URIs.
ListeningPoint listeningPoint; // SIP listening IP address/port.
Properties properties; // Other properties.
ClientTransaction inviteTid;
Request request;
Response response;
// Objects keeping local configuration.
String proxy = null;
String sipIP="10.99.00.00";
String localIP= null;
// The local IP address.
int sipport = 5060; // The local port.
int rport = 52216;
String protocol = "UDP"; // The local protocol (UDP).
int tag = (new Random()).nextInt(); // The local tag.
Address contactAddress; // The contact address.
ContactHeader contactHeader; // The contact header.
private Dialog dialog;
private Logger logger;
private String current_process;
public test() throws NoSuchAlgorithmException, ParseException{
init();
Response response = null;
register(response);
}
public void init() {
try {
// Get the local IP address.
localIP = InetAddress.getLocalHost().getHostAddress();
// Create the SIP factory and set the path name.
sipFactory = SipFactory.getInstance();
sipFactory.setPathName("gov.nist");
// Create and set the SIP stack properties.
properties = new Properties();
properties.setProperty("javax.sip.STACK_NAME", "stack");
properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32");
if(proxy != null) {
properties.setProperty("javax.sip.OUTBOUND_PROXY", sipIP + ':' + sipport + '/' + protocol);
}
properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "true");
properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "mss-jsip-debuglog.txt");
properties.setProperty("gov.nist.javax.sip.SERVER_LOG","mss-jsip-messages.xml");
// Create the SIP stack.
sipStack = sipFactory.createSipStack(this.properties);
// Create the SIP message factory.
messageFactory = sipFactory.createMessageFactory();
// Create the SIP header factory.
headerFactory = sipFactory.createHeaderFactory();
// Create the SIP address factory.
addressFactory = sipFactory.createAddressFactory();
// Create the SIP listening point and bind it to the local IP
// address, port and protocol.
listeningPoint = sipStack.createListeningPoint(localIP, rport, protocol);
// Create the SIP provider.
sipProvider = sipStack.createSipProvider(listeningPoint);
// Add our application as a SIP listener.
sipProvider.addSipListener(this);
// 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);
}
}
int cseq;
public void register(Response response) {
try {
cseq++;
current_process = cseq + "REGISTER";
ArrayList viaHeaders = new ArrayList();
ViaHeader viaHeader = headerFactory.createViaHeader(localIP,
rport, "udp", null);
viaHeader.setRPort();
viaHeaders.add(viaHeader);
// The "Max-Forwards" header.
MaxForwardsHeader maxForwardsHeader = headerFactory.createMaxForwardsHeader(70);
// The "Call-Id" header.
CallIdHeader callIdHeader = sipProvider.getNewCallId();
// The "CSeq" header.
@SuppressWarnings("deprecation")
CSeqHeader cSeqHeader = headerFactory.createCSeqHeader(1L,Request.REGISTER);
Address fromAddress = addressFactory.createAddress("sip:"
+ "username" + '@' + server);
FromHeader fromHeader = headerFactory.createFromHeader(
fromAddress, String.valueOf(this.tag));
// The "To" header.
ToHeader toHeader = headerFactory.createToHeader(fromAddress , null);
// Create the contact address used for all SIP messages.
contactAddress = addressFactory.createAddress("sip:" + username + "@"+ localIP +":"+rport+ ";"+ "transport=UDP");
// Create the contact header used for all SIP messages.
contactHeader = headerFactory.createContactHeader(contactAddress);
URI requestURI = addressFactory.createURI("sip:" + server);
request = messageFactory.createRequest(requestURI, Request.REGISTER,callIdHeader, cSeqHeader, fromHeader, toHeader, viaHeaders, maxForwardsHeader);
request.addHeader(contactHeader);
// System.out.println(request.toString());
if (response != null) {
AuthorizationHeader authHeader = makeAuthHeader(headerFactory, response, request, username, password);
request.addHeader(authHeader);
}
inviteTid = sipProvider.getNewClientTransaction(request);
// send the request out.
inviteTid.sendRequest();
// dialog = inviteTid.getDialog();
System.out.println(request.toString());
// Send the request statelessly through the SIP provider.
// this.sipProvider.sendRequest(request);
// Display the message in the text area.
// logger.debug("Request sent:\n" + request.toString() + "\n\n");
} catch (Exception e) {
// If an error occurred, display the error.
e.printStackTrace();
// logger.debug("Request sent failed: " + e.getMessage() + "\n");
}
}
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 = username + ":" + realm + ":" + password;
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(username);
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;
}
这是我发送的请求和我得到的响应。
REGISTER sip:10.99.00.00 SIP/2.0
Via: SIP/2.0/UDP 10.99.00.00:52016;rport;branch=z9hG4bK- 363430-38c329167b2d9108d20c996fec776b29
Max-Forwards: 70
To: <sip:tusername7@10.99.00.00>
From: <sip:username@10.99.00.00>;tag=421569181
Call-ID: 37cd8463e628a6960f62267027cf0720@10.99.00.00
CSeq: 1 REGISTER
Contact: <sip:username@10.99.00.00:52016;transport=UDP>
Content-Length: 0
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 10.99.00.00:52016;branch=z9hG4bK- 363430-38c329167b2d9108d20c996fec776b29;received=10.99.00.00;rport=52016
From: <sip:username@10.99.00.00>;tag=421569181
To: <sip:username@10.99.00.00>;tag=as64c39fdc
Call-ID: 37cd8463e628a6960f62267027cf0720@10.99.00.00
CSeq: 1 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="xyz.com",nonce="13250a39"
Content-Length: 0
REGISTER sip:10.99.00.00 SIP/2.0
Via: SIP/2.0/UDP 10.99.00.00:52016;rport;branch=z9hG4bK- 363430-19fd7f5d12dc78762617b26d61129919
Max-Forwards: 70
To: <sip:username@10.99.00.00>
From: <sip:username@10.99.00.00>;tag=421569181
Call-ID: 68bd42d26ac8f9f90729927434eb5ad3@10.99.70.106
CSeq: 2 REGISTER
Contact: <sip:username@10.99.00.00:52016;transport=UDP>
Authorization: Digest username="username",realm="xyz.com",nonce="13250a39",uri="sip:10.99.00.00",algorithm=MD5,response="f525cda4442d7388e6ea4a737e46b639"
Content-Length: 0
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 10.99.00.00:52016;branch=z9hG4bK- 363430-19fd7f5d12dc78762617b26d61129919;received=10.99.00.00;rport=52016
From: <sip:username@10.99.00.00>;tag=421569181
To: <sip:username@10.99.00.00>;tag=as3b3b0796
Call-ID: 68bd42d26ac8f9f90729927434eb5ad3@10.99.00.00
CSeq: 2 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE,ACK,CANCEL,OPTIONS,BYE,REFER,SUBSCRIBE,NOTIFY,INFO,PUBLISH
Supported: replaces,timer
WWW-Authenticate: Digest algorithm=MD5,realm="xyz.com",nonce="22cbe904"
Content-Length: 0
当我使用具有相同凭据的 SIP 应用程序时,我得到了这个请求和响应
2015-04-22 11:55:42,794 SENT to 10.99.00.00/5060 [AWT-EventQueue-0]
REGISTER sip:10.99.00.00 SIP/2.0
Via: SIP/2.0/UDP 10.99.00.00:52016;rport;branch=z9hG4bKcABnbdE6G
Max-Forwards: 70
To: <sip:username@10.99.00.00>
From: <sip:username@10.99.00.00>;tag=vGbh8M9A
Call-ID: mCbF4794-1429696542758@10.99.00.00
CSeq: 1 REGISTER
Contact: <sip:username@10.99.00.00:52016;transport=UDP>
2015-04-22 11:55:42,795 RECEIVED from 10.99.00.00/5060 [TransportManager 0]
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 10.99.00.00:52016;branch=z9hG4bKcABnbdE6G; received=10.99.00.00;rport=52016
From: <sip:username@10.99.00.00>;tag=vGbh8M9A
To: <sip:username@10.99.00.00>;tag=as7c9471aa
Call-ID: mCbF4794-1429696542758@10.99.00.00
CSeq: 1 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH
Supported: replaces, timer
WWW-Authenticate: Digest algorithm=MD5, realm="xyz.com", nonce="7d0754cc"
Content-Length: 0
2015-04-22 11:55:43,637 SENT to 10.99.00.00/5060 [TransportManager 0]
REGISTER sip:10.99.00.00 SIP/2.0
Via: SIP/2.0/UDP 10.99.00.00:52016;rport;branch=z9hG4bK3Oe6XIIh8
Max-Forwards: 70
To: <sip:username@10.99.00.00>
From: <sip:username@10.99.00.00>;tag=vGbh8M9A
Call-ID: mCbF4794-1429696542758@10.99.00.00
CSeq: 2 REGISTER
Contact: <sip:username@10.99.00.00:52016;transport=UDP>
Authorization: Digest username="username", realm="xyz.com", nonce="7d0754cc", uri="sip:10.99.00.00", response="4150b8392729806ff601eb6d67da7c19"
2015-04-22 11:55:43,638 RECEIVED from 10.99.00.00/5060 [TransportManager 0]
OPTIONS sip:username@10.99.00.00:52016;transport=UDP SIP/2.0
Via: SIP/2.0/UDP 10.99.00.00:5060;branch=z9hG4bK21f59b09
Max-Forwards: 70
From: "asterisk" <sip:asterisk@10.99.00.00>;tag=as2093e268
To: <sip:username@10.99.00.00:52016;transport=UDP>
Contact: <sip:asterisk@10.99.00.00:5060>
Call-ID: 77805e3c524799632da223b942a4e8f1@10.99.00.00:5060
CSeq: 102 OPTIONS
User-Agent: Asterisk PBX 10.5.1
Date: Wed, 22 Apr 2015 09:55:43 GMT
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH
Supported: replaces, timer
Content-Length: 0
2015-04-22 11:55:43,660 RECEIVED from 10.99.00.00/5060 [TransportManager 0]
SIP/2.0 200 OK
Via: SIP/2.0/UDP 10.99.00.00:52016;branch=z9hG4bK3Oe6XIIh8;received=10.99.00.00;rport=52016
From: <sip:username@10.99.00.00>;tag=vGbh8M9A
To: <sip:username@10.99.00.00>;tag=as7c9471aa
Call-ID: mCbF4794-1429696542758@10.99.00.00
CSeq: 2 REGISTER
Server: Asterisk PBX 10.5.1
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH
Supported: replaces, timer
Expires: 240
Contact: <sip:username@10.99.00.00:52016;transport=UDP>;expires=240
Date: Wed, 22 Apr 2015 09:55:43 GMT
Content-Length: 0
我比较了两个数据包,没有发现任何差异。我不明白为什么我没有获得授权。在这种情况下,localIP 和 SIPIP 也是不同的。
我认为问题可能出在端口上,但我没有在网上找到任何有关分配 rport 和 sipport 的帮助:5060。我也想获得更多相关信息。
最佳答案
REGISTERs CSeq 1 和 CSeq 2 上的调用 ID 应该相同。它们与您的情况不同。
关于java - JAIN SIP 未经授权的响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29798213/
让我先描述一下我的问题。我将 Sofia SIP 用于电话应用程序,而我使用的 SIP 代理位于 NAT 后面。这意味着来自代理的传入邀请将内部代理 IP(例如 10.0.0.1)作为 Contact
我试图找出 的可能值范围接受 和 接受-联系 header 字段,但我在 RFC 中找不到完整列表。有谁知道他们在哪里?我经常看到 Accept: application/sdp;level=1,
我使用的 SIP 服务器通过端口 5070 监听 SIP/TLS 请求。我正在尝试跟踪和分析为什么我的拨号器没有通过 Wireshark 在网络上注册。 我已经在 Wireshark 的首选项中编辑了
我一直非常坚持解决这个问题,我去过几乎所有谈论这个主题的网站(包括旧的堆栈溢出帖子),现在我正在尝试遵循 Android“官方”文档以便让我的 SIP 客户端在我的 Asterisk 服务器上注册,应
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我已经从一个 Asterisk(版本 11.2.1)创建了一个 sip 中继,说“A”服务器到另一个 Asterisk 服务器(11.7.0)说“B”,我得到 sip 响应 200 ok。 但是当我开
我几乎设法发起了一个 2 方通话(点击通话):第一个到我的办公室,第二个到我的手机,使用 Michal Niklas 回答(感谢 Michal) Asterisk click to call . 主要
本地和远程标记以及Call-ID的组合用于识别对话。据说Call-ID是一次调用的唯一值。那么为什么 Call-ID 不单独用于识别对话呢? 最佳答案 一句话:“发夹”。 “Hairpinning”是
我想在SIPBYE报头中获取Custom-Order的值。我尝试使用${sip_yee_h_Custom-Order},但它是空的,因为头名称前没有X前缀。。我可以编辑freeswitch sofia
我在使用以下代码时遇到错误。 我已经包含了 Sip 所需的所有 jar ;但是,我仍然不明白为什么会发生这个错误。你能给我解释一下吗? 我的代码类是: import java.net.InetAddr
我有一个 res_mysql.conf 配置为使用从 db.sql 文件重新填充的一些数据库 db。加载转储后,我重新加载配置,我的 SIP 对等点消失了: dev-ast*CLI> sip show
我正在制作 SIP 电话并且必须开发一个功能来支持多个注册。如果手机的主注册服务器关闭,手机应自动注册到辅助注册器,并在主注册器处于事件状态时再次返回主注册器。我的问题是:如何确定主注册商再次活跃起来
我正在尝试实现一个 sip 服务器以连接到 HTML sip 客户端(使用 sipml5 制作)。在我研究这样做的过程中,我遇到了 sip over web-sockets,这可能对我有用,但是,我不
我需要通过 Lua 脚本在 Kamailio 3.3.1 中设置自定义 header 。理论上我可以像这样在配置脚本中设置一个 - append_hf("X-MyHeader: myvalue\r\n
我需要通过 Lua 脚本在 Kamailio 3.3.1 中设置自定义 header 。理论上我可以像这样在配置脚本中设置一个 - append_hf("X-MyHeader: myvalue\r\n
DTMF 用于一些基于 sip 的软电话来处理负载类型。但是我不清楚使用 DTMF 的过程和重要性。开源软件电话,如 Red5phone和 Sipdroid使用 DTMF。任何人都可以解释这个问题或指
我需要一种在使用 Asterisk 调用文件发起调用时添加 SIP header 的方法。 有什么办法可以在通话文件中添加SIP头吗? 我知道我可以使用 Asterisk AGI 完成此操作,但是我找
我目前在连接到我的 SIP 客户端(IVR 语音服务)的对称 NAT 后面存在 SIP 用户代理问题。 我读到 Asterisk 在 sip.conf 中有一个解决方案,我可以在那里设置属性 nat=
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭11 年前。 Improve th
我的客户公司有一个简单的 Web 应用程序 (Python Flask),我需要向它添加电话通知功能。 主要要求是应用程序应该调用用户、播放某个声音文件并接受一些音调输入(“您好!这是来自您的 Web
我是一名优秀的程序员,十分优秀!