From b0f1017dd711f095efdac3db4c743e128c499056 Mon Sep 17 00:00:00 2001 From: Ching-Kang Yen Date: Wed, 14 Oct 2020 15:57:21 +0800 Subject: common: motion_sense: Add spoofing activity make spoof command able to spoof activity state: ectool motionsense spoof -- NUM activity ACT [EN] [0/1] This commit also remove unused parameter |sensor_num| from list_activities, set_activity, get_activity in ectool. BRANCH=None BUG=b:123434029 TEST=buildall TEST=ectool motionsense spoof 4 activity 4 1 0 ectool motionsense spoof 4 activity 4 ectool motionsense get_activity 4 ectool motionsense spoof 4 activity 4 1 1 ectool motionsense get_activity 4 ectool motionsense spoof 4 activity 4 0 ectool motionsense get_activity 4 ectool motionsense spoof 4 activity 4 1 ectool motionsense get_activity 4 Signed-off-by: Ching-Kang Yen Change-Id: I819c156ae7fe50c5cf6216d0f44012d192fb528e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2477393 Reviewed-by: Gwendal Grignou --- common/body_detection.c | 29 +++++++++++--- common/motion_sense.c | 49 +++++++++++++++++++++++ include/body_detection.h | 5 ++- include/ec_commands.h | 15 ++++++- test/body_detection.c | 2 +- util/ectool.c | 101 +++++++++++++++++++++++++++++++++++------------ 6 files changed, 167 insertions(+), 34 deletions(-) diff --git a/common/body_detection.c b/common/body_detection.c index c15e1bc6bb..ed74a2545d 100644 --- a/common/body_detection.c +++ b/common/body_detection.c @@ -29,6 +29,7 @@ static enum body_detect_states motion_state = BODY_DETECTION_OFF_BODY; static bool history_initialized; static bool body_detect_enable; +STATIC_IF(CONFIG_ACCEL_SPOOF_MODE) bool spoof_enable; static struct body_detect_motion_data { @@ -90,8 +91,10 @@ static int calculate_motion_confidence(uint64_t var) } /* Change the motion state and commit the change to AP. */ -void body_detect_change_state(enum body_detect_states state) +void body_detect_change_state(enum body_detect_states state, bool spoof) { + if (IS_ENABLED(CONFIG_ACCEL_SPOOF_MODE) && spoof_enable && !spoof) + return; if (IS_ENABLED(CONFIG_GESTURE_HOST_DETECTION)) { struct ec_response_motion_sensor_data vector = { .flags = MOTIONSENSE_SENSOR_FLAG_WAKEUP, @@ -172,7 +175,7 @@ void body_detect_reset(void) int resolution = body_sensor->drv->get_resolution(body_sensor); int rms_noise = body_sensor->drv->get_rms_noise(body_sensor); - body_detect_change_state(BODY_DETECTION_ON_BODY); + body_detect_change_state(BODY_DETECTION_ON_BODY, false); /* * The sensor is suspended since its ODR is 0, * there is no need to reset until sensor is up again @@ -208,7 +211,7 @@ void body_detect(void) switch (motion_state) { case BODY_DETECTION_OFF_BODY: if (motion_confidence > CONFIG_BODY_DETECTION_ON_BODY_CON) - body_detect_change_state(BODY_DETECTION_ON_BODY); + body_detect_change_state(BODY_DETECTION_ON_BODY, false); break; case BODY_DETECTION_ON_BODY: stationary_timeframe += 1; @@ -218,7 +221,8 @@ void body_detect(void) /* if no motion for enough time, change state to off_body */ if (stationary_timeframe >= CONFIG_BODY_DETECTION_STATIONARY_DURATION * window_size) - body_detect_change_state(BODY_DETECTION_OFF_BODY); + body_detect_change_state(BODY_DETECTION_OFF_BODY, + false); break; } } @@ -226,10 +230,25 @@ void body_detect(void) void body_detect_set_enable(int enable) { body_detect_enable = enable; - body_detect_change_state(BODY_DETECTION_ON_BODY); + body_detect_change_state(BODY_DETECTION_ON_BODY, false); } int body_detect_get_enable(void) { return body_detect_enable; } + +#ifdef CONFIG_ACCEL_SPOOF_MODE +void body_detect_set_spoof(int enable) +{ + spoof_enable = enable; + /* After disabling spoof mode, commit current state. */ + if (!enable) + body_detect_change_state(motion_state, false); +} + +bool body_detect_get_spoof(void) +{ + return spoof_enable; +} +#endif diff --git a/common/motion_sense.c b/common/motion_sense.c index 4b3f66cd07..f708abb26f 100644 --- a/common/motion_sense.c +++ b/common/motion_sense.c @@ -1381,6 +1381,55 @@ static enum ec_status host_cmd_motion_sense(struct host_cmd_handler_args *args) #ifdef CONFIG_ACCEL_SPOOF_MODE case MOTIONSENSE_CMD_SPOOF: { + /* spoof activity if it is activity sensor */ + if (IS_ENABLED(CONFIG_GESTURE_HOST_DETECTION) && + in->spoof.sensor_id == MOTION_SENSE_ACTIVITY_SENSOR_ID) { + switch (in->spoof.activity_num) { +#ifdef CONFIG_BODY_DETECTION + case MOTIONSENSE_ACTIVITY_BODY_DETECTION: + switch (in->spoof.spoof_enable) { + case MOTIONSENSE_SPOOF_MODE_DISABLE: + /* Disable spoofing. */ + body_detect_set_spoof(false); + break; + case MOTIONSENSE_SPOOF_MODE_CUSTOM: + /* + * Enable spoofing, but use provided + * state + */ + body_detect_set_spoof(true); + body_detect_change_state( + in->spoof.activity_state, true); + break; + case MOTIONSENSE_SPOOF_MODE_LOCK_CURRENT: + /* + * Enable spoofing, but lock to current + * state + */ + body_detect_set_spoof(true); + break; + case MOTIONSENSE_SPOOF_MODE_QUERY: + /* + * Query the spoof status of the + * activity + */ + out->spoof.ret = + body_detect_get_spoof(); + args->response_size = + sizeof(out->spoof); + break; + default: + return EC_RES_INVALID_PARAM; + } + break; +#endif + default: + return EC_RES_INVALID_PARAM; + } + break; + } + + /* spoof accel data */ sensor = host_sensor_id_to_real_sensor(in->spoof.sensor_id); if (sensor == NULL) return EC_RES_INVALID_PARAM; diff --git a/include/body_detection.h b/include/body_detection.h index d3c1865e36..59af6580c6 100644 --- a/include/body_detection.h +++ b/include/body_detection.h @@ -7,6 +7,7 @@ #define __CROS_EC_BODY_DETECTION_H #include +#include enum body_detect_states { BODY_DETECTION_OFF_BODY, @@ -15,7 +16,7 @@ enum body_detect_states { /* get/set the state of body detection */ enum body_detect_states body_detect_get_state(void); -void body_detect_change_state(enum body_detect_states state); +void body_detect_change_state(enum body_detect_states state, bool spoof); /* Reset the data. This should be called when ODR is changed*/ void body_detect_reset(void); @@ -29,5 +30,7 @@ void body_detect_set_enable(int enable); /* get enable state of body detection */ int body_detect_get_enable(void); +void body_detect_set_spoof(int enable); +bool body_detect_get_spoof(void); #endif /* __CROS_EC_BODY_DETECTION_H */ diff --git a/include/ec_commands.h b/include/ec_commands.h index 190f44f981..ebef2b69dd 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -2877,8 +2877,19 @@ struct ec_params_motion_sense { /* Ignored, used for alignment. */ uint8_t reserved; - /* Individual component values to spoof. */ - int16_t components[3]; + union { + /* Individual component values to spoof. */ + int16_t components[3]; + + /* Used when spoofing an activity */ + struct { + /* enum motionsensor_activity */ + uint8_t activity_num; + + /* spoof activity state */ + uint8_t activity_state; + }; + }; } spoof; /* Used for MOTIONSENSE_CMD_TABLET_MODE_LID_ANGLE. */ diff --git a/test/body_detection.c b/test/body_detection.c index fe86b457c5..aa131f0a31 100644 --- a/test/body_detection.c +++ b/test/body_detection.c @@ -45,7 +45,7 @@ static int get_trigger_time(const struct body_detect_test_data *data, * that we do not need to wait for 15 second if the testcase * is in off-body initially. */ - body_detect_change_state(BODY_DETECTION_OFF_BODY); + body_detect_change_state(BODY_DETECTION_OFF_BODY, false); for (i = 0; i < size; ++i) { enum body_detect_states motion_state; diff --git a/util/ectool.c b/util/ectool.c index 2cd71eb3d4..f34a7c88c6 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -4972,25 +4972,41 @@ BUILD_ASSERT(ARRAY_SIZE(ms_command_sizes) == MOTIONSENSE_NUM_CMDS); static int ms_help(const char *cmd) { printf("Usage:\n"); - printf(" %s - dump all motion data\n", cmd); + printf(" %s - dump all motion data\n", + cmd); printf(" %s active - print active flag\n", cmd); printf(" %s info NUM - print sensor info\n", cmd); - printf(" %s ec_rate [RATE_MS] - set/get sample rate\n", cmd); - printf(" %s odr NUM [ODR [ROUNDUP]] - set/get sensor ODR\n", cmd); - printf(" %s range NUM [RANGE [ROUNDUP]] - set/get sensor range\n", cmd); - printf(" %s offset NUM [-- X Y Z [TEMP]] - set/get sensor offset\n", cmd); - printf(" %s kb_wake NUM - set/get KB wake ang\n", cmd); + printf(" %s ec_rate [RATE_MS] - set/get sample rate\n", + cmd); + printf(" %s odr NUM [ODR [ROUNDUP]] - set/get sensor ODR\n", + cmd); + printf(" %s range NUM [RANGE [ROUNDUP]] - set/get sensor range\n", + cmd); + printf(" %s offset NUM [-- X Y Z [TEMP]] - set/get sensor offset\n", + cmd); + printf(" %s kb_wake NUM - set/get KB wake ang\n", + cmd); printf(" %s fifo_info - print fifo info\n", cmd); - printf(" %s fifo_int_enable [0/1] - enable/disable/get fifo interrupt " - "status\n", cmd); + printf(" %s fifo_int_enable [0/1] - enable/disable/get fifo " + "interrupt status\n", cmd); printf(" %s fifo_read MAX_DATA - read fifo data\n", cmd); - printf(" %s fifo_flush NUM - trigger fifo interrupt\n", cmd); - printf(" %s list_activities NUM - list supported activities\n", cmd); - printf(" %s set_activity NUM ACT EN - enable/disable activity\n", cmd); + printf(" %s fifo_flush NUM - trigger fifo interrupt\n", + cmd); + printf(" %s list_activities - list supported " + "activities\n", cmd); + printf(" %s set_activity ACT EN - enable/disable activity\n", + cmd); + printf(" %s get_activity ACT - get activity status\n", + cmd); printf(" %s lid_angle - print lid angle\n", cmd); - printf(" %s spoof -- NUM [0/1] [X Y Z] - enable/disable spoofing\n", cmd); - printf(" %s tablet_mode_angle ANG HYS - set/get tablet mode angle\n", cmd); - printf(" %s calibrate NUM - run sensor calibration\n", cmd); + printf(" %s spoof -- NUM [0/1] [X Y Z] - enable/disable spoofing\n", + cmd); + printf(" %s spoof -- NUM activity ACT [0/1] [STATE] - enable/disable " + "activity spoofing\n", cmd); + printf(" %s tablet_mode_angle ANG HYS - set/get tablet mode " + "angle\n", cmd); + printf(" %s calibrate NUM - run sensor calibration\n", + cmd); return 0; } @@ -5612,9 +5628,8 @@ static int cmd_motionsense(int argc, char **argv) return 0; } - if (argc == 3 && !strcasecmp(argv[1], "list_activities")) { + if (argc == 2 && !strcasecmp(argv[1], "list_activities")) { param.cmd = MOTIONSENSE_CMD_LIST_ACTIVITIES; - param.list_activities.sensor_num = strtol(argv[2], &e, 0); rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, ¶m, ms_command_sizes[param.cmd].outsize, resp, ms_command_sizes[param.cmd].insize); @@ -5627,11 +5642,10 @@ static int cmd_motionsense(int argc, char **argv) motionsense_display_activities(resp->list_activities.disabled); return 0; } - if (argc == 5 && !strcasecmp(argv[1], "set_activity")) { + if (argc == 4 && !strcasecmp(argv[1], "set_activity")) { param.cmd = MOTIONSENSE_CMD_SET_ACTIVITY; - param.set_activity.sensor_num = strtol(argv[2], &e, 0); - param.set_activity.activity = strtol(argv[3], &e, 0); - param.set_activity.enable = strtol(argv[4], &e, 0); + param.set_activity.activity = strtol(argv[2], &e, 0); + param.set_activity.enable = strtol(argv[3], &e, 0); rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, ¶m, ms_command_sizes[param.cmd].outsize, @@ -5640,10 +5654,9 @@ static int cmd_motionsense(int argc, char **argv) return rv; return 0; } - if (argc == 4 && !strcasecmp(argv[1], "get_activity")) { + if (argc == 3 && !strcasecmp(argv[1], "get_activity")) { param.cmd = MOTIONSENSE_CMD_GET_ACTIVITY; - param.get_activity.sensor_num = strtol(argv[2], &e, 0); - param.get_activity.activity = strtol(argv[3], &e, 0); + param.get_activity.activity = strtol(argv[2], &e, 0); rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, ¶m, ms_command_sizes[param.cmd].outsize, @@ -5653,7 +5666,6 @@ static int cmd_motionsense(int argc, char **argv) printf("State: %d\n", resp->get_activity.state); return 0; } - if (argc == 2 && !strcasecmp(argv[1], "lid_angle")) { param.cmd = MOTIONSENSE_CMD_LID_ANGLE; rv = ec_command(EC_CMD_MOTION_SENSE_CMD, 2, @@ -5680,8 +5692,47 @@ static int cmd_motionsense(int argc, char **argv) fprintf(stderr, "Bad %s arg.\n", argv[2]); return -1; } + /* spoof activity state */ + if (argc >= 5 && !strcasecmp(argv[3], "activity")) { + int enable = 0; - if (argc >= 4) { + param.spoof.activity_num = strtol(argv[4], &e, 0); + if (e && *e) { + fprintf(stderr, "Base %s arg.\n", argv[4]); + return -1; + } + if (argc >= 6) { + enable = strtol(argv[5], &e, 0); + if ((e && *e) || (enable != 0 && enable != 1)) { + fprintf(stderr, "Bad %s arg.\n", + argv[5]); + return -1; + } + } + if ((enable == 1) && (argc == 6)) { + /* Enable spoofing, but lock to current state */ + param.spoof.spoof_enable = + MOTIONSENSE_SPOOF_MODE_LOCK_CURRENT; + } else if ((enable == 1) && (argc == 7)) { + /* Enable spoofing, but use provided state */ + int state = strtol(argv[6], &e, 0); + + if ((e && *e) || (state != 0 && state != 1)) { + fprintf(stderr, "Bad %s arg.\n", + argv[6]); + return -1; + } + param.spoof.activity_state = state; + param.spoof.spoof_enable = + MOTIONSENSE_SPOOF_MODE_CUSTOM; + } else if ((enable == 0) && (argc == 6)) { + param.spoof.spoof_enable = + MOTIONSENSE_SPOOF_MODE_DISABLE; + } else if (argc != 5) { + return ms_help(argv[0]); + } + /* spoof accel data */ + } else if (argc >= 4) { int enable, i; int16_t val; -- cgit v1.2.1