Photon softAP usage?

@msolters This is incredible. Great work! :thumbsup:

Looking through your other post and the npm package, there seems to be an implication that this could be a feasible solution for mobile (Ionic, Angular) as well, but I can’t seem to find any info about whether those shell commands are available on Android or iOS. Was this tested in a PhoneGap app?

The wifi-control NPM module is using nmcli for Linux, netsh for Windows, and networksetup for MacOS. None of those will function in a mobile environment, and more importantly, the app can only run natively on a desktop or laptop environment since the server is being implicitly hosted by Electron, and a mobile device can’t do that. (I mean maybe it could but I don’t think that’s responsible use of resources.)

But this web app will function on mobile. Just visit http://photonsoftap.meteor.com from your phone’s browser, select the browser-based option, and then manually connect to the Photon from your WiFi settings, hit next. OK, fine. Big deal. Anyone could do that.

For WiFi automation on mobile:

  • Possible on Android.
  • iOS explicitly disallows automatic WiFi control from an app.

So, there may be Cordova packages that allow this, but it’ll only work on Android at best. But for any real product I’d recommend just making your own native apps, just like the actual Particle Android app.

I tried the web setup from Safari on my mac (http://photonsoftap.meteor.com), was able to connect to my photon fine, scanned the networks fine, but when I type in a password and hit connect nothing seemed to happen. Looking at the dev panel I dont see any network requests being made either. Perhaps a bug @msolters ? I will note that my photon is running 4.4, thanks.

Hey it’s the same exact issue we already discussed a few posts back, and that is in your GitHub issue with other SoftAP implementations. I have no answers so far, but let me reiterate how interested I am in these reports of SoftAP working fine in Safari.

Bugs like this are why I moved towards rolling this into an Electron app – it always works there.

Ah, ok, didnt realize this was still the same codebase. Perhaps @kefir135 can shed some light on how he got it working on Safari and Mobile Safari. What version was your photon running?

Hey, I just found a super basic bug: the connect button was misidentified by the event definition.

So, @anthonywebb, that weird nonresponsive behavior is no longer present on Safari – it is replaced by the far more specific failure of the SoftAP .configure() command to actually do anything (http://192.168.0.1/configure-ap request never returns).

Try out http://photonsoftap.meteor.com now. Clicking the connect button will fire the sap.configure()… but it just hangs forever. If the network configuration is manually broken then you may get an XHR error about the resource http://192.168.0.1/configure-ap not being loaded as your machine goes back to another WiFi network.

I’d also like to point out that, if I leave Safari waiting for that configure-ap request to resolve, I find that other machines cannot connect to the Photon-**** beacon AP.

Hey, I did some testing with @mibrad Angular app - uploaded to a server, then opened in PC Safari and Ipad Safari, both worked - I was able to get a list of SSID’s and connect.
I have no possibility to compile the Ionic app for IOS (no mac), but tried with the Ionic View app on Ipad (anables for running the app without compiling manually, sending to appstore etc) - and this DID NOT WORK.
That’s all I know and did.

I did a little testing with your web app and it appears to be the same result as before in safari (appears as though the connect button doesnt work). Looking at the dev console and I see that when you do a configure the method is ā€œOPTIONSā€ as opposed to ā€œPOSTā€, which I assume is why it spins and never gets anything back from the photon. It does work great for chrome though.

My web code (which also does not work on safari, but is fine in chrome) attempts to configure via a POST, and as you can see, the photon accepts the configuration request and returns {ā€œrā€:0} like all was well, then I kick off the connect call, but it can not connect because the photon did not store the credentials.

To try it you can go here: http://23.253.54.117/setup
JS is here: http://23.253.54.117/setup/script.js

2 Likes

Yes, totally confirmed. As I’ve said before, I’ve ran into cross-origin problems, both of the silent and verbose flavours, many times with Safari. Perhaps what we’re seeing is something like this?

Ok, so I did a little more digging. I found out there’s a few browserify gotchas behind the scene that take place. Node’s http module becomes http-browserify, and part of this process is that, if any http.request() takes place where the options do not explicitly state withCredentials: false, the credentials flag will be set.

This will cause an XHR error because you can’t have the credentials flag set AND have a server using Access-Control-Allow-Origin: * – depending on how anal your browser is about it. (hint hint, Chrome vs Safari)

So, I am working on a fork of softap-setup right now, where I have explicitly disabled the credentials flag inside the SoftAP.prototype.__httpRequest() command to prevent those XHR errors. And I’ve managed to coax some more information out of the errors to find out what’s taking place with that configure-ap call:

So what’s going on here?

We see that device-id, public-key, and scan-ap GET requests all resolved just fine and got proper responses.

But that configure-ap POST fails – and it says that, according to the server (the Photon), that Access-Control-Allow-Origin is not *. If this is true, that means the problem is not SoftAP, but rather the firmware.

How can we make sure that Access-Control-Allow-Origin: * response header is being set on the configure-ap POST resource in the firmware?

So far I get this behaviour on 0.4.5 (cloud compiled) and develop (locally compiled).

2 Likes

I figured there was something with how it was being browserified. According to this conversation, that should be the header being set throughout the firmware (unless this particular endpoint just has a bug in it) :confused:

@mebrunet any thoughts/insight?

Just to re-iterate from what I see is working:

WORKING:
-Google Chrome on Mac and Android

NOT WORKING:
-ANY iOS browser (Chrome, Safari, etc.)
-Safari on Mac

Chrome on iOS (and any other device) works fine, it is just Safari in all its variations (mac, ios, etc) that has the issue. I have heard that Safari was working so long as it connected to an OPEN network with no password, but I have not confirmed.

1 Like

Safari on OPEN, as far as I can tell, only reproducable in El Capitan.

All other browsers = OK!

@mibrad - Unfortunately I haven’t had the bandwidth to further debug the Safari/iOS issues… I think @msolters is on to the root of the problem. The only other thing I can think of would be that somehow the RSA encryption libraries are running differently on Safari. I think decryption failure returns a 200 with json data {ā€œrā€:1024} from configure-ap on v0.4.5, but I’m not sure what it does on v0.4.4.

Recall that the Setup Page I built was really designed to be embedded into the firmware (which would solve all the CORS issues), and not be used as a separate website. When compiled into v0.4.4 it seemed to work fine across devices. I haven’t tried embedding it into 0.4.5, but I imagine that would work fine too…

Personally, I’ve been giving my clients a PhoneGap app with the wifi connection process integrated into their account setup. I haven’t had any issues (when running firmware v0.4.5) as of yet. I’ll share it eventually, but I’ve had no time to separate and open source the wifi connection portion of our app yet.

Interestingly another little bug that I’ve come accross, is that the softap http calls return the device id in capitalized hex (i.e. 2A4D… ), while the Particle cloud API url enpoints appear to require lowercase ( i.e. 2a4d…). @mdma & @nexxy - any way to consolidate that? (By either making the cloud API case insensitive or making softap http calls return lowercase). It left us looking for a mystery bug for a while…

@mebrunet, that’s a great catch! I will log a bug internally to make sure that’s on someone’s radar.

@msolters, thank you for such an in-depth analysis of these bugs!

I am more than happy to add the credentials fix to the mainline release and publish a new version to NPM. So I understand it correctly, we want to send withCredentials: false with every HTTP request made from within a browser?

Well, it’s a bit more complex than that flag alone. Successful implementation of the HTTP SoftAP mechanism depends on two things:

  • Correct definition of request headers from the client. While this should be defined uniquely by the JavaScript, as we see there is some browser-specific over ride. Why does Chrome and Firefox not require that flag be explicit, for example?
  • Proper and well defined configuration of WICED HTTP server. What request headers are permitted? What methods are allowed? What are the response headers?

I’d hold off on modifying the softap-setup node module until such time as we can really pin down that magic combination of server and client configuration.

Hi ,

I have tried to use ti with the following but without success .

  • Android 4.4.2 , Chrome
  • Ubuntu 14.04 Chrome - Mozilla
  • Windows 7 Chrome -Mozilla

No luck at any of these

Any suggestions?

I have been running some of my own tests to try and get the softap-setup-js library working in the browser. Apologies for the wall of text, but perhaps some of this info will help:

I’m using @mibrad’s neat little angularjs/ionic framework wrapper UI ā€˜ngphoton’ and have patched it with @msolters’s updated softap.js that sets withCredentials to false to try and fix XHR issues (see: this commit). I couldn’t work out what version of softap.js was in the ngphoton repo so there may be other changes included as well by updating it. The patched ngphoton app is up on my fork here (i just copied in and re-minified the softap.js file)

The ngphoton app (before I patched it) had worked with firmware v0.4.4 , however we have also had issues with firmware v0.4.6 which prompted me to try updating the softap.js library in ngphoton. I am not sure if the issues are firmware-specific though as I haven’t done enough testing to isolate anything between versions.

What I have found is that on iOS 9.0.2 Safari (testing on an iPad Mini with remote inspect debugging) seems to get stuck sending the /configure POST request that actually sets the wireless network. I’m not 100% sure but I think it may be to do with the underlying request calls implemented by nodejs/browserify’s implementation of nodejs libraries.

Before testing the iPad I was testing on Chrome on an Android tablet (Android version 5.1.1, Chrome version 45.0.2454.94). The whole process actually worked fine with this setup - however when debugging the HTTP requests with the Chrome dev tools, I noticed that I couldn’t see the HTTP POST body of the /configure request in the usual place I’d expect it to be in the ā€˜Network’ tab.

I dug through the Javascript to make sure that the correct data was actually being sent through to the device, and discovered that under the hood it was using a call to ā€˜fetch()’ to do the POST, which seems to be an upcoming replacement/improvement on XMLHttpRequest that has limited browser support at the moment (e.g. only in Chrome versions 42 and onwards). I also found that it was using a Blob object as a request payload, which appears to be why I can’t see its internals in the Dev Tools’s Network tab. I couldn’t seem to read any data out of the Blob either, but it must have had the right data in it as it was able to configure the wireless properly.

Doing the same debugging back on iOS Safari, I found that the same /configure request (the one that was stalling) was being made with an XMLHttpRequest instead - however again still with a Blob as the request payload. There’s obviously some kind of feature detection in place here - perhaps it could be the cause of these browser compatibility issues?

I’ve put what I think is the relevant section of code from the browserified softap library in a BitBucket snippet here for reference: https://bitbucket.org/snippets/nuclearpidgeon/rLkAb (the browserified file is too big for BitBucket to display other than as a raw file). That _onFinish() function is what ultimately triggers a HTTP request for the /configure POST call.

I can’t work out where in the nodejs/browserify stack this code comes from, and I’m not sure if I’ll have the time to debug this further. But hopefully some of this information helps.

1 Like