-
Notifications
You must be signed in to change notification settings - Fork 9
/
mce-sensorfw.c
5510 lines (4488 loc) · 153 KB
/
mce-sensorfw.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/**
* @file mce-sensorfw.c
*
* Mode Control Entity - Interprocess communication with sensord
*
* <p>
*
* Copyright (C) 2013-2014 Jolla Ltd.
*
* <p>
*
* @author Simo Piiroinen <simo.piiroinen@jollamobile.com>
*
* mce is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation.
*
* mce is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mce. If not, see <http://www.gnu.org/licenses/>.
*/
#include "mce-sensorfw.h"
#include "mce.h"
#include "mce-log.h"
#include "mce-dbus.h"
#include "libwakelock.h"
#include <linux/input.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <inttypes.h>
/* ========================================================================= *
*
* Internal Layering - Top-Down
*
* ========================================================================= *
*
* SENSORFW_MODULE:
* - implements internal mce interface defined in mce-sensorfw.h
*
* SENSORFW_SERVICE:
* - state machine that tracks availablity of sensord on system bus
* - availalibility changes trigger activity in SENSORFW_PLUGIN
*
* SENSORFW_PLUGIN:
* - state machine that takes care of sensord plugin loading ipc
* - one instance / sensor
* - finishing plugin loading triggers activity in SENSORFW_SESSION
*
* SENSORFW_SESSION:
* - state machine that takes care of data session start ipc
* - one instance / sensor
* - acquiring a session id triggers activity in SENSORFW_CONNECTION
*
* SENSORFW_CONNECTION:
* - state machine that takes care of data connection with sensord
* - one instance / sensor
* - establishing a connection triggers activity in SENSORFW_OVERRIDE
* and SENSORFW_REPORTING
*
* SENSORFW_OVERRIDE:
* - state machine that takes care of standby override ipc
* - one instance / sensor
*
*
* SENSORFW_REPORTING:
* - state machine that takes care of sensor start/stop ipc
* - one instance / sensor
* - value changes reported via sensor specific SENSORFW_BACKEND
*
* SENSORFW_BACKEND:
* - contains all sensor specific constants and logic
*
* SENSORFW_NOTIFY:
* - manages cached sensor state
* - provides default values used when sensord is not available
* - feeds sensor data to upper level logic when state changes
* and/or listening callbacks are registered
*
* Error handling:
* - The layer where error occurred makes transition to ERROR state
* and all layers below that are reset to IDLE state and sensor
* states are reverted to sensord-is-not-available defaults.
* - The failed operation is reattempted after brief delay until it
* succeeds
* - Sensord restart might still be needed for full recovery.
*
* State transitions:
* - state transition diagram can be generated from mce-sensorfw.dot
* via installing graphviz package and running from command line
* dot -Tpng mce-sensorfw.dot -o mce-sensorfw.png
*
* ========================================================================= *
*
* Rough Data/Control Flow Diagram - Error Handling and EVDEV Input Excluded
*
* ========================================================================= *
*
* .--------------------. .--------------------.
* | MCE INIT/EXIT | | MCE SENSOR LOGIC |
* `--------------------' `--------------------'
* | |
* | init/quit enable/disable |
* | |
* v v
* .--------------------------------------------------------.
* | SENSORFW_MODULE |
* `--------------------------------------------------------'
* | | |
* | start | probe/reset enable/disable |
* | | |
* | v v
* | .---------------------------------------------------.
* | | SENSORFW_SERVICE |
* | `---------------------------------------------------'
* | | | | |
* | | start | load/reset set/unset | |
* | | | | | start/stop
* | | v | |
* | | .------------------------------. | |
* | | | SENSORFW_PLUGIN | | |
* | | `------------------------------' | |
* | | | | |
* | | | start/reset | |
* | | | | |
* | | v | |
* | | .------------------------------. | |
* | | | SENSORFW_SESSION | | |
* | | `------------------------------' | |
* | | | | |
* | | | connect/reset | |
* | | | | |
* | | v | |
* | | .------------------------------. | |
* | | | SENSORFW_CONNECTION | | |
* | | `------------------------------' | |
* | | | | | |
* | | | rethink/reset | | |
* | | | | | |
* | | | rethink/reset | | |
* | | | | | |
* | | | v v |
* | | | .--------------------------------. |
* | | | | SENSORFW_OVERRIDE | |
* | | | `--------------------------------' |
* | | v v
* | | .--------------------------------------------.
* | | | SENSORFW_REPORTING |
* | | `--------------------------------------------'
* | | |
* | | | initial/change/reset
* | | |
* | | v
* | | .--------------------------------------------.
* | | | SENSORFW_BACKEND |
* | | `--------------------------------------------'
* v v |
* .--------------------. | sensor state
* | SENSORFW_EXCEPTION | |
* `--------------------' |
* | |
* active | |
* v v
* .--------------------------------------------.
* | SENSORFW_NOTIFY |
* `--------------------------------------------'
* |
* | sensor state
* |
* v
* .--------------------------------------------.
* | MCE SENSOR LOGIC |
* `--------------------------------------------'
*
* ========================================================================= */
/** ID numbers for sensors supported by mce-sensorfwd module
*/
typedef enum
{
SFW_SENSOR_ID_PS,
SFW_SENSOR_ID_ALS,
SFW_SENSOR_ID_ORIENT,
SFW_SENSOR_ID_ACCELEROMETER,
SFW_SENSOR_ID_COMPASS,
SFW_SENSOR_ID_GYROSCOPE,
SFW_SENSOR_ID_LID,
SFW_SENSOR_ID_HUMIDITY,
SFW_SENSOR_ID_MAGNETOMETER,
SFW_SENSOR_ID_PRESSURE,
SFW_SENSOR_ID_ROTATION,
SFW_SENSOR_ID_STEPCOUNTER,
SFW_SENSOR_ID_TAP,
SFW_SENSOR_ID_TEMPERATURE,
SFW_SENSOR_ID_COUNT
} sensor_id_t;
static bool
sensor_id_available(sensor_id_t id)
{
bool available = true;
switch( id ) {
case SFW_SENSOR_ID_PS:
case SFW_SENSOR_ID_ALS:
case SFW_SENSOR_ID_ORIENT:
break;
default:
available = mce_in_sensortest_mode();
break;
}
return available;
}
/* ========================================================================= *
* D-BUS CONSTANTS FOR D-BUS DAEMON
* ========================================================================= */
/** org.freedesktop.DBus.NameOwnerChanged D-Bus signal */
#define DBUS_SIGNAL_NAME_OWNER_CHANGED "NameOwnerChanged"
#define DBUS_METHOD_GET_NAME_OWNER "GetNameOwner"
/* ========================================================================= *
* D-BUS CONSTANTS FOR SENSORD SERVICE
* ========================================================================= */
/** How long to wait before retrying failed sensorfw dbus requests */
#define SENSORFW_RETRY_DELAY_MS 10000
/** D-Bus name of the sensord service */
#define SENSORFW_SERVICE "com.nokia.SensorService"
// ----------------------------------------------------------------
/** D-Bus object path for sensord sensor manager */
#define SENSORFW_MANAGER_OBJECT "/SensorManager"
/** D-Bus interface used by sensor manager */
#define SENSORFW_MANAGER_INTEFCACE "local.SensorManager"
/** D-Bus method for loading sensor plugin */
#define SENSORFW_MANAGER_METHOD_LOAD_PLUGIN "loadPlugin"
/** D-Bus method for starting sensor session */
#define SENSORFW_MANAGER_METHOD_START_SESSION "requestSensor"
// ----------------------------------------------------------------
/* D-Bus interfaces for accessing sensor specific data
*
* Note: Sensorfwd uses separate interface for each sensor. */
#define SFW_SENSOR_INTERFACE_PS "local.ProximitySensor"
#define SFW_SENSOR_INTERFACE_ALS "local.ALSSensor"
#define SFW_SENSOR_INTERFACE_ORIENT "local.OrientationSensor"
#define SFW_SENSOR_INTERFACE_ACCELEROMETER "local.AccelerometerSensor"
#define SFW_SENSOR_INTERFACE_COMPASS "local.CompassSensor"
#define SFW_SENSOR_INTERFACE_GYROSCOPE "local.GyroscopeSensor"
#define SFW_SENSOR_INTERFACE_LID "local.LidSensor"
#define SFW_SENSOR_INTERFACE_HUMIDITY "local.HumiditySensor"
#define SFW_SENSOR_INTERFACE_MAGNETOMETER "local.MagnetometerSensor"
#define SFW_SENSOR_INTERFACE_PRESSURE "local.PressureSensor"
#define SFW_SENSOR_INTERFACE_ROTATION "local.RotationSensor"
#define SFW_SENSOR_INTERFACE_STEPCOUNTER "local.StepcounterSensor"
#define SFW_SENSOR_INTERFACE_TAP "local.TapSensor"
#define SFW_SENSOR_INTERFACE_TEMPERATURE "local.TemperatureSensor"
/** D-Bus method for enabling sensor
*
* @Note All sensor specific interfaces have start method.
*/
#define SFW_SENSOR_METHOD_START "start"
/** D-Bus method for disabling sensor
*
* @Note All sensor specific interfaces have stop method.
*/
#define SFW_SENSOR_METHOD_STOP "stop"
/** D-Bus method for changing sensor standby override
*
* @Note All sensor specific interfaces have have this method,
* but unless it is actually explicitly implemented, a
* virtual dummy method call handler gets invoked and
* it will just return "false".
*/
#define SFW_SENSOR_METHOD_SET_OVERRIDE "setStandbyOverride"
/* D-Bus methods for getting current sensor value
*
* The method name and returned data varies from one sensor to
* another, and in some cases there is no "current state" to
* query (such as tap detection sensor which emits events).
*/
#define SFW_SENSOR_METHOD_READ_PS "proximity"
#define SFW_SENSOR_METHOD_READ_ALS "lux"
#define SFW_SENSOR_METHOD_READ_ORIENT "orientation"
#define SFW_SENSOR_METHOD_READ_ACCELEROMETER "xyz"
#define SFW_SENSOR_METHOD_READ_COMPASS "value" // or "declinationvalue"?
#define SFW_SENSOR_METHOD_READ_GYROSCOPE "value"
#define SFW_SENSOR_METHOD_READ_LID "closed"
#define SFW_SENSOR_METHOD_READ_HUMIDITY "relativeHumidity"
#define SFW_SENSOR_METHOD_READ_MAGNETOMETER "magneticField"
#define SFW_SENSOR_METHOD_READ_PRESSURE "pressure"
#define SFW_SENSOR_METHOD_READ_ROTATION "rotation"
#define SFW_SENSOR_METHOD_READ_STEPCOUNTER "steps"
#define SFW_SENSOR_METHOD_READ_TAP NULL // event, not state
#define SFW_SENSOR_METHOD_READ_TEMPERATURE "temperature"
// ----------------------------------------------------------------
/** Connect path to sensord data unix domain socket */
#define SENSORFW_DATA_SOCKET "/run/sensord.sock"
// ----------------------------------------------------------------
/* Sensor names used by senseofwd */
#define SFW_SENSOR_NAME_PS "proximitysensor"
#define SFW_SENSOR_NAME_ALS "alssensor"
#define SFW_SENSOR_NAME_ORIENT "orientationsensor"
#define SFW_SENSOR_NAME_ACCELEROMETER "accelerometersensor"
#define SFW_SENSOR_NAME_COMPASS "compasssensor"
#define SFW_SENSOR_NAME_GYROSCOPE "gyroscopesensor"
#define SFW_SENSOR_NAME_LID "lidsensor"
#define SFW_SENSOR_NAME_HUMIDITY "humiditysensor"
#define SFW_SENSOR_NAME_MAGNETOMETER "magnetometersensor"
#define SFW_SENSOR_NAME_PRESSURE "pressuresensor"
#define SFW_SENSOR_NAME_ROTATION "rotationsensor"
#define SFW_SENSOR_NAME_STEPCOUNTER "stepcountersensor"
#define SFW_SENSOR_NAME_TAP "tapsensor"
#define SFW_SENSOR_NAME_TEMPERATURE "temperaturesensor"
// ----------------------------------------------------------------
/* ========================================================================= *
* FORWARD_DECLARATIONS
* ========================================================================= */
typedef struct sfw_service_t sfw_service_t;
typedef struct sfw_plugin_t sfw_plugin_t;
typedef struct sfw_session_t sfw_session_t;
typedef struct sfw_connection_t sfw_connection_t;
typedef struct sfw_override_t sfw_override_t;
typedef struct sfw_reporting_t sfw_reporting_t;
typedef struct sfw_backend_t sfw_backend_t;
typedef struct sfw_sample_als_t sfw_sample_als_t;
typedef struct sfw_sample_ps_t sfw_sample_ps_t;
typedef struct sfw_sample_orient_t sfw_sample_orient_t;
typedef struct sfw_sample_accelerometer_t sfw_sample_accelerometer_t;
typedef struct sfw_sample_compass_t sfw_sample_compass_t;
typedef struct sfw_sample_gyroscope_t sfw_sample_gyroscope_t;
typedef struct sfw_sample_lid_t sfw_sample_lid_t;
typedef struct sfw_sample_humidity_t sfw_sample_humidity_t;
typedef struct sfw_sample_magnetometer_t sfw_sample_magnetometer_t;
typedef struct sfw_sample_pressure_t sfw_sample_pressure_t;
typedef struct sfw_sample_rotation_t sfw_sample_rotation_t;
typedef struct sfw_sample_stepcounter_t sfw_sample_stepcounter_t;
typedef struct sfw_sample_tap_t sfw_sample_tap_t;
typedef struct sfw_sample_temperature_t sfw_sample_temperature_t;
/* ========================================================================= *
* SENSORFW_NOTIFY
* ========================================================================= */
/** Proximity state to use when sensor can't be enabled
*
* This must be "uncovered" so that absense of or failures within
* sensord do not make the device unusable due to proximity values
* blocking display power up and touch input.
*/
#define SFW_NOTIFY_DEFAULT_PS false
/** Proximity state to use when waiting for sensord startup
*
* This must be "covered" so that we do not prematurely unblock
* touch input / allow display power up during bootup and during
* sensord restarts.
*/
#define SFW_NOTIFY_EXCEPTION_PS true
/** Ambient light level [lux] to use when sensor can't be enabled */
#define SFW_NOTIFY_DEFAULT_ALS 400
/** Orientation state to use when sensor can't be enabled */
#define SFW_NOTIFY_DEFAULT_ORIENT MCE_ORIENTATION_UNDEFINED
/** Dummy sensor value to use when re-sending cached state data */
#define SFW_NOTIFY_DUMMY 0
typedef enum
{
/** Cached sensor state should be reset to default value */
NOTIFY_RESET,
/** Cached sensor state should be restored from last-known value */
NOTIFY_RESTORE,
/** Cached sensor state should be sent again */
NOTIFY_REPEAT,
/** Sensor state was received from evdev source */
NOTIFY_EVDEV,
/** Sensor state was received from sensord */
NOTIFY_SENSORD,
/** Flush cached state */
NOTIFY_FORGET,
NOTIFY_NUMTYPES
} sfw_notify_t;
static const char *sfw_notify_name (sfw_notify_t type);
static gboolean sfw_name_owner_changed_cb (DBusMessage *const msg);
/* ========================================================================= *
* SENSORD_DATA_TYPES
* ========================================================================= */
/** ALS data block as sensord sends them */
struct sfw_sample_als_t
{
/** microseconds, monotonic */
uint64_t als_timestamp;
/** amount of light [lux] */
uint32_t als_value;
};
static const char *sfw_sample_als_repr(const sfw_sample_als_t *self);
/** PS data block as sensord sends them */
struct sfw_sample_ps_t
{
/** microseconds, monotonic */
uint64_t ps_timestamp;
/** distance of blocking object [cm] */
uint32_t ps_value;
/** sensor covered [bool]
*
* This should be the size of a C++ bool on the same platform.
* Unfortunately there's no way to find out in a C program
*/
uint8_t ps_withinProximity;
};
static const char *sfw_sample_ps_repr(const sfw_sample_ps_t *self);
/** Orientation data block as sensord sends them */
struct sfw_sample_orient_t
{
/* microseconds, monotonic */
uint64_t orient_timestamp;
/* orientation [enum orientation_state_t] */
int32_t orient_state;
};
static const char *sfw_sample_orient_repr(const sfw_sample_orient_t *self);
typedef enum sfw_lid_type_t
{
SFW_LID_TYPE_UNKNOWN = -1, // UnknownLid
SFW_LID_TYPE_FRONT = 0, // FrontLid
SFW_LID_TYPE_BACK = 1, // BackLid
} sfw_lid_type_t;
static const char *sfw_lid_type_repr(sfw_lid_type_t type);
typedef enum sfw_tap_direction_t
{
/** Left or right side tapped */
SFW_TAP_DIRECTION_X = 0,
/** Top or down side tapped */
SFW_TAP_DIRECTION_Y = 1,
/** Face or bottom tapped */
SFW_TAP_DIRECTION_Z = 2,
/** Tapped from left to right */
SFW_TAP_DIRECTION_LEFT_RIGHT = 3,
/** Tapped from right to left */
SFW_TAP_DIRECTION_RIGHT_LEFT = 4,
/** Tapped from top to bottom */
SFW_TAP_DIRECTION_TOP_BOTTOM = 5,
/** Tapped from bottom to top */
SFW_TAP_DIRECTION_BOTTOM_TOP = 6,
/** Tapped from face to back */
SFW_TAP_DIRECTION_FACE_BACK = 7,
/** Tapped from back to face */
SFW_TAP_DIRECTION_BACK_FACE = 8,
} sfw_tap_direction_t;
static const char *sfw_tap_direction_repr(sfw_tap_direction_t direction);
typedef enum sfw_tap_type_t
{
/** placeholder */
SFW_TAP_TYPE_NONE = -1,
/** Double tap. */
SFW_TAP_TYPE_DOUBLE_TAP = 0,
/**< Single tap. */
SFW_TAP_TYPE_SINGLE_TAP = 1,
} sfw_tap_type_t;
static const char * sfw_tap_type_repr(sfw_tap_type_t type);
typedef struct sfw_xyz_t
{
int32_t x,y,z;
} sfw_xyz_t;
struct sfw_sample_accelerometer_t
{
/** microseconds, monotonic */
uint64_t accelerometer_timestamp;
/** amount of TBD */
sfw_xyz_t accelerometer_xyz;
};
static const char *sfw_sample_accelerometer_repr(const sfw_sample_accelerometer_t *self);
struct sfw_sample_compass_t
{
/** microseconds, monotonic */
uint64_t compass_timestamp;
/** Angle to north which may be declination corrected or not. This is the value apps should use */
int32_t compass_degrees;
/** Angle to north without declination correction */
int32_t compass_raw_degrees;
/** Declination corrected angle to north */
int32_t compass_corrected_degrees;
/** Magnetometer calibration level. Higher value means better calibration. */
int32_t compass_level;
};
static const char *sfw_sample_compass_repr(const sfw_sample_compass_t *self);
struct sfw_sample_gyroscope_t
{
/** microseconds, monotonic */
uint64_t gyroscope_timestamp;
/** amount of TBD */
sfw_xyz_t gyroscope_xyz;
};
static const char *sfw_sample_gyroscope_repr(const sfw_sample_gyroscope_t *self);
struct sfw_sample_lid_t
{
/** microseconds, monotonic */
uint64_t lid_timestamp;
/** amount of TBD */
int32_t lid_type; // sfw_lid_type_t
uint32_t lid_value;
};
static const char *sfw_sample_lid_repr(const sfw_sample_lid_t *self);
struct sfw_sample_humidity_t
{
/** microseconds, monotonic */
uint64_t humidity_timestamp;
/** amount of TBD */
uint32_t humidity_value;
};
static const char *sfw_sample_humidity_repr(const sfw_sample_humidity_t *self);
struct sfw_sample_magnetometer_t
{
/** microseconds, monotonic */
uint64_t magnetometer_timestamp;
/** X coordinate value */
int32_t magnetometer_x;
/** Y coordinate value */
int32_t magnetometer_y;
/** Z coordinate value */
int32_t magnetometer_z;
/** raw X coordinate value */
int32_t magnetometer_rx;
/** raw Y coordinate value */
int32_t magnetometer_ry;
/** raw Z coordinate value */
int32_t magnetometer_rz;
/** Magnetometer calibration level. Higher value means better calibration. */
int32_t magnetometer_level;
};
static const char *sfw_sample_magnetometer_repr(const sfw_sample_magnetometer_t *self);
struct sfw_sample_pressure_t
{
/** microseconds, monotonic */
uint64_t pressure_timestamp;
/** amount of TBD */
uint32_t pressure_value;
};
static const char *sfw_sample_pressure_repr(const sfw_sample_pressure_t *self);
struct sfw_sample_rotation_t
{
/** microseconds, monotonic */
uint64_t rotation_timestamp;
/** amount of TBD */
sfw_xyz_t rotation_xyz;
};
static const char *sfw_sample_rotation_repr(const sfw_sample_rotation_t *self);
struct sfw_sample_stepcounter_t
{
/** microseconds, monotonic */
uint64_t stepcounter_timestamp;
/** amount of TBD */
uint32_t stepcounter_value;
};
static const char *sfw_sample_stepcounter_repr(const sfw_sample_stepcounter_t *self);
struct sfw_sample_tap_t
{
/** microseconds, monotonic */
uint64_t tap_timestamp;
/** amount of TBD */
uint32_t tap_direction; // sfw_tap_direction_t
int32_t tap_type; // sfw_tap_type_t
};
static const char *sfw_sample_tap_repr(const sfw_sample_tap_t *self);
struct sfw_sample_temperature_t
{
/** microseconds, monotonic */
uint64_t temperature_timestamp;
/** amount of TBD */
uint32_t temperature_value;
};
static const char *sfw_sample_temperature_repr(const sfw_sample_temperature_t *self);
/* ========================================================================= *
* SENSORFW_BACKEND
* ========================================================================= */
/** Callback function type: parsing initial value reply */
typedef bool (*sfw_value_fn)(sfw_plugin_t *plugin, DBusMessageIter *data);
/** Callback function type: value change reporting */
typedef void (*sfw_sample_fn)(sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
/** Sensor specific data and callbacks */
struct sfw_backend_t
{
/** Name of the sensor as expected by sensord */
const char *be_sensor_name;
/** D-Bus object path for the sensor, or NULL to construct default one */
const char *be_sensor_object;
/** D-Bus interface for the sensor */
const char *be_sensor_interface;
/** Size of sensor data blobs sensord will be sending */
size_t be_sample_size;
/** Callback for handling initial value reply */
sfw_value_fn be_value_cb;
/** Callback for handling sensor data blob */
sfw_sample_fn be_sample_cb;
/** D-Bus method name for querying the initial sensor value */
const char *be_value_method;
};
static bool sfw_backend_parse_data (DBusMessageIter *data, int arg_type, ...);
static bool sfw_backend_als_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static bool sfw_backend_ps_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static bool sfw_backend_orient_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static bool sfw_backend_accelerometer_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static bool sfw_backend_compass_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static bool sfw_backend_gyroscope_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static bool sfw_backend_lid_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static bool sfw_backend_humidity_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static bool sfw_backend_magnetometer_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static bool sfw_backend_pressure_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static bool sfw_backend_rotation_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static bool sfw_backend_stepcounter_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static bool sfw_backend_tap_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static bool sfw_backend_temperature_value_cb (sfw_plugin_t *plugin, DBusMessageIter *data);
static void sfw_backend_als_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
static void sfw_backend_ps_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
static void sfw_backend_orient_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
static void sfw_backend_accelerometer_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
static void sfw_backend_compass_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
static void sfw_backend_gyroscope_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
static void sfw_backend_lid_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
static void sfw_backend_humidity_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
static void sfw_backend_magnetometer_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
static void sfw_backend_pressure_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
static void sfw_backend_rotation_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
static void sfw_backend_stepcounter_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
static void sfw_backend_tap_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
static void sfw_backend_temperature_sample_cb (sfw_plugin_t *plugin, sfw_notify_t type, const void *sample);
/* ========================================================================= *
* SENSORFW_HELPERS
* ========================================================================= */
static bool sfw_socket_set_blocking (int fd, bool blocking);
static int sfw_socket_open (void);
static guint sfw_socket_add_notify (int fd, bool close_on_unref, GIOCondition cnd, GIOFunc io_cb, gpointer aptr);
/* ========================================================================= *
* SENSORFW_REPORTING
* ========================================================================= */
typedef enum
{
/** Initial state used before availability of sensord is known */
REPORTING_INITIAL,
/** Sensord is not available */
REPORTING_IDLE,
/** Choose between start() and stop() */
REPORTING_RETHINK,
/** Waiting a reply to start() */
REPORTING_ENABLING,
/** Sensor started succesfully */
REPORTING_ENABLED,
/** Waiting a reply to stop() */
REPORTING_DISABLING,
/** Sensor stopped succesfully */
REPORTING_DISABLED,
/** Something went wrong */
REPORTING_ERROR,
REPORTING_NUMSTATES
} sfw_reporting_state_t;
/** State machine for handling sensor start/stop */
struct sfw_reporting_t
{
/** Pointer to containing plugin object */
sfw_plugin_t *rep_plugin;
/** Current reporting state */
sfw_reporting_state_t rep_state;
/** Pending start/stop dbus method call */
DBusPendingCall *rep_change_pc;
/** Pending initial value dbus method call */
DBusPendingCall *rep_value_pc;
/** Flag for: MCE wants sensor to be enabled */
bool rep_target;
/** Timer for: Retry after ipc error */
guint rep_retry_id;
};
static const char *sfw_reporting_state_name (sfw_reporting_state_t state);
static sfw_reporting_t *sfw_reporting_create (sfw_plugin_t *plugin);
static void sfw_reporting_delete (sfw_reporting_t *self);
static void sfw_reporting_cancel_change (sfw_reporting_t *self);
static void sfw_reporting_cancel_value (sfw_reporting_t *self);
static void sfw_reporting_cancel_retry (sfw_reporting_t *self);
static void sfw_reporting_trans (sfw_reporting_t *self, sfw_reporting_state_t state);
static void sfw_reporting_change_cb (DBusPendingCall *pc, void *aptr);
static void sfw_reporting_value_cb (DBusPendingCall *pc, void *aptr);
static gboolean sfw_reporting_retry_cb (gpointer aptr);
static void sfw_reporting_do_rethink (sfw_reporting_t *self);
static void sfw_reporting_do_start (sfw_reporting_t *self);
static void sfw_reporting_do_reset (sfw_reporting_t *self);
static void sfw_reporting_set_target (sfw_reporting_t *self, bool enable);
/* ========================================================================= *
* SENSORFW_OVERRIDE
* ========================================================================= */
typedef enum {
/** Initial state used before availability of sensord is known */
OVERRIDE_INITIAL,
/** Sensord is not available */
OVERRIDE_IDLE,
/** Choose between standby override set/unset */
OVERRIDE_RETHINK,
/** Waiting for a reply to set standby override */
OVERRIDE_ENABLING,
/** Standby override succesfully set */
OVERRIDE_ENABLED,
/** Waiting for a reply to unset standby override */
OVERRIDE_DISABLING,
/** Standby override succesfully unset */
OVERRIDE_DISABLED,
/** Something went wrong */
OVERRIDE_ERROR,
/** Not supported */
OVERRIDE_NA,
OVERRIDE_NUMSTATES
} sfw_override_state_t;
/** State machine for handling sensor standby override */
struct sfw_override_t
{
/** Pointer to containing plugin object */
sfw_plugin_t *ovr_plugin;
/** Current override state */
sfw_override_state_t ovr_state;
/** Pending standby override set/unset method call */
DBusPendingCall *ovr_start_pc;
/** Flag for: MCE wants standby override to be set */
bool ovr_target;
/** Timer for: Retry after ipc error */
guint ovr_retry_id;
};
static const char *sfw_override_state_name (sfw_override_state_t state);
static sfw_override_t *sfw_override_create (sfw_plugin_t *plugin);
static void sfw_override_delete (sfw_override_t *self);
static void sfw_override_cancel_start (sfw_override_t *self);
static void sfw_override_cancel_retry (sfw_override_t *self);
static void sfw_override_trans (sfw_override_t *self, sfw_override_state_t state);
static void sfw_override_start_cb (DBusPendingCall *pc, void *aptr);
static gboolean sfw_override_retry_cb (gpointer aptr);
static void sfw_override_do_rethink (sfw_override_t *self);
static void sfw_override_do_start (sfw_override_t *self);
static void sfw_override_do_reset (sfw_override_t *self);
static void sfw_override_set_target (sfw_override_t *self, bool enable);
/* ========================================================================= *
* SENSORFW_CONNECTION
* ========================================================================= */
typedef enum
{
/** Initial state used before availability of sensord is known */
CONNECTION_INITIAL,
/** Sensord is not available */
CONNECTION_IDLE,
/** Waiting for data socket to come writable */
CONNECTION_CONNECTING,
/** Waiting for handshake reply */
CONNECTION_REGISTERING,
/** Waiting for sensor data */
CONNECTION_CONNECTED,
/** Something went wrong */
CONNECTION_ERROR,
CONNECTION_NUMSTATES
} sfw_connection_state_t;
static const char *sfw_connection_state_name (sfw_connection_state_t state);
/** State machine for handling sensor data connection */
struct sfw_connection_t
{
/** Pointer to containing plugin object */
sfw_plugin_t *con_plugin;
/** Current connection state */
sfw_connection_state_t con_state;
/** File descriptor for data socket */
int con_fd;
/** I/O watch id id for: ready to write */
guint con_rx_id;
/** I/O watch id id for: data available */
guint con_tx_id;
/** Timer for: Retry after ipc error */
guint con_retry_id;
};
static sfw_connection_t *sfw_connection_create (sfw_plugin_t *plugin);
static void sfw_connection_delete (sfw_connection_t *self);
static bool sfw_connection_handle_samples (sfw_connection_t *self, char *data, size_t size);
static int sfw_connection_get_session_id (const sfw_connection_t *self);
static bool sfw_connection_tx_req (sfw_connection_t *self);
static bool sfw_connection_rx_ack (sfw_connection_t *self);
static bool sfw_connection_rx_dta (sfw_connection_t *self);
static gboolean sfw_connection_tx_cb (GIOChannel *chn, GIOCondition cnd, gpointer aptr);
static gboolean sfw_connection_rx_cb (GIOChannel *chn, GIOCondition cnd, gpointer aptr);
static void sfw_connection_remove_tx_notify(sfw_connection_t *self);
static void sfw_connection_remove_rx_notify(sfw_connection_t *self);
static void sfw_connection_close_socket (sfw_connection_t *self);
static bool sfw_connection_open_socket (sfw_connection_t *self);
static gboolean sfw_connection_retry_cb (gpointer aptr);
static void sfw_connection_cancel_retry (sfw_connection_t *self);
static void sfw_connection_trans (sfw_connection_t *self, sfw_connection_state_t state);
static void sfw_connection_do_start (sfw_connection_t *self);
static void sfw_connection_do_reset (sfw_connection_t *self);
/* ========================================================================= *
* SENSORFW_SESSION
* ========================================================================= */
typedef enum
{
/** Initial state used before availability of sensord is known */
SESSION_INITIAL,
/** Sensord is not available */
SESSION_IDLE,