CloudHopper Server sending MO to connected client - java

I have a project where we are using ArdanStudios smppclient to connect to an SMPPServer. We can send messages to the SMPP Server and they get delivered to the handset. When the hand set replies or sends to the shortcode we do get a received message event but the message text is blank.
We are using CloudHopper internally to simulate the SMPP Server, I want to confirm that there isn't a problem on our end when receiving messages but I can not figure out a way to simulate an MO (mobile originated) message sent from Cloudhopper server to our connected ArdanClient. Any ideas ?

You have two questions in one Pal. I suggest you break it up. For the first one basically you have to override the firePduRequestReceived methos of class DefaultSmppSessionHandler:
#Override
public PduResponse firePduRequestReceived(PduRequest pduRequest) {
PduResponse response = pduRequest.createResponse();
if (pduRequest.getCommandId() == SmppConstants.CMD_ID_DELIVER_SM) {
processMO(pduRequest);
}
return response;
}
private void processsMO(PduRequest request){
DeliverSm mo = (DeliverSm) request;
int length = mo.getShortMessageLength();
Address sourceAddr = mo.getSourceAddress();
Address destAddr = mo.getDestAddress();
byte[] shortMessage = mo.getShortMessage();
String sms= new String(shortMessage);
//Do Something....
}

Related

Netty server send a byte[] encoded by Protobuf, but C# client Socket.Receive keeps being 0

I am trying to accomplish an Unity game demo with network function, using C# for programming of client, and Java for server.
To be specific, server communication is implemented by Netty.
I also brought in Protobuf, which helps me define protocols of messages.
As I am new to server programming, dealing with packet merging and loss in TCP has not been considered in my code yet.
When I created sockets from client, and sent message to server, everything went well.
Problem happened when server replied:
In the client, an async method is ready to receive message. When I simply sent a string-format message from server, the method were able to get it.
But when I replaced the message with a 4-length byte[], which encoded from a Protobuf Message object, client just showed that it received NOTHING.
when I print what I've sent in the server console, it is like this:
00001000
00000001
00010000
00000001
My server code overrides channelRead and channelReadComplete functions of Netty.
In channelRead, ChannelHandlerContext.write was invoked to write the message to the transmission cache.
And in channelReadComplete, ChannelHandlerContext.flush was invoked, so that the message could be sent finally.
channelRead()
#Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
Request.MsgPack msgPack = (Request.MsgPack) msg;
Request.MsgPack.MsgType type = msgPack.getType();
switch (type)
{
case GetServerState:
final Request.GetServerState gssbody = msgPack.getGetServerState();
System.out.println("收到类型为" + type + "的消息,内容为:" +
"\nrequestId = " + gssbody.getRequestId()
);
byte[] bytes = ServerStateManager.getState(gssbody.getRequestId());
ctx.write(bytes);
break;
getState(): including Protobuf-encoding procedure
public static byte[] getState(int requestId)
{
ReturnServerState.Message.Builder replyBuilder = ReturnServerState.Message.newBuilder();
replyBuilder.setRequestId(requestId);
replyBuilder.setIsIdle(new ServerStateManager().isIdle());
return replyBuilder.build().toByteArray();
}
channelReadComplete()
#Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
try
{
ctx.flush();
}
finally
{
ctx.close();
}
}
Client code:
public class ShortLink
{
Socket clientSocket = null;
static byte[] result = new byte[1024];
Task ReceiveAsync<T>(string ip, int port)
{
return Task.Run(() =>
{
T component = default(T);
while (clientSocket.Receive(result) == 0)
{
break;
ReceiveAsync is invoked in the way of:
await ReceiveAsync<ReturnServerState>(ip, port);
when I found clientSocket.Receive(result) always output 0, I tried to log result[0], result[1], result[2], result[3] like this:
Debug.Log(Convert.ToString(result[0]) + ", " +
Convert.ToString(result[1]) + ", " +
Convert.ToString(result[2]) + ", " +
Convert.ToString(result[3]));
And the log turned to be 0,0,0,0.
I will be grateful for any idea of "why the client socket received nothing", and the solution.
Since I come from Asia, there may be a time lag between your reply and mine, and also English is not my mother tongue. However, I will try my best to reply in time.
Thanks a lot!
Okay..I have finally solve it myself
1.The usage "return replyBuilder.build().toByteArray()" is wrong because ProtoEncoder has already do toByteArray() for me:
public class ProtobufEncoder extends MessageToMessageEncoder<MessageLiteOrBuilder> {
public ProtobufEncoder() {
}
protected void encode(ChannelHandlerContext ctx, MessageLiteOrBuilder msg, List<Object> out) throws Exception {
if (msg instanceof MessageLite) {
out.add(Unpooled.wrappedBuffer(((MessageLite)msg).toByteArray()));
} else {
if (msg instanceof Builder) {
out.add(Unpooled.wrappedBuffer(((Builder)msg).build().toByteArray()));
}
}
}
}
So once I registered "new ProtobufEncoder()" in the Netty Channel Pipeline, I can just use "return replyBuilder.build()" - that is correct.
2.In "static byte[] result = new byte[1024];", The length of received message is defined casually, and it doesn't matter - until it really receives a message.
When receiving message, I shall always copy the message bytes to a new byte[] with a correct length firstly - or there will be just a 1024-length bytes[], with the data I need at the beginning, and several zeroes following, which will certainly fail to be decoded.

Netty UDP broadcast receiver works on one NIC but not on another - why?

Hi – I wonder if anyone can help me. I’m using Netty 4.1.9 to send UDP messages between two Linux machines:
Both machines are attached via 3 separate NICs to the same 3 networks.
I have some working code that sends the messages from one to the other and that is received okay.
I then changed the code to force the UDP traffic onto a different network, out through a different NIC on the sender.
The sending works, I can see the traffic on the different network, but now the netty receiver can’t see the traffic.
As far as I can see the receiver code shouldn’t care which NIC the data comes in on, so I don’t understand what the issue is.
I’m sure the data arrives at the receiver host on the correct NIC because running “tshark -i ” on the receiver shows the traffic on the correct network, with the correct destination port, and expected length.
The broadcast address I'm using in both cases is 255.255.255.255.
Here's the code for the setting up the receiver channel, this code works fine when the traffic arrives on the first NIC, but not when it arrives on the other:
public Channel createReceivingChannel(final int port,
final EventLoopGroup myGroup) throws InterruptedException
{
return new Bootstrap()
.group(myGroup)
.channelFactory(new ChannelFactory<NioDatagramChannel>()
{
#Override
public NioDatagramChannel newChannel()
{
return new NioDatagramChannel(InternetProtocolFamily.IPv4);
}
})
.handler(new ReceiverInitializer(this.protocolConfig))
.bind(port).sync().channel();
}
Here's the sender code that works with the receiver, but puts the UDP messages on the wrong network:
public Channel createSendingChannel( final NetworkAddress localAddress,
final int port,
final EventLoopGroup myGroup) throws InterruptedException
{
return new Bootstrap()
.group(myGroup)
.channelFactory(new ChannelFactory<NioDatagramChannel>()
{
#Override
public NioDatagramChannel newChannel()
{
return new NioDatagramChannel(InternetProtocolFamily.IPv4);
}
})
.localAddress(localAddress.address, port)
.option(ChannelOption.SO_BROADCAST, true)
.handler(new SenderInitializer(this.protocolConfig))
.bind(0).sync().channel();
}
And here's my sender code that puts the data on the right network, but the receiver above can't see it:
public Channel createSendingChannel(
final NetworkAddress localAddress,
final int port,
final EventLoopGroup myGroup) throws InterruptedException
{
final InetSocketAddress localSocketAddress = new InetSocketAddress(localAddress.address, port);
return new Bootstrap()
.group(myGroup)
.channelFactory(new ChannelFactory<NioDatagramChannel>()
{
#Override
public NioDatagramChannel newChannel()
{
return new NioDatagramChannel(InternetProtocolFamily.IPv4);
}
})
.localAddress(localAddress.address, port)
.option(ChannelOption.SO_BROADCAST, true)
.handler(new SenderInitializer(this.protocolConfig))
.bind(localSocketAddress).sync().channel(); // difference here to bind the sender to correct NIC
}
Any help gratefully received at this stage. I'm stuck.
Many thanks in advance,
Michael.

Library ZMQ for Java not work

I am trying to connect to a bitcoin node using the ZMQ library for Java. the problem is that when I try to receive a response the code remains frozen. Returns nothing.
This is my code:
public class CBETest {
private static final String TEST_URL = "obelisk.airbitz.co";
public static void main(String[] args) {
System.out.println("\t--- ZMQ ---");
Ctx c = zmq.ZMQ.createContext();
SocketBase s = c.createSocket(zmq.ZMQ.ZMQ_DEALER);
zmq.ZMQ.connect(s, "tcp://"+TEST_URL+":9091");
System.out.println("Connected!");
int sent = zmq.ZMQ.send(s, "blockchain.fetch_last_height", 0);
System.out.println("Sent: " + sent);
Msg msg = zmq.ZMQ.recv(s, 0);
System.out.println("Response " + Arrays.toString(msg.data()));
}
}
The code freezes in the line Msg msg = zmq.ZMQ.recv(s, 0);. I am using the calls described here for the full node implemetation. Thanks in advance!
The code is not freezing, it is blocking while waiting to receive a message.
I would suggest you put your above code in a thread/runnable class and use localhost as the TEST_URL and start the server.
Then create another Runnable class with a client that tries to connect to that port and send back a message and start that thread and see if the message gets through.
There is an example here:
http://zguide.zeromq.org/java:rtdealer

Not able to receive ACLMessage in android via JADE

I'm currently using Topic based communication using JADE. I'm able to register a JADE agent using jade.core.messaging.TopicManagementFEService thereby connecting to the main-container in the same platform.
The details are below:
Main-Container: a simple LAMP/WAMP Server that hosts the Main-Container.
Client: An Android Emulator(testing purpose) to connect to the main-container.
Currently,
Server starts the main-container
Android emulator connects to the Main-container successfully (Agent created along with Topic Mgmt Service enabled)
Server is sending messages based on a specific topic.
But my Android Client is not able to receive this message although the topic registered is the same on both ends!
You can see the code below:
Server Side:
TopicManagementHelper topicHelper = (TopicManagementHelper) getHelper(TopicManagementHelper.SERVICE_NAME);
final AID sensorTopic = topicHelper.createTopic("JADE");
topicHelper.register(sensorTopic);
addBehaviour(new TickerBehaviour(this, TIMER_VALUE_IN_MILLISECONDS) {
private static final long serialVersionUID = -2567778187494378326L;
public void onTick() {
ACLMessage msg = new ACLMessage(ACLMessage.INFORM);
msg.addReceiver(eventTopic);
msg.setContent(eventValue);
myAgent.send(msg);
}
});
Android Side:
// Registering on Android Side as well
TopicManagementHelper topicHelper = (TopicManagementHelper) getHelper(TopicManagementHelper.SERVICE_NAME);
topic = topicHelper.createTopic("JADE"); // See, same topic!
topicHelper.register(topic);
behaviour = new myBehaviour(this, TIMER_VALUE_IN_MILLISECONDS, topic);
addBehaviour(behaviour);
private class myBehaviour extends TickerBehaviour {
private static final long serialVersionUID = 4782913834042415090L;
AID topic;
Agent agent;
MessageTemplate tpl;
public myBehaviour(Agent a, long period, AID topic) {
super(a, period);
this.agent = a;
this.topic = topic;
}
public void onTick() {
tpl = MessageTemplate.MatchTopic(topic);
ACLMessage msg = receive(tpl);
if (msg != null) {
logger.log(Level.INFO, "Agent "+ agent.getLocalName() +
": Message about topic "+ topic.getLocalName() +" received. \n" +
"Content is " + msg.getContent());
data = msg.getContent();
} else {
logger.log(Level.INFO, "In here..."); // Always executes only this code!
block();
}
}
}
Where am I going wrong here? It always executes the else part in the Android side which is obvious to say that message received is NULL!
Never mind. The logic was wrong. The Android-Agent was not identifying itself to the Central-Agent.
I set the Ontology so that the Central Agent is able to identify such message and sends the message accordingly. Now, it is receiving messages!
Self-help works sometimes! ;-)
Receiving topic messages doesn't work correctly with Android up to version 4.3.0 in JADE. Android can send out topic messages but can't receive them. I found this out through my own issues. I've posted more info about it in my own question on stack overflow.
Take a look. JADE Leap Android App unable to receive topic messages

XMPP reply from GAE to Google+ doesn't work

I've noticed errors in my Google App Engine Log while parsing messages. The stack trace was unhelpful to diagnose the problem, so I wrote a small message dumper inspired by Google's implementation of InboundMessageParser.
public class ChatRequestParser extends HttpRequestParser {
public static Map<String, String> parseMessage(HttpServletRequest request)
throws IOException {
try {
Map<String, String> message = new HashMap<String, String>();
MimeMultipart multipart = parseMultipartRequest(request);
int parts = multipart.getCount();
for (int i = 0; i < parts; i++) {
BodyPart part = multipart.getBodyPart(i);
String fieldName = getFieldName(part);
String fieldValue = getTextContent(part);
message.put(fieldName, fieldValue);
}
return message;
} catch (MessagingException ex) {
throw new IOException("Could not parse incoming request.", ex);
}
}
}
I found out that Google+ sends two messages for each message, only one of which contains a body (Gmail Talk client sends only one message).
Here is the first message, without a body:
{to=xxx#appspot.com, stanza=<message to="xxx#appspot.com" type="chat"
from="yyy#gmail.com/TalkGadgetD9F45A83" xmlns="jabber:client">
<cha:composing xmlns:cha="http://jabber.org/protocol/chatstates"/>
<nos:x value="disabled" xmlns:nos="google:nosave"/>
<arc:record otr="false" xmlns:arc="http://jabber.org/protocol/archive"/>
</message>, from=yyy#gmail.com/TalkGadgetD9F45A83}
And the second one is (my payload is many asterisks, mails changed):
{to=xxx#appspot.com, body=**********************************,
stanza=<message to="xxx#appspot.com" type="chat"
id="7279D79D0.17809585028724073_:sl" from="yyy#gmail.com/TalkGadgetD9F45A83"
xmlns="jabber:client"><body>**********************************</body>
<cha:active xmlns:cha="http://jabber.org/protocol/chatstates"/>
<nos:x value="disabled" xmlns:nos="google:nosave"/><arc:record otr="false"
xmlns:arc="http://jabber.org/protocol/archive"/></message>,
from=yyy#gmail.com/TalkGadgetD9F45A83}
Since the first message doesn't have a body calling parseMessage() on XMPPService throws exception. Has anyone noticed this problem?
Now I am catching the IllegalArgumentException and throwing away meaningless messages, but the real problem is, that the reply to the valid message doesn't arrive back to Google+ client, while works perfectly with Gmail and also with my Jabber client on Linux.
I've filed issue 6467.
I can reproduce the crash when no body is set and parseMessage is called, and I'm fixing it. Thanks for finding it!
However, I can't repro the "send reply doesn't work" bug. I have code like this:
XMPPService xmpp = XMPPServiceFactory.getXMPPService();
Message message = xmpp.parseMessage(req);
Message reply = new MessageBuilder().withFromJid(message.getRecipientJids()[0])
.withRecipientJids(message.getFromJid())
.withBody("Back at you!")
.build();
xmpp.sendMessage(reply);
And I receive the reply both in Google+ and in Gmail. What are you doing differently?

Categories