我遇到的问题是,当我在远程PC上启动设备管理器时,我有一个带有10GigE端口的外部硬件设备连接设备管理器的registerDevice消息注册连接到设备管理器PC的外部设备使用的10GigE接口的IP地址,而不是设备管理器机器的实际IP地址。
网络设置:<>之前PC1域经理:192.168.5.10设备管理器A(GPP):192.168.5.10(与域管理器在同一台机器上)之前<>之前PC2设备管理器B(GPP):192.168.5.11设备接口:192.168.100.10(连接外部硬件)之前如果我在没有外部设备连接到PC2的情况下运行我的场景,该机器上的设备管理器注册IP地址:192.168.5.11。如果我将外部硬件连接到PC2并且10GigE接口在线,设备管理器注册IP地址:192.168.100.10并且整个REDHAWK域挂起。
我通过检查PC1和PC2上的wireshark日志验证了这个问题。除了使用10GigE端口的UHD设备外,我们在连接UHD设备时没有遇到此问题。重要的是要注意,此时实际上没有使用它们的设备或设备管理器。设备刚刚上电,只有GPP的节点已经启动。在UHD和外部硬件情况下,两个10GigE端口都是自定义的,并实现有限的10GigE接口。当连接到另一台具有10GigE的PC而不是具有有限10GigE实现的设备时,设备管理器工作。
如果在节点处于活动状态后连接10GigE设备,则FE 2.0设备工作完全正常。然而,这种情况并不适用于我们,因为在我们的用例中,物理地走过去并打开设备是无效的。此外,使用在同一台计算机上启动的域中的设备运行不会出现这些问题。此问题仅在域位于远程PC时发生。
我们目前正在使用以下REDHAWK版本,它在两个版本上都有同样的问题。
CentOS 6.6与REDHAWK 2.0.3和OmniORB 4.1
Fedora 24 with REDHAWK 2.0.3 and OmniORB 4.2
还有其他人遇到过这个问题吗?我能做些什么吗?
让我们使用docker来运行一个完整的示例。您需要启动3个终端并安装docker,但我们可以在一台主机上完成所有操作。我将这3个终端分别称为"Domain"、"Sandbox"one_answers"Host system"。
在域终端中,启动一个新的redhawk 2.0.2实例:
docker run -it --name=domain axios/redhawk:2.0.2 bash -l
在沙盒终端中,启动另一个redhawk 2.0.2实例:
docker run -it --name=sandbox axios/redhawk:2.0.2 bash -l
如果你不熟悉docker,这两个docker实例有独特的文件系统、内存和网络。执行ifconfig
检查各节点的IP地址并记录。请注意,它们在同一子网上,并且可以相互ping通。
我们现在可以模拟你的10GigE端口通过创建两个新的网络,不能到达对方。在主机终端上,使用docker创建两个独立的假网络,并将它们分配给您的容器实例。
docker network create -o "com.docker.network.bridge.host_binding_ipv4"="1.1.1.1" bad_net_1
docker network create -o "com.docker.network.bridge.host_binding_ipv4"="2.2.2.2" bad_net_2
docker network connect bad_net_1 domain
docker network connect bad_net_2 sandbox
回到Domain和Sandbox终端中重新运行ifconfig
,注意您现在有一个eth0和eth1接口,其中Domain和Sandbox实例上的eth1在唯一的子网上并且不能通信。
你的IP地址可能不同,但对我来说,我有:
<>之前域:eth0: 172.17.0.2eth1: 172.19.0.2沙盒:eth0: 172.17.0.3eth1: 172.20.0.2之前我现在将域配置为omniNames主机,设置omniORB连接超时,这样我们就不会挂在corba调用上,并且错误地配置端点,以便发布错误的IP地址。
在域计算机上:
sudo tee /etc/omniORB.cfg << EOF
InitRef = NameService=corbaname::172.17.0.2:2809
supportBootstrapAgent = 1
InitRef = EventService=corbaloc::172.17.0.2:11169/omniEvents
endPoint = giop:tcp:172.19.0.2:
serverCallTimeOutPeriod = 5000
clientConnectTimeOutPeriod = 5000
clientCallTimeOutPeriod = 5000
EOF
在Sandbox机器上:
sudo tee /etc/omniORB.cfg << EOF
InitRef = NameService=corbaname::172.17.0.2:2809
supportBootstrapAgent = 1
InitRef = EventService=corbaloc::172.17.0.2:11169/omniEvents
endPoint = giop:tcp:172.20.0.2:
serverCallTimeOutPeriod = 5000
clientConnectTimeOutPeriod = 5000
clientCallTimeOutPeriod = 5000
EOF
在Domain机器上通过cleanomni
启动omniNames和事件,这也将清除任何陈旧的状态:
cleanomni
在沙盒机器上运行nameclt list
查看omniORB对象。请注意,它不起作用,因为为域发布的端点地址是错误的。如果我们通过traceLevel=40
登录/etc/omniorb .cfg,我们甚至可以在消息中看到错误的IP地址。
omniORB: inputMessage: from giop:tcp:172.17.0.2:2809 236 bytes
omniORB:
4749 4f50 0100 0101 e000 0000 0000 0000 GIOP............
0400 0000 0000 0000 0000 0000 2a00 0000 ............*...
4944 4c3a 6f6d 672e 6f72 672f 436f 734e IDL:omg.org/CosN
616d 696e 672f 4269 6e64 696e 6749 7465 aming/BindingIte
7261 746f 723a 312e 3000 0000 0100 0000 rator:1.0.......
0000 0000 9400 0000 0101 0200 0b00 0000 ................
3137 322e 3139 2e30 2e32 0000 23ae 0000 172.19.0.2..#...
0e00 0000 ff00 bb05 0a58 0100 003c 0000 .........X...<..
0002 0000 0400 0000 0000 0000 0800 0000 ................
0100 0000 0054 5441 0100 0000 1c00 0000 .....TTA........
0100 0000 0100 0100 0100 0000 0100 0105 ................
0901 0100 0100 0000 0901 0100 0300 0000 ................
1600 0000 0100 0000 0b00 0000 3137 322e ............172.
3137 2e30 2e32 0000 f90a 0000 0354 5441 17.0.2.......TTA
0800 0000 bb05 0a58 0100 003c .......X...<
在域终端上,使用vim或emacs修复/etc/omniORB.cfg中的endPoint,并运行cleanomni
清除所有旧的引用并重新启动omni服务。现在可以从沙盒终端正确地运行nameclt list
。
在域终端上使用nodeBooter -D
启动域,并从沙盒终端通过python连接到域,并确认您可以与预期的域进行交互。
>>> from ossie.utils import redhawk
>>> dom = redhawk.attach('REDHAWK_DEV')
>>> dom.name
'REDHAWK_DEV'
>>> fs = dom.fileManager
>>> fs.list('.')
请注意,到目前为止,我们只是从沙箱到域进行调用,所以只有域机器的广告端点有关系。像"start"one_answers"stop"这样的调用是由您向组件发出的,但像pushPacket这样的调用是由组件向您发出的。我们可以通过将域机器上的SigGen连接到沙盒机器上的HardLimit来确认这一点。请记住,现在域机器是正确配置的,而沙箱机器不是。
在Domain机器上,停止域并运行以下命令以安装波形并使用GPP启动域:
sudo yum install -y rh.basic_components_demo
nodeBooter -D -d /var/redhawk/sdr/dev/nodes/DevMgr_12ef887a9000/DeviceManager.dcd.xml
现在回到python中的沙盒机器:
from ossie.utils import redhawk, sb
import time
dom = redhawk.attach('REDHAWK_DEV')
app = dom.createApplication('/waveforms/rh/basic_components_demo/basic_components_demo.sad.xml')
siggen = app.comps[0]
siggen.start()
hardlimit = sb.launch('rh.HardLimit')
sink = sb.DataSink()
hardlimit.connect(sink)
siggen.connect(hardlimit)
sb.start()
time.sleep(1)
sink.getData()
由于沙盒机器发布了错误的端点,因此您应该不会在接收器中获得数据。现在退出python,修复Sandbox实例上的endPoint并重新运行此实验。这次您可以获得数据,因为两个端点都正确配置了。
最后,如果根本不设置endPoint会发生什么?(我想这是您的情况)omniORB样例配置文件:
默认情况下,没有定义endPoint配置。在这种情况下ORB将只创建1个tcp端点,就像下面这行一样:端点= giop:tcp::在配置文件
中指定。
和
主机和端口可选参数。如果两者之一两者都缺失,ORB将填补空白。例如,"giop:tcp::"将导致ORB选择任意tcp端口作为端点,它将选择主机的一个IP地址作为主机地址。
所以你可能会得到非常奇怪的行为。希望这个例子对你有所帮助,并且对每个人来说都足够简单。
现在我们完成了我们可以清理我们的docker实例和docker网络:
docker rm -f domain sandbox
docker network rm bad_net_1 bad_net_2