Adding a BLE (Bluetooth 4.0) dongle to Mac OS X (Mavericks)

I recently started playing around with one of those RFDuino’s. These are microchips with BLE built-in and with the Arduino framework built around it. It’s easy to connect them to a iOS device, but if you want to connect them directly to your Mac, it’s a little bit harder.

One of the things you’ll need, is BLE support on your Mac. One way to check this is issuing the following command:

system_profiler -detailLevel full SPBluetoothDataType | grep "LMP Version"

If you see a response like

LMP Version: 0x6

Then you’re in luck, if you see a lower value, like

LMP Version: 0x4

Then you need to buy a BLE Dongle, like me. I bought a LM506 Bluetooth 4.0 adapter from LM Technologies, which actually has the Broadcom BCM20702A0 chip inside it. On Mavericks, this chip should work ‘out of the box’, but it didn’t 😦
dongle

You’ll have to select which Bluetooth chip you want to use. The built-in one or the external. You can’t use both. To do this you have to download the Hardware IO Tools for Xcode from the Apple Developers site (just search for it). Then, run Bluetooth Explorer. Choose ‘HCI Controller Selector’ from the tools menu.
bluetooth explorer
Select your BLE chip and press activate!
ble

If you’re using a Bluetooth mouse, you will have to re-pair your mouse again.

So that’s it. Now I can start using those RFDuino’s with my Mac πŸ™‚

Posted in Uncategorized

Google I/O 2013 registration page: under the hood

I’ve tried registering for Google I/O from 3pm till 3:55 pm (GMT+1 time).

Screen Shot 2013-03-13 at 16.50.56

While trying and waiting, I checked out their javascript code. There’s actually not much to it:

q.registration.checkWaitListStatus = function (a, b) {
	var d = "/events/register/noticket/" + q.registration.waitListKey + "/";
	b && (d = "/events/io/register?tryagain=1");
	var e = "/events/register/waitlist/status/" + q.registration.waitListKey + "/";
	$.get(e, function (e) {
		var l = e.status;
		"waiting" == l ? a.setTimeout(q.registration.checkWaitListStatus, 25E3 + 1E4 * Math.random(), a, b) : q.location.href = "fulfilled" == l ? e.redirect_url : d
	}).error(function () {
		q.location.href = d
	})
};

The checkWaitListStatus function checks the following url every 10 seconds or so: https://developers.google.com/events/register/waitlist/status/googleio2013_academic/ for academic tickets or https://developers.google.com/events/register/waitlist/status/googleio2013_general/ for regular tickets.

The urls return a JSON object containing either

{"status": "waiting"}

 

{"status": "reregister"}

or…

{"status": "fulfilled", "redirect_url": "/events/register/waitlist/claim/googleio2013_general/"}

So what happens in this line of code:

var l = e.status;
"waiting" == l ? a.setTimeout(q.registration.checkWaitListStatus, 25E3 + 1E4 * Math.random(), a, b) : q.location.href = "fulfilled" == l ? e.redirect_url : d

Let’s rewrite it based on the code around it:

response.status == "waiting" ? window.setTimeout(registration.checkWaitListStatus, 25E3 + 1E4 * Math.random(), window, true) : ( window.location.href = (response.status == "fulfilled"? response.redirect_url : "/events/io/register?tryagain=1") )

That means, if status equals “waiting“, then retry after some time, else set window.location.href to “/events/io/register?tryagain=1”. Except when status equals “fulfilled“, then set window.location.href toΒ redirect_url

Now here’s the interesting part. The time it waits is actually a random value between 25E3 and 25E3 + 1E4 milliseconds, which boils down to 9699 and 10183 milliseconds. Now, if was paying more attention, using the live debugger, I could’ve just changed the javascript code 25E3 + 1E4 * Math.random() to 100 for example πŸ™‚ So that it checked the registration url faster.

But I didn’t… My adrenaline was to high and I couldn’t think straight…

But next year, I will be prepared.

Posted in Uncategorized

Apple’s HTTP Live Streaming (HLS) in Flash !

Yes, it’s possible. You create hundreds of .ts files holding an h264 video. You then create a m3u8 playlist and it plays on any iPhone, iPad or other iDevice.Β  Now how can you play this in Firefox, Chrome or IE?Β  JWPlayer now support HLS (Apple’s HTTP Live Streaming) right from its Flash player… But wait…they’re asking money for this? Yes, it’s only available in the $50 and $300 per month plan… my god.

Luckily, some brave developer named danrossi created a plugin for the free Flowplayer Flash. If you don’t know what Flowplayer is, here’s a short intro: Flowplayer seems to have developed two versions of it’s software: Flowplayer Flash and Flowplayer HTML5. Flowplayer Flash seems somewhat outdated and while they state that they support HLS in their HTML5 version, it’s not working. They probably support it, but only as a fallback on HLS-enabled devices.

So back to danrossi’s HLS plugin. Apparently, one can write plugins for Flowplayer Flash and that’s exactly what he has done. Let’s dive into some code. If you open up his website, you’ll get all you’ll need. I cleaned it up a bit, so you get the bare things you need:

<html>
<head>
  <script src="flowplayer-3.2.11.min.js"></script>
  <script src="flowplayer.playlist-3.0.8.min.js"></script>
</head>
<body>
<!-- player container-->
<div id="player" style="width: 425px; height: 300px;"></div>
<!-- Flowplayer installation and configuration -->
<script type="text/javascript">
    flowplayer("player", "flowplayer.swf", {
        // configure the required plugins
        plugins:  {
            httpstreaming: {
                url: 'flowplayer.httpstreaminghls-3.2.10.swf'
            }
        },
        clip: {
            url: "http://184.72.239.149/vod/smil:bigbuckbunnyiphone.smil/chunklist-b400000.m3u8",
            urlResolvers: "httpstreaming",
            provider: "httpstreaming",
            autoPlay: false
        }
    });
</script>
</body>
</html>

Apparently, he made a plugin for the 3.2.10 version of Flowplayer Flash. You can’t use a newer version with his plugin, I’ve tried it. Luckily, you can still use the skinning features from Flowplayer Flash. The modern light skin, for example, can be achieved like this:

<html>
<head>
  <script src="flowplayer-3.2.11.min.js"></script>
  <script src="flowplayer.playlist-3.0.8.min.js"></script>
</head>
<body>
<!-- player container-->
<div id="player" style="width: 425px; height: 300px;"></div>
<!-- Flowplayer installation and configuration -->
<script type="text/javascript">
    flowplayer("player", "flowplayer.swf", {
        // configure the required plugins
        plugins:  {
            httpstreaming: {
                url: 'flowplayer.httpstreaminghls-3.2.10.swf'
            },
            controls: {
                url: "http://releases.flowplayer.org/swf/flowplayer.controls-3.2.15.swf",

                // customize the appearance make it have a lighter look
                buttonColor: 'rgba(0, 0, 0, 0.9)',
                buttonOverColor: '#000000',
                backgroundColor: '#D7D7D7',
                backgroundGradient: 'medium',
                sliderColor: '#FFFFFF',

                sliderBorder: '1px solid #808080',
                volumeSliderColor: '#FFFFFF',
                volumeBorder: '1px solid #808080',

                timeColor: '#000000',
                durationColor: '#535353'
            }
        },
        clip: {
            url: "http://184.72.239.149/vod/smil:bigbuckbunnyiphone.smil/chunklist-b400000.m3u8",
            urlResolvers: "httpstreaming",
            provider: "httpstreaming",
            autoPlay: false
        }
    });
</script>
</body>
</html>

hls

I packed it all up for you, so you can play around with it and serve it from your own server: download

So go out and spread the word. Make JWPlayer suffer for not open sourcing their HLS version!! πŸ™‚

Posted in apple

Google I/O Easter Eggs explained

Google just updated their website around Google I/O and added tons of Easter Eggs to it.Screen Shot 2013-03-07 at 14.54.47

After trying out some codes, I got bored and started digged into their source code. It’s located here: https://developers.google.com/events/io/js/app.min.js

Just search for: ww.mode.register(“home”

I you deminify it, you get something more readable:

ww.mode.register("home", ww.mode.HomeMode, null);
ww.mode.register("cat", ww.mode.CatMode, 231, 8);
var isAndroid = navigator.userAgent.match(/Android/);
isAndroid || ww.mode.register("space", ww.mode.SpaceMode, 42, 8);
ww.mode.register("pong", ww.mode.PongMode, 129, 8);
ww.mode.register("bacon", ww.mode.BaconMode, 144, 8);
ww.mode.register("simone", ww.mode.SimoneMode, 211, 8);
ww.mode.register("eightbit", ww.mode.EightBitMode, 83, 8);
ww.util.getAudioContextConstructor() && (ww.mode.register("song", ww.mode.SongMode, 219, 8), ww.mode.register("synth", ww.mode.SynthMode, 136, 8));
ww.mode.register("ascii", ww.mode.AsciiMode, 127, 8);
ww.mode.register("bowling", ww.mode.BowlingMode, 117, 8);
ww.mode.register("rocket", ww.mode.RocketMode, 69, 8);
ww.mode.register("burger", ww.mode.BurgerMode, 57, 8);

The key here is the third parameter. You have to convert this to binary and then use the I and the O keys to enter the code.
I’ve converted them for you:

cat:      11100111
space:    00101010
pong:     10000001
bacon:    10010000
simone:   11010011
eightbit: 01010011
song:     11011011
synth:    10001000
ascii:    01111111
bowling:  01110101
rocket:   01000101
burger:   00111001

So, there you have it. Play “Simone says” or do some bowling. Right from your browser! Should I mention you best use Chrome for this?

Posted in google