@@ -30,7 +30,9 @@ enum sensor_state {
30
30
};
31
31
32
32
typedef struct sensor_handle {
33
- zjs_callback_id id ;
33
+ zjs_callback_id onchange_cb_id ;
34
+ zjs_callback_id onstart_cb_id ;
35
+ zjs_callback_id onstop_cb_id ;
34
36
enum sensor_channel channel ;
35
37
int frequency ;
36
38
enum sensor_state state ;
@@ -83,6 +85,20 @@ static void zjs_sensor_free_handles(sensor_handle_t *handle)
83
85
}
84
86
}
85
87
88
+ static sensor_handle_t * zjs_sensor_get_handle (jerry_value_t obj )
89
+ {
90
+ uintptr_t ptr ;
91
+ sensor_handle_t * handle = NULL ;
92
+ if (jerry_get_object_native_handle (obj , & ptr )) {
93
+ handle = (sensor_handle_t * )ptr ;
94
+ if (handle ) {
95
+ return handle ;
96
+ }
97
+ }
98
+ ERR_PRINT ("cannot find handle" );
99
+ return NULL ;
100
+ }
101
+
86
102
static bool zjs_sensor_ipm_send_sync (zjs_ipm_message_t * send ,
87
103
zjs_ipm_message_t * result )
88
104
{
@@ -178,11 +194,9 @@ static void zjs_sensor_set_state(jerry_value_t obj, enum sensor_state state)
178
194
if (jerry_value_is_function (func )) {
179
195
// if onstatechange exists, call it
180
196
jerry_value_t new_state = jerry_create_string (state_str );
181
- jerry_value_t rval = jerry_call_function (func , obj , & new_state , 1 );
182
- if (jerry_value_has_error_flag (rval )) {
183
- ERR_PRINT ("calling onstatechange\n" );
184
- }
185
- jerry_release_value (rval );
197
+ zjs_callback_id id = zjs_add_callback_once (func , obj , NULL , NULL );
198
+ zjs_signal_callback (id , & new_state , sizeof (new_state ));
199
+ jerry_release_value (new_state );
186
200
}
187
201
jerry_release_value (func );
188
202
@@ -191,11 +205,8 @@ static void zjs_sensor_set_state(jerry_value_t obj, enum sensor_state state)
191
205
func = zjs_get_property (obj , "onactivate" );
192
206
if (jerry_value_is_function (func )) {
193
207
// if onactivate exists, call it
194
- jerry_value_t rval = jerry_call_function (func , obj , NULL , 0 );
195
- if (jerry_value_has_error_flag (rval )) {
196
- ERR_PRINT ("calling onactivate\n" );
197
- }
198
- jerry_release_value (rval );
208
+ zjs_callback_id id = zjs_add_callback_once (func , obj , NULL , NULL );
209
+ zjs_signal_callback (id , NULL , 0 );
199
210
}
200
211
jerry_release_value (func );
201
212
}
@@ -262,11 +273,8 @@ static void zjs_sensor_trigger_error(jerry_value_t obj,
262
273
zjs_set_property (error_obj , "name" , name_val );
263
274
zjs_set_property (error_obj , "message" , message_val );
264
275
zjs_set_property (event , "error" , error_obj );
265
- jerry_value_t rval = jerry_call_function (func , obj , & event , 1 );
266
- if (jerry_value_has_error_flag (rval )) {
267
- ERR_PRINT ("calling onerrorhange\n" );
268
- }
269
- jerry_release_value (rval );
276
+ zjs_callback_id id = zjs_add_callback_once (func , obj , NULL , NULL );
277
+ zjs_signal_callback (id , & event , 1 );
270
278
jerry_release_value (name_val );
271
279
jerry_release_value (message_val );
272
280
jerry_release_value (error_obj );
@@ -321,10 +329,10 @@ static void zjs_sensor_signal_callbacks(struct sensor_data *data)
321
329
xyz [0 ] = data -> reading .x ;
322
330
xyz [1 ] = data -> reading .y ;
323
331
xyz [2 ] = data -> reading .z ;
324
- zjs_signal_callback (h -> id , & xyz , sizeof (xyz ));
332
+ zjs_signal_callback (h -> onchange_cb_id , & xyz , sizeof (xyz ));
325
333
} else {
326
334
double dval = data -> reading .dval ;
327
- zjs_signal_callback (h -> id , & dval , sizeof (dval ));
335
+ zjs_signal_callback (h -> onchange_cb_id , & dval , sizeof (dval ));
328
336
}
329
337
}
330
338
}
@@ -357,53 +365,103 @@ static void zjs_sensor_callback_free(uintptr_t handle)
357
365
zjs_free ((sensor_handle_t * )handle );
358
366
}
359
367
360
- static jerry_value_t zjs_sensor_start (const jerry_value_t function_obj ,
361
- const jerry_value_t this ,
362
- const jerry_value_t argv [],
363
- const jerry_length_t argc )
368
+ static void zjs_sensor_onstart_c_callback (void * h , void * argv )
364
369
{
365
- // requires: this is a Sensor object from takes no args
366
- // effects: activates the sensor and start monitoring changes
367
- enum sensor_state state = zjs_sensor_get_state (this );
368
- if (state == SENSOR_STATE_ACTIVATING || state == SENSOR_STATE_ACTIVATED ) {
369
- return ZJS_UNDEFINED ;
370
- }
371
-
372
- uintptr_t ptr ;
373
- sensor_handle_t * handle = NULL ;
374
- if (jerry_get_object_native_handle (this , & ptr )) {
375
- handle = (sensor_handle_t * )ptr ;
376
- if (!handle ) {
377
- return zjs_error ("zjs_sensor_start: cannot find handle" );
378
- }
370
+ sensor_handle_t * handle = (sensor_handle_t * )h ;
371
+ if (!handle ) {
372
+ ERR_PRINT ("handle not found\n" );
373
+ return ;
379
374
}
380
375
381
- zjs_sensor_set_state ( this , SENSOR_STATE_ACTIVATING ) ;
376
+ jerry_value_t obj = handle -> sensor_obj ;
382
377
zjs_ipm_message_t send ;
383
378
send .type = TYPE_SENSOR_START ;
384
379
send .data .sensor .channel = handle -> channel ;
385
380
send .data .sensor .frequency = handle -> frequency ;
386
381
if (handle -> channel == SENSOR_CHAN_LIGHT ) {
387
382
// AmbientLightSensor needs provide AIO pin value
388
383
uint32_t pin ;
389
- if (!zjs_obj_get_uint32 (this , "pin" , & pin )) {
390
- return zjs_error ("zjs_sensor_start: pin not found" );
384
+ if (!zjs_obj_get_uint32 (obj , "pin" , & pin )) {
385
+ zjs_sensor_trigger_error (obj , "DataError" ,
386
+ "pin not found" );
387
+ return ;
391
388
}
392
389
send .data .sensor .pin = pin ;
393
390
}
391
+
394
392
int error = zjs_sensor_call_remote_function (& send );
395
393
if (error != ERROR_IPM_NONE ) {
396
394
if (error == ERROR_IPM_OPERATION_NOT_ALLOWED ) {
397
- zjs_sensor_trigger_error (this , "NotAllowedError" ,
395
+ zjs_sensor_trigger_error (obj , "NotAllowedError" ,
398
396
"permission denied" );
399
- return ZJS_UNDEFINED ;
397
+ } else {
398
+ zjs_sensor_trigger_error (obj , "UnknownError" ,
399
+ "IPM failed" );
400
+ }
401
+ }
402
+
403
+ zjs_sensor_set_state (obj , SENSOR_STATE_ACTIVATED );
404
+ }
405
+
406
+ static void zjs_sensor_onstop_c_callback (void * h , void * argv )
407
+ {
408
+ sensor_handle_t * handle = (sensor_handle_t * )h ;
409
+ if (!handle ) {
410
+ ERR_PRINT ("handle not found\n" );
411
+ return ;
412
+ }
413
+
414
+ jerry_value_t obj = handle -> sensor_obj ;
415
+ zjs_ipm_message_t send ;
416
+ send .type = TYPE_SENSOR_STOP ;
417
+ send .data .sensor .channel = handle -> channel ;
418
+
419
+ jerry_value_t reading_val = jerry_create_null ();
420
+ zjs_set_property (obj , "reading" , reading_val );
421
+ jerry_release_value (reading_val );
422
+ if (handle -> channel == SENSOR_CHAN_LIGHT ) {
423
+ // AmbientLightSensor needs provide AIO pin value
424
+ uint32_t pin ;
425
+ if (!zjs_obj_get_uint32 (obj , "pin" , & pin )) {
426
+ zjs_sensor_trigger_error (obj , "DataError" ,
427
+ "pin not found" );
428
+ return ;
400
429
}
401
- else {
402
- // throw exception for all other errors
403
- return zjs_error ("zjs_sensor_start: operation failed" );
430
+ send .data .sensor .pin = pin ;
431
+ }
432
+
433
+ int error = zjs_sensor_call_remote_function (& send );
434
+ if (error != ERROR_IPM_NONE ) {
435
+ if (error == ERROR_IPM_OPERATION_NOT_ALLOWED ) {
436
+ zjs_sensor_trigger_error (obj , "NotAllowedError" ,
437
+ "permission denied" );
438
+ } else {
439
+ zjs_sensor_trigger_error (obj , "UnknownError" ,
440
+ "IPM failed" );
404
441
}
442
+ zjs_sensor_set_state (obj , SENSOR_STATE_ERRORED );
405
443
}
406
- zjs_sensor_set_state (this , SENSOR_STATE_ACTIVATED );
444
+ }
445
+
446
+ static jerry_value_t zjs_sensor_start (const jerry_value_t function_obj ,
447
+ const jerry_value_t this ,
448
+ const jerry_value_t argv [],
449
+ const jerry_length_t argc )
450
+ {
451
+ // requires: this is a Sensor object from takes no args
452
+ // effects: activates the sensor and start monitoring changes
453
+ enum sensor_state state = zjs_sensor_get_state (this );
454
+ if (state == SENSOR_STATE_ACTIVATING || state == SENSOR_STATE_ACTIVATED ) {
455
+ return ZJS_UNDEFINED ;
456
+ }
457
+
458
+ sensor_handle_t * handle = zjs_sensor_get_handle (this );
459
+ if (!handle ) {
460
+ return zjs_error ("cannot find handle" );
461
+ }
462
+
463
+ zjs_sensor_set_state (this , SENSOR_STATE_ACTIVATING );
464
+ zjs_signal_callback (handle -> onstart_cb_id , NULL , 0 );
407
465
return ZJS_UNDEFINED ;
408
466
}
409
467
@@ -419,27 +477,15 @@ static jerry_value_t zjs_sensor_stop(const jerry_value_t function_obj,
419
477
return ZJS_UNDEFINED ;
420
478
}
421
479
422
- uintptr_t ptr ;
423
- sensor_handle_t * handle = NULL ;
424
- if (jerry_get_object_native_handle (this , & ptr )) {
425
- handle = (sensor_handle_t * )ptr ;
426
- if (!handle ) {
427
- return zjs_error ("zjs_sensor_stop: cannot find handle" );
428
- }
480
+ sensor_handle_t * handle = zjs_sensor_get_handle (this );
481
+ if (!handle ) {
482
+ return zjs_error ("cannot find handle" );
429
483
}
430
484
431
- zjs_ipm_message_t send ;
432
- send .type = TYPE_SENSOR_STOP ;
433
- send .data .sensor .channel = handle -> channel ;
434
- int error = zjs_sensor_call_remote_function (& send );
435
- if (error != ERROR_IPM_NONE ) {
436
- // throw exception for all other errors
437
- return zjs_error ("zjs_sensor_start: operation failed" );
438
- }
439
- jerry_value_t reading_val = jerry_create_null ();
440
- zjs_set_property (this , "reading" , reading_val );
441
- jerry_release_value (reading_val );
485
+ // we have to set state to idle first and then check if error occued
486
+ // in the onstop_c_callback()
442
487
zjs_sensor_set_state (this , SENSOR_STATE_IDLE );
488
+ zjs_signal_callback (handle -> onstop_cb_id , NULL , 0 );
443
489
return ZJS_UNDEFINED ;
444
490
}
445
491
@@ -450,6 +496,7 @@ static jerry_value_t zjs_sensor_create(const jerry_value_t function_obj,
450
496
enum sensor_channel channel )
451
497
{
452
498
double frequency = DEFAULT_SAMPLING_FREQUENCY ;
499
+ bool hasPin = false;
453
500
uint32_t pin ;
454
501
455
502
if (argc < 1 && channel == SENSOR_CHAN_LIGHT ) {
@@ -486,9 +533,7 @@ static jerry_value_t zjs_sensor_create(const jerry_value_t function_obj,
486
533
}
487
534
488
535
if (channel == SENSOR_CHAN_LIGHT ) {
489
- if (!zjs_obj_get_uint32 (options , "pin" , & pin )) {
490
- return zjs_error ("zjs_sensor_create: missing required field (pin)" );
491
- }
536
+ hasPin = zjs_obj_get_uint32 (options , "pin" , & pin );
492
537
}
493
538
}
494
539
@@ -508,14 +553,16 @@ static jerry_value_t zjs_sensor_create(const jerry_value_t function_obj,
508
553
zjs_set_property (sensor_obj , "reading" , reading_val );
509
554
jerry_release_value (reading_val );
510
555
511
- if (channel == SENSOR_CHAN_LIGHT ) {
556
+ if (channel == SENSOR_CHAN_LIGHT && hasPin ) {
512
557
zjs_obj_add_number (sensor_obj , pin , "pin" );
513
558
}
514
559
515
560
jerry_set_prototype (sensor_obj , zjs_sensor_prototype );
516
561
517
562
sensor_handle_t * handle = zjs_sensor_alloc_handle (channel );
518
- handle -> id = zjs_add_c_callback (handle , zjs_sensor_onchange_c_callback );
563
+ handle -> onchange_cb_id = zjs_add_c_callback (handle , zjs_sensor_onchange_c_callback );
564
+ handle -> onstart_cb_id = zjs_add_c_callback (handle , zjs_sensor_onstart_c_callback );
565
+ handle -> onstop_cb_id = zjs_add_c_callback (handle , zjs_sensor_onstop_c_callback );
519
566
handle -> channel = channel ;
520
567
handle -> frequency = frequency ;
521
568
handle -> sensor_obj = jerry_acquire_value (sensor_obj );
0 commit comments