I have 2 P2P devices (android smartphones). They created a Wifi Direct Group. So, we have a Group owner and a Client. A third device appears, and wants to join the group sending a connection request to the GO. When this happens the GO BroadcastReceiver detects a disconnect. I would like to know if that is a normal behavior or I'm doing something wrong.
This is part of my BroadcastReceiver
else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION
.equals(action)) {
if (manager == null) {
return;
}
NetworkInfo networkInfo = (NetworkInfo) intent
.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
WifiP2pInfo wifiP2pInfo = (WifiP2pInfo) intent
.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_INFO);
WifiP2pGroup wifiP2pGroup = (WifiP2pGroup) intent
.getParcelableExtra(WifiP2pManager.EXTRA_WIFI_P2P_GROUP);
if (networkInfo.isConnected()) {
// we are connected with the other device, request connection
// info to find group owner IP
} else {
// It's a disconnect
}
} else if ....
Related
I am trying to retrieve OTP in Huawei device. but it is not working.
I have created the app in Huawei developer console with all the requirements.
Below is the code i am using to retrieve the sms.
private fun initSmsManager() {
val task = ReadSmsManager.start(this#MainActivity)
task.addOnCompleteListener {
if (task.isSuccessful) {
// The service is enabled successfully. Continue with the process.
Toast.makeText(this, "ReadSms service has been enabled.", Toast.LENGTH_LONG).show()
} else
Toast.makeText(this, "The service failed to be enabled.", Toast.LENGTH_LONG).show()
}
task.addOnSuccessListener(this, OnSuccessListener {
if(task.isSuccessful){
Toast.makeText(this, "ReadSms service has been enabled.", Toast.LENGTH_LONG).show()
myReceiver = MyBroadcastReceiver();
val intentFilter = IntentFilter(READ_SMS_BROADCAST_ACTION)
registerReceiver(myReceiver, intentFilter)
}
})
task.addOnFailureListener(this, OnFailureListener {
Toast.makeText(this,it.message,Toast.LENGTH_SHORT).show();
})
}
Broadcast receiver
class MyBroadcastReceiver : BroadcastReceiver() {
companion object {
val TAG = MyBroadcastReceiver::class.java.simpleName
}
override fun onReceive(context: Context?, intent: Intent?) {
val bundle = intent!!.extras
if (bundle != null) {
val status: Status? = bundle.getParcelable(ReadSmsConstant.EXTRA_STATUS)
if (status?.statusCode == CommonStatusCodes.TIMEOUT) {
// Service has timed out and no SMS message that meets the requirement is read. Service ended.
// doSomethingWhenTimeOut()
} else if (status?.statusCode == CommonStatusCodes.SUCCESS) {
if (bundle.containsKey(ReadSmsConstant.EXTRA_SMS_MESSAGE)) {
// An SMS message that meets the requirement is read. Service ended.
//doSomethingWhenGetMessage(bundle.getString(ReadSmsConstant.EXTRA_SMS_MESSAGE))
bundle.getString(ReadSmsConstant.EXTRA_SMS_MESSAGE)?.let {
Log.d(TAG, it)
val local = Intent()
local.action = "service.to.activity.transfer"
local.putExtra("sms", it)
context!!.sendBroadcast(local)
}
}
}
}
}
}
Any help in this would be beneficial.
Please confirm the following points:
Check whether the broadcast for receiving SMS verification codes is enabled. You can do that by performing breakpoint debugging or recording logs.
Check whether the SMS message format meets the rules for automatically reading SMS messages.
For details,See Docs.
Check whether the hash_value field is correct.
If no error occurs during the preceding check, could you pls provide a complete log trace then i will try to find out what can be wrong about this issue. :)
All code is working fine it works well on debug mode when I build released apk then keystore changed also hash changes for release mode. If you know anything about how to run on release mode , please let us know. Maybe some changes are made in Huawei developer account
I am trying to make a simple SIP user agent using https://github.com/pjsip/pjproject. I can succesfully connect to a sip server (Twilio) and place calls to PSTN numbers using the pjsua_* interface. This works fine.
What I would like now is to get a notification (through a callback or such) from pjsip when the user that I am calling answers the call.
I am using on_call_state() to get updates on the invite, but this goes through the same states
CALLING -> CONNECTING -> CONFIRMED -> DISCONNCTD
even if the user rejects the call. So I guess I am not looking at the right callback for this.
How can I definitely tell if the user has answered or rejected the call?
for me it is working this way. in on_call_state callback:
pjsua_call_info callInfo;
pjsua_call_get_info(call_id, &callInfo);
pjsip_inv_state state = callInfo.state;
pjsip_status_code statusCode = callInfo.last_status;
switch (state) {
.....
case PJSIP_INV_STATE_CONFIRMED:
// remote party answered the call normally
break;
case PJSIP_INV_STATE_DISCONNECTED:
if (statusCode == PJSIP_SC_BUSY_HERE) {
// rejected
} else {
// finished ok
}
break;
i reject call this way:
pj_status_t state;
int sendCode = PJSIP_SC_DECLINE;
try {
state = pjsua_call_answer((pjsua_call_id) call_id, sendCode, nullptr, nullptr);
} catch (...) {
return -1;
}
return state;
We have 2 UWP apps. One app shares data to the other app through StreamSocket. The server app will send data to client app. There will be 30-40 or more devices running the client app and connecting to the server's socket to receive data.
When we test with one client app, all the data sharing happens without any issue. But when we started testing with about 10 devices using the client app, sometimes some apps don't receive data. And there seems to be an error saying A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
In general it get shared to most of the devices, but few fails sometimes randomly. What could be the reason for this? Is there a connection limit to connect to a socket with given IP and port using Stream Socket?
Here is some parts of our code. Please let me know what we have to correct here to avoid getting that error.
Server side
public async Task StartServer(string serverIp, string serverPort)
{
try
{
HostName serverAddress = new HostName(serverIp);
//Create a StreamSocketListener to start listening for TCP connections.
StreamSocketListener socketListener = new StreamSocketListener();
//Hook up an event handler to call when connections are received.
socketListener.ConnectionReceived += SocketListener_ConnectionReceived;
//Start listening for incoming TCP connections on the specified port.
await socketListener.BindEndpointAsync(serverAddress, serverPort);
}
catch (Exception e)
{
}
}
private async void SocketListener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
try
{
await Task.Run(() => ShareFile(args.Socket));
}
catch (Exception e)
{
}
}
Client side
public async Task ServerConnect(string serverIP, string serverPort)
{
try
{
HostName serverAddress = new HostName(serverIP);
StreamSocket socket = new StreamSocket();
socket.Control.KeepAlive = false;
// Connect to the server.
await socket.ConnectAsync(serverAddress, serverPort, SocketProtectionLevel.PlainSocket);
}
catch (Exception e)
{
}
}
Also would like to get these clarified
-What is the difference between BindServiceNameAsync and BindEndpointAsync? Most examples seems to use the first one. When should we use the second one?
-If we call sender.Dispose(); in SocketListener_ConnectionReceived, will that affect the other clients trying to join the same socket?
-In the ShareFile() function, if we close args.Socket() after sending data, can it close the socket before the client actually read the data from that side?
I am building a OPC UA Client using OPC Foundation SDK. I am able to create a subscription containing some Monitoreditems.
On the OPC UA server these monitored items change value constantly (every second or so).
I want to disconnect the client (simulate a connection broken ), keep the subcription alive and wait for a while. Then I reconnect having my subscriptions back, but I also want all the monitored Item values queued up during the disconnect. Right now I only get the last server value on reconnect.
I am setting a queuesize:
monitoredItem.QueueSize = 100;
To kind of simulate a connection error I have set the "delete subscription" to false on ClosesSession:
m_session.CloseSession(new RequestHeader(), false);
My question is how to capture the content of the queue after a disconnect/connection error???
Should the ‘lost values’ be “new MonitoredItem_Notification” automatically when the client reconnect?
Should the SubscriptionId be the same as before the connection was broken?
Should the sessionId be the same or will a new SessionId let med keep the existing subscriptions? What is the best way to simulate a connection error?
Many questions :-)
A sample from the code where I create the subscription containing some MonitoredItems and the MonitoredItem_Notification event method.
Any OPC UA Guru out there??
if (node.Displayname == "node to monitor")
{
MonitoredItem mon = CreateMonitoredItem((NodeId)node.reference.NodeId, node.Displayname);
m_subscription.AddItem(mon);
m_subscription.ApplyChanges();
}
private MonitoredItem CreateMonitoredItem(NodeId nodeId, string displayName)
{
if (m_subscription == null)
{
m_subscription = new Subscription(m_session.DefaultSubscription);
m_subscription.PublishingEnabled = true;
m_subscription.PublishingInterval = 3000;//1000;
m_subscription.KeepAliveCount = 10;
m_subscription.LifetimeCount = 10;
m_subscription.MaxNotificationsPerPublish = 1000;
m_subscription.Priority = 100;
bool cache = m_subscription.DisableMonitoredItemCache;
m_session.AddSubscription(m_subscription);
m_subscription.Create();
}
// add the new monitored item.
MonitoredItem monitoredItem = new MonitoredItem(m_subscription.DefaultItem);
//Each time a monitored item is sampled, the server evaluates the sample using a filter defined for each monitoreditem.
//The server uses the filter to determine if the sample should be reported. The type of filter is dependent on the type of item.
//DataChangeFilter for Variable, Eventfilter when monitoring Events. etc
//MonitoringFilter f = new MonitoringFilter();
//DataChangeFilter f = new DataChangeFilter();
//f.DeadbandValue
monitoredItem.StartNodeId = nodeId;
monitoredItem.AttributeId = Attributes.Value;
monitoredItem.DisplayName = displayName;
//Disabled, Sampling, (Report (includes sampling))
monitoredItem.MonitoringMode = MonitoringMode.Reporting;
//How often the Client wish to check for new values on the server. Must be 0 if item is an event.
//If a negative number the SamplingInterval is set equal to the PublishingInterval (inherited)
//The Subscriptions KeepAliveCount should always be longer than the SamplingInterval/PublishingInterval
monitoredItem.SamplingInterval = 500;
//Number of samples stored on the server between each reporting
monitoredItem.QueueSize = 100;
monitoredItem.DiscardOldest = true;//Discard oldest values when full
monitoredItem.CacheQueueSize = 100;
monitoredItem.Notification += m_MonitoredItem_Notification;
if (ServiceResult.IsBad(monitoredItem.Status.Error))
{
return null;
}
return monitoredItem;
}
private void MonitoredItem_Notification(MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs e)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new MonitoredItemNotificationEventHandler(MonitoredItem_Notification), monitoredItem, e);
return;
}
try
{
if (m_session == null)
{
return;
}
MonitoredItemNotification notification = e.NotificationValue as MonitoredItemNotification;
if (notification == null)
{
return;
}
string sess = m_session.SessionId.Identifier.ToString();
string s = string.Format(" MonitoredItem: {0}\t Value: {1}\t Status: {2}\t SourceTimeStamp: {3}", monitoredItem.DisplayName, (notification.Value.WrappedValue.ToString().Length == 1) ? notification.Value.WrappedValue.ToString() : notification.Value.WrappedValue.ToString(), notification.Value.StatusCode.ToString(), notification.Value.SourceTimestamp.ToLocalTime().ToString("HH:mm:ss.fff"));
richTextBox1.AppendText(s + "SessionId: " + sess);
}
catch (Exception exception)
{
ClientUtils.HandleException(this.Text, exception);
}
}e here
I don't know how much of this, if any, the SDK you're using does for you, but the approach when reconnecting is generally:
try to resume (re-activate) your old session. If this is successful your subscriptions will already exist and all you need to do is send more PublishRequests. Since you're trying to test by closing the session this probably won't work.
create a new session and then call the TransferSubscription service to transfer the previous subscriptions to your new session. You can then start sending PublishRequests and you'll get the queued notifications.
Again, depending on the stack/SDK/toolkit you're using some or none of this may be handled for you.
I'm working on a UWP application which should communicate via TCP/UDP to a remote device. My issue is that the UWP app successfully sends UDP messages to the remote device, but does not receive the replies.
Here follows the code extracted from the app (simplified):
async Task TestUdpIP()
{
// Writer to the DatagramSocket
DataWriter writer;
using (var udpClient = new DatagramSocket())
{
try
{
// UDP Socket binding
udpClient.MessageReceived += UdpClient_MessageReceived;
var controllerName = new Windows.Networking.HostName(controllerIpAddress.ToString());
await udpClient.BindEndpointAsync(controllerName, controllerIpPort.ToString());
var remoteHostName = new Windows.Networking.HostName(hostIpAddres.ToString());
await udpClient.ConnectAsync(remoteHostName, remoteHostPort.ToString());
// Create a message to send
string message = "Some message";
// Reset the counter of messages received back from the remote robot
messagesReceived = 0;
// Send the message
writer = new DataWriter(udpClient.OutputStream);
writer.WriteString(message);
await writer.StoreAsync();
// Wait for robot status messages
await Task.Delay(5000);
}
catch
{
}
}
}
void UdpClient_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
// Just increment the number of messages received
messagesReceived++;
}
However the UdpClient_MessageReceived handler does not fire. I'm sure that UDP messages are correctly sent from the UWP app and that the remote device replies back as shown in the following screenshot from Wireshark (the test has been taken on the same PC where the UWP app is running)
.
(IP Address, Port) details are shown in the following list to better explain the picture above
UWP application: (192.168.1.108, 19000) to send and receive.
Remote device: (192.168.1.152, 15999) to receive and (192.168.1.152, 54697) to send
Note: this is a similar question, where the answer says that for whatever reason the DatagramSocket should fire some messages before being able to receive. In my example a message is sent out however the message received handler does not fire anyway.
Note: The UWP app has been granted the internet (client) and the internet (client and server) capabilities
Note: I've tried also this (more readable) approach to bind the inbound/outbound datagram socket on the UWP app obtaining the same results:
// UDP Socket binding
var controllerName = new HostName(controllerIpAddress.ToString());
var remoteHostName = new HostName(hostIpAddres.ToString());
EndpointPair endpointpar = new EndpointPair(controllerName,
controllerIpPort.ToString(),
remoteHostName,
remoteHostPort.ToString());
udpClient.MessageReceived += UdpClient_MessageReceived;
await udpClient.ConnectAsync(endpointpar);
Where is the issue? Many thanks!
Please try to also add the Private Networks (Client & Server) capability in your app's manifest.
On other hand, you can try the Official DatagramSocket sample to see whether the both devices can communicate with each other.
After some experimenting, I came out with the idea of using two different DatagramSocket instances: one to send out UDP messages, and one to listen for incoming messages. With this code, I've been able to send UDP messages to the remote device (as before) and also I've been able to receive UDP messages from the remote device.
async Task TestUdpIP_DifferentPorts()
{
// Writer to the DatagramSocket
DataWriter writer;
// Inbound and outbound DatagramSocket
DatagramSocket udpListener = new DatagramSocket();
DatagramSocket udpSender = new DatagramSocket();
try
{
// String containing the serializaed message
string serializedMessage = "Some message";
var controllerName = new HostName(controllerIpAddress.ToString());
var remoteHostName = new HostName(hostIpAddres.ToString());
// Bind listener
udpListener.MessageReceived += UdpClient_MessageReceived;
await udpListener.BindEndpointAsync(controllerName, controllerIpPort.ToString());
// Connect sender
await udpSender.ConnectAsync(remoteHostName, remoteHostPort.ToString());
// Reset the counter of messages received back from the remote robot
messagesReceived = 0;
// Send the message
writer = new DataWriter(udpSender.OutputStream);
writer.WriteString(JsonConvert.SerializeObject(message));
await writer.StoreAsync();
// Wait for robot status messages
await Task.Delay(1000);
}
catch (Exception ex)
{
// Some exception handling
}
udpSender.Dispose();
udpListener.Dispose();
}
void UdpClient_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
// Just increment the number of messages received
messagesReceived++;
}
With this approach only the IP port (or service name) of the inbound listener needs to be specified. The framework will choose the next available outbound IP port.
Note: If I understand well the DatagramSocket.ConnectAsync(EndpointPair) documentation, the same DatagramSocket instance can be used to send and listen for incoming message, so I could not figure out the need for two different instances. From the documentation:
This ConnectAsync(EndPointPair) method on a DatagramSocket is used to define the local and remote endpoint where datagrams will be sent when using the OutputStream property. This method also restricts remote IP addresses of packets that will be accepted to the remote hostname in the endpointPair parameter. Only incoming packets that match the remote endpoint in the endpointPair parameter will trigger the MessageReceived event on the DatagramSocket.