Wake on Lan for iOS Using GCDAsyncUdpSocket

I’ve spent the last couple of weeks working on a new app which runs in the background, and uses cell tower ‘significant change’ functionality to do geofencing. Having got it to work, I’ve now turned my attention to one of the ultimate goals, which is to start sending WoL packets when I enter a CLRegion I’ve defined around the house. [This is actually going to be quite tricky, by virtue of the fact that the regions need to be pretty big, given the sort of accuracy that startMonitoringSignificantLocationChanges provides, but I’ll come back to that another time].

There is a fair amount of example code for WoL, but I couldn’t find anything particularly easy to adapt. What I’ve ended up doing is grafting this C example onto GCDAsyncUdpSocket. It works fine, but there is one annoying side effect, which I haven’t been able to work out yet.

First the code:

//http://shadesfgray.wordpress.com/2010/12/17/wake-on-lan-how-to-tutorial/
    unsigned char tosend[102];
    unsigned char mac[6];
    for(int i = 0; i < 6; i++)
    {
        tosend[i] = 0xff;
    }
    // substitute MAC address: E.g.,
    mac[0] = 0x00;
    mac[1] = 0x2a;
    mac[2] = 0x00;
    mac[3] = 0xfe;
    mac[4] = 0xff;
    mac[5] = 0x33;

for(int i = 1; i <= 16; i++)
    {
        memcpy(&tosend[i * 6], &mac, 6 * sizeof(unsigned char));
    }
    

    NSData *payLoad = [NSData dataWithBytes:tosend length:102];
    GCDAsyncUdpSocket *mysocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    [mysocket enableBroadcast:YES error:nil]; 
    [mysocket sendData:payLoad toHost:@"192.168.1.255" port:9 withTimeout:-1 tag:0];

So, this works for me insofar as I'm happy enough with broadcasting to the network, with the final quad of the IP set to 255. What I haven't been able to work out is how to send the packet to a single machine. I've written about WoL functionality before - unfortunately the project I mentioned in that post is no longer making the source code available. However, I still have the executable and resorted to WireShark to see if I could fiddle around with the code above to make it play ball:

WireShark

So the .69 example above is from my iPhone, and the .73 is from my MBA, using wol from the command line. To cut a long story short, the full IP is identified as being sufficiently well formed for the WireShark filter to call it WoL, but it won't wake the machine. Final point: all 255s will also wake the machine.