Setting the major and minor value of iBeacon - ios

I want to set the major and minor value correctly as I enter in a region.For example,I have different queues for different kinds of customer. Like Premium and silver categories.
If a customer goes in the lane of Premium, He should broadcast his major value as the value of the lane he is standing i.e. Premium and the number as minor.
How to set these values correctly according to the current position of the customer?
Premium = 1;
Silver = 2;
self.myBeaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:premium minor:2 identifier:#"com.example.beacon"];

The major and minor values are set on the beacon - these are the values that are received by your app to indicate the region where the device is located.
So, in your case you would have to have two beacons, one configured the with 'premium' value and one with the 'silver' values but with the same UUID. In your app you can define the region just by UUID and examine the major/minor in didEnterRegion To determine which specific beacon was detected.
However, Unless the queues are a fair distance apart you may have difficulty locating the user accurately

Related

Change beacon sending frequency in AltBeacon

I am using the AltBeacon API to send beacons in an Android app. I am using the startRangingBeacon method with the deafult region as an argument -
region = Region("all-beacons", null, null, null).
I know that beacons are sent with the frequency of 1 second. Is it possible to change this frequency?
I tried to search for a frequency variable in the BeaconManager but could not find one.
Simply call:
beaconManager.scanPeriod = 2000L // set callback to 2000ms instead of the default 1100ms
Be aware that increasing the frequency of callbacks will sometimes mean you don’t get detections, as some beacons do not advertise more frequently than once per second. If no detections are made, the callback will have a beacon count of zero.

Does stopMonitoringForRegion stops only the duplicated region or also the original region as well?

I am working on a beacon monitoring project and currently I am investigating the stopMonitoringForRegion method. What I am doing is, duplicate the original region and start a new monitoring for it. After 30 - 60 seconds, I stop the copied region:
[self.locationManager stopMonitoringForRegion:self.duplicatedRegion];
So the original and the duplicated regions minor and major ids are same. When I stop monitoring the duplicated region am I also stoping the original region? Because the minor and major ids are same. The only difference in between the original and duplicated region is the identifiers. The original one has a Vendor GUID whereas the duplicated has "testRegion" string.
self.duplicatedRegion = [[CLBeaconRegion alloc] initWithProximityUUID:self.originalRegion.proximityUUID
major:[self.originalRegion.major intValue]
minor:[self.originalRegion.minor intValue]
identifier:#"testRegion"];
self.duplicatedRegion.notifyEntryStateOnDisplay = NO;
self.duplicatedRegion.notifyOnEntry = YES;
self.duplicatedRegion.notifyOnExit = YES;
[self.locationManager startMonitoringForRegion:self.duplicatedRegion];
I am asking this because when I stop monitoring the duplicated region, the app doesn't receive any enter and exit region events anymore. In my code I am checking whether the original region is being monitored and yes it is on the self.locationManager monitoredRegions array. Also I never stop the original region. I am just start and stoping the duplicated one.
The critical point is to use a different string for the identifier field:
self.duplicatedRegion = [[CLBeaconRegion alloc] initWithProximityUUID:self.originalRegion.proximityUUID
major :[self.originalRegion.major intValue]
minor :[self.originalRegion.minor intValue]
identifier :#"testRegion"];
If originalRegion has an identifier of testRegion and the duplicated one has that same value, it will cause the symptoms you describe. This is because CoreLocation uses the identifier field to signal that the Region objects are the same, allowing you to replace one object with another.
To have both regions active at the same time, simply supply a different identifier value.

Do beacons work like geo fences and have the same limit of 20?

I read somewhere, that beacons on apple, work in a similar way as geo fences, and there too is a limit of 20 per phone.
Is this the case?
Our use case: We want to send push notifications to users when the app is not running and the phone is not awake (in the pocket). We are thinking of relying on beacons instead of geo fences in order to avoid hitting the limit of 20 fences per phone and having to deal with significant location change function and similar solutions (for now).
Beacons work similar as geofences. You will get notified when entering or exiting a beacon-region (in bluetooth range) and you can also range all beacons around to get their ids.
There is also for CLBeaconRegions the 20 regions limit. See:
https://developer.apple.com/reference/corelocation/cllocationmanager/1423656-startmonitoringforregion
With a combination of monitoring regions and ranging, you could be able to do your stuff even with one region. (Depends heavily on your use case)
If you want to send geo-based notifications, beacons could work for you.
Yes there is a limit of max 20 regions (both beacon and geofence combine).
There are ways you can monitor 1000s of beacons but it depends on the use case.
You can use different wildcards and monitor 1000s of beacons but with some limitations. You have to play with beacon configurations like beacon UDID, major and minor values.
If you are only interested in enter or exit of any of the beacons (and not interested in specific beacon). You can actually just set the same UDID of the all the beacons and only monitor one beacon region will solve your problem.
let region = CLBeaconRegion.init(proximityUUID: UUID.init(uuidString: "YOUR_BEACONS_UDID_32_DIGITS")!, identifier: "beacon_region1")
locationManager.startMonitoring(for: region)
You can also group the beacons with UDID and Major value.
let r1 = CLBeaconRegion.init(proximityUUID: UUID.init(uuidString: "YOUR_BEACONS_UDID_32_DIGITS")!, major: 1000, identifier: "region_1000")
So you can monitor 20 groups of beacons in background and each group can have as many beacons as you want.
Although CoreLocation APIs limit beacon region monitoring to 20 regions (combined with geofence regions), you can look for nearly 86 billion different beacon locations for the purpose of sending notifications to a user.
Yes, that's right. 86 billion -- 85,899,345,920 to be precise. Think that's enough?
The simple technique is to combine beacon monitoring APIs with beacon ranging APIs. Using monitoring, you can wake up your app in the background when any one of your beacons is detected. Then using ranging APIs you can read the exact beacon identifiers detected, and send a push notification to the user. This will all work with the phone still sitting in the user's pocket.
Because each beacon identifier includes a major (0-63355) and a minor (0-63335), you can monitor for the maximum 20 beacon regions with a different ProximityUUID, and get 20 x 65536 x 65536 = 85,899,345,920 different combinations.
let region = CLBeaconRegion.init(proximityUUID: UUID.init(uuidString: "2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6")!, identifier: "beacon_region1")
locationManager.startMonitoring(for: region)
locationManager.startRangingBeacons(in: region)
// TODO: repeat the above for up to 19 more regions
...
public func locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion) {
for beacon in beacons {
var uuid = beacon.proximityUUID
var major = beacon.major
var minor = beacon.minor
// TODO: Send a unique local notification to the user for this
// uuid/major/minor combination identifying a particular place
}
}
There are some limits to this approach. If your beacons are placed within overlapping radio range of each other (~ 50 meters) then a user dwelling by one beacon for awhile then walking to the one next door will not get a background wakeup unless the beacons are in two different regions. There are some games you can play to get around this limitation, but for many use cases you don't even need to bother.

Timing Advance in GSM

I have a bunch of questions concerning Timing Advance in GSM :
When is it defined ?
Is it the phone or the BTS who's in charge of defining it's value ?
is it dynamic, does it depends on certain situations ?
Let's say that I figured out a way to get the exact value of the Timing Advance (GSM Layer 1 Transmission level) from the phone's modem :
In order to verify my solution, I'm supposed to put my phone over and over in a situation where he have to use/change the Timing Advance while I log its value...
How can I do that ?
Thanks
In the GSM cellular mobile phone standard, timing advance value corresponds to the length of time a signal takes to reach the base station from a mobile phone. GSM uses TDMA technology in the radio interface to share a single frequency between several users, assigning sequential timeslots to the individual users sharing a frequency. Each user transmits periodically for less than one-eighth of the time within one of the eight timeslots. Since the users are at various distances from the base station and radio waves travel at the finite speed of light, the precise arrival-time within the slot can be used by the base station to determine the distance to the mobile phone. The time at which the phone is allowed to transmit a burst of traffic within a timeslot must be adjusted accordingly to prevent collisions with adjacent users. Timing Advance (TA) is the variable controlling this adjustment.
Technical Specifications 3GPP TS 05.10[1] and TS 45.010[2] describe the TA value adjustment procedures. The TA value is normally between 0 and 63, with each step representing an advance of one bit period (approximately 3.69 microseconds). With radio waves travelling at about 300,000,000 metres per second (that is 300 metres per microsecond), one TA step then represents a change in round-trip distance (twice the propagation range) of about 1,100 metres. This means that the TA value changes for each 550-metre change in the range between a mobile and the base station. This limit of 63 × 550 metres is the maximum 35 kilometres that a device can be from a base station and is the upper bound on cell placement distance.
A continually adjusted TA value avoids interference to and from other users in adjacent timeslots, thereby minimizing data loss and maintaining Mobile QoS (call quality-of-service).
Timing Advance is significant for privacy and communications security, as its combination with other variables can allow GSM localization to find the device's position and tracking the mobile phone user. TA is also used to adjust transmission power in Space-division multiple access systems.
This limited the original range of a GSM cell site to 35km as mandated by the duration of the standard timeslots defined in the GSM specification. The maximum distance is given by the maximum time that the signal from the mobile/BTS needs to reach the receiver of the mobile/BTS on time to be successfully heard. At the air interface the delay between the transmission of the downlink (BTS) and the uplink (mobile) has an offset of 3 timeslots. Until now the mobile station has used a timing advance to compensate for the propagation delay as the distance to the BTS changes. The timing advance values are coded by 6 bits, which gives the theoretical maximum BTS/mobile separation as 35km.
By implementing the Extended Range feature, the BTS is able to receive the uplink signal in two adjacent timeslots instead of one. When the mobile station reaches its maximum timing advance, i.e. maximum range, the BTS expands its hearing window with an internal timing advance that gives the necessary time for the mobile to be heard by the BTS even from the extended distance. This extra advance is the duration of a single timeslot, a 156 bit period. This gives roughly 120 km range for a cell.[3] and is implemented in sparsely populated areas and to reach islands for example.
Hope this Answer the question:)
It's defined everytime the BTS needs to set the define the phone's transmission power, which happens quite often.
It's the core system (BTS in GSM) who totally in charge of defining it's value.
It's very dynamic, and change a lot. Globally, the GSM core system is constantly trying to find the exact distance between the BTS and the MS, so it constantly make a kind of "ping" to calculate it. The result of such operations is generally not that accurate since there are a lot of obstacles between the mobile and the BTS (it's not a direct link in an open space).
Such operations happens a lot, so use your smartphone. Simply.

Tracking multiple (20+) locations with iOS geofencing

An iOS application uses the geofencing for notifying the user about predefined nearby locations. The application is allowed to miss some location (the user is not getting a notification about a nearby location), but it is desirable to keep the missing rate low.
One way to implement this would be to start monitoring for significant change locations with startMonitoringSignificantLocationChanges and each time the "location change" event is fired, look for locations within, let say, 500m radius of the reported location.
What worries me is the requirement to perform the query for the nearby regions each time the significant location change occurs and it impact on the battery.
The other way to do it would be to register the locations with startMonitoringForRegion but Apple has put a (reasonable) limitation on the number of simultaneously tracked regions which is 20 and we have significantly more than 20 locations. So some sort of dynamic updating of the tracked regions is required but I am still unsure what is the best way to do it.
Any ideas on how can it be done so that it keeps the battery consumption low but also has the low missing rate for locations?
Since there was not much activity on the question I will describe how we are currently solving this problem.
We tied the reloading of the new regions to significant location change (SLC) events. When an SLC takes place, we check for 20 neighbouring regions that should be "geofenced". To find the 20 closest regions we are simply approximating 1'' of the latitude and longitude according to the following formulae:
Latitude: 1 deg = 110.54 km
Longitude: 1 deg = 111.320 * cos(latitude) km
and just check the bounding square of the current position of the device for the centers of the monitored regions (see: Simple calculations for working with lat/lon + km distance?)
So, for example, if (10N,10E) is the current location of the device we start with the bounding square with vertices at (10-1',10-1'), (X-10',10+1'), (10+1',10+1'), (10+1',10-1') (at latitude (10N,10E) one latitude/longitude minute approximates 1,85 km).
If there are 20 (or almost 20) - we register them for the geofencing and wait for the next SCL. If less/more, just increase/decrease the size of the bounding rectangle and repeat the search.
You can tweak this search algorithm for a better performance, but the one described here will already do the job.
You could reserve a location for a "meta-geofence" encompassing all the currently monitored locations. When the user leaves this geofence, the app will be notified. Then the app can update itself and stop tracking the farthest areas and start tracking new areas in the vicinity.
I thought I would add another option for using more than 20 Geofences in your app. This way has been working well in our app for a long time now and uses CLLocation methods that are built-in.
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
if (locations.count > 0) {
CLLocation *location = locations[0];
NSMutableArray *sortedFences = [[NSMutableArray alloc] init];
// add distance to each fence to be sorted
for (GeofenceObject *geofence in enabledFences) {
// create a CLLocation object from my custom object
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(geofence.latitude, geofence.longitude);
CLLocation *fenceLocation = [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude];
// calculate distance from current location
CLLocationDistance distance = [location distanceFromLocation:fenceLocation];
// save distance so we can filter array later
geofence.distance = distance;
[sortedFences addObject:geofence];
}
// sort our array of geofences by distance and add we can add the first 20
NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:#"distance" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
NSArray *sortedArray = [sortedFences sortedArrayUsingDescriptors:sortDescriptors];
// should only use array of 20, but I was using hardcoded count to exit
for (GeofenceObject *geofence in sortedArray) {
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(geofence.latitude, geofence.longitude);
CLLocationDistance radius = geofence.radius;
NSString *ident = geofence.geofenceId;
CLCircularRegion *fenceRegion = [[CLCircularRegion alloc] initWithCenter:coordinate radius:radius identifier:ident];
fenceRegion.notifyOnEntry = geofence.entry;
fenceRegion.notifyOnExit = geofence.exit;
[locationController.locationManager startMonitoringForRegion:fenceRegion];
}
}
}
Hopefully this will help someone or steer them on the right path.
If you are concerned about performing the proximity check on each significant location change, you could use a spatial indexing/search method like R-trees or R*-tree to reduce the number of comparisons needed for each location change, as those search algorithms will filter out (possibly large) spatially irrelevant regions. That should reduce the time/battery power needed to perform the proximity checks.
I know this post is old, but for those looking to do something similar, Skyhook offers the ability to geofence an infinite number of venues.
From their marketing:
Skyhook’s Context Accelerator enables app developers and advertisers to instantly deploy Infinite Geofences to any brand chain (such as CVS) or venue category (such as convenience stores) through a simple web interface. Using the same patented technology from Skyhook’s first-party location network, the Context Accelerator SDK manages those active geofences on-device, regardless of OS limitations allowing for infinite geofencing.

Resources