I am working on a BLE Scanner.Basically I am looking for an iBeacon device with 0x4c type and a payload size of 30. However when i run this mbed crashes after spitting out few print lines. This code is very hit and miss.
it is getting an index out of bound error(understandably). How do I catch the error and skip it?
void Scanner::onAdvertisingReport(const AdvertisingReportEvent &event)
{
printf("Looking for Devices\r\n");
AdvertisingDataParser adv_data(event.getPayload());
while(adv_data.hasNext())
{
if (event.getPayload().size() == 30 and event.getPayload()[5] == 0x4c)
{
beacon_found = true;
while(beacon_found)
{
printf("Found Beacon!\r\n");
::print_address(event.getPeerAddress());
printf("RSSI : %d\r\n",event.getRssi());
printf("PL: %d\r\n",event.getPayload().size());
printf("Major Value: %d\r\n",event.getPayload()[26]);
printf("Minor Value: %d\r\n",event.getPayload()[27]);
break;
}
beacon_found = false;
break;
}
else
{
printf("Couldnt find beacon!\r\n");
break;
}
}
adv_data.next();
}
Error:
Error Status: 0x80FF0140 code 324 module 255
Assertion failed: 0 <= index && index < _size in Span.h
Related
This is origin code
if (!isNullOrEmpty(configTypeBuilder.destinationField, RULE_CRITERIA_CONFIG_TYPE_BUILDER_DESTINATION_FIELD_PATH)) {
if (ruleAttributes.firstOrNull { ruleAttribute -> ruleAttribute == destinationField } == null) {
addValidationError(RULE_CRITERIA_CONFIG_TYPE_BUILDER_DESTINATION_FIELD_PATH, configTypeBuilder.destinationField, NOT_EXIST_CONSTRAINT)
}
}
I modify the code, just add the invalid value to a list, and then print them, but now when I enter valid destinationField after invalid destinationField, it will still show the error message, I don't know what's going on
val invalidDestination = hashSetOf<String>()
if (!isNullOrEmpty(configTypeBuilder.destinationField, RULE_CRITERIA_CONFIG_TYPE_BUILDER_DESTINATION_FIELD_PATH)) {
for (destinationField in destinationFieldList) {
if (!ruleAttributes.contains(destinationField)) {
invalidDestination.add(destinationField)
}
}
if (invalidDestination.size > 0) {
addValidationError(
"$RULE_CRITERIA_CONFIG_TYPE_BUILDER_DESTINATION_FIELD_PATH $NOT_EXIST_CONSTRAINT",
DESTINATION,
"$ADD_TAX_ENGINE_ATTRIBUTE_FIELDS $invalidDestination"
)
}
}
If your goal is to show error message only if there are no valid destinations, you need to add one more condition to your if statement. If not please clarify your question and post the whole function
Condition example:
var foundValid = false
for (destinationField in destinationFieldList) {
if (!ruleAttributes.contains(destinationField)) {
invalidDestination.add(destinationField)
}else {
foundValid = true
break //if you need invalidDestination list for later remove this break
}
}
if (invalidDestination.size > 0 && !foundValid) {
...
}
Version
vert.x core:3.5.0
vert.x redis client:3.5.0
Context
2018-06-02 17:40:55.981 ERROR 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection : No handler waiting for message: 14751915
2018-06-02 17:41:10.937 ERROR 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection : No handler waiting for message: false
2018-06-02 17:41:10.947 ERROR 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection : No handler waiting for message: false
2018-06-02 17:41:20.937 ERROR 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection : No handler waiting for message: true
2018-06-02 17:41:30.937 ERROR 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection : No handler waiting for message: true
2018-06-02 17:41:35.927 ERROR 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection : No handler waiting for message: false
2018-06-02 17:41:40.937 ERROR 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection : No handler waiting for message: true
2018-06-02 17:41:50.948 ERROR 4933 --- [ntloop-thread-2] io.vertx.redis.impl.RedisConnection : No handler waiting for message: true
After view code of the io.vertx.redis.impl.RedisConnectioni find the why:
When server started, create redis connetion,it's ok for runing.
After long time (eg.days),the state of connection is DISCONNECTED. Vert.x redis client reconnect redis server when send command to redis server:
void send(final Command command) {
// start the handshake if not connected
if (state.get() == State.DISCONNECTED) {
connect();
}
connect() call clearQueue()
clearQueue(): waiting command quene will be empty.
Call handleReply() when receive from redis server with new connection.
note: An error log appears here(the third line to bottom).
private void handleReply(Reply reply) {
final Command cmd = waiting.poll();
if (cmd != null) {
switch (reply.type()) {
case '-': // Error
cmd.handle(Future.failedFuture(reply.asType(String.class)));
return;
case '+': // Status
switch (cmd.responseTransform()) {
case ARRAY:
cmd.handle(Future.succeededFuture(new JsonArray().add(reply.asType(String.class))));
break;
default:
cmd.handle(Future.succeededFuture(reply.asType(cmd.returnType())));
break;
}
return;
case '$': // Bulk
switch (cmd.responseTransform()) {
case ARRAY:
cmd.handle(Future.succeededFuture(new JsonArray().add(reply.asType(String.class, cmd.encoding()))));
break;
case INFO:
String info = reply.asType(String.class, cmd.encoding());
if (info == null) {
cmd.handle(Future.succeededFuture(null));
} else {
String lines[] = info.split("\\r?\\n");
JsonObject value = new JsonObject();
JsonObject section = null;
for (String line : lines) {
if (line.length() == 0) {
// end of section
section = null;
continue;
}
if (line.charAt(0) == '#') {
// begin section
section = new JsonObject();
// create a sub key with the section name
value.put(line.substring(2).toLowerCase(), section);
} else {
// entry in section
int split = line.indexOf(':');
if (section == null) {
value.put(line.substring(0, split), line.substring(split + 1));
} else {
section.put(line.substring(0, split), line.substring(split + 1));
}
}
}
cmd.handle(Future.succeededFuture(value));
}
break;
default:
cmd.handle(Future.succeededFuture(reply.asType(cmd.returnType(), cmd.encoding())));
break;
}
return;
case '*': // Multi
switch (cmd.responseTransform()) {
case HASH:
cmd.handle(Future.succeededFuture(reply.asType(JsonObject.class, cmd.encoding())));
break;
default:
cmd.handle(Future.succeededFuture(reply.asType(JsonArray.class, cmd.encoding())));
break;
}
return;
case ':': // Integer
switch (cmd.responseTransform()) {
case ARRAY:
cmd.handle(Future.succeededFuture(new JsonArray().add(reply.asType(Long.class))));
break;
default:
cmd.handle(Future.succeededFuture(reply.asType(cmd.returnType())));
break;
}
return;
default:
cmd.handle(Future.failedFuture("Unknown message type"));
}
} else {
// **An error log appears here**
log.error("No handler waiting for message: " + reply.asType(String.class));
}
}
question:
It's a bug or not?
If not a bug , the post commands will be discarded when reconnect redis server.
What's a good way to deal with this situation?
The problem has been solved. The reason for the above problem is that the connection has been reused and has not been closed. The solution is:
`
RedisClient redisClient = RedisClient.create(this.vertx, redisOptions);
//do some thing;
redisClient.close(h-{})...
`
for each session.
Scenario
Our app aims to detect beacons placed inside the restaurants our app
uses react-native-beacons-manager
When our app detects a beacon, I have developed a cloud function that accepts the beacon's major key and use it to query data of that restaurant from my database
The Cloud function then sends a push notification on the user about the restaurant details.
The Problem
The way I detect the beacons is not stable. this is my flow. I created a function located at
this.beaconsDidRangeEvent = Beacons.BeaconsEventEmitter.addListener(
//function-here
);
I can receive the beacons information like uuid, major and minor key and proximity (immediate, near, far, unknown) . Now inside that function I use the major key to determine the individuality of each beacons. Now, I've made a condition like this:
let beaconArr = data.beacons;
console.log(beaconArr);
console.log(count);
if (beaconArr.length > 0) {
console.log("beacons detected!");
let major = data.beacons[0].major;
let prox = data.beacons[0].proximity;
if ((prox === "near" || prox === "far") && beaconFlag === false && count === 0) {
console.log("beacon Action");
this.props.beaconAction(major);
this.props.createCheckInHistory(user.uid);
beaconFlag = true;
count++;
} else {
console.log("counter turned to 1!");
console.log(data);
beaconFlag = true;
}
} else {
console.log("no beacons detected!");
count = 0;
beaconFlag = false;
}
Expected Result
I expect that the functions inside the condition is true will only fire once.
Actual Result
Sometimes, its ok sometimes its not. even if im still at the range of the beacon, suddenly the beacon's array got 0. Then suddenly i'll receive a push notification again and again.
componentDidMount() Code
componentDidMount() {
this.props.selectedIcon('map');
firebase
.messaging()
.getInitialNotification()
.then(notification => {
console.log("Notification which opened the app: ", notification);
});
const user = firebase.auth().currentUser;
let count = 0;
let beaconFlag = false;
// will be set as a reference to "regionDidEnter" event:
this.beaconsDidRangeEvent = Beacons.BeaconsEventEmitter.addListener(
"beaconsDidRange",
_.throttle(data => {
let beaconArr = data.beacons;
console.log(beaconArr);
console.log(count);
if (beaconArr.length > 0) {
console.log("beacons detected!");
let major = data.beacons[0].major;
let prox = data.beacons[0].proximity;
if ((prox === "near" || prox === "far") && beaconFlag === false && count === 0) {
console.log("beacon Action");
this.props.beaconAction(major);
this.props.createCheckInHistory(user.uid);
beaconFlag = true;
count++;
} else {
console.log("counter turned to 1!");
console.log(data);
beaconFlag = true;
}
} else {
console.log("no beacons detected!");
count = 0;
beaconFlag = false;
}
}, 3000)
);
// monitoring events
this.regionDidEnterEvent = Beacons.BeaconsEventEmitter.addListener(
"regionDidEnter",
data => {
console.log("monitoring - regionDidEnter data: ", data);
}
);
// Monitoring: Listen for device leaving the defined region
this.regionDidExitEvent = Beacons.BeaconsEventEmitter.addListener(
"regionDidExit",
data => {
console.log("monitoring - regionDidExit data: ", data);
}
);
}
This is a common problem when ranging in beacon apps. Sometimes the detected beacons will briefly drop out then come back again. This can be solved by a software filter where you keep track of all beacons you have recently seen, and only perform an operation of it has not happened recently. In your case, you may use the major as the key to the index into the filter object.
// scope this globally
var minimumRetriggerMillis = 3600 * 1000; // 1hr
var recentTriggers = {};
// Before executing your trigger action:
var now = new Date().getTime();
if (recentTriggers[minor] == null || now-recentTriggers[minor] > minimumRetriggerMillis) {
recentTriggers[minor] = now;
// TODO: execute trigger logic here
}
I use Gstreamer as base for playing videos and audio and so far its working fine. Now I want to know when media is stopped, paused, loaded or started playing and notify the GUI. Now the Messages keep repeating itself (see the attached image). Now in that situation, it will be flooding my GUI. I want to receive event only once (for example when media is stopped or pause or loaded).
The only Message that I get consistently (once) is End of Stream.
Is there a way to get the said message only once, when they happen?
Here is my current code
extern "C"
{
static GstBusSyncReply
bus_sync(GstBus* bus, GstMessage* message, gpointer user_data)
{
CustomData* data = reinterpret_cast<CustomData*>(user_data);
GstState old_state, new_state, pending;
gst_message_parse_state_changed(message, &old_state, &new_state, &pending);
g_print ("State set from %s to %s --- %s\n", gst_element_state_get_name (old_state), gst_element_state_get_name (new_state), gst_element_state_get_name (pending));
switch(GST_MESSAGE_TYPE(message))
{
case GST_MESSAGE_STATE_CHANGED:
{
wxGStreamer* win = dynamic_cast<wxGStreamer*>(data->parent);
if(win)
{
win->SendMessage(wxMEDIASTATE_CHANGED);
}
if(data->state!=new_state)
{
//state changed, save it
data->state = new_state;
if(old_state==GST_STATE_NULL && new_state == GST_STATE_READY && pending== GST_STATE_PLAYING)
{
g_print ("***Loaded***\n");
}
else if(old_state==GST_STATE_PLAYING && new_state == GST_STATE_PAUSED && pending== GST_STATE_VOID_PENDING)
{
g_print ("***Paused***\n");
}
else if(old_state==GST_STATE_READY && new_state == GST_STATE_NULL && pending== GST_STATE_VOID_PENDING)
{
g_print ("***Stopped***\n");
}
else if(new_state == GST_STATE_PLAYING &&(old_state==GST_STATE_READY||old_state==GST_STATE_PAUSED) )
{
g_print ("***Playing***\n");
}
}
break;
}
}
}
}
Simply answered: you get more messages from GstBus other than play/stop states.
Implement a switch in your code and your if/else statements are called only once:
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_ERROR:
break;
case GST_MESSAGE_WARNING:
break;
case GST_MESSAGE_INFO:
break;
case GST_MESSAGE_EOS:
break;
case GST_MESSAGE_BUFFERING:
break;
case GST_MESSAGE_STATE_CHANGED: {
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed (msg, &old_state,
&new_state, &pending_state);
if (GST_MESSAGE_SRC (msg) == GST_OBJECT (__YOUR_PIPELINE_POINTER__)) {
// your code here
}
}
break;
}
// DON'T FORGET TO RETURN
return GST_BUS_DROP;
Hope, that helps ;-)
The program runs fine when the user is connected to the internet. However, when the user is not connected, the app crashes with:
Error:The operation couldn’t be completed. (kCLErrorDomain error 8.)
fatal error: unexpectedly found nil while unwrapping an Optional value
I'd like the catch the error before it crashes and display an alertcontroller
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: { (placemarks, error) -> Void in
if (error != nil) {
println("Error:" + error.localizedDescription)
}
if placemarks.count > 0 {
let pm = placemarks[0] as CLPlacemark
self.displayLocationInfo(pm)
currentLoc = manager.location
currentLocGeoPoint = PFGeoPoint(location:currentLoc)
var query = PFQuery(className:"Restaurant") //default: Restaurant
query.whereKey("RestaurantLoc", nearGeoPoint:currentLocGeoPoint, withinMiles:setDistanceMiles) //filter by miles
query.limit = 1000 //limit number of results
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) -> Void in
if objects.isEmpty {
//NO RESULTS
let alertController = UIAlertController(title: "Unavailable Area", message:
"This app is not available in your area yet. We'll try our best to have it up and running as soon as possible.", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default,handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
self.navigationController!.popViewControllerAnimated(true)
} else {
newArray = objects
}
self.hideActivityIndicator(self.view)
}
} else {
println("error: \(error)")
}
})
}
The problem is your if statement. You are saying this:
if (error != nil) {
println("Error:" + error.localizedDescription)
}
if placemarks.count > 0 { // ...
Well, there was an error. And you were told that there was an error. But you didn't listen! You didn't stop! You just go right on as if nothing had happened, and try to access the placemarks variable - which wasn't returned. You need to use logic here so that you exit if there's an error:
if (error != nil) {
println("Error:" + error.localizedDescription)
return // go no further!
}
if placemarks.count > 0 { // ...
Note, however, that it would be better to check placemarks for nil first:
if placemarks == nil {
// check error
// return
}
if placemarks.count > 0 { // ...
I believe you need to implement locationManager:didFailWithError which tells the delegate when it is unable to retrieve the location. Then, you just need to handle the error with appropriate response.
For references: CLLocationManagerDelegate apple docs