Is there any RIM API available which will help to get the list of available network service or only Wi-Fi networks for a device and set selected network access point for any network communications?
Is it possible for my application to disable the mobile networks like GPRS, WAP, etc.?
Example:
When the application is started it should scan for Wi-Fi connections, even if there are no previous Wi-Fi network access points set on the device, and list the available Wi-Fi connections. Then the user will select the appropriate Wi-Fi connection to connect for any network communication. Outside the application any Internet communication, like the browser or any other application, should be done through the same selected Wi-Fi connection.
The scanning for Wi-Fi and setting the connection is almost similar to BlackBerry Wi-Fi Setup.
I am looking to do this for BlackBerry OS 4.5, 4.7 and 5.0.
Update
The thing is I'm looking for Wi-Fi scanning through application. It's like through the application I am able to scan available Wi-Fi access points or hotspots and set one of access point by selecting it to device, then connect to it for communication.
Basically it's like, how do we set the Wi-Fi connection in "Manage connetion" of BlackBerry? I have to do a similar thing through the applicaiton.
From some BlackBerry forums I got to know there is package in OS v5.0, that is, a net.rim.device.api.wlan.hotspot package to get the Wi-Fi hotspots. But after a long search I didn't find any sample example or much explanation on it. As I am trying to implement by looking into its API documentation, but I did not succeded.
If you have any idea related to this or any sample code it will be very helpful.
Well, to scan for all available networks for the application you can use the NetworkDiagnostic tool from RIM.
Anther piece of code to scan for your phone connectivity and get the best connection string can be found in How to reliably establish a network connection on any BlackBerry device,
/**
* Determines what connection type to use and returns the necessary string to use it.
* #return A string with the connection info
*/
private static String getConnectionString()
{
// This code is based on the connection code developed by Mike Nelson of AccelGolf.
// http://blog.accelgolf.com/2009/05/22/blackberry-cross-carrier-and-cross-network-http-connection
String connectionString = null;
// Simulator behavior is controlled by the USE_MDS_IN_SIMULATOR variable.
if (DeviceInfo.isSimulator())
{
if (UploaderThread.USE_MDS_IN_SIMULATOR)
{
logMessage("Device is a simulator and USE_MDS_IN_SIMULATOR is true");
connectionString = ";deviceside=false";
}
else
{
logMessage("Device is a simulator and USE_MDS_IN_SIMULATOR is false");
connectionString = ";deviceside=true";
}
}
// Wi-Fi is the preferred transmission method.
else if (WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED)
{
logMessage("Device is connected via Wifi.");
connectionString = ";interface=wifi";
}
// Is the carrier network the only way to connect?
else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_DIRECT) == CoverageInfo.COVERAGE_DIRECT)
{
logMessage("Carrier coverage.");
String carrierUid = getCarrierBIBSUid();
if (carrierUid == null)
{
// Has carrier coverage, but not BIBS. So use the carrier's TCP network
logMessage("No Uid");
connectionString = ";deviceside=true";
}
else
{
// otherwise, use the Uid to construct a valid carrier BIBS request
logMessage("uid is: " + carrierUid);
connectionString = ";deviceside=false;connectionUID="+carrierUid + ";ConnectionType=mds-public";
}
}
// Check for an MDS connection instead (BlackBerry Enterprise Server).
else if ((CoverageInfo.getCoverageStatus() & CoverageInfo.COVERAGE_MDS) == CoverageInfo.COVERAGE_MDS)
{
logMessage("MDS coverage found");
connectionString = ";deviceside=false";
}
// If there is no connection available abort to avoid bugging the user unnecssarily.
else if (CoverageInfo.getCoverageStatus() == CoverageInfo.COVERAGE_NONE)
{
logMessage("There is no available connection.");
}
// In theory, all bases are covered so this shouldn't be reachable.
else
{
logMessage("no other options found, assuming device.");
connectionString = ";deviceside=true";
}
return connectionString;
}
/**
* Looks through the phone's service book for a carrier provided BIBS network
* #return The uid used to connect to that network.
*/
private static String getCarrierBIBSUid()
{
ServiceRecord[] records = ServiceBook.getSB().getRecords();
int currentRecord;
for (currentRecord = 0; currentRecord < records.length; currentRecord++)
{
if (records[currentRecord].getCid().toLowerCase().equals("ippp"))
{
if (records[currentRecord].getName().toLowerCase().indexOf("bibs") >= 0)
{
return records[currentRecord].getUid();
}
}
}
return null;
}
Related
Working on a new product at work that will be using an ESP8266, Xamarin app, and the Azure IoTHub to enable bidirectional communication for customer's devices.
We've got C2D (Cloud 2 Device) and D2C (Device 2 Cloud) communication working properly on both the app and the ESP, but we are not finding any information on setting up the IoTHub to interpret incoming Telemetry messages, process their respective "To:" field and put them back in to the C2D topic, which should allow our target device to receive it.
What we have tried:
Logic Apps. Were able to trigger on incoming messages to the queue, but not sure what HTTP request to do in order to forward it back in to the C2D event hub.
We have successfully been able to forward each message in to a queue, but the PCL library for Xamarin is not capable of connecting to Azure Service Bus Queues (bummer).
I found a reference for an intern at Microsoft developing direct device to device communication for a garage door opener, but the library she is using is only available for UWP apps, which isn't all that convenient, when we really want to target iOS, Android and UWP (reason for choosing Xamarin in the first place).
https://blogs.windows.com/buildingapps/2016/09/08/device-to-device-communication-with-azure-iot-hub/#ykPJrVE734GpSEzV.97
Has anyone been able to trigger C2D conditional events using the Azure portal?
Through some conversations with Microsoft Azure team, we determined that a webjob combined with a route to a queue was the best solution for us.
All messages are routed to the queue and as they arrive in the queue, the webjob processes the message and sends the message on using a ServiceBus Messaging object to send the cloud to device response message.
Here's the code for anyone who wants to use it.
As long as the original sender of the message specifies the "To" property in the brokered message, it will be delivered to that device in the registry. You will need the Service Bus and Azure.Messaging NuGet packages in order to use this. This code will copy the entire message and send the whole thing to the desired registry device.
private const string queueName = "<queue_name>";
private const string IoTHubConnectionString = "HostName=<your_host>;SharedAccessKeyName=<your_service_user>;SharedAccessKey=<your sas>";
// This function will get triggered/executed when a new message is written
// on an Azure Queue called <queue_name>.
public static void ReceiveQueueMessages(
[ServiceBusTrigger(queueName)] BrokeredMessage message,
TextWriter log)
{
if (message.To == null)
{
//message = null
return;
}
else
{
//Retrieve the message body regardless of the content as a stream
Stream stream = message.GetBody<Stream>();
StreamReader reader;
if (stream != null)
reader = new StreamReader(stream);
else
reader = null;
string s;
Message serviceMessage;
if ( reader != null )
{
s = reader.ReadToEnd();
serviceMessage = new Microsoft.Azure.Devices.Message(Encoding.ASCII.GetBytes(s));
}
else
{
serviceMessage = new Microsoft.Azure.Devices.Message();
}
foreach (KeyValuePair<string, object> property in message.Properties)
{
serviceMessage.Properties.Add(property.Key, property.Value.ToString());
}
SendToIoTHub(message.To.ToString(), serviceMessage);
}
}
static async void SendToIoTHub(string target, Microsoft.Azure.Devices.Message message)
{
// Write it back out to the target device
ServiceClient serviceClient = ServiceClient.CreateFromConnectionString(IoTHubConnectionString);
var serviceMessage = message;
serviceMessage.Ack = DeliveryAcknowledgement.Full;
serviceMessage.MessageId = Guid.NewGuid().ToString();
try
{
await serviceClient.SendAsync(target, serviceMessage);
}
catch
{
await serviceClient.CloseAsync();
return;
}
await serviceClient.CloseAsync();
}
I have searched a lot for this but could not find any specific answer that applies to my case. I have made device using GPS module and GSM/GPRS module with Arduino Mega 2560, and it sends me the location through SMS. Now I want to get the location parameters using GPRS. I have in mind to use TCP. I will send data through AT Commands from GPRS module, but I am confused on how to make a server on C#. I know that I would be needing a static/public IP for this. But I don't know how to get the public IP, and start receiving data which I send from GPRS module. Please please I need help because I am a beginner in Client/Server programming, and I am working on my final year project. Many thanks in advance!
please take a look at this TCP server and client example.
You will need a public static IP address. That is something you have to ask your broadband provider, and they will explain you the available options they have, probably you will have to pay extra money. You can use your current public IP address, that will be probably dynamic, but they don't use to change way to often, so whenever you are unable to connect, you will have to check if the IP changed or not, and set the new one.
This video series maybe a good introduction: https://vimeo.com/38103518
Here is the Server Code:
class Server
{
TcpListener server = null;
public Server(string ip, int port)
{
IPAddress localAddr = IPAddress.Parse(ip);
server = new TcpListener(localAddr, port);
server.Start();
StartListener();
}
public void StartListener()
{
try
{
while (true)
{
Console.WriteLine("Waiting for a connection... ");
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Connected!");
Thread t = new Thread(new ParameterizedThreadStart(HandleDeivce));
t.Start(client);
}
}
catch (SocketException e)
{
Console.WriteLine("SocketException: {0}", e);
}
}
public void HandleDeivce(Object obj)
{
TcpClient client = (TcpClient)obj;
NetworkStream stream = client.GetStream();
string data = null;
Byte[] bytes = new Byte[256];
int i;
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine("{1}: Received: {0}", data, Thread.CurrentThread.ManagedThreadId);
if (data.StartsWith("##"))
{
data = "LOAD";
}
else
{
data = "ON";
}
byte[] msg = Encoding.ASCII.GetBytes(data);
stream.Write(msg, 0, msg.Length);
Console.WriteLine("{1}: Sent: {0}", data, Thread.CurrentThread.ManagedThreadId);
}
client.Close();
}
}
I have a WebMatrix 3 (same as ASP.NET) web page that opens a socket to a server process running on an Azure hosted Linux VM that listens on a TCP connection for clients. The Linux VM server process is mine too. When I run the WebMatrix 3/ASP.NET web site locally from my home PC using a local copy of IIS it works fine (local publish). When I publish my web site to the web and it is now running on Azure I get the Exception:
An attempt was made to access a socket in a way forbidden by its access permissions
What is really confusing is that the error occurs when I read from the socket but oddly enough not when I connect to it or write to it before-hand. I know this because the Exception message is adorned with the current operation, and that is set to:
Waiting for and then reading the response from the ChatScript server.
You can see this line in the code below. Is there something going on with the Azure side that could be blocking reads from the TCP connection to the Linux VM, yet allows connections to that VM and even sends? I say "even sends" because as you can see from the code below, I immediately send a message to the Linux VM process before I try to read from that connection.
public static string readChatScriptMessage(NetworkStream myNetworkStream)
{
if (myNetworkStream == null)
throw new ArgumentNullException("(readChatScriptMessage) The network stream is unassigned.");
StringBuilder myCompleteMessage = new StringBuilder();
// Check to see if this NetworkStream is readable.
if (myNetworkStream.CanRead)
{
byte[] myReadBuffer = new byte[1024];
int numberOfBytesRead = 0;
// Incoming message may be larger than the buffer size.
do
{
numberOfBytesRead = myNetworkStream.Read(myReadBuffer, 0, myReadBuffer.Length);
myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
}
while (myNetworkStream.DataAvailable);
}
else
{
if (myNetworkStream == null)
throw new InvalidOperationException("(readChatScriptMessage) The network stream is unassigned.");
}
// Print out the received message to the console.
return myCompleteMessage.ToString();
} // public static string readChatScriptMessage(NetworkStream myNetworkStream)
// Lookup the IP address for our chatscript server. (Cache this value
// in a later build since GetHostEntry() is reportedly a slow call.)
ipAddress = Dns.GetHostEntry("myazureapp.cloudapp.net").AddressList[0];
strCurrentOperation = "Validating URL arguments (parameters).";
// LoginName, is mandatory.
strLoginName = checkForValidURLArgument("LoginName", true);
// BotName, is optional.
strBotName = checkForValidURLArgument("BotName", false);
// User message (chat input), is optional. But remember,
// only send a blank message to start a new session
// with ChatScript! After that, send the user's input
// each time.
strMessage = checkForValidURLArgument("Message", false);
strCurrentOperation = "Connecting to Linux VM TCP server.";
// OK, we're good to go. We have the 3 URL arguments we were expecting.
// Connect to the ChatScript server.
tcpCli.Connect(ipAddress, 1024);
strCurrentOperation = "Opening the stream with the server.";
// Open the stream
streamChatScript = tcpCli.GetStream();
StreamReader sr = new StreamReader(streamChatScript);
BinaryWriter sw = new BinaryWriter(streamChatScript);
// Create a message to send to the server, using the URL argument values
// passed to us.
ChatMessage cm = new ChatMessage(strLoginName, strBotName, strMessage);
strCurrentOperation = "Sending the desired chat message to the server.";
// Send the message to the chat server.
string strSendChatMsg = cm.ToString();
// Translate the passed message into ASCII and store it as a Byte array.
Byte[] data = System.Text.Encoding.ASCII.GetBytes(strSendChatMsg);
for (int i = 0; i < strSendChatMsg.Length; i++)
{
data[i] = (byte)strSendChatMsg[i];
}
// Send the chat message.
streamChatScript.Write(data, 0, data.Length);
strCurrentOperation = "Waiting for and then reading the response from the server.";
strResponseMsg = ChatMessage.readChatScriptMessage(streamChatScript);
How can I send a custom response upon a custom request on a xampp/wamp based Apache server upon a connection to a specific port?
I'm trying to reply to the \0 a flash app is requesting in order to allow a crossdomain http GET request.
The flash policy request, is made to port 843 by default and i'd like to keep it that way.
The port should get a \0 (ending with a null char,\0 is just for the reference) and replying with something like:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<site-control permitted-cross-domain-policies="master-only"/>
<allow-http-request-headers-from domain="*" headers="*" secure="true" />
<allow-access-from domain="*" to-ports="*" />
</cross-domain-policy>
As far as i know, the request should be return as a plain text, although Content-type, might be needed as well.
I've tried using the following: http://socketpolicyserver.com/ and although it listens to the port and accepts connections, it doesn't reply with the specified xml upon request.
Any methods / ways of achieving a proper reply will be appreciated,
with regards,
Mike.
!---UPDATE--->
I wrote a simple C# web server which listens to port 843, and serves the aforementioned policy - it worked out just fine, however, when using a SecureSocket connection for a secure connection (i.e opening a socket to a HTTPS/SSL protocol) - the request that is sent is encrypted using the hosts certificate. As far as i know, there's no way of listening or acquiring the servers certificate and decrypting the data via an external app hence, the only way is to somehow 'teach' Apache to respond with the crossdomain policy after a proper request is sent via an appropriate port.
Another idea i have is to read the server's certificate file stored in the Apache directory regardless of what happens on the server itself, though imo it's an overkill.
Would love to hear your comments,
Mike.
So here's how i eventually solved it:
I've used this guys code with some modifications: http://www.switchonthecode.com/tutorials/csharp-tutorial-simple-threaded-tcp-server
and created a simple multithreaded web server that listens to port 843, and provides a somewhat general policy upon the appropriate flash request.
There were several examples provided by Adobe, but for some reason, windows didn't like those.
Also note that if you're using the SecureSocket object of flash it should allegedly use the target servers (IIS'/Apaches'/Tomcats' etc..) SSL credentials and will initiate a client Authentication using the public key of the target servers certificate, then again, it might not so this code doesn't have SSL support, although i've started implementing one using C#'s SSL Streams, so far without any luck. If you can make it work via SSL, please let me know.
Hope this code will help,
Mike.
using System;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.IO;
namespace TCPSexyServer
{
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
private void ListenForClients(int p)
{
throw new NotImplementedException();
}
public Server()
{
this.tcpListener = new TcpListener(IPAddress.Any, 843);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication
//with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
UTF8Encoding encoder = new UTF8Encoding();
string sentData = encoder.GetString(message, 0, bytesRead);
Console.WriteLine(sentData);
if (sentData == "<policy-file-request/>\0")
{
String policy = "<?xml version=\"1.0\"?>\n" +
"<!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">\n" +
"<cross-domain-policy>\n" +
"<site-control permitted-cross-domain-policies=\"master-only\"/>\n" +
"<allow-http-request-headers-from domain=\"*\" headers=\"*\" secure=\"true\" />\n" +
"<allow-access-from domain=\"*\" to-ports=\"*\" />\n" +
"</cross-domain-policy>\0";
byte[] buffer = encoder.GetBytes(policy);
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
Console.WriteLine(policy);
}
else
{
tcpClient.Close();
}
System.Diagnostics.Debug.WriteLine(encoder.GetString(message, 0, bytesRead));
}
tcpClient.Close();
}
public static void Main(string[] args)
{
Server blah = new Server();
}
}
}
I am trying to send data using UDP (datagram). I am not able to test application on simulator. I tried running MDS first and then simulator,but it did not work. The error is displayed as Port 8080 already in use on BlackBerry simulator console. How do I change port in simulator? The UDP port to which I am connecting is localhost:5014
I am using simulator for BlackBerry Pearl 8100.
On the Blackberry forum there are comments about issues with datagram under 4.5.0.x up to 4.5.0.83. No wonder there are no UDP samples in sdk.
You always can download 8100 with 4.5.0.108 simulator from http://na.blackberry.com/eng/developers/
Another thing is to use ip, although hostname is allowed in api reference, but when you use MDS simulator it grabs localhost alias.
In the following code you have simple server which is listening to port 135, and bb client which is sending data packet to 127.0.0.1 on port 135.
Desktop server code:
public static void main(String[] args) {
byte[] inBuff = new byte[32];
DatagramSocket socket;
try {
socket = new DatagramSocket(137);
DatagramPacket pckt = new DatagramPacket(inBuff, inBuff.length);
while (true) {
socket.receive(pckt);
System.out.println(new Date() + " " + pckt.getAddress()
+ ":" + pckt.getPort());
socket.send(pckt);
}
} catch (Exception e) {
System.out.println(e.getMessage()+":");
System.out.println(e.getClass().getName());
}
}
BlackBerry client code (tested with Bold 8900 under 4.6.1):
UDPDatagramConnection connection = null;
byte[] outBuff = "Hello!".getBytes();
Datagram outDatagram = null;
try {
connection = (UDPDatagramConnection) Connector
.open("datagram://127.0.0.1:137");
outDatagram = connection.newDatagram(outBuff, outBuff.length);
connection.send(outDatagram);
System.out.println("Datagram packet was sent");
} catch (Exception e) {
System.out.println(e.getMessage()+":");
System.out.println(e.getClass().getName());
}