Using bluecove to receive messages from phone - bluetooth

I am trying to implement a server type specification on my pc that receives messages from my phone and then does stuff with them. I may have the entirely wrong end of the stick here, but I am using bluecove and have this on my pc:
public static void main(String[] args) throws IOException {
System.out.println(System.getProperty("java.class.path"));
//display local device address and name
LocalDevice localDevice = LocalDevice.getLocalDevice();
System.out.println("Address: "+localDevice.getBluetoothAddress());
System.out.println("Name: "+localDevice.getFriendlyName());
System.out.println("Discoverable: "+localDevice.getDiscoverable());
DiscoveryAgent agent = localDevice.getDiscoveryAgent();
RemoteDevice remoteDeviceArray[] = agent.retrieveDevices(0);
System.out.println("array: " + Arrays.toString(remoteDeviceArray));
SelectServiceHandler handler = new SelectServiceHandler(agent);
for (int i=0; i<remoteDeviceArray.length; i++)
{
RemoteDevice remoteDevice = (RemoteDevice)remoteDeviceArray[i];
String address = remoteDevice.getBluetoothAddress();
System.out.println("remoteAddress: " + address);
if (address.equals(myAddress))
{
UUID[] uuidSet = new UUID[1];
uuidSet[0] = new UUID(0x1105); //OBEX Object Push service
int[] attrSet = new int[] {0x0100}; //Service name
agent.searchServices(attrSet, uuidSet, remoteDevice, handler);
System.out.println("successfully found phone");
String service = agent.selectService(uuidSet[0], ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
Server server = new Server();
server.startServer(service);
}
}
}
private void startServer(String service) throws IOException{
DataInputStream inputStream = Connector.openDataInputStream(service);
}
The pc, on boot, looks through the devices it has already paired with. If one of them has "myAddress" (which I specified somewhere else - the id of my phone), it searches the phone's services, and tries to find the OBEX Object Push Service (which I have seen from various guides is what I want to be looking for here).
I then try and open an input stream for this service, to receive messages.
Currently, I get the error:
Exception in thread "main" java.lang.ClassCastException: com.intel.bluetooth.obex.OBEXClientSessionImpl cannot be cast to javax.microedition.io.InputConnection
at com.intel.bluetooth.MicroeditionConnector.openInputStream(MicroeditionConnector.java:565)
at com.intel.bluetooth.MicroeditionConnector.openDataInputStream(MicroeditionConnector.java:545)
at javax.microedition.io.Connector.openDataInputStream(Connector.java:127)
at Server.startServer(Server.java:24)
at Server.main(Server.java:80)
Which I understand from other posts might be because I am trying to cast a client service connection to a server inputstream, but I don't think that's what I am doing here.
Any help would be greatly appreciated, I am really struggling with the whole concept of bluecove.
Cheers.

Related

Connecting using shared access policy and key to IoT Hub using AMQP lite

Following the samples on the AMQP lite github page, I have successfully connected using SASL ANONYMOUS then token on $cbs endpoint. (https://github.com/Azure/amqpnetlite/blob/master/docs/articles/service_to_iothub.md)
Generating SAS tokens on every request is redundant and I would like to use the shared access policy and key as user and password when connecting to IoT Hub.
I have followed the documentation at https://github.com/Azure/amqpnetlite/blob/master/docs/articles/building_application.md#specifying-an-address together with the indications on https://learn.microsoft.com/en-us/azure/iot-hub/iot-hub-devguide-security#protocol-specifics , but i keep getting some unauthenticated error with code "Sys".
Credentials are certainly good as I use them to generate SAS tokens and I've tried variations of the username (with/without domain) with no success. I have specifically checked that username and password are URL encoded.
Following the documentation on SASL standard, the error code Sys seems to indicate some issue on the receiver side (http://www.rfc-base.org/txt/rfc-3206.txt page 3).
Has anyone else hit this problem? Is there any solution or it is possible to connect to IoT Hub this way?
Thanks,
George
I get "amqp:unauthorized-access" error due to without sending put-token message:
string sasToken = GetSharedAccessSignature(null, device_key, resourceUri, new TimeSpan(1, 0, 0));
bool cbs = PutCbsToken(connection, host, sasToken, audience);
I test on Windows 10 desktop with the following code, it works for both sending and receiving:
static string host = "[IOT_HUB_NAME].azure-devices.net";
static int port = 5671;
static string device_id = "[DEVICE_ID]";
static string device_key = "[DEVICE_KEY]";
static Session session;
static void Main(string[] args)
{
Address address = new Address(host, port, null, null);
Connection connection = new Connection(address);
string audience = Fx.Format("{0}/devices/{1}", host, device_id);
string resourceUri = Fx.Format("{0}/devices/{1}", host, device_id);
string sasToken = GetSharedAccessSignature(null, device_key, resourceUri, new TimeSpan(1, 0, 0));
bool cbs = PutCbsToken(connection, host, sasToken, audience);
session = new Session(connection);
SendEvent();
ReceiveCommands();
Console.ReadLine();
}
static private void SendEvent()
{
string entity = Fx.Format("/devices/{0}/messages/events", device_id);
SenderLink senderLink = new SenderLink(session, "sender-link", entity);
var messageValue = Encoding.UTF8.GetBytes("i am a message.");
Message message = new Message()
{
BodySection = new Data() { Binary = messageValue }
};
senderLink.Send(message);
senderLink.Close();
}
static private void ReceiveCommands()
{
string entity = Fx.Format("/devices/{0}/messages/deviceBound", device_id);
ReceiverLink receiveLink = new ReceiverLink(session, "receive-link", entity);
Message received = receiveLink.Receive();
if (received != null)
receiveLink.Accept(received);
Console.WriteLine(received.BodySection.ToString());
receiveLink.Close();
}
For more information you can reference "CONNECTING TO THE AZURE IOT HUB USING AN AMQP STACK".
Update:
Instead of using SAS token like above code piece, the following code use shared access policy and key(SASL PLAIN):
static string host = "[IOT_HUB_NAME].azure-devices.net";
static int port = 5671;
static string device_id = "[DEVICE_ID]";
static string device_key = "[DEVICE_KEY]";
private const string username_hublevel = "iothubowner#sas.root.[IOT_HUB_NAME]";
private const string password_hublevel = "SharedAccessSignature sr={URL-encoded-resourceURI}&sig={signature-string}&se={expiry}&skn={policyName}";
static Session session;
static void Main(string[] args)
{
Address address = new Address(host, port, username_hublevel, password_hublevel);
Connection connection = new Connection(address);
string audience = Fx.Format("{0}/devices/{1}", host, device_id);
string resourceUri = Fx.Format("{0}/devices/{1}", host, device_id);
session = new Session(connection);
SendEvent();
Console.WriteLine("Sent Hello AMQP!");
ReceiveCommands();
Console.ReadLine();
}

Internet Connectivity Listener in Xamarin.Forms

I am new in Xamarin.Forms and I want to check internet connectivity status in iOS and Android app. In fact using CrossConnectivity Plugins I am able to check internet connectivity successfully but It is not working as Listener. For example, When I open my app and internet connection is not there then it shows me message that "No internet connection" and now if I ON my mobile data then also it shows me same message. I am using below code for this:
string isConnected=CrossConnectivity.Current.IsConnected?"Connected":"No Connection";
My app is not able to listen the changing status of internet connectivity in middle something.
Using the plugin CrossConnectivity, you need to listen to changes via the event ConnectivityChanged, so in your page, or your App class, add this code to write an event handler:
CrossConnectivity.Current.ConnectivityChanged += (sender, args) =>
{
//your implementation
this.DisplayAlert("Connectivity Changed", "IsConnected: " + args.IsConnected.ToString(), "OK");
};
I have the solution for Android but i haven't started working on ios part
(better than nothing ;)
First Create a broadcastReceiver
public class Localize: BroadcastReceiver
{
public static Context context;
public Localize(Context ctx)
{
context = ctx;
}
public override void OnReceive (Context context, Intent intent)
{
isNetworkAvailable (context);
}
public void isNetworkAvailable(Context context)
{
Boolean state = false;
ConnectivityManager connectivity = (ConnectivityManager)
context.GetSystemService(Context.ConnectivityService);
if (connectivity != null)
{
NetworkInfo[] info = connectivity.GetAllNetworkInfo();
foreach (NetworkInfo nwork in info)
{
if (nwork.GetState () == NetworkInfo.State.Connected) {
ConnectionDetected();//Execute your fonction here
break;
}
}
}
}
Then register your broadcastreceiver with intent in your activity (in MainActivity for example)
IntentFilter filter = new IntentFilter(ConnectivityManager.ConnectivityAction);
receiver = new Localize(this);
RegisterReceiver(receiver, filter);
This should work as long as your application is running.. If you want a service that runs even if your App is killed you should create a service and then register broadcastReceiver in your service..
CrossConnectivity.Current.IsReachable("localhost");
this also works if you download package. I haven't tested it thoroughly

"Location not available"?

In my android app that I want to develope, I would like the users can find their position. To do this I have this code in the MainActivity but on the device (when i run it) it can't find latitute longitude and the address.Why?
public class MainActivity extends Activity implements LocationListener {
private TextView latituteField;
private TextView longitudeField;
private TextView addressField; //Add a new TextView to your activity_main to display the address
private LocationManager locationManager;
private String provider;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
latituteField = (TextView) findViewById(R.id.TextView02);
longitudeField = (TextView) findViewById(R.id.TextView04);
addressField = (TextView) findViewById(R.id.TextView05); //Make sure you add this to activity_main
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
Location location = locationManager.getLastKnownLocation(provider);
if (location != null) {
System.out.println("Provider " + provider + " has been selected.");
onLocationChanged(location);
} else {
latituteField.setText("Location not available");
longitudeField.setText("Location not available");
}
}
#Override
protected void onResume() {
super.onResume();
locationManager.requestLocationUpdates(provider, 400, 1, this);
}
#Override
protected void onPause() {
super.onPause();
locationManager.removeUpdates(this);
}
#Override
public void onLocationChanged(Location location) {
double lat = location.getLatitude();
double lng = location.getLongitude();
Geocoder geoCoder = new Geocoder(this, Locale.getDefault());
StringBuilder builder = new StringBuilder();
try {
List<Address> address = geoCoder.getFromLocation(lat, lng, 1);
int maxLines = address.get(0).getMaxAddressLineIndex();
for (int i=0; i<maxLines; i++) {
String addressStr = address.get(0).getAddressLine(i);
builder.append(addressStr);
builder.append(" ");
}
String fnialAddress = builder.toString(); //This is the complete address.
latituteField.setText(String.valueOf(lat));
longitudeField.setText(String.valueOf(lng));
addressField.setText(fnialAddress); //This will display the final address.
} catch (IOException e) {}
catch (NullPointerException e) {}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
Toast.makeText(this, "Enabled new provider " + provider,
Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider) {
Toast.makeText(this, "Disabled provider " + provider,
Toast.LENGTH_SHORT).show();
}
}
Note: This is an old answer which did not help solve the particular problem. However, it is valuable information so I don't delete it.
The blinking GPS icon is a good sign. It means that your app is asking the operating system for the location and the operating system tries to fetch it.
The blinking indicates that the operating system did not complete fetching the location via GPS. If this problem persists for, e.g. more than 1 or 2 minutes, it can have the following reasons:
You do not receive the GPS signal (e.g. because you are in a building with too thick walls).
You do not have a data connection to the internet (on some versions of phones and/or android, GPS doesn't work without data connection. Sounds stupid, but it's true. I am a proud owner of such a phone.)
There is some other bug that causes your GPS to be in a state where it does not generate any more location updates. This happened for me sometimes and I do not know any more background info. After a reboot of the phone, it always worked again.
My guess would be that the best provider is not enabled.
try calling getBestProvider(criteria, true)
also Log.d the provider and you can use isProviderEnabled(provider) to see if the provider is enabled.
I've compiled your example and tested it on a Galaxy S2. Here are my findings:
You have code in your examples for two different approaches of getting the location. One approach is to use LocationManager.getLastKnownLocation(...) to fetch the location directly and the other approach is to implement the LocationListener interface and registering for location updates to get notified about new location updates later.
Upfront info: I got the second approach work fine, but I did not get the approach with the getLastKnownLocation method to work reliably.
The location fetching does not work because as provider, "network" is returned. This happens although GPS is on. The subsequent effect is that, because I have the network location provider switched off, the getLastKnowLocation method returns null as documented there: "If the provider is currently disabled, null is returned." (from getLastKnownLocation )
You can fix this by changing
provider = locationManager.getBestProvider(criteria, false);
to
provider = locationManager.getBestProvider(criteria, true);
.
This will give you the GPS provider, if it is available (switched on). However, the getLastKnownLocation(...) method still returns null for me, although the correct provider (gps) is selected and the provider is available. That means that the documentation of the getLastKnownLocation method is lacking information about another case when it returns null. This seems to be because no last known location was saved for this provider. You can not know if this is the case when starting your application, so you can not rely on this method returning a non-null value at application startup.
And here is the good news: Now that we got the correct location provider, the location updates through the second approach (the registering for future location update notifications) works as expected through the gps provider. Updates are coming in and the locations are shown and updated in the textfields on my test phone.

Custom FileResult on Azure: Browser Waits forever

I have an action that returns an Excel as a custom FileResult. My solution is based on the ClosedXml library (internaly using OpenXml).
My XlsxResult class uses a read-only .xlsx file on the server as a template. It then passes on the template into a memory stream that gets manipulated and saved back with ClosedXml. In the end the memory stream get written to the response.
This works fine both on Cassini as well as IIS Express but fails when deployed on azure with no error whatsoever. The only effect I am experiencing is the request sent to the server never gets any response. I am still waiting for something to happen after 60 minutes or so...
My action:
[OutputCache(Location= System.Web.UI.OutputCacheLocation.None, Duration=0)]
public FileResult Export(int year, int month, int day) {
var date = new DateTime(year, month, day);
var filename = string.Format("MyTemplate_{0:yyyyMMdd}.xlsx", date);
//return new FilePathResult("~/Content/templates/MyTemplate.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
var result = new XlsxExportTemplatedResult("MyTemplate.xlsx", filename, (workbook) => {
var ws = workbook.Worksheets.Worksheet("My Export Sheet");
ws.Cell("B3").Value = date;
// Using a OpenXML's predefined formats (15 stands for date)
ws.Cell("B3").Style.NumberFormat.NumberFormatId = 15;
ws.Columns().AdjustToContents(); // You can also specify the range of columns to adjust, e.g.
return workbook;
});
return result;
}
My FileResult
public class XlsxExportTemplatedResult : FileResult
{
// default buffer size as defined in BufferedStream type
private const int BufferSize = 0x1000;
public static readonly string TEMPLATE_FOLDER_LOCATION = #"~\Content\templates";
public XlsxExportTemplatedResult(string templateName, string fileDownloadName, Func<XLWorkbook, XLWorkbook> generate)
: base("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") {
this.TempalteName = templateName;
this.FileDownloadName = fileDownloadName;
this.Generate = generate;
}
public string TempalteName { get; protected set; }
public Func<XLWorkbook, XLWorkbook> Generate { get; protected set; }
protected string templatePath = string.Empty;
public override void ExecuteResult(ControllerContext context) {
templatePath = context.HttpContext.Server.MapPath(System.IO.Path.Combine(TEMPLATE_FOLDER_LOCATION, this.TempalteName));
base.ExecuteResult(context);
}
//http://msdn.microsoft.com/en-us/library/office/ee945362(v=office.11).aspx
protected override void WriteFile(System.Web.HttpResponseBase response) {
FileStream fileStream = new FileStream(templatePath, FileMode.Open, FileAccess.Read);
using (MemoryStream memoryStream = new MemoryStream()) {
CopyStream(fileStream, memoryStream);
using (var workbook = new XLWorkbook(memoryStream)) {
Generate(workbook);
workbook.Save();
}
// At this point, the memory stream contains the modified document.
// grab chunks of data and write to the output stream
Stream outputStream = response.OutputStream;
byte[] buffer = new byte[BufferSize];
while (true) {
int bytesRead = memoryStream.Read(buffer, 0, BufferSize);
if (bytesRead == 0) {
// no more data
break;
}
outputStream.Write(buffer, 0, bytesRead);
}
}
fileStream.Dispose();
}
static private void CopyStream(Stream source, Stream destination) {
byte[] buffer = new byte[BufferSize];
int bytesRead;
do {
bytesRead = source.Read(buffer, 0, buffer.Length);
destination.Write(buffer, 0, bytesRead);
} while (bytesRead != 0);
}
}
So am I missing something (apparently I am).
Please Note:
There are no dlls missing from Azure because I checked using RemoteAccess feature of the Windows Azure Tools 1.7
My export is not a heavy long running task.
when I changed the action to just return a FilePathResult with the template xlsx it worked on azure. But I need to process the file before returning it as u might suspect :-)
Tanks.
UPDATE:
After I logged extensively in my code the execution hangs with no error at the ClosedXml "Save" method call. But still no error. Abstract from the WADLogsTable:
Opening template file from path:
E:\sitesroot\0\Content\templates\MyTemplate.xlsx
Opened template from path:
E:\sitesroot\0\Content\templates\MyTemplate.xlsx just
copied template to editable memory stream. Bytes copied: 15955,
Position: 15955
modified the excel document in memory.
here it hangs when a it calls to workbook.Save(); This is a ClosedXml method call.
I was facing the exact same error situation as you. I can't offer a fix in your specific situation, and I know you switched tracks, but after going through the same frustrating steps you had faced, I'd like to "pave the way" for an answer for you (or others).
Drop into your package manager console in Visual Studio and install Elmah with the MVC goodies (routing):
Install-Package elmah.MVC
Now, in your root web.config, update your Elmah entry. It's likely at the end of the file, looking like this:
<elmah></elmah>
Update that bad boy to allow remote access and set up your log path:
<elmah>
<security allowRemoteAccess="1" />
<errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/app_data/elmah" />
</elmah>
Now, push that up to Azure.
Finally, visit your site, force the error then navigate to http://your-site-here.azurewebsites.net/elmah and you'll see the exact cause of the error.
Elmah is so the awesome.
Sheepish confession: The error for me wasn't in the third party code, it turned out to be in my connection string, for which I hadn't set MultipleActiveResultsSets to true. The other fix I had to do was pass my entities in after calling ToList() to one of the internal methods on that library, leaving it as IQueryable borked the method up.

applet access control problem

i have applet which in turn is connecting to server for filewriting .When i tried to connect to the server using localhost :
it works on my machine (server is on the same machine ), but doesnot work on other machine .
when i try with IP address it works no where
my applet code :
public class dynamicTreeApplet extends JPrefuseApplet {
private static final long serialVersionUID = 1L;
public static int i = 1;
public String dieasenameencode;
public void init() {
System.out.println("the value of i is " + i);
URL url = null;
//Here dieasesname is important to make the page refresh happen
//String dencode = dieasenameencode.trim();
try {
//String dieasename = URLEncoder.encode(dencode, "UTF-8");
// i want this piece of the code to be called
url = new URL("http://localhost:8080/docRuleTool/appletRefreshAction.do?dieasename=");
URLConnection con = url.openConnection();
con.setDoOutput(true);
con.setDoInput(true);
con.setUseCaches(false);
InputStream ois = con.getInputStream();
this.setContentPane(dynamicView.demo(ois, "name"));
ois.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (FileNotFoundException f) {
f.printStackTrace();
} catch (IOException io) {
io.printStackTrace();
}
++i;
}
}
java policy file :
grant {
permission java.net.SocketPermission "*", "accept";
permission java.net.SocketPermission "*", "connect";
};
my jar are not signed and i donot want them to be signed as well from maintaince perspective .
it works on my machine (server is on the same machine ), but doesnot work on other machine
Yes but it really only makes sense for the applet being served from 'the other machine' to be writing back to 'the other machine. The code above has..
url = new URL("http://localhost:8080/docRuleTool/appletRefreshAction.do?dieasename=");
Which means the applet coming from the other host is attempting to write the data back to a 'localhost' that probably does not exist. Instead, your applet should form the URL using something more along the lines of..
url = new URL(getDocumentBase(), "/docRuleTool/appletRefreshAction.do?dieasename=");
If the code does that, it should be able to remain sand-boxed.
And as an aside, policy files are really only of use for development purposes. If the code needs trust for real world deployment, it needs to be digitally signed.

Resources