我正在尝试连接到 Unify OpenScape Business 并监控来电。从我目前的发现看来,最好的办法是使用 CSTA 协议。
在以下页面 http://wiki.unify.com/wiki/Developer_Program__-_OpenScape_Voice我找到 了 openscape-csta-sdk-1.5.2.zip:http://wiki.unify.com/images/4/47/openscape -csta-sdk-1.5.2.zip
现在我正在尝试根据 SDK 中的示例建立连接。我的 OpenScape 监听 8800 端口。但是,当我在该端口上 telnet 或在大约 20 秒后通过随附的示例应用程序连接时,我得到了一些垃圾。
当基于 SDK 的监控代码启动时,它会在日志中显示类似的内容:
2015-12-28 22:48:17,429 [main] INFO com.sen.openscape.csta.provider.CstaProvider - Welcome to use OpenScape Voice CSTA SDK V1.5.2!
2015-12-28 22:48:17,525 [main] DEBUG com.sen.openscape.csta.transport.tcp.CstaTcpLink - Connected to CSTA Server.
2015-12-28 22:49:16,985 [main] INFO com.sen.openscape.csta.transport.tcp.CstaTcpLink - Received CSTA Message: aDˇ+€Ş˘ ˇ M-CM10.00 1.0.0.018ľ(
2015-12-28 22:49:17,005 [main] DEBUG com.sen.openscape.csta.transport.CstaLink - Sending SystemRegister Request
2015-12-28 22:49:17,074 [main] INFO com.sen.openscape.csta.transport.tcp.CstaTcpLink - Sent CSTA Message: 0001<?xml version="1.0" encoding="UTF-8"?>
<SystemRegister xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.ecma-international.org/standards/ecma-323/csta/ed4"><requestTypes><systemStatus>true</systemStatus><requestSystemStatus>true</requestSystemStatus><switchingFunctionCapsChanged>true</switchingFunctionCapsChanged><switchingFunctionDevicesChanged>true</switchingFunctionDevicesChanged></requestTypes></SystemRegister>
Failed to connect: CstaErrorCause=NetworkFailure; ErrorMessage=Timeout waiting for response
我收到的垃圾是(十六进制转储)
61 44 cb 87 07 06 05 2b 0c 20 c3 9a 01 cb 98 03 02 01 02 c5 81 05 cb 98 03 02 01 20 ef bf bd 02 06 e2 82 ac c5 9e 1c cb 98 1a c2 a0 18 cb 87 16 04 09 4d 2d 4f 4d 31 30 2e 30 30 04 09 33 2e 30 2e 30 2e 30 35 37 c4 be 0b 28 09 c2 a0 07 c2 a0 05 03 03 20 10 20
这使我得出结论,端口 8800 上的连接不一定是我正在寻找的,但是我找不到其他任何东西。
我收到的“垃圾”可能是 ASN.1 编码的消息,但我无法正确解码。
下面附上要监控的代码,
import com.sen.openscape.csta.callcontrol.CstaDevice;
import com.sen.openscape.csta.callcontrol.CstaMonitor;
import com.sen.openscape.csta.provider.CstaEventListener;
import com.sen.openscape.csta.provider.CstaEventObject;
import com.sen.openscape.csta.provider.CstaProvider;
import com.sen.openscape.csta.util.CstaException;
public class CstaDeviceMonitor implements CstaEventListener {
private CstaMonitor monitor;
public boolean startMonitor(CstaProvider provider, String device) {
CstaDevice myDevice = provider.addDevice(device);
try {
monitor = provider.MonitorStart(myDevice);
provider.registerEventListener(this);
System.out.println("\n---\nStarted monitoring " + monitor.fqnDn + "\n---\n");
return true;
} catch (CstaException e) {
System.err.println("Failed to start monitor: " + e.toString());
return false;
}
}
public void stopMonitor(CstaProvider provider) {
try {
provider.MonitorStop(monitor.crossRefId);
System.out.println("\n---\nStopped monitoring " + monitor.fqnDn + "\n---\n");
provider.removeDevice(monitor.fqnDn);
} catch (CstaException e) {
System.err.println("Failed to stop monitor: " + e.toString());
}
}
@Override
public void newCstaEvent(CstaEventObject evt) {
System.out.print("\n--- Device " + evt.fqnDn + " received event: type=" + evt.evtType
+ ", callID=" + evt.callID + "\n");
}
}
import com.sen.openscape.csta.provider.CstaProvider;
import com.sen.openscape.csta.util.CstaConfiguration;
import com.sen.openscape.csta.util.CstaException;
import java.util.Scanner;
public class CstaMonitorMain {
/**
*
* The IP address of the CSTA interface in OpenScape Voice
*
*/
private static final String CSTA_SERVER_IP_ADDRESS = "192.168.1.12";
/**
*
* The port number - it's usually 1040, very rarely changed
*
*/
private static final int CSTA_SERVER_PORT = 8800;
/**
*
* The phone number we will monitor Must match the configured in OSV and
* must
*
* have CSTA service assigned
*
*/
private static final String DEVICE_TO_MONITOR = "101";
public static void main(String[] args) {
CstaProvider myProvider = connect();
if (myProvider != null) {
CstaDeviceMonitor monitor = new CstaDeviceMonitor();
if (monitor.startMonitor(myProvider, DEVICE_TO_MONITOR)) {
// Let it run until the user hits the enter key
Scanner keyIn = new Scanner(System.in);
System.out.print("\n\nPress Enter to exit\n\n");
keyIn.nextLine();
monitor.stopMonitor(myProvider);
}
disconnect(myProvider);
}
}
private static CstaProvider connect() {
CstaConfiguration cfg = new CstaConfiguration(CSTA_SERVER_IP_ADDRESS, CSTA_SERVER_PORT);
// cfg.setTransportType(CstaTransports.HTTP_SOAP);
try {
CstaProvider provider = new CstaProvider();
provider.connectToSystem(cfg);
System.out.println("\n---\nConnected to " + CSTA_SERVER_IP_ADDRESS + "\n---\n");
provider.startHeartbeat(60, 60);
return provider;
} catch (CstaException e) {
System.err.println("Failed to connect: " + e.toString());
return null;
}
}
private static void disconnect(CstaProvider provider) {
try {
provider.endHeartbeat();
provider.disconnectFromSystem();
System.out.println("\n---\nDisconnected from " + CSTA_SERVER_IP_ADDRESS + "\n---\n");
} catch (CstaException e) {
System.err.println("Failed to disconnect: " + e.toString());
}
}
}
我还在 sourceforge 上找到了 CSTA 客户端,但它也无法监控设备。
我也尝试在 Unify 论坛上发布问题,但遗憾的是,这是我遇到过的最糟糕的编程论坛,总之我不能在那里发布我的问题,这就是我试图在这里寻求帮助的方式。
我正在寻找有关通过 CSTA 访问 OpenScape 业务 V5 的一些提示。如果有人已经为我指出了正确的方向,我将不胜感激,谢谢。
进展,第 1 步
也许有人像我一样有类似的问题......然后我发布第一个更新。
我取得了一些进展,但还没有完全成功,但有一个亮点 :-) 我通过 SDK 解决这个问题的主要方法是错误的。没有 SDK。我终于在这里找到了一些文档http://wiki.unify.com/wiki/Developer_Program_-_OpenScape_4000。正确对话的描述显示在该页面上的 CSTA3_ADG1.pdf 中,http: //wiki.unify.com/images/1/11/Application_Guide_%28part_I%29.zip
我还设法获得了 CSTA 浏览器工具,这对于理解 asn.1 与 PBX 的通信非常有帮助。我认为值得记下通信应该是什么样子,下面是在 CSTA 浏览器中完成的“对话模拟”的转储,来自 Unify (Siemens) 的工具
< aCSE.aarq
< { -- SEQUENCE --
< application-context-name = {iso(1) identified-organization(3) icd-ecma(12) standard(0) csta(218)},
< sender-acse-requirements = '10'B -- NrBits = 2 --
< { -- true bits --
< authentication
< },
< calling-authentication-value.external
< { -- SEQUENCE --
< encoding.single-ASN1-type
< { -- SEQUENCE --
< sender-authentication
< { -- SEQUENCE --
< authentication-name = "AMHOST" '41 4D 48 4F 53 54'H,
< authentication-password = "77777" '37 37 37 37 37'H
< }
< }
< },
< user-information
< { -- SEQUENCE OF --
< { -- SEQUENCE --
< encoding.single-ASN1-type.newDefinition
< { -- SEQUENCE --
< cSTAVersion = '0001000000000000'B -- NrBits = 16 --
< { -- true bits --
< versionFour
< }
< }
< }
< }
< }
Time = 22:13:49:992
S(00,AMHOST): 60 31 A1 07 06 05 2B 0C 00 81 5A 8A 02 06 80 AC 15 A2 13 A0 11 A0 0F 04 06 41 4D 48 4F 53 54 04 05 37 37 37 37 37 BE 0B 28 09 A0 07 A0 05 03 03 00 10 00
Time = 22:13:49:992
R(00,AMHOST): 61 48 A1 07 06 05 2B 0C 00 81 5A A2 03 02 01 00 A3 05 A1 03 02 01 00 88 02 06 80 AA 21 A2 1F A0 1D A1 1B 04 10 48 45 35 32 30 4D 2E 30 30 2E 34 33 37 2E 35 31 04 07 34 33 37 2E 30 30 30 BE 0A 28 08 A0 06 A0 04 03 02 04 10
Time = 22:13:49:992
> aCSE.aare
> { -- SEQUENCE --
> application-context-name = {iso(1) identified-organization(3) icd-ecma(12) standard(0) csta(218)},
> result = 0 (accepted),
> result-source-diagnostic.acse-service-user = 0 (null),
> responder-acse-requirements = '10'B -- NrBits = 2 --
> { -- true bits --
> authentication
> },
> responding-authentication-value.external
> { -- SEQUENCE --
> encoding.single-ASN1-type
> { -- SEQUENCE --
> responding-authentication
> { -- SEQUENCE --
> aps-stamp = "HE520M.00.437.51" '48 45 35 32 30 4D 2E 30 30 2E 34 33 37 2E 35 31'H,
> system-version = "437.000" '34 33 37 2E 30 30 30'H
> }
> }
> },
> user-information
> { -- SEQUENCE OF --
> { -- SEQUENCE --
> encoding.single-ASN1-type.newDefinition
> { -- SEQUENCE --
> cSTAVersion = '0001'B -- NrBits = 4 --
> { -- true bits --
> versionFour
> }
> }
> }
> }
> }
Time = 22:13:50:003
R(00,AMHOST): A1 0C 02 01 01 02 02 00 D3 30 03 0A 01 01
Time = 22:13:50:007
> rOSE.roiv-apdu
> { -- SEQUENCE --
> invokeID = 1,
> operation-value = 211 (systemStatus),
> argument
> { -- SEQUENCE --
> systemStatus = 1 (enabled)
> }
> }
在模拟之后,我可以向 CSTA PBX 发送一个 CSE.aarq 消息。现在我将它存储在这样的简单数组中:
int[] aCSEaarq = {0x60, 0x31, 0xA1, 0x07, 0x06, 0x05, 0x2B, 0x0C, 0x00, 0x81, 0x5A, 0x8A, 0x02, 0x06, 0x80, 0xAC, 0x15, 0xA2, 0x13, 0xA0, 0x11, 0xA0, 0x0F, 0x04, 0x06, 0x41, 0x4D, 0x48, 0x4F, 0x53, 0x54, 0x04, 0x05, 0x37, 0x37, 0x37, 0x37, 0x37, 0xBE, 0x0B, 0x28, 0x09, 0xA0, 0x07, 0xA0, 0x05, 0x03, 0x03, 0x00, 0x10, 0x00};
在 PBX 中发送数据时,计算其长度并将其作为前两个字节传递是很重要的。
如果我这样做,我会立即收到答案。所以我的简单java中的对话转储看起来像这样:
doWrite [aCSE.aarq]
60 31 A1 07 06 05 2B 0C 00 81 5A 8A 02 06 80 AC 15 A2 13 A0 11 A0 0F 04 06 41 4D 48 4F 53 54 04 05 37 37 37 37 37 BE 0B 28 09 A0 07 A0 05 03 03 00 10 00
doRead [aCSE.aare]
00 46 (70 bytes)
61 44 A1 07 06 05 2B 0C 00 DA 01 A2 03 02 01 00 A3 05 A2 03 02 01 00 88 02 06 80 AA 1C A2 1A A0 18 A1 16 04 09 4D 2D 4F 4D 31 30 2E 30 30 04 09 33 2E 30 2E 30 2E 30 35 37 BE 0B 28 09 A0 07 A0 05 03 03 00 10 00
doRead [rOSE.roiv-apdu]
00 0F (15 bytes)
A1 0D 02 02 1D 1D 02 02 00 D3 30 03 0A 01 02
这与 CSTA 浏览器模拟非常相似。
现在我试图找出如何编码/解码消息。我想我必须为此使用 asn.1 编译器,但还不知道如何正确执行它以及我应该从哪里获取 asn1 源文件。当谈到编译器时,我更愿意坚持免费的解决方案。