I try to connect a Pc with and Android device via TCPp using the eneter library
When I send data from the android device to the PC, data is transferred and answer back to android is received immediately but I get problems transfering data from PC to the android device
With the following code the PC is sending the data to itself because I receive the data on the OnMessageReceived procedure of the C# code not in the android
public NCProgram()
{
aReceiverFactory = new DuplexTypedMessagesFactory();
myReceiver = aReceiverFactory.CreateDuplexTypedMessageReceiver<MyResponse, MyRequest>();
mySender = aReceiverFactory.CreateDuplexTypedMessageSender<MyResponse, MyRequest>();
// Subscribe to handle messages.
myReceiver.MessageReceived += OnMessageReceived;
mySender.ResponseReceived += OnResponseReceived;
// Create TCP messaging.
IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
IDuplexInputChannel anInputChannel = aMessaging.CreateDuplexInputChannel("tcp://192.168.173.1:6060/");
IDuplexOutputChannel anOutputChannel = aMessaging.CreateDuplexOutputChannel("tcp://192.168.173.1:6060/");
// Attach the input channel and start to listen to messages.
myReceiver.AttachDuplexInputChannel(anInputChannel);
// Attach output channel to the sender and be able to send
// request messages and receive responses.
mySender.AttachDuplexOutputChannel(anOutputChannel);
m_TexteRebut = "Comunicació establerta";
}
public void Enviar()
{
MyRequest aRequestMessage = new MyRequest();
aRequestMessage.Text = m_Texte_Enviar;
mySender.SendRequestMessage(aRequestMessage);
}
If I don't use the the outputchannel and I send the message as if it was an answer to a communication from the android device, then the data are transferred to the android device but sometimes it takes one second, sometimes a few ones and sometimes 20 or 30 seconds.
public NCProgram()
{
aReceiverFactory = new DuplexTypedMessagesFactory();
myReceiver = aReceiverFactory.CreateDuplexTypedMessageReceiver<MyResponse, MyRequest>();
//mySender = aReceiverFactory.CreateDuplexTypedMessageSender<MyResponse, MyRequest>();
// Subscribe to handle messages.
myReceiver.MessageReceived += OnMessageReceived;
//mySender.ResponseReceived += OnResponseReceived;
// Create TCP messaging.
IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
IDuplexInputChannel anInputChannel = aMessaging.CreateDuplexInputChannel("tcp://192.168.173.1:6060/");
//IDuplexOutputChannel anOutputChannel = aMessaging.CreateDuplexOutputChannel("tcp://192.168.173.1:6060/");
// Attach the input channel and start to listen to messages.
myReceiver.AttachDuplexInputChannel(anInputChannel);
// Attach output channel to the sender and be able to send
// request messages and receive responses.
//mySender.AttachDuplexOutputChannel(anOutputChannel);
m_TexteRebut = "Comunicació establerta";
}
public void Enviar()
{
MyRequest aRequestMessage = new MyRequest();
aRequestMessage.Text = m_Texte_Enviar;
myReceiver.SendResponseMessage(IPAddress,aRequestMessage);
}
Any advice on how to solve the communication from PC to android device will be appreciated
Related
I'm creating windows application in C++, which connect's PC with mobile via bluetooth and winsock. Allow's you to call and send messages from mobile via computer.
I'm using AT command's to tell mobile what i want to do. Pair with mobile device and force a call with At command
ATD+420******;
works perfect, but all commands for handling SMS like
AT+CMGL, AT+CMGF, AT+CMGS etc.
phone probably doesnt recognize them and returns ERROR.
Here is code which connects PC with mobile via bluetooth and socket:
SOCKADDR_BTH RemoteEndPoint;
RemoteEndPoint.port = 0;
RemoteEndPoint.addressFamily = AF_BTH;
RemoteEndPoint.btAddr = m_foundDevices[m_deviceIndex].Address.ullLong;
RemoteEndPoint.serviceClassId = HandsfreeServiceClass_UUID;
int BTHAddrLength = sizeof(RemoteEndPoint);
// Create the socket.
if ((m_localSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM)) == INVALID_SOCKET)
{
// handle error.
}
// Connect the socket.
if ((iResult = connect(m_localSocket, (SOCKADDR *)&RemoteEndPoint, sizeof(RemoteEndPoint))) == INVALID_SOCKET)
{
// handle error.
}
Notice line
RemoteEndPoint.serviceClassId = HandsfreeServiceClass_UUID
I think the problem is here, becouse u cant send sms from Handsfree, but when i use another UUID, it doesnt even pair with mobile.
=== Here is just for info, how am i sending and receiving data from mobile ===
char recvbuf[DEFAULT_BUFLEN] = "";
const char *sendbuf = "AT+CMGL\r";
int len = (int)strlen(sendbuf);
if ((iResult = send(m_localSocket, sendbuf, len, MSG_OOB)) == SOCKET_ERROR)
{
// handle error. return ~0
}
if ((iResult = recv(m_localSocket, recvbuf, recvbuflen, 0)) == SOCKET_ERROR)
{
// handle error. return ~0
}
// Here recvbuf == "\r\nERROR\r\n"
-- I would like to find out the problem, why AT command's for SMS doesnt work.
Thank you for any advices!
If you have any question's about problem, i'll kindly explain.
Regards,
Filip.
EDIT
I found out answer "If you want to send SMS Messages, a Server Socket will be needed on the GSM Device", but after hours of googling i have no clue how to do that. Any suggestion's? Thank you.
Can someone show me a code example of how to send serialized objects back and forth from a Xamarin Android application using a BinaryFormatter instead of Json? It's going to be over WiFi inside the Server Farm.
I'm currently trying to port a simple administrative console application over to an Xamarin Android forms application. I don't understand PCL yet or it's lack of [serializable] attribute. I've heard from the guys at Xamarin that I should probably try Android specific Xamarin instead of forms. I'm new to this so I'm not sure. This will be connecting to a custom Windows Service using standard TCPListeners. Any help would be greatly appreciated. Thanks.
This is an example of the type of console code that I am trying to port over.
public static void HeartBeatPulseListener()
{
Int32 hbPort = 8002;
Console.WriteLine("\nStarting Heart Beat Listener on Port: {0}", hbPort.ToString());
TcpListener heartBeatListener = new TcpListener(IPAddress.Any, hbPort);
heartBeatListener.Start();
while (true)
{
using (TcpClient client = heartBeatListener.AcceptTcpClient())
{
Console.BackgroundColor = ConsoleColor.DarkRed;
Console.ForegroundColor = ConsoleColor.Yellow;
NetworkStream netStream = client.GetStream();
IFormatter formater = new BinaryFormatter();
HeartBeatPulse pulseMSG = (HeartBeatPulse)formater.Deserialize(netStream);
if (pulseMSG != null) Console.WriteLine("\nPulse:{0} \n tStamp:{1}\n FROM:{2}\n Instance:{3} \n Original Unique:{4} \n Type: {5}", pulseMSG.Id.ToString(), pulseMSG.TimeStamp.ToString(), pulseMSG.A.ToString(), pulseMSG.ServerCoreInstanceId, pulseMSG.OriginalUnique, pulseMSG.Type);
if (pulseMSG.Roles.Count() > 1)
{
Console.WriteLine("\nRoles:");
foreach (string role in pulseMSG.Roles)
{
Console.WriteLine("\n{0}", role);
}
}
else Console.WriteLine("\nSum Ting Wong");
Console.ResetColor();
}
}
}
I'm trying to get data from a monitor to an Android application and I've took the IHE - PCD-01 transaction as a model.
The scheme is simple, is based on achieve the interconnection between the monitor and the tablet, where the monitor sends constantly information and the application is listening.
But what I don't understand is if I need an ACK or not after every message. Does anyone can help me with this?
TL;DR yes, nothing special here, support the usual HL7 ACK/NACK driven by MSH-15, MSH-16 fields. ACK-ing everything by default is "better safe then sorry"
The document "IHE Patient Care Device (PCD), Technical Framework, Volume 2 (PCD TF-2) Transactions, Revision 1.0 - Final Text, August 12, 2011" available at http://www.ihe.net/technical_framework/upload/ihe_pcd_tf_vol2_ft_2011-08-12.pdf says
..The common static definition of the HL7 acknowledgement (ACK) message is described in Appendix G, "HL7 Implementation Notes"..
which says
G.1 Network Guidelines
The HL7 2.6 standard does not define a network communications protocol. Beginning with HL7 2.2, the definitions of lower layer protocols were moved to the Implementation Guide, but are not HL7 requirements. The IHE Framework makes these recommendations:
Applications shall use the Minimal Lower Layer Protocol defined in Appendix C of the HL7 Implementation Guide.
An application that wants to send a message (initiate a transaction) will initiate a network connection to start the transaction. The receiver application will respond with an acknowledgement or response to query but will not initiate new transactions on this network connection
G.1.1 Acknowledgment Modes
ACKNOWLEDGMENT MESSAGES
Acknowledgment messages may be defined on an application basis. However the simple general acknowledgment message (ACK) may be used where the application does not define a special message (application level acknowledgment) and in other cases as described in Section 2.9, "Message Processing Rules".
The IHE PCD transaction PCD-03 supports „enhanced mode‟ acknowledgements. See discussion under PCD-03 Transactions as well as in B.1 MSH – Message Header Segment and B.2 MSA – Message Acknowledgement Segment
and document "Health Level Seven, Version 2.6 © 2007, Chapter 2: Control" coming from the "HL7 Messaging Standard Version 2.6" package which can be downloaded from http://www.hl7.org/implement/standards/product_brief.cfm?product_id=185 describes the accept and validate behavior in
2.9.2 Message response using the original processing rules
..too long to quote..
2.9.3 Response using enhanced acknowledgement
..too long to quote..
depending on the values of MSH-15 Accept Acknowledgement Type and MSH-16 Application Acknowledgment Type fields in the HL7 message
The above chapters from the HL7 standard contain what you want to read and implement/support.
EDIT:
Simply put, in HL7 protocol in every message sent the sender may request an ACK receipt by flagging appropriate fields in the message header segment. IHE does not remove this rule and does not enforce any other but enables any other convention to be defined on an application basis. Correct expected behavior is defined by the HL7 specification and in order to get it right and create a conforming implementation (without hidden surprises for your 3rd parties) you may need to read it several times (see also Stack Overflow: How can I make my system HL7 certified?)
For example this is how HAPI library handles the ACKing, snippet comes from http://sourceforge.net/p/hl7api/code/764/tree/tags/Root_REL_1_2/hapi-mvn/hapi-base/src/main/java/ca/uhn/hl7v2/protocol/impl/ProcessorImpl.java
/**
* #see ca.uhn.hl7v2.protocol.Processor#cycle(boolean)
*/
public void cycle(boolean expectingAck) throws HL7Exception {
log.debug("In cycle({})", expectingAck);
cleanReservations();
cleanAcceptAcks();
cleanReservedMessages();
Transportable in = null;
try {
if (expectingAck) {
in = tryReceive(myContext.getLocallyDrivenTransportLayer());
} else {
in = tryReceive(myContext.getRemotelyDrivenTransportLayer());
}
} catch (TransportException e) {
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {}
throw e;
}
// log
if (in != null) {
log.debug("Received message: {}", in.getMessage());
} else {
log.debug("Received no message");
}
// If we have a message, handle it
if (in != null) {
String acceptAckNeeded = null;
// String appAckNeeded = null;
String ackCode = null;
String ackId = null;
try {
String[] fieldPaths = {"MSH-15", "MSH-16", "MSA-1", "MSA-2"};
String[] fields = PreParser.getFields(in.getMessage(), fieldPaths);
acceptAckNeeded = fields[0];
// appAckNeeded = fields[1];
ackCode = fields[2];
ackId = fields[3];
} catch (HL7Exception e) {
log.warn("Failed to parse accept ack fields in incoming message", e);
}
if (ackId != null && ackCode != null && ackCode.startsWith("C")) {
long expiryTime = System.currentTimeMillis() + 1000 * 60;
myAcceptAcks.put(ackId, new ExpiringTransportable(in, expiryTime));
} else {
AcceptAcknowledger.AcceptACK ack = AcceptAcknowledger.validate(getContext(), in);
if ((acceptAckNeeded != null && acceptAckNeeded.equals(AL))
|| (acceptAckNeeded != null && acceptAckNeeded.equals(ER) && !ack.isAcceptable())
|| (acceptAckNeeded != null && acceptAckNeeded.equals(SU) && ack.isAcceptable())) {
trySend(myContext.getRemotelyDrivenTransportLayer(), ack.getMessage());
}
if (ack.isAcceptable()) {
if (isReserved(ackId)) {
log.debug("Received expected ACK message with ACK ID: {}", ackId);
removeReservation(ackId);
long expiryTime = System.currentTimeMillis() + 1000 * 60 * 5;
myAvailableMessages.put(ackId, new ExpiringTransportable(in, expiryTime));
} else {
log.debug("Sending message to router");
Transportable out = myContext.getRouter().processMessage(in);
sendAppResponse(out);
}
} else {
// TODO: should we do something more here? Might be nice to
// allow a configurable handler for this situation
log.warn("Incoming message was not acceptable");
}
}
} else {
String transport = expectingAck ? " Locally driven " : "Remotely driven";
log.debug("{} TransportLayer.receive() returned null.", transport);
}
sleepIfNeeded();
log.debug("Exiting cycle()");
}
Thanks for your answer :)
of course that it is better to use an ACK to make sure if the receiver is getting the message but what I wanted to know if it was mandatory or not using the PCD-01 transaction.
I've read your documents and what I've understood is that the use of ACK depends on the MSH-15 and MSH-16 fields content, but with the following information:
An application that wants to send a message (initiate a transaction) will initiate a network connection to start the transaction. The receiver application will respond with an acknowledgement or response to query but will not initiate new transactions on this network connection
I understand that the ACK is only at the beginning of the connection not after every message, is it right?
I created a custom receiver for Chromecast that plays video and I am trying to send messages back to my Android sender app on the same namespace. I'm currently doing it this way in Javascript:
window.castReceiverManager = cast.receiver.CastReceiverManager.getInstance();
window.castReceiverManager.start();
//use namespace urn:x-cast:com.google.cast.media to communicate to VideoCastManager in Android...?
window.customMessageBus = castReceiverManager.getCastMessageBus('urn:x-cast:com.google.cast.media', cast.receiver.CastMessageBus.MessageType.JSON);
//overwrite the onMessage function
var defaultFunction = window.customMessageBus.onMessage;
window.customMessageBus.onMessage = function(event) {
window.senderId = event.senderId;
window.message = event.data;
defaultFunction(event);
};
//send message
window.customMessageBus.send(window.senderId, {message: "test"});
In Android, I am trying to receive the messages in this way:
mCastConsumer = new VideoCastConsumerImpl() {
//removed all the other override functions to save space
#Override
public void onDataMessageReceived(String message) {
System.out.println("CAST RECEIVED MESSAGE:" + message);
}
};
This doesn't work, and I was hoping someone could point me in the right direction?
Thanks
You need to use a custom namespace not the Media namespace.
I am using the cordova plugin for GCM at GCM-Cordova. On the server side, I am using ToothlessGear's node module.
I think I am not going to use a 'collapsible' key as I require a payload to be sent to the client. The problem I am facing is that the message keeps on arriving after an interval of about 30 seconds. Why is the google server not realizing that the message has been received? Do I have to explicitly do something to stop repeating notifications?
The node-gcm code for triggering push :
gcm = require('node-gcm');
message = new gcm.Message();
sender = new gcm.Sender(app.settings.gcm.server_key);
registrationId = [];
registrationId.push(regid);
message.addData('title', 'Payment Request');
message.addData('message', JSON.stringify(someObj));
message.delayWhileIdle = true;
message.timeToLive = 3;
sender.send(message, registrationId, 1, function(result) {
return console.log(result);
});