OpenDDS Messenger RTPS across 2 virtual machines - opendds

I have built OpenDDS-3.20 and I am able to run the Messenger sample code under (OpenDDS-3.20/DevGuideExamples/DCPS/Messenger) by using the run_test.pl. I am also able to run it without the run_test.pl file like this:
OpenDDS-3.20/bin/DCPSInfoRepo &
./publisher &
./subscriber
After this I can see the result:
...
...
...
Subscriber is available
SampleInfo.sample_rank = 0
SampleInfo.instance_state = ALIVE_INSTANCE_STATE
Message: subject = Review
subject_id = 99
from = Comic Book Guy
count = 0
text = Worst. Movie. Ever.
...
...
...
Even with the RTSP, I am able to execute it from the same machine ./run_test.pl --rtps. But, when I am trying to run DCPSInfoRepo and publisher in a VirtualBox-1 and subscriber in VirtualBox-2 using the default rtps.ini file then the sample application does not work.
I am able to ping from VirtualBox-1 to VirtualBox-2. They are both running Ubuntu Server. Can someone please share the process by which RTPS can be used to communicate between publisher and subscriber across 2 virtual machines.

Related

How to fix a python "pyverbs" application with RDMA write getting a not acknowledge (NACK)

Im currently working on a RoCE (RDMA over Converged Ethernet) python application with the library pyverbs. First, i want to do a simple loopback test with an RDMA Write. I tested the setup with ib_write_bw from perftest, which worked like a charm.
This is my setup:
OS: Ubuntu 20.04.05 LTS
Kernel: 5.15.0-56-generic
NIC: Mellanox ConnectX-5 MC516A-GCA_Ax 50Gbe dual-port QSFP28
I'm developing the application with a jupyter notebook. The ports are connected together with a QSFP28 cable. I set up a "client" and "server" on the same system. Both use one port of the NIC. The client performs the "RDMA Write" action. In the future, metadata will be exchanged over tcp, but for ease of debugging i exchange metadata locally in the same notebook.
Now i was able to perform an "RDMA Write" action and capture the packets.
Captured RDMA packets
I keep getting not acknowledeges (NACK) from the "server". The RDMA Write packet look correct to me. It got the right payload and the headers are the same as i configured (i can post it if it would help).
I got three ideas in my head, why it would work.
wrong server memory adress/rkey used for rdma write
missing flags at server memory allocation
missing/wrong flags at server queue pair modification
I tried all different combinations of flags and values at the queue pair modification and memory allocation.
I start the NIC in the shi
ell with
sudo mst start
Then i run my python application. I posted some codesnipped below, which i am not sure i implemented those right.
Server and client qp modification init to RTR
gid_index = 0
port_num = 1
server_attr.qp_state = e.IBV_QPS_RTR
server_attr.path_mtu = e.IBV_MTU_4096
server_attr.rq_psn = 0
server_attr.min_rnr_timer = 12
server_attr.max_dest_rd_atomic = 10
server_attr.dest_qp_num = client_qp.qp_num
server_attr.qp_access_flags = e.IBV_ACCESS_LOCAL_WRITE | e.IBV_ACCESS_REMOTE_READ | e.IBV_ACCESS_REMOTE_WRITE
server_gr = GlobalRoute(dgid=client_ctx.query_gid(port_num=port_num,index=gid_index), sgid_index=gid_index)
server_ah_attr = AHAttr(gr=server_gr, is_global=1, port_num=1)
server_attr.ah_attr = server_ah_attr
server_qp.to_rtr(server_attr)
client_attr.qp_state = e.IBV_QPS_RTR
client_attr.path_mtu = e.IBV_MTU_4096
client_attr.rq_psn = 0
client_attr.min_rnr_timer = 12
client_attr.max_dest_rd_atomic = 10
client_attr.dest_qp_num = server_qp.qp_num
client_attr.qp_access_flags = e.IBV_ACCESS_LOCAL_WRITE | e.IBV_ACCESS_REMOTE_READ | e.IBV_ACCESS_REMOTE_WRITE
client_gr = GlobalRoute(dgid=server_ctx.query_gid(port_num=port_num,index=gid_index), sgid_index=gid_index)
client_ah_attr = AHAttr(gr=client_gr, is_global=1, port_num=port_num)
client_attr.ah_attr = client_ah_attr
client_qp.to_rtr(client_attr)
Client qp modification RTR to RTS
client_attr.qp_state = e.IBV_QPS_RTS
client_attr.timeout = 14
client_attr.retry_cnt = 7
client_attr.rnr_retry = 7
client_attr.sq_psn = 0
client_attr.max_rd_atomic = 10
RDMA Write instruction to client
client_sge = SGE(client_mr.buf,len(SEND_STRING),client_mr.lkey)
send_wr = pwr.SendWR(num_sge = 1, sg = [client_sge],opcode=e.IBV_WR_RDMA_WRITE)
send_wr.set_wr_rdma(rkey = server_mr.rkey, addr = server_mr.buf)
client_qp.post_send(send_wr)
sleep(1)
print(server_mr.read(len(SEND_STRING),0))
If there is someone with knowledge in RMDA/RoCE/Pyverbs, i would be glad for some help. I don't have any prior knowledge in those topics. This is why i have choosen to write an application in python. I have knowledge in C, but python is for me much more convient for prototyping :)
Thank for your help!

How to run AutoHotKey scripts on several PCs at once, controlled from one place?

For some load testing simulations, I'm looking at scripting with AHK 1.1. The issue is we have a client-server setup with multiple workstations so I'd really like to be able to trigger the same script (or even variations) to run on multiple PCs at once, to accurately simulate multiple users all hammering the system.
Even more useful would be to make sure the same test happens at exactly (within some tolerance) the same time, to check this doesn't cause problems.
What be would the best way to do this? Do it from within AHK itself, or use some separate remote-control tool to let me fire off scripts on PCs of my choosing?
With ahk you will need scripts acting as server and clients so both needs to be running no matter the method used...
As to the TCP/IP you can do this, you just need to find out if you have any usable/open posts your scripts can use...
I just helped an australian guy the other day setup a great working lot of server/client scripts
using the Socket Class by Bentschi looking something like this
Server:
;Server
#include Socket.ahk
myTcp := new SocketTCP()
myTcp.bind("addr_any", 54321)
myTcp.listen()
myTcp.onAccept := Func("OnTCPAccept")
return
OnTCPAccept(this)
{
newTcp := this.accept()
newTcp.onRecv := func("OnTCPRecv")
newTcp.sendText("Connected")
}
OnTCPRecv(this)
{
msgbox % this.recvText()
}
Client:
;Client
#include Socket.ahk
myTcp := new SocketTCP()
myTcp.connect("your servers A_IPAddress1", 54321) ; lokal
myTcp.onRecv := Func("OnTcpRecv")
return
OnTcpRecv(this)
{
ToolTip % this.RecvText()
}
But to use and or set something like this up you may need to know what ports are usable on the network or have the ability to change settings as needed.
The speed of the TCP/IP scripts are in the low milliseconds (under 20 on my network) so no real tolerance to speak of.
Hope it helps
As wrote Sidola you can check shared folder for some file or folder. You can use
IfExist command for it. Here is example:
Loop
{
IfExist, c:\a.txt
{
break
}
}
;code to execute if c:\a.txt exists comes below.
MsgBox, 1
Also you can add Sleep command to put less stress on hdd like for example in code below:
Loop
{
IfExist, c:\a.txt
{
break
}
Sleep, 1000
}
;code to execute if c:\a.txt exists comes below.
MsgBox, 1
Also, always use AutoHotkey and its documenatation from http://ahkscript.org/ (current uptodate version, new official website)! AutoHotkey and its documentation from autohotkey.com is outdated and you may have some problems using them!
I can't provide actual code, but there is a way to kind of inject a service into your LAN machines through the Admin$ share and remotely control it. This way AHK wouldn't need to run on the LAN computers all the time.
I don't know how exactly this could be done, but PsShutdown does it to hibernate LAN PCs which is normally impossible.
In case you actually manage to do it, it would be great if you could share it.

How to send an email without using the program RSCONN01?

I am trying to send an email with an excel attachment without using rsconn01. If this is possible could you show me how this is done?
I would also like a little bit more information about how rsconn01 works. I am using rsconn01 to send the emails but, I received a complaint that this program was also resending out emails that failed earlier that day.
This is the code I am using now. It works, but I want to know another way to do it without using rsconn01.
`CALL FUNCTION 'SO_DOCUMENT_SEND_API1'
EXPORTING
document_data = w_doc_data
put_in_outbox = 'X'
commit_work = 'X'
IMPORTING
sent_to_all = w_sent_all
TABLES
packing_list = t_packing_list
contents_bin = t_attachment
contents_txt = it_message
receivers = t_receivers
EXCEPTIONS
too_many_receivers = 1
document_not_sent = 2
document_type_not_exist = 3
operation_no_authorization = 4
parameter_error = 5
x_error = 6
enqueue_error = 7
OTHERS = 8.
if sy-subrc = 0.
WAIT UP TO 2 SECONDS.
SUBMIT rsconn01 WITH mode = 'INT'
WITH output = 'X'
AND RETURN.
else.
WRITE:/ 'ERROR IN MAIL ', sy-subrc.
endif.`
You will have to use RSCONN01 unless you'd like to implement your own protocol handling. You're using the standard SAPconnect functionality (although with an API that's a bit outdated, I'd switch to the BCS if I were in your shoes). As long as you're using this, you're stuck with that report. However, you usually won't have to call it for yourself. It's a background process that is called every few minutes to process outgoing mail. Perhaps you're working in a development environment where the SAPconnect system isn't properly setup - in that case, you should talk to your system administrators. There are ways to tune the SAPconnect system to work in many cases. You should try to use the existing and well supported facilities before trying to circumvent them.

Necessity of cloning classes for background processes running through rake?

I have a resque worker class which works with ActionMailer and another that works with Mail directly. Here's a short example:
class NotificationWorker
def self.perform(id)
Mailer.delivery_method.settings = {
# custom settings here
}
# Working with Mailer to deliver mails
end
end
Assuming that there may be two workers running on NotificationWorker, I am not sure if these interfer each other. From my understanding, working directly on the Mail class would break functionality because this would result in both mailers using the same settings instead of their assigned ones. A solution would be to create a clone of such a class (which works with ActionMailer, but not with Mail AFAIK).
According to the Resque docs:
Resque workers are rake tasks that run forever. They basically do
this:
start
loop do
if job = reserve
job.process
else
sleep 5 # Polling frequency = 5
end
end
shutdown
I am not familiar with rake besides the basic usage for rails apps. So can anyone enlighten me?
not quite sure what you're trying to achieve here. I have a resque system which queue and delivers automated emails. I have it set up like this:
1) env.rb
config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {...}
2) notification_job.rb # its the job not the worker that needs creating.
class NotificationWorker
def self.perform(id)
# Working with Mailer to deliver mails
end
end
If you really need to work with mailer directly and each worker needs different settings then you may need to create a yaml file which relates to a variable that you give the worker on startup.

How to ping meter with Modbus

I am trying to ping a Socomec meter using the Modbus protocol, having researched, I found NModbus, a C# library. I have never used libraries or C# before (normally Java), but I have to dive right in.
I set myself up with Visual Studio Express for C# and installed .Net. I have copied then contents of the NModbus file into my project folder and added the references to the two main DLLs. Its didn't work with .Net 4, but I retargeted to 3.5 (and removed the Microsoft.Csharp reference) and things seemed to compile.
I am using this sample, below, to attempt to connect to the slave device. When I run this, and set the startAdress variable to the desired one (found in Socomec documentation) however all I get is a blank console window.
In short, am I using the correct method/parameters, is my setup/code incorrect? How do I connect to this meter?
My code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using Modbus.Data;
using Modbus.Device;
using Modbus.Utility;
namespace NModbus
{
class SerialMaster
{
static void Main(string[] args)
{
ModbusSerialAsciiMasterReadRegisters();
}
public static void ModbusSerialAsciiMasterReadRegisters()
{
using (SerialPort port = new SerialPort("COM1"))
{
// configure serial port
port.BaudRate = 9600;
port.DataBits = 8;
port.Parity = Parity.None;
port.StopBits = StopBits.One;
port.Open();
// create modbus master
IModbusSerialMaster master = ModbusSerialMaster.CreateAscii(port);
byte slaveId = 1;
ushort startAddress = 50536;
ushort numRegisters = 5;
// read five registers
ushort[] registers = master.ReadHoldingRegisters(slaveId, startAddress, numRegisters);
for (int i = 0; i < numRegisters; i++)
Console.WriteLine("Register {0}={1}", startAddress + i, registers[i]);
Console.ReadLine();
}
// output:
// Register 1=0
// Register 2=0
// Register 3=0
// Register 4=0
// Register 5=0
}
}
}
Why don't you use some Java MODBUS library when you are already familiar with Java? I haven't worked with Socomec meters, but in general for MODBUS devices you need to know the protocol and addresses you are interested in. Then try to read tags from the device with some tool that you know is working well, like MODPOLL. Then when you get usable values as expected, you go to programming the polling connection in any language you like. Otherwise, you risk to loose a lot of time wondering what's going on.
One hint... From your code I see that you are acting as MODBUS ASCII serial master. Although such devices exist, 95% of RS232/RS485 devices I worked with were MODBUS RTU. Read specification if you don't know the difference.
You can run Java applications as a Windows service. There is a Tomcat Java service starter that I use with my company's Java application. You have create a method that will be called to stop the service, but that's just a method.
Here's the line I use to install my application as a service --
"%~dp0windows\tomcat6" //IS//%1 --DisplayName %1 --Description "gmServer for %1" ^
--JavaHome "%JAVA_HOME%" --Classpath "%PR_CLASSPATH%" --LogPrefix gmserver ^
--StartMode jvm --StopMode jvm --Jvm auto --StartPath "%~dp0." ^
--LogPath "%~dp0." --LogLevel debug --StdOutput %1.out --StdError %1.err ^
--StartClass greenMonitor.gmServer --StartParams -I#%I#-u#3600 ^
--StopMethod windowsService --StopParams stop --StopTimeout 10
The caret characters ("^") are line continuations characters in .BAT files. You should be able to find the meanings of the Tomcat command line options with the Tomcat documentation.
And for a Java-based Modbus library, complete with lots of handy programs you can use to test the connection, check out j2mod on Sourceforge. My company did a fork of jamod, along with a bunch of cleanups and that was the result.