Photon softAP usage?

@nuclearpideon excellent work! I totally agree with all your hunches – that this is due in part to the browser, as well as due to browserify. Browserify will substitute some of the HTTP request functions, and then those functions get limited mileage as far as browser compatibility.

I’d like to reiterate – and I’d be interested to see if anyone else can confirm – the fact that I find Safari in El Capitan to be working if I replace http.request with xhr before browserifying.

@nexxy, @zachary, can you please summarize what is the actual status for the JS libraries ?

  1. Is the Soft-AP setup JS library already browser compatible, working correctly with Safari and all other environments like Cordova / Phonegap ?

  2. Do you plan to integrate this library with the main JS SDK ?

  3. Does the main JS SDK support the “organizations” structure ?

And, what are the plans for above topics (and expected time of completions) ?

Thanks

1 Like

Hello,

First of all, Congratulations for such an incredible job.

I have tried photonsoftapmeteor and http://23.253.54.117/setup/ in Chrome, Firefox and Internet Explorer in a Windows 8.1 machine but it never finds the Photon.
The laptop is connected to the photon wireless network and it is also connected to Internet by Ethernet.

What I am doing wrong? Thanks.

Possibly slightly off topic here, but relevant to hosting services in AP mode:
The softap implementation starts a dns_redirector service. What redirections does it do? How can this be configured?

My usecase: I’d like to redirect all requests to the photon ip, or, I want to redirect a specific domain or hostname.

I haven’t been able to configure a Photon using Safari OR Chrome on my iPad. Both attempt to reload photonsoftap.meteor.com immediately after hitting the “Connect” button. After setting up Safari on my Mac to debug further, it seems that there’s some kind of error during encryption of the password, after which the page immediately tries to refresh:

I could debug further but I’d have to clone and run my own version of the app.

1 Like

Now that is interesting. Have you ever seen it happen on something that’s not an iPad?

Interesting and disappointing update…

The POST /configure-ap issue may run deeper than Safari itself. I’m having the same issue with Phonegap. (i.e. compiled as an apk for Android it works fine, but compiled as a ipa for iOS the command does nothing).

Note I’m using jQuery.ajax directly.

$.ajax(this.props.base_url + '/configure-ap', {
  method: "POST",
  timeout: 8000,
  data: JSON.stringify(jsonData),
  processData: false,
  contentType: "multipart/form-data",
  success: (data) => {
    if(data.r === 0){
      this.connect();
    } else { 
      this.setState({
        alertType: "danger",
        alertMsg: "Your device rejected the credentials. Please try again. If this problem persists contact technical support."
      });
    }
  },
  error: () => {
    this.setState({
      alertType: "danger",
      alertMsg: "Error sending credentials to your device. Verify your connection with the device and try again."
    });
  }
});

Will keep you posted.

I’ve configured Photons successfully using the Meteor app on OSX, Windows, and Android devices, just never Safari or Chrome on iOS.

Ugh, it looks like this particular issue goes pretty deep. Using the Safari debugger, I traced the error to this section of code inside softap.browserify.js, which comes from the original rsa.js library:

var crypto = global.crypto || global.msCrypto                          // 3
if(crypto && crypto.getRandomValues) {                                 // 4
  module.exports = randomBytes;                                        // 5
} else {                                                               // 6
  module.exports = oldBrowser;                                         // 7
}                                                                      // 8
function randomBytes(size, cb) {                                       // 9
  var bytes = new Buffer(size); //in browserify, this is an extended Uint8Array
    /* This will not work in older browsers.                           // 11
     * See https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues
     */                                                                // 13
                                                                       // 14
  crypto.getRandomValues(bytes);                                       // 15
  if (typeof cb === 'function') {                                      // 16
    return process.nextTick(function () {                              // 17
      cb(null, bytes);                                                 // 18
    });                                                                // 19
  }                                                                    // 20
  return bytes;                                                        // 21
}                                                                      // 22

Specifically, line 15 is where the error happens. I can recreate this from the console:

It looks like the “extended Uint8Array” passed into getRandomValues is at fault:

I’ll investigate the possible fixes in that issue more.

Sorry, I guess the best fix for now is to just update my iOS version. I’ll do that and try again.

When you say the command does nothing, what do you mean exactly? Are you getting a success response without the configuration seeming to happen?

Yup. The response from the device is {"r": 0} to both /configure-ap and /connect-ap but it just keeps blinking blue in listening mode.

I’m going to rip out the Phonegap browser and stick in Crosswalk to see if that changes anything.

Yup, and it’s at least partially localized to the browserify shim too! This tastes truthy.

Looks like we need to to replace the code with something more considerate to shitty Apple older browsers. Maybe something like this:

var crypto = global.crypto || global.msCrypto                          // 3
if(crypto && crypto.getRandomValues) {                                 // 4
  module.exports = randomBytes;                                        // 5
} else {                                                               // 6
  module.exports = oldBrowser;                                         // 7
}                                                                      // 8
function randomBytes(size, cb) {                                       // 9
  // An attempt to fix it from the above linked issue
  // We're basically demanding TYPED_ARRAY_SUPPORT on the Buffer prototype for specific Apple browsers
  if (navigator && navigator.vendor &&
      navigator.vendor.indexOf('Apple') > -1) {
      var versionStart = navigator.userAgent.toLowerCase().indexOf('applewebkit') + 12;
      var version = navigator.userAgent.substr(versionStart, 1);

      if (version && typeof(parseInt(version)) === 'number' && parseInt(version) < 6) {
          Buffer.TYPED_ARRAY_SUPPORT = true;
      }
  }
  var bytes = new Buffer(size); //in browserify, this is an extended Uint8Array
    /* This will not work in older browsers.                           // 11
     * See https://developer.mozilla.org/en-US/docs/Web/API/window.crypto.getRandomValues
     */                                                                // 13
                                                                       // 14
  crypto.getRandomValues(bytes);                                       // 15
  if (typeof cb === 'function') {                                      // 16
    return process.nextTick(function () {                              // 17
      cb(null, bytes);                                                 // 18
    });                                                                // 19
  }                                                                    // 20
  return bytes;                                                        // 21
}

Please! Can someone help me or telling me what I am doing bad:

I have tried photonsoftapmeteor and http://23.253.54.117/setup/4 in Chrome, Firefox and Internet Explorer in a Windows 8.1 machine but it never finds the Photon.
The core is in listening mode, the laptop is connected to the photon wireless network and it is also connected to Internet by Ethernet.

Do I have to change the Photon Firmware or it would be work with the original one? Any help will be apreciated.

Thanks

Well, if it’s not working, try upgrading! Just flash an LED blink app to the Photon from the cloud IDE.

Okay I experimented with Wireshark packet captures today to try and get at the root of the
Safari/iOS issue.

Using:

  • This SoftAP connection page I put together. Which uses the raw XMLHttpRequest object to make XHR requests,
  • A Photon running stock v0.4.5 as flashed via the Particle CLI,
  • OSX 10.7.5,
  • Chrome Version 45.0.2454.101 (64-bit),
  • Safari Version 6.1.6 (7537.78.2),

I got the following TCP stream from Chrome. Which worked

POST /configure-ap HTTP/1.1
Host: 192.168.0.1
Connection: keep-alive
Content-Length: 318
Origin: http://app.neosmartblinds.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Content-Type: multipart/form-data
Accept: */*
Referer: http://app.neosmartblinds.com/connect/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.8

{"idx":0,"ssid":"VIDEOTRON9054","sec":4194308,"ch":6,"pwd":"2f788f8cf7554ef5cecf9ec7e7424d42ed794473f473d221cb30b401bfcae3f2f47b8087fde722b96ed89e2bc6f24de49eb64a4133285388ba33092b6f9a0fffdee30e93fe637df53c8621249934eee54238f1825b45a1439bdb5c7126281e042114b5235d1400083c7c95b8feba8c59ac78f310cb9e0509e10f6e0dc2c978da"}HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Connection: Keep-Alive
Access-Control-Allow-Origin: *
Transfer-Encoding: chunked

1
{
1
"
1
r
1
"
1
:
1
0
1
}
0

And this from Safari, which didn’t get the device to connect…

POST /configure-ap HTTP/1.1
Host: 192.168.0.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.78.2 (KHTML, like Gecko) Version/6.1.6 Safari/537.78.2
Content-Length: 318
Accept: */*
Referer: http://app.neosmartblinds.com/connect/
Origin: http://app.neosmartblinds.com
Content-Type: multipart/form-data
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive

{"idx":0,"ssid":"VIDEOTRON9054","sec":4194308,"ch":6,"pwd":"4902d3e432f21dfc5f3defa6f2b08d68d47b1aba2649dfed7381f29b8446e836dc89258de60039a59b52e9b936d9132d868579eeafdb8abeb48d06141a7bed224e8ff9fd60c3b3cc14485ea66f9b10dd4d413fe677ddd0675456a765cd4cf024792a12ff7b8ece4e2a2e4a42cbcd7717e31b7b5f5250a6cf9342179a358bcca1"}HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Connection: Keep-Alive
Access-Control-Allow-Origin: *
Transfer-Encoding: chunked

1
{
1
"
1
r
1
"
1
:
1
0
1
}
0

Can anyone spot a relevant difference in the TCP stream? @mdma ? This is basically as raw as it gets…

1 Like

@mebrunet While there’s a small difference in Accept-Language, I think at this point we may fairly retire the hypothesis that the HTTP server configuration is to blame.

I can confirm @indraastra 's errors. Further, I am seeing errors stemming from Uint8Array being thrown from inside the Browserify shim for XHR (where it handles responses) as well!

I think, at this point, we are seeing a pervasive JS problem centered on the way different browsers handle Buffer() and Uint8Array. That’s why we’re seeing problems in RSA land, as well as the slightly less abstruse XHR land.

@javier_pelaez you need to:

  1. open http://23.253.54.117/setup in your browser of choice (note, I’ve only tested chrome to work)
  2. put your photon in listening mode
  3. you photon will now be publishing an open wifi hotspot, connect to it
  4. return to your browser and press the “scan” button
  5. select the wifi access point your would like to connect to
  6. enter your password and your photon will connect to the specified wifi network
1 Like

I have to disagree. I think it’s precisely a bug with the Photon’s (or Broadcom’s) HTTP sever that is causing this problem.

If the raw TCP communication stream contains the same essential information, differing only in the order of the headers, some capitalization… etc. Then it’s likely some obscure bug related either to those differences, or some other lower-level differences in the way the HTTP protocol is being executed/interpreted (e.g. TCP/IP headers). Keep in mind those TCP streams were raw network traffic… by the time Wireshark picks them up the browser isn’t changing anything about them anymore.

Additionally, other HTTP servers seem to have no problem extracting JSON POST data from both Safari and Chrome. So it’s quite hard not to point the finger at the Photon. Whether the issue lies with Particle’s firmware or Broadcom’s underlying WICKED SDK remains TBD.

(Note: I made sure “pwd” field passed by Safari in the above capture was able to get the Photon working with Chrome - so you can rule out an RSA issue in this case.)

@mebrunet: Aha, this is exactly why I asked the question. I should have nipped it in the bud yesterday to save you the probably migraine-inducing debug session of diffing these two TCP streams. If you still have the streams or can recreate them, look at the individual TCP packets and see if Safari sends two packets: one with the HTTP header only, and one with the request body. This is the issue I ran into with my react-native app and posted about here:

Basically, the requests are reconstructed by every debugging tool to be nearly identical apart from a few inconsequential headers because they ARE valid. The problem is that the HTTP server doesn't treat them the same at the packet level. Hopefully, that's what you're running into as well.

1 Like

It is good to know that the same PWD data worked in Chrome.

Consider the following discussion: https://github.com/spark/firmware/issues/635

At the end of the day, @mdma was not able to let us actually look at the server source due to licensing restrictions.

Which sort of throws a spanner in the works as far as debugging and ultimately solving the problem, if it is the server.

Edit: Nice find, @indraastra !!! Yes!