IOS bluetooth serial connection to a remote PC/MAC - java

I have read about several questions about similar issue. But most of them are related with 3rd party bluetooth device connections. What I need is, to establish a bluetooth serial connection between IOS and a server applet which is waiting for a connection. This applet is supposed to run on Windows or MAC OS. Here is the Java code of the server applet:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import static my.remote.RemoteUI.OSName;
import javax.bluetooth.*;
import javax.microedition.io.*;
import static my.remote.ProcessInput.line;
import static my.remote.RemoteUI.OSName;
/**
* Class that implements an SPP Server which accepts single line of
* message from an SPP client and sends a single line of response to the client.
*/
public class Sspserver implements Runnable {
private static boolean Connected = true;
//start server
private void startServer() throws IOException{
//Create a UUID for SPP
UUID uuid = new UUID("1101", true);
//Create the servicve url
String connectionString = "btspp://localhost:" + uuid +";name=Sample SPP Server";
//open server url
StreamConnectionNotifier streamConnNotifier = (StreamConnectionNotifier)Connector.open( connectionString );
//Wait for client connection
System.out.println("\nServer Started. Waiting for clients to connect...");
StreamConnection connection=streamConnNotifier.acceptAndOpen();
RemoteDevice dev = RemoteDevice.getRemoteDevice(connection);
System.out.println("Remote device address: "+dev.getBluetoothAddress());
System.out.println("Remote device name: "+dev.getFriendlyName(true));
//read string from spp client
InputStream inStream=connection.openInputStream();
BufferedReader bReader=new BufferedReader(new InputStreamReader(inStream));
while(Connected){
try {
String lineRead=bReader.readLine();
System.out.println(lineRead);
String com = lineRead.substring(0, lineRead.length());
CommandActivity command = new CommandActivity();
if ((lineRead != null) && (OSName != null)) {
command.Command(com,OSName);
System.out.println(com);
}
}catch(Exception e) {
return;
}
}
}
#Override
public void run() {
try {
//display local device address and name
LocalDevice localDevice = LocalDevice.getLocalDevice();
System.out.println("Address: "+localDevice.getBluetoothAddress());
System.out.println("Name: "+localDevice.getFriendlyName());
//Sspserver sampleSPPServer=new Sspserver();
startServer();
} catch (BluetoothStateException ex) {
System.out.println(ex.getMessage());
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
CommandActivity class is just parsing the line of data coming from device. Android devices can easily connect to this server using PC's MAC address. But for IOS I couldn't find any solution for socket connection for bluetooth.
I tried EAAccessoryManager but unfortunately IOS device couldn't detect PC as an accessory. It needs Supported external accessory protocols definitions but I can't find all PC or MAC protocols.
Also I tried CoreBluetooth. But this applet is not advertising name or UUID of services/characteristics.
There must be an easy way which I may be missing. A simple serial connection shouldn't be a problem for an operating system which has lots of features like IOS. Any suggestion appreciated. Thanks.

You cannot estalish a serial port connection from an iOS app over Bluetooth unless the device you are connecting to is MFi certified, which lets you use the external accessory framework. Since your PC is not an MFi certified device, it won't work.
You will either need your PC to advertise as a BLE device so that you can use Core Bluetooth or use an alternative connection method, such as TCP/IP via wifi.

Related

How to give certificate to Java Websocket?

Forgive me for the newb question, but I am confused and obviously not understanding the fundamentals or explanations of how to use a Websocket server hosted over HTTPS. Everything I find online leads me to have more questions than answers.
I have a Websocket server hosted on my HTTPS website using Java code.
This is my WebsocketServer.java file:
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import java.net.InetSocketAddress;
import java.util.HashSet;
import java.util.Set;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class WebsocketServer extends WebSocketServer {
private static final Logger logger = LogManager.getLogger(WebsocketServer.class);
private static int TCP_PORT = 6868;
private static Set<WebSocket> conns;
public WebsocketServer() {
super(new InetSocketAddress(TCP_PORT));
conns = new HashSet<>();
}
#Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
conns.add(conn);
logger.info("New connection from " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
logger.info("Size of connection list: " + conns.size());
}
#Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
conns.remove(conn);
logger.info("Closed connection to " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
}
#Override
public void onMessage(WebSocket conn, String message) {
logger.info("Message from client: {}", message);
// for (WebSocket sock : conns) {
// sock.send("SENDING BACK" + message);
// }
}
#Override
public void onError(WebSocket conn, Exception ex) {
// ex.printStackTrace();
try {
if (conn != null) {
conns.remove(conn);
// do some thing if required
}
logger.info("ERROR from {}", conn.getRemoteSocketAddress().getAddress().getHostAddress());
} catch (Exception e) {
logger.info("onError: WebSocketServer may already be running");
}
}
public Set<WebSocket> getConns() {
return conns;
}
}
Then I started the WebsocketServer like this:
WebsocketServer websocketServer;
// Start socket server
websocketServer = new WebsocketServer();
websocketServer.start();
And on the client side, I connect to it like this:
// APP_WEB_SOCKET is the url to my site: api.my_custom_domain.com
var connection = new WebSocket("wss://" + APP_WEB_SOCKET + ":6868");
QUESTIONS:
I keep reading that I need a certificate if I want to use wss over HTTPS, but cannot find any documents that explain what this means in a way that I can understand.
My app is hosted in AWS Elastic Beanstalk environment. Do I need to somehow add a certificate to the setup of the WebsocketServer in my Java code?
Example:
WebsocketServer websocketServer;
// Start socket server
websocketServer = new WebsocketServer();
// example guessing
websocketServer.cert = "SOMETHING";??
websocketServer.start();
Does the client code need to be changed at all?
Who needs the certificate?
If someone could please explain what I am missing or point me in the correct direction, I would really appreciate it.
Keep it easy.
Certs inside your application are complex - they are hard to manage and you will get problems to run your application in a modern cloud environment (start new environments, renew certs, scale your application, ...).
Simple conclusion: Dont implement any certs.
How-to get encrypted connections?
As Mike already pointed out in the comments: WebSockets are just upgraded HTTP(S) connections. A normal webserver (nginx, apache) takes care about the certs. It can be done in kubernetes (as ingress-controller) or with a "bare-metal" webserver.
Both of them should act as a reverse-proxy. This means: Your java-application doesn't know anything about certs. It has just unencrypted connections - like in your code on port 6868.
But the client will not use this port. 6868 is only internally reachable.
The client will call your reverse-proxy at the normal HTTPS port (=443). The reverse-proxy will forward the connection to your java-application.
Here some links for further information:
nginx reverse-proxy
nginx reverse-proxy for websocket
tutorial for java behind reverse-proxy
LetsEncrypt for automatic and free certs

Java unknownhostException with two computers

import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;
public class ChatClient{
private final String serverName;
private final int serverPort;
private Socket socket;
private InputStream serverIn;
private OutputStream serverOut;
public ChatClient(String serverName, int serverPort) {
this.serverName = serverName;
this.serverPort = serverPort;
}
public static void main(String[] args){
ChatClient client = new ChatClient("raspberrypi", 6342);
if (!client.connect()){
System.err.println("Connect failed");
}else{
System.out.println("Connected");
}
}
private boolean connect(){
try{
this.socket = new Socket("raspberrypi", 6342);
this.serverOut = socket.getOutputStream();
this.serverIn = socket.getInputStream();
return true;
}catch (IOException e){
e.printStackTrace();
}
return false;
}
}
I have a server which I am running which is waiting for an client to join. However since I am using the client on my computer and the server on my raspberry pi, I keep getting the unknown host exception. I have tried to put the hostname of the raspberry pi in but it doesn't seem to work. P.s I might be getting the host name wrong.
It does not work, because the value you provide to the first argument (raspberrypi) is not a valid host name.
You need to pass there the IP address of your raspberry in your network.
If you are using home router, you can even set static IP for your raspberry (it's common, because without that, every time you restart your raspberry, you may get different address from DHCP server).
After you know the address of your raspberry, simply replace "raspberrypi" with the address (in form of "192.168.0.10" depending on your configuration).
Here's how to set static IP: https://www.raspberrypi.org/learning/networking-lessons/rpi-static-ip-address/
Edit the file /etc/dhcpcd.conf as follows:
Type sudo nano /etc/dhcpcd.conf at the command prompt.
Scroll to the bottom of the script, and add the following lines:
interface eth0
static ip_address=192.168.0.2/24 static routers=192.168.0.1 static
domain_name_servers=192.168.0.1
interface wlan0
static ip_address=192.168.0.2/24 static routers=192.168.0.1 static
domain_name_servers=192.168.0.1
Save the file with ctrl + o and then
exit nano with ctrl + x. Your Raspberry Pi will now boot up with the
IP address 192.168.0.2 every time; we didn't use 192.168.0.1 as this
is reserved for the router. You can of course use any address you
like, but in the configuration above the range must be between
192.168.0.2 and 192.168.0.255.

cannot get android app to connect to my server on my local computer

Hi I'm new to android and Im
Trying to get my android app to connect to a my server that is running on my local computer. Im just trying to get the app to send a simple string message to the server first but keep getting an error. From the print out statements i can see that the app terminates as soon as it hits the line with the try in it so i believe there is an issue with creating the client connection. I have also enable Internet,ACCESS_NETWORK_STATE, ACCESS_WIFI_STATE,READ_EXTERNAL_STORAGE,WRITE_EXTERNAL_STORAGE permissions
i tried changing the localhost to InetAddress.getLocalHost() but still wouldn't work
heres my code :
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.util.StringBuilderPrinter;
import android.view.View;
import android.widget.Button;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import static java.net.InetAddress.getLocalHost;
public class MainActivity extends AppCompatActivity{
private Button cam;
private Socket client;
DataOutputStream os;
private String IP = "localhost";
private static final String TAG = "testing";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (android.os.Build.VERSION.SDK_INT > 9)
{
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
setContentView(R.layout.activity_main);
cam = (Button) findViewById(R.id.Button_camera);
cam.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v(TAG, "trying to connect to server");
try {
client = new Socket("My IP address entered", 8080);
Log.v(TAG, "client socket initalised");
String hey = "hey";
os = new DataOutputStream(client.getOutputStream());
Log.v(TAG, "outptu stream created");
os.flush();
Log.v(TAG, "flush");
os.writeBytes(hey);
Log.v(TAG, "written to server");
os.close();
} catch (UnknownHostException e) {
Log.v(TAG, "Unknown error");
Log.v(TAG, e.toString());
} catch (IOException e) {
Log.v(TAG, "IO exception u numpty");
Log.v(TAG, e.toString());
}
Intent intent = new Intent(MainActivity.this, Main2Activity.class);
startActivity(intent);
}
});
}
}
my code prints out the statement trying to connect to server but doesn't reach any of the other print out statements and my server is still not receiving anything
connect failed: ETIMEDOUT (Connection timed out)
ACTION_DOWN before UnsetPressedState. invoking mUnsetPressedState.run()
I/Choreographer: Skipped 3792 frames! The application may be doing too much work on its main thread.
I believe this is definitely just an issue with your IP, you are obviously giving ti the wrong ip address because everything else is fine. I would recommend either accessing the terminal and using the ifconfig command to find your ip or access your network settings, if your using a mac like I am select network , advance options , select tcp/ip tab and use ipv4 address as the ip address. If that doesn't work try using a different port or checking your firewall setting on your local computer. Hope that helps.
Localhost is the phone itself, not your computer. If on a simulator, localhost is the simulator, not your computer- the simulator doesn't know its a simulator, it has its own IP address. Fix the IP you're using.

Java RMI for remote ip (host)

I am newbie. I cannot understand RMI correctly. There are tons of tutorials available on the internet ,but all of them are for the local host as I can understand. Both server and client run on the same machine.
I want to run client on any machine and the host will be on the one computer lets consider IP - 11.11.11.11. On the 1099.
But how can I achieve this, where should I specify my IP on the client side. As I understand naming convertion is used, like DNS but anyway when I need to connect to some machine remotely I need to know at least IP address (+mask) and port.
I guess I missed something really important.
Please give some example how to configure RMI remotly not on the same host.
First you have to setup a server whose method or object can be accessed by any remote client
Below is example code for the server.
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface MyCalc extends Remote{
int add(int a, int b) throws RemoteException;
}
import java.rmi.RemoteException;
public class MyCalcImpl implements MyCalc {
#Override
public int add(int a, int b) throws RemoteException {
return (a + b);
}
}
Start the rmi registry on server machine so you can register your object to this registry and better you run it where you have placed your classes otherwise you will get ClassNotFound.
rmiregistry 1099
Note: you might need to change the port if port is already in use.
Register you object to rmi registry with name 'calculator'.
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class MyRMIServer {
public static void main(String[] args) throws Exception {
System.setProperty("java.security.policy","file:///tmp/test.policy");
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
String name = "Calculator";
MyCalc engine = new MyCalcImpl();
MyCalc stub = (MyCalc) UnicastRemoteObject.exportObject(engine, 0);
Registry registry = LocateRegistry.getRegistry(1099);
System.out.println("Registering Calculator Object");
registry.rebind(name, stub);
} catch (Exception e) {
System.err.println("Exception:" + e);
e.printStackTrace();
}
}
}
Note: To run the program you have to setup a security policy file and for that creat a file e.g. test.policy and copy below content.
grant {
permission java.security.AllPermission;
permission java.net.SocketPermission "localhost:1099", "connect, resolve";
permission java.net.SocketPermission "127.0.0.1:1099", "connect, resolve";
permission java.net.SocketPermission "localhost:80", "connect, resolve";
};
You can change IP and port as per your case.
After starting the server, suppose your server's IP address is 11.11.11.11 then you can invoke the MyCalc's add() on the server. So on your client machine your client code would be like:
Copy the MyCalc class from server to client machine so you can set it to the classpath while compiling client's code.
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class MyRMIClient {
public static void main(String args[]) {
System.setProperty("java.security.policy","file:///tmp/test.policy");
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
try {
String name = "Calculator";
String serverIP = "11.11.11.11"; // or localhost if client and server on same machine.
int serverPort = 1099;
Registry registry = LocateRegistry.getRegistry(serverIP, serverPort);
MyCalc mycalc = (MyCalc) registry.lookup(name);
int result = mycalc.add(10, 20);
System.out.println("Result:" + result);
} catch (Exception e) {
System.err.println("ComputePi exception:");
e.printStackTrace();
}
}
}
compile and test the client's code.
EDIT: edited to remove dependency on rmi compiler (rmic)
You only have to specify the server's IP address in one place: the lookup string supplied to Naming.lookup().
[Unless you have the Linux problem referred to in the RMI FAQ item A.1.]

Trouble connecting to the Internet using MDS from a Blackberry (works fine in the Simulator)

I have some code to connect to the internet, it works fine in the simulator
but when I try it on a real device, I always get a 400 http response code
(the response body says "Connection timed out")
I'm using JRE 5
and using Blackberry 9000 on OS version 5 for both the real device and the simulator.
It is activated according to Advanced Options > Enterprise Activation
Is there something else I need to change on the real device to make it work?
I slowly whittled down my code to get to the root of the issue
and I'm down to this code:
package mypackage;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import net.rim.device.api.io.transport.TransportInfo;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.container.MainScreen;
public class MyApp extends UiApplication {
public static void main(String[] args) {
MyApp theApp = new MyApp();
theApp.enterEventDispatcher();
}
public MyApp() {
pushScreen(new SimpleScreen());
}
}
class SimpleScreen extends MainScreen {
public SimpleScreen() {
this.setTitle("Hello");
ConnectionThread ct = new ConnectionThread();
ct.start();
}
}
class ConnectionThread extends Thread {
private static String url = "http://www.wikipedia.org/";
public void run() {
System.out.println(" -- ConnectionThread.run()");
System.out.println(" ---- MDS hasSufficientCoverage? " + TransportInfo.hasSufficientCoverage(TransportInfo.TRANSPORT_MDS));
try {
HttpConnection httpConn;
httpConn = (HttpConnection) Connector.open(url);
final int iResponseCode = httpConn.getResponseCode();
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert("Response code: " + Integer.toString(iResponseCode));
}
});
} catch (Exception e) {
System.err.println("Caught IOException: " + e.getMessage());
}
System.out.println(" -- /ConnectionThread.run()");
}
}
==============================================
// EDIT:
I'm pretty sure its a device config issue now, I just the Network Diagnostic Tool and it also returns a 400 HTTP Response with the message "connect timed out".
==============================================
//EDIT #2:
I just tried options->mobile network->diagnostics test
Here are the results:
ICMP Ping Echo: No
------
Blackberry Registration: Yes
Connected to Blackberry: Yes
Blackberry PIN-PIN: Yes
------
Server Name: <my enterprise server>
Email Address: <my email>
Connected to <my email>: Yes
Then I tried options->mobile network->tools->ping
and pinged google and wikipedia and both say A network error occurred
Are you sure that your BB device is connected to any BES server? I would suggest that you first try to access internet from BB browser.
I asked the BES Admin and he says its Docomo issue.. and he has taken it up with them.
Basically there's no code problem (as far as I can tell)

Categories

Resources