AirFloat icon indicating copy to clipboard operation
AirFloat copied to clipboard

multiple instances of AirFloat in one network

Open johndoe8967 opened this issue 12 years ago • 5 comments

Hi,

first of all great work :-) I downloaded and compiled for my iPhone 4s and my iPad. Worked on both of them individually great.

But when both are running on the same time only the first is visible (e.g. in iTunes)

I analyses it a little bit and found out:

  • both share the same ID on bonjour: 020000000000@AirFloat
  • if I change the name the ID changes immediately, but on some unknown reason the settings are not stored until the next startup -> no settings file on my device => I still can debug the location where the settings should be written, but it is not done

I use iOS 7.0.4 with the actual Xcode

best regards and a merry XMAS john doe

johndoe8967 avatar Dec 26 '13 11:12 johndoe8967

ok, I found out why :-)


Now iOS 7 devices – are always returning a MAC address of 02:00:00:00:00:00. So better use [UIDevice identifierForVendor]. so better to call this method to get app specific unique key

Category will more suitable

johndoe8967 avatar Dec 26 '13 14:12 johndoe8967

Changing the MAC address it works great with multiple instances, so for example it's possible to use Airfoil to stream a movie's sound to multiple iPhone as headphone wireless. Great app, thanks!

appcornerit avatar Apr 26 '15 16:04 appcornerit

Dear All,

Could you share how to solve this issue? Especially, how to modify the code?

Have a nice day!

Best Regards, yfliao

yfliao avatar Dec 05 '15 01:12 yfliao

If anyone struggles with this in the future:

The bonjour device identifier is given by CFStringRef combined_name = ...

in the zeroconf_raop_ad_create(uint16_t port, const char *name) function which is in libairfloat/Server/Bonjour/zeroconf_apple.c.

Naively all that is required is to generate combined_name using iOS7+-compatible methods rather than using the MAC address, namely [[[UIDevice currentDevice] identifierForVendor] UUIDString].

However if we only change the identifier here, AirFloat does not work properly. It is found by devices on the network, but as soon as playback starts it switches out of the AirFloat and back to the device's speaker. I was just looking for a quick and dirty solution so don't know where the underlying problem comes from.

I guessed that there is some implicit dependency between the value of combined_name and the function originally used to generate it, hardware_identifier() defined in libairfloat/Tools/Hardware/hardware_apple.c

So I went back and changed hardware_identifier() directly. Success! Multiple AirFloats playing around the apartment!

Any solution that uniquely generates hardware_identifier() for each device should do, but if anyone wants mine (again, quick and dirty):

// -----------------------------------
//  DeviceIDRetriver.h
// -----------------------------------

#include <CoreFoundation/CoreFoundation.h>

uint64_t iOSdeviceID();
// -----------------------------------
//  DeviceIDRetriver.m (ARC-managed)
// -----------------------------------

#import "DeviceIDRetriver.h"
#import <UIKit/UIKit.h>

uint64_t iOSDeviceID() {

    uint64_t returned = 0;

    // get ID string
    NSString *idString = [[[UIDevice currentDevice] identifierForVendor] UUIDString];

    // convert to data, then store sufficient data into uint64_t.
    // this is a crude NSString -> uint64_t hash
    NSData *idData = [idString dataUsingEncoding:NSUTF8StringEncoding];
    [idData getBytes:&returned length:sizeof(uint64_t)];

    return returned;
}

and now in hardware_apple.c (don't forget to #include "DeviceIDRetriver.h"):

uint64_t hardware_identifier() {

    return iOSDeviceID();
}

ataibarkai avatar Dec 27 '15 15:12 ataibarkai