Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UDP Broadcast/Device Discovery on iOS?

I am working on trying develop a means of discovering Logitech Harmony Hub devices on my local network, from an iOS app. The concept is inspired by this NODE.JS project, which seems to send out a UDP broadcast to the 255.255.255.255 address, and then procures the Logitech's IP address (which is all I'm after). When testing the NODE.JS project on my home network from my Mac, it successfully finds the Logitech Harmony Hub.

I am using CocoaASyncSocket, and must admit, my understanding of how UDP broadcast/discovery works may be askew here. Here's what I'm doing;

import UIKit
import CocoaAsyncSocket

class ViewController: UIViewController, GCDAsyncUdpSocketDelegate {

var address = "255.255.255.255"
var port:UInt16 = 5224
var socket:GCDAsyncUdpSocket!
var socketReceive:GCDAsyncUdpSocket!
var error : NSError?

override func viewDidLoad() {
    super.viewDidLoad()

    let message = "_logitech-reverse-bonjour._tcp.local.\n61991".dataUsingEncoding(NSUTF8StringEncoding)

    socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
    socket.sendData(message, toHost: address, port: port, withTimeout: 1000, tag: 0)

    do {
        try socket.bindToPort(port)
    } catch {
        print(error)
    }

    do {
        try socket.enableBroadcast(true)
    } catch {
        print(error)
    }

    do {
        try socket.beginReceiving()
    } catch {
        print(error)
    }

}

    func udpSocket(sock: GCDAsyncUdpSocket!, didConnectToAddress address: NSData!) {
        print("didConnectToAddress");
    }

    func udpSocket(sock: GCDAsyncUdpSocket!, didNotConnect error: NSError!) {
        print("didNotConnect \(error)")
    }

    func udpSocket(sock: GCDAsyncUdpSocket!, didSendDataWithTag tag: Int) {
        print("didSendDataWithTag")
    } 

    func udpSocket(sock: GCDAsyncUdpSocket!, didNotSendDataWithTag tag: Int, dueToError error: NSError!) {
        print("didNotSendDataWithTag")
    }

func udpSocket(sock: GCDAsyncUdpSocket!, didReceiveData data: NSData!, fromAddress address: NSData!, withFilterContext filterContext: AnyObject!) {

    var host: NSString?
    var port1: UInt16 = 0
    GCDAsyncUdpSocket.getHost(&host, port: &port1, fromAddress: address)
    print("From \(host!)")

    let gotdata: NSString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
    print(gotdata)

}

}

When I compile this, the only response I get is the message I just sent out;

didSendDataWithTag
From ::ffff:192.168.1.101
_logitech-reverse-bonjour._tcp.local.
61991
From 192.168.1.101
_logitech-reverse-bonjour._tcp.local.
61991

I fear that I have a conceptual understanding issue with the broadcast here, and am sincerely hoping that someone may be able to point me to a resource or help to understand why I'm not getting any response from the device in my code.

Thanks!

like image 875
ZbadhabitZ Avatar asked Feb 11 '16 23:02

ZbadhabitZ


Video Answer


1 Answers

From the looks of the code it seems that you have only implemented half of the solution. The way it works is:

  • A broadcast message is sent to port 5224. This message includes the string logitech-reverse-bonjour._tcp.local. plus the port number that the Harmony should connect back to - in your case you have hardcoded 61991.
  • Presumably the Harmony receives this packet, recognises the message and then initiates a connection back to the device that sent the broadcast on the nominated port (61991 in this case).

Since your app is not listening on this port you don't get any response. This is implemented in the responseCollector.js file in the node.js project

like image 57
Paulw11 Avatar answered Oct 07 '22 11:10

Paulw11