Skip to content
This repository was archived by the owner on Mar 2, 2019. It is now read-only.
This repository was archived by the owner on Mar 2, 2019. It is now read-only.

Major/Minor values #6

Open
Open

Description

@realsurfer

Hi,
From what I understood by briefly looking at your code there is no support for the major/minor values when broadcasting? Without them it's impossible to get a unique identifier per device without connecting to the device I guess?
From my research Apple seems to prohibit adding any useful information to the advertisement packet which is a shame.

Thanks!
Michael

Activity

  1. objectiveSee commented on Apr 1, 2014

    @objectiveSee

    Here's an alternate way to make the advertising info dictionary which specifies minor and major:

    - (NSDictionary *)beaconAdvertisement {
    
        NSString *beaconKey = @"kCBAdvDataAppleBeaconKey";
    
        uint16_t major = 0;
        uint16_t minor = [self.minor_out integerValue];
    
        unsigned char advertisementBytes[21] = {0};
    
        [self.friendUUID getUUIDBytes:(unsigned char *)&advertisementBytes];
    
        advertisementBytes[16] = (unsigned char)(major >> 8);
        advertisementBytes[17] = (unsigned char)(major & 255);
    
        advertisementBytes[18] = (unsigned char)(minor >> 8);
        advertisementBytes[19] = (unsigned char)(minor & 255);
    
        advertisementBytes[20] = -59;
    
        NSMutableData *advertisement = [NSMutableData dataWithBytes:advertisementBytes length:21];
    
        return [NSDictionary dictionaryWithObject:advertisement forKey:beaconKey];
    }

    From http://www.blendedcocoa.com/blog/2013/11/02/mavericks-as-an-ibeacon/

  2. realsurfer commented on Apr 1, 2014

    @realsurfer
    Author

    Thanks for your reply! Will this work on ios? Won't core bluetooth reject this as the docs state that setting the advertisement only accepts two keys. The service uuids and local name.
    Will this trigger Ibeacon on the central side?

    On 1 apr 2014, at 19:21, objectiveSee notifications@github.com wrote:

    Here's an alternate way to make the advertising info dictionary which specifies minor and major:

    • (NSDictionary *)beaconAdvertisement {

      NSString *beaconKey = @"kCBAdvDataAppleBeaconKey";

      uint16_t major = 0;
      uint16_t minor = [self.minor_out integerValue];

      unsigned char advertisementBytes[21] = {0};

      [self.friendUUID getUUIDBytes:(unsigned char *)&advertisementBytes];

      advertisementBytes[16] = (unsigned char)(major >> 8);
      advertisementBytes[17] = (unsigned char)(major & 255);

      advertisementBytes[18] = (unsigned char)(minor >> 8);
      advertisementBytes[19] = (unsigned char)(minor & 255);

      advertisementBytes[20] = -59;

      NSMutableData *advertisement = [NSMutableData dataWithBytes:advertisementBytes length:21];

      return [NSDictionary dictionaryWithObject:advertisement forKey:beaconKey];
      }
      From http://www.blendedcocoa.com/blog/2013/11/02/mavericks-as-an-ibeacon/

    —
    Reply to this email directly or view it on GitHub.

  3. objectiveSee commented on Apr 1, 2014

    @objectiveSee

    this works. I am testing with it right now actually. Unfortunately I cannot
    get iOS7.1 to broadcast a beacon from the background so my test is failing.

    On Tue, Apr 1, 2014 at 5:49 PM, realsurfer notifications@github.com wrote:

    Thanks for your reply! Will this work on ios? Won't core bluetooth reject
    this as the docs state that setting the advertisement only accepts two
    keys. The service uuids and local name.
    Will this trigger Ibeacon on the central side?

    On 1 apr 2014, at 19:21, objectiveSee notifications@github.com wrote:

    Here's an alternate way to make the advertising info dictionary which
    specifies minor and major:

    • (NSDictionary *)beaconAdvertisement {

    NSString *beaconKey = @"kCBAdvDataAppleBeaconKey";

    uint16_t major = 0;
    uint16_t minor = [self.minor_out integerValue];

    unsigned char advertisementBytes[21] = {0};

    [self.friendUUID getUUIDBytes:(unsigned char *)&advertisementBytes];

    advertisementBytes[16] = (unsigned char)(major >> 8);
    advertisementBytes[17] = (unsigned char)(major & 255);

    advertisementBytes[18] = (unsigned char)(minor >> 8);
    advertisementBytes[19] = (unsigned char)(minor & 255);

    advertisementBytes[20] = -59;

    NSMutableData *advertisement = [NSMutableData
    dataWithBytes:advertisementBytes length:21];

    return [NSDictionary dictionaryWithObject:advertisement
    forKey:beaconKey];
    }
    From
    http://www.blendedcocoa.com/blog/2013/11/02/mavericks-as-an-ibeacon/

    Reply to this email directly or view it on GitHub.

    Reply to this email directly or view it on GitHubhttps://github.com//issues/6#issuecomment-39264214
    .

  4. realsurfer commented on Apr 2, 2014

    @realsurfer
    Author

    I assume iOS treats the packet as an iBeacon packet and therefore doesn't work in the background as iOS doesn't allow background advertising of beacons.
    What I am basically trying to do is to have similar functionality as iBeacons but have it broadcasting in the background. I prefer just reading the advertising packets and not connecting to every device as that takes time and probably more battery power. I think there is also a limit to how many concurrent connections core bluetooth can handle.
    Broadcasting in the background works. The problem is that Apple doesn't allow any unique identifier data to be set to the advertisement packet other than the service UUID. As I must be searching for the UUID in the background it's not possible to transmit a dynamic UUID. Right now it's looking like I must connect to every device I discover, read the characteristic and disconnect. Any other ideas?

  5. bentford commented on Apr 2, 2014

    @bentford
    Contributor

    We used separate UUIDs for each device in our game. This probably wouldn't scale infinitely large, but it worked for the game we built.

    We used a server to coordinate the bluetooth UUIDs that each player needed. Each app would spawn a separate INBeaconService for each device it was searching for (and also a separate INBeaconService for it's broadcast).

    This worked well because we had less than 8 devices actively searching for each other at a time. The entire game had 100 or so active players, but they were not all looking for each other at once.

    I wish I knew more about the major/minor values but I can't help much on that topic.

    Hope this helps.

  6. realsurfer commented on Apr 2, 2014

    @realsurfer
    Author

    Thanks for your reply! Yes that is one way of solving the problem. But as you mention I don't think that would be a viable solution for 1000's of devices.

    What I have done so far is kind of a combo solution. When I discover a new device I instantly connect and read a characteristic that contains a unique identifier. I then map this with the peripheral UUID and save it for future use. As I now have this mapping data I don't have to connect anymore to that device and only need to listen to the advertisement packets. I would only have to connect again if the peripheral UUID changes.
    This way I keep connections to a minimum and still sort of get ibeacon functionality.

  7. objectiveSee commented on Apr 2, 2014

    @objectiveSee

    Did you find any useful libraries for connecting and reading characteristics? Right now we only need basic broadcast but im curious to demo a solution using characteristics as well. —
    Sent from Mailbox for iPhone

    On Wed, Apr 2, 2014 at 3:50 PM, realsurfer notifications@github.com
    wrote:

    Thanks for your reply! Yes that is one way of solving the problem. But as you mention I don't think that would be a viable solution for 1000's of devices.
    What I have done so far is kind of a combo solution. When I discover a new device I instantly connect and read a characteristic that contains a unique identifier. I then map this with the peripheral UUID and save it for future use. As I now have this mapping data I don't have to connect anymore to that device and only need to listen to the advertisement packets. I would only have to connect again if the peripheral UUID changes.

    This way I keep connections to a minimum and still sort of get ibeacon functionality.

    Reply to this email directly or view it on GitHub:
    #6 (comment)

  8. bentford commented on Apr 2, 2014

    @bentford
    Contributor

    @realsurfer That sounds promising. Great work.

  9. realsurfer commented on Apr 2, 2014

    @realsurfer
    Author

    Thanks @bentford. Hopefully it will scale well with several devices. In general the core bluetooth stack still seems a little unpredictable and unstable but hopefully this will improve and that Apple will expand the functionality.

    @objectiveSee Didn't use any libraries. My characteristic is just a simple ID so my code is very basic. You simply go through the didDiscoverServices, didDiscoverCharacteristicsForService and didUpdateValueForCharacteristic delegate events.

  10. fitch commented on Jun 13, 2014

    @fitch

    @realsurfer I'm trying to understand what you're doing:

    • You keep a dictionary (perhaps stored into a backend server) of temporary advertisement peripheral UUIDs (that can change over time) mapped to the persistent unique device IDs
    • When you find new devices on didDiscoverPeripheral: you check your dictionary if it contains the peripheral UUID as a key
    • If it does, you can determine the actual unique identifier from the dictionary
    • If the dictionary doesn't contain the advertisement peripheral UUID, you connect and read the persistent unique device ID from a characteristic and store it to your dictionary.

    Am I correct? Are you able to share any code?

  11. realsurfer commented on Jun 20, 2014

    @realsurfer
    Author

    @fitch That is pretty much how I did it. Unfortunately I have discovered that the peripheral UUID is not at all very persistent. Apple seems to change the UUID every few minutes or so. Not sure why they do this but It makes my solution less functional. Apparently if you pair two devices the UUID becomes persistent. Anyone have any suggestions on how to improve this or other solutions to get iBeacon functionality via core bluetooth?

  12. fitch commented on Jun 21, 2014

    @fitch

    @realsurfer It seems to change every few minutes (5 to 15 min) indeed. However, you'll still get the unique ID by connecting to the peripheral - this just consumes more battery.

    Also, I implemented a workaround by transmitting an encoded unique ID with peripheral name (works only if the transmitting app is foreground).

    I opened a more general Stack Overflow discussion about how to do this (and also provided my sample code): http://stackoverflow.com/questions/24352764/how-to-detect-nearby-devices-with-bluetooth-le-in-ios-7-1-both-in-background-and/24352964#24352964

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions