From 0bd46b2a3a4b46dcf25d9eeca6d190c346ea76c7 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Mon, 14 Mar 2022 11:01:37 +0900 Subject: [PATCH 01/16] battery: fix name of battery charging state Change-Id: Ide4c233bf2c69ffdec270622a5d23736cfb661e4 Signed-off-by: Youngjae Cho --- src/battery/lowbat-handler.c | 6 ++--- src/battery/power-supply.c | 50 +++++++++++++++++------------------ src/battery/power-supply.h | 14 +++++----- tests/auto-test/battery.c | 62 ++++++++++++++++++++++---------------------- 4 files changed, 66 insertions(+), 66 deletions(-) diff --git a/src/battery/lowbat-handler.c b/src/battery/lowbat-handler.c index 56a4959..7358f40 100644 --- a/src/battery/lowbat-handler.c +++ b/src/battery/lowbat-handler.c @@ -737,7 +737,7 @@ static void lowbat_exit(void *data) } } -static gboolean low_battery_charge_status(void *data) +static gboolean low_battery_charging_status(void *data) { low_batt_sig_timer = 0; battery->charging_level = lowbat_monitor(data); @@ -768,9 +768,9 @@ static int lowbat_execute(void *data) * This prevents poweroff from being delayed infinitely when the uevent continues * to occur shorter than 1.5 seconds on realoff capacity */ if (capacity <= battery_info.realoff || !uevent_buffering) - low_battery_charge_status(data); + low_battery_charging_status(data); else - low_batt_sig_timer = g_timeout_add(1500, low_battery_charge_status, data); + low_batt_sig_timer = g_timeout_add(1500, low_battery_charging_status, data); return 0; } diff --git a/src/battery/power-supply.c b/src/battery/power-supply.c index 08f00cd..ace82a3 100644 --- a/src/battery/power-supply.c +++ b/src/battery/power-supply.c @@ -400,14 +400,14 @@ static void charger_state_send_system_event(int state) const char *str; switch (state) { - case CHARGE_STATUS_CHARGING: + case CHARGING_STATUS_CHARGING: str = EVT_VAL_BATTERY_CHARGER_CHARGING; break; - case CHARGE_STATUS_FULL: + case CHARGING_STATUS_FULL: str = EVT_VAL_BATTERY_CHARGER_DISCHARGING; CRITICAL_LOG("Battery charger: %s", str); break; - case CHARGE_STATUS_DISCHARGING: + case CHARGING_STATUS_DISCHARGING: str = EVT_VAL_BATTERY_CHARGER_DISCHARGING; CRITICAL_LOG("Battery charger: %s", str); break; @@ -546,7 +546,7 @@ static void check_abnormal_status(void) } } -static void check_charge_status(const char *env_value) +static void check_charging_status(const char *env_value) { int len; @@ -555,26 +555,26 @@ static void check_charge_status(const char *env_value) len = strlen(env_value); if (strncmp(env_value, CHARGEFULL_NAME, len) == 0) - battery.charge_status = CHARGE_STATUS_FULL; + battery.charging_status = CHARGING_STATUS_FULL; else if (strncmp(env_value, CHARGENOW_NAME, len) == 0) - battery.charge_status = CHARGE_STATUS_CHARGING; + battery.charging_status = CHARGING_STATUS_CHARGING; else if (strncmp(env_value, DISCHARGE_NAME, len) == 0) - battery.charge_status = CHARGE_STATUS_DISCHARGING; + battery.charging_status = CHARGING_STATUS_DISCHARGING; else if (strncmp(env_value, NOTCHARGE_NAME, len) == 0) - battery.charge_status = CHARGE_STATUS_NOT_CHARGING; + battery.charging_status = CHARGING_STATUS_NOT_CHARGING; else - battery.charge_status = CHARGE_STATUS_UNKNOWN; + battery.charging_status = CHARGING_STATUS_UNKNOWN; - if (battery.charge_status == CHARGE_STATUS_FULL) { + if (battery.charging_status == CHARGING_STATUS_FULL) { battery.charge_full = CHARGING_FULL; battery.charge_now = CHARGER_DISCHARGING; - } else if (battery.charge_status == CHARGE_STATUS_CHARGING) { + } else if (battery.charging_status == CHARGING_STATUS_CHARGING) { battery.charge_full = CHARGING_NOT_FULL; battery.charge_now = CHARGER_CHARGING; - } else if (battery.charge_status == CHARGE_STATUS_DISCHARGING) { + } else if (battery.charging_status == CHARGING_STATUS_DISCHARGING) { battery.charge_full = CHARGING_NOT_FULL; battery.charge_now = CHARGER_DISCHARGING; - } else if (battery.charge_status == CHARGE_STATUS_NOT_CHARGING) { + } else if (battery.charging_status == CHARGING_STATUS_NOT_CHARGING) { battery.charge_full = CHARGING_NOT_FULL; battery.charge_now = CHARGER_ABNORMAL; } else { @@ -769,8 +769,8 @@ static void process_power_supply(void *data) } } - if (old_battery.charge_status != battery.charge_status) - charger_state_send_system_event(battery.charge_status); + if (old_battery.charging_status != battery.charging_status) + charger_state_send_system_event(battery.charging_status); if (old_battery.online_type != battery.online_type) { ret_val = vconf_set_int(VCONFKEY_SYSMAN_CHARGER_TYPE, battery.online_type); @@ -815,7 +815,7 @@ static void process_power_supply(void *data) old_battery.charging_level = battery.charging_level; old_battery.charger_connected = battery.charger_connected; old_battery.online_type = battery.online_type; - old_battery.charge_status = battery.charge_status; + old_battery.charging_status = battery.charging_status; old_battery.charge_full = battery.charge_full; old_battery.misc = battery.misc; @@ -869,7 +869,7 @@ static void uevent_power_handler(struct udev_device *dev) return; env_value = udev_device_get_property_value(dev, CHARGE_STATUS); - check_charge_status(env_value); + check_charging_status(env_value); env_value = udev_device_get_property_value(dev, CHARGE_ONLINE); check_online_type(env_value); env_value = udev_device_get_property_value(dev, CHARGE_HEALTH); @@ -913,7 +913,7 @@ static int battery_state(struct battery_info *info) } if (battery.capacity != 0 && prev_status.capacity == battery.capacity && - prev_status.charge_status == battery.charge_status && + prev_status.charging_status == battery.charging_status && prev_status.online_type == battery.online_type && prev_status.charge_full == battery.charge_full && prev_status.charge_now == battery.charge_now && @@ -924,7 +924,7 @@ static int battery_state(struct battery_info *info) return 0; prev_status.capacity = battery.capacity; - prev_status.charge_status = battery.charge_status; + prev_status.charging_status = battery.charging_status; prev_status.charge_full = battery.charge_full; prev_status.charge_now = battery.charge_now; prev_status.health = battery.health; @@ -987,7 +987,7 @@ static void battery_changed(struct battery_info *info, void *data) if (info->status) { snprintf(battery.status_s, sizeof(battery.status_s), "%s", info->status); - check_charge_status(info->status); + check_charging_status(info->status); } else battery.status_s[0] = '\0'; @@ -1022,11 +1022,11 @@ static void battery_changed(struct battery_info *info, void *data) ret_val = delayed_init_done(NULL); if (ret_val) { /* If the same notification is requested repeatedly, it is ignored by power_supply_noti(). - * A notification will be triggered only when charge_status changes between - * CHARGE_STATUS_CHARGING/FULL <-> CHARGE_STATUS_DISCHARGING. */ - if (battery.charge_status == CHARGE_STATUS_CHARGING || battery.charge_status == CHARGE_STATUS_FULL) + * A notification will be triggered only when charging_status changes between + * CHARGING_STATUS_CHARGING/FULL <-> CHARGING_STATUS_DISCHARGING. */ + if (battery.charging_status == CHARGING_STATUS_CHARGING || battery.charging_status == CHARGING_STATUS_FULL) power_supply_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_ON); - else if (battery.charge_status == CHARGE_STATUS_DISCHARGING) + else if (battery.charging_status == CHARGING_STATUS_DISCHARGING) power_supply_noti(DEVICE_NOTI_BATT_CHARGE, DEVICE_NOTI_OFF); } @@ -1257,7 +1257,7 @@ static GVariant *dbus_get_power_supply_handler(GDBusConnection *conn, return g_variant_new("(iiiiiiiisiiiii)", 0, battery.capacity, - battery.charge_status, + battery.charging_status, battery.health, battery.charger_connected, battery.present, diff --git a/src/battery/power-supply.h b/src/battery/power-supply.h index 547a2d2..1350299 100644 --- a/src/battery/power-supply.h +++ b/src/battery/power-supply.h @@ -30,12 +30,12 @@ enum device_change_type { DEVICE_CHANGE_NORMAL, }; -enum charge_status_type { - CHARGE_STATUS_UNKNOWN, - CHARGE_STATUS_CHARGING, - CHARGE_STATUS_DISCHARGING, - CHARGE_STATUS_NOT_CHARGING, - CHARGE_STATUS_FULL, +enum charging_status_type { + CHARGING_STATUS_UNKNOWN, + CHARGING_STATUS_CHARGING, + CHARGING_STATUS_DISCHARGING, + CHARGING_STATUS_NOT_CHARGING, + CHARGING_STATUS_FULL, }; enum charge_full_type { @@ -94,7 +94,7 @@ enum charger_type { struct battery_status { int capacity; - int charge_status; + int charging_status; int charge_full; int charge_now; int health; diff --git a/tests/auto-test/battery.c b/tests/auto-test/battery.c index 14b3964..e245b64 100644 --- a/tests/auto-test/battery.c +++ b/tests/auto-test/battery.c @@ -101,12 +101,12 @@ #define S_ENTER 1 #define S_LEAVE 0 -enum charge_status_type { - CHARGE_STATUS_UNKNOWN, - CHARGE_STATUS_CHARGING, - CHARGE_STATUS_DISCHARGING, - CHARGE_STATUS_NOT_CHARGING, - CHARGE_STATUS_FULL, +enum charging_status_type { + CHARGING_STATUS_UNKNOWN, + CHARGING_STATUS_CHARGING, + CHARGING_STATUS_DISCHARGING, + CHARGING_STATUS_NOT_CHARGING, + CHARGING_STATUS_FULL, }; enum charge_now_type { @@ -135,7 +135,7 @@ static struct power_supply_type { const char *scenario; const int status; const char *capacity; - const char *charge_status; + const char *charging_status; const char *health; const int online; const char *present; @@ -445,7 +445,7 @@ static bool get_battery_info_direct(struct device_battery_info *info) return capi_result(METHOD_BATTERY_GETINFO_DIRECT, ret); } -static int change_charge_status_to_enum(const char *env_value) +static int change_charging_status_to_enum(const char *env_value) { int len, ret; @@ -454,15 +454,15 @@ static int change_charge_status_to_enum(const char *env_value) len = strlen(env_value); if (strncmp(env_value, CHARGEFULL, len) == 0) - ret = CHARGE_STATUS_FULL; + ret = CHARGING_STATUS_FULL; else if (strncmp(env_value, CHARGENOW, len) == 0) - ret = CHARGE_STATUS_CHARGING; + ret = CHARGING_STATUS_CHARGING; else if (strncmp(env_value, DISCHARGE, len) == 0) - ret = CHARGE_STATUS_DISCHARGING; + ret = CHARGING_STATUS_DISCHARGING; else if (strncmp(env_value, NOTCHARGE, len) == 0) - ret = CHARGE_STATUS_NOT_CHARGING; + ret = CHARGING_STATUS_NOT_CHARGING; else - ret = CHARGE_STATUS_UNKNOWN; + ret = CHARGING_STATUS_UNKNOWN; return ret; } @@ -492,7 +492,7 @@ static int change_health_status_to_enum(const char *env_value) static bool compare_vconf(struct power_supply_type list) { int value, ret, temp; - int capacity, online, charge_status; + int capacity, online, charging_status; int invalid; invalid = (strcmp(list.present, PRESENT_ABNORMAL) == 0); @@ -504,22 +504,22 @@ static bool compare_vconf(struct power_supply_type list) } if (invalid) { - charge_status = CHARGE_STATUS_NOT_CHARGING; + charging_status = CHARGING_STATUS_NOT_CHARGING; temp = -ENODEV; - } else if (!strcmp(list.charge_status, CHARGEFULL)) { - charge_status = CHARGE_STATUS_FULL; + } else if (!strcmp(list.charging_status, CHARGEFULL)) { + charging_status = CHARGING_STATUS_FULL; temp = CHARGER_DISCHARGING; - } else if (!strcmp(list.charge_status, CHARGENOW)) { - charge_status = CHARGE_STATUS_CHARGING; + } else if (!strcmp(list.charging_status, CHARGENOW)) { + charging_status = CHARGING_STATUS_CHARGING; temp = CHARGER_CHARGING; - } else if (!strcmp(list.charge_status, DISCHARGE)) { - charge_status = CHARGE_STATUS_DISCHARGING; + } else if (!strcmp(list.charging_status, DISCHARGE)) { + charging_status = CHARGING_STATUS_DISCHARGING; temp = CHARGER_DISCHARGING; - } else if (!strcmp(list.charge_status, NOTCHARGE)) { - charge_status = CHARGE_STATUS_NOT_CHARGING; + } else if (!strcmp(list.charging_status, NOTCHARGE)) { + charging_status = CHARGING_STATUS_NOT_CHARGING; temp = CHARGER_ABNORMAL; } else { - charge_status = CHARGE_STATUS_UNKNOWN; + charging_status = CHARGING_STATUS_UNKNOWN; temp = CHARGER_DISCHARGING; } @@ -538,7 +538,7 @@ static bool compare_vconf(struct power_supply_type list) if (invalid) { temp = -ENODEV; } else if (capacity <= DEFAULT_REALOFF) { - if (charge_status == CHARGE_STATUS_CHARGING) + if (charging_status == CHARGING_STATUS_CHARGING) temp = VCONFKEY_SYSMAN_BAT_POWER_OFF; else temp = VCONFKEY_SYSMAN_BAT_REAL_POWER_OFF; @@ -549,7 +549,7 @@ static bool compare_vconf(struct power_supply_type list) } else if (capacity <= DEFAULT_WARNING) { temp = VCONFKEY_SYSMAN_BAT_WARNING_LOW; } else if (capacity >= DEFAULT_NORMAL && - charge_status == CHARGE_STATUS_FULL) { + charging_status == CHARGING_STATUS_FULL) { temp = VCONFKEY_SYSMAN_BAT_FULL; } else { temp = VCONFKEY_SYSMAN_BAT_NORMAL; @@ -629,8 +629,8 @@ static bool compare_power_supply(struct power_supply_type list, int value[], con return false; } - if (change_charge_status_to_enum(list.charge_status) != value[1]) { - _E("Different charge_status : %d %d", change_charge_status_to_enum(list.charge_status), value[1]); + if (change_charging_status_to_enum(list.charging_status) != value[1]) { + _E("Different charging_status : %d %d", change_charging_status_to_enum(list.charging_status), value[1]); return false; } @@ -696,7 +696,7 @@ static bool set_battery_power_supply(int index) var = g_variant_new("(sisssisssssssss)", POWER_SUBSYSTEM, 13, power_supply_types[index].capacity, - power_supply_types[index].charge_status, + power_supply_types[index].charging_status, power_supply_types[index].health, power_supply_types[index].online, power_supply_types[index].present, @@ -711,7 +711,7 @@ static bool set_battery_power_supply(int index) _I("C(%s) S(%s) H(%s) O(%d) P(%s) M(%s) F(%s) SRC(%s) Vol(%s %s) Cur(%s %s) T(%s)", power_supply_types[index].capacity, - power_supply_types[index].charge_status, + power_supply_types[index].charging_status, power_supply_types[index].health, power_supply_types[index].online, power_supply_types[index].present, @@ -767,7 +767,7 @@ static bool get_battery_power_supply(int out_rsp[], char **out_power_source) if (!g_variant_get_safe(reply, "(iiiiiiiisiiiii)", &reply_val, //return value &out_rsp[0], //capacity - &out_rsp[1], //charge_status + &out_rsp[1], //charging_status &out_rsp[2], //health &out_rsp[3], //online &out_rsp[4], //present -- 2.7.4 From 501f642b1f0517310744f24998fecf4416559db5 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Mon, 14 Mar 2022 14:32:36 +0900 Subject: [PATCH 02/16] Support silent boot via cmdline bootmode The /proc/cmdline has changed to have bootmode=silent parameter on silent booting. Change-Id: I15ebb44bdd86155fc1a65489e23ec527fd9cbf86 Signed-off-by: Youngjae Cho --- src/core/main.c | 8 ++++++-- tests/auto-test/boot.c | 32 +++++++++++++++++++++++++------- tests/auto-test/test.c | 15 --------------- tests/auto-test/test.h | 3 +-- 4 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index fa1e4a1..ecbf942 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include "display/core.h" @@ -99,6 +99,8 @@ static int deviced_main(int argc, char **argv) int ret; dbus_handle_h handle = NULL; guint timer; + char bootmode[32] = "normal"; + int retval; CRITICAL_LOG("Initializing deviced."); mainloop = g_main_loop_new(NULL, FALSE); @@ -118,7 +120,9 @@ static int deviced_main(int argc, char **argv) load_plugins(); - silent_boot = device_get_reboot_mode(); + retval = device_board_get_boot_mode(bootmode, sizeof(bootmode)); + silent_boot = (retval == 0 && strncmp(bootmode, "silent", sizeof("silent")) == 0); + CRITICAL_LOG("bootmode=%s", bootmode); devices_init(NULL); diff --git a/tests/auto-test/boot.c b/tests/auto-test/boot.c index d589f8c..26f7193 100644 --- a/tests/auto-test/boot.c +++ b/tests/auto-test/boot.c @@ -16,17 +16,35 @@ * limitations under the License. */ #include "test.h" -#include +#include #define METHOD_GET_REBOOT_MODE "GetRebootMode" -static bool get_reboot_mode(void) +static bool get_boot_mode(void) { - int ret; + int retval; + char bootmode[32] = {0, }; - ret = device_get_reboot_mode(); + retval = device_board_get_boot_mode(bootmode, sizeof(bootmode)); + if (retval != 0) { + _E("bootmode not supported."); + return 1; + } + + if (strncmp(bootmode, "normal", sizeof("normal")) == 0) + return 1; + if (strncmp(bootmode, "silent", sizeof("silent")) == 0) + return 1; + if (strncmp(bootmode, "fota", sizeof("fota")) == 0) + return 1; + if (strncmp(bootmode, "recovery", sizeof("recovery")) == 0) + return 1; + if (strncmp(bootmode, "download", sizeof("download")) == 0) + return 1; - return capi_reboot_result(METHOD_GET_REBOOT_MODE, ret); + _E("Invalid bootmode=%s", bootmode); + + return 0; } static void booting_test_all(int *success, int *fail) @@ -34,7 +52,7 @@ static void booting_test_all(int *success, int *fail) int s = 0; int f = 0; - (get_reboot_mode()) ? s++ : f++; + (get_boot_mode()) ? s++ : f++; if (NULL != success) *success = s; if (NULL != fail) *fail = f; @@ -67,7 +85,7 @@ static int booting_unit(int argc, char **argv) booting_test_all(&success, &fail); _I("Total: %d, Success: %d, Fail: %d", success+fail, success, fail); } else if (0 == strcasecmp(argv[3], METHOD_GET_REBOOT_MODE)) { - get_reboot_mode(); + get_boot_mode(); } else { _E("Unknown test case!!!"); } diff --git a/tests/auto-test/test.c b/tests/auto-test/test.c index f50faf1..142310a 100644 --- a/tests/auto-test/test.c +++ b/tests/auto-test/test.c @@ -146,18 +146,3 @@ bool capi_result(const char *method, int val) return ret; } - -bool capi_reboot_result(const char *method, int val) -{ - bool ret = FALSE; - - if (val == NORMAL_BOOT || val == SILENT_BOOT) { - _I("success (%s): %d", method, val); - ret = TRUE; - } else { - _E("fail (%s): returned fail (%d)", method, val); - ret = FALSE; - } - - return ret; -} diff --git a/tests/auto-test/test.h b/tests/auto-test/test.h index 0ba59c6..ef10f18 100644 --- a/tests/auto-test/test.h +++ b/tests/auto-test/test.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include "shared/common.h" #include "core/udev.h" @@ -107,6 +107,5 @@ const struct test_ops *find_test(const char *name); void _R(const char *format, ...); void __cb(GVariant *result, void *data, GError *err); bool capi_result(const char *method, int val); -bool capi_reboot_result(const char *method, int val); int feature_supported(const char *feature); #endif -- 2.7.4 From f596affda397bc4f21d05eeb32d2b294227fe39a Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Wed, 16 Mar 2022 17:25:33 +0900 Subject: [PATCH 03/16] usb-gadget: introduce configurable usb-gadget Change-Id: Iaf2adf68666b1def8dcf6b04707d0f5a3f5fc3e0 Signed-off-by: Youngjae Cho --- src/usb/usb-state.c | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/usb/usb.c | 1 + src/usb/usb.h | 2 + 3 files changed, 183 insertions(+), 4 deletions(-) diff --git a/src/usb/usb-state.c b/src/usb/usb-state.c index 17df193..77375c6 100644 --- a/src/usb/usb-state.c +++ b/src/usb/usb-state.c @@ -17,10 +17,12 @@ */ +#include #include #include #include #include +#include #include "core/log.h" #include "apps/apps.h" @@ -29,6 +31,8 @@ #include "usb.h" #include "usb-debug.h" +#define PATH_USB_GADGET_CONF "/hal/etc/deviced/usb_gadget.conf" + static int noti_id = -1; static unsigned int usb_current_mode = USB_FUNCTION_NONE; @@ -49,6 +53,7 @@ static extcon_usb_state_e usb_connection = USB_DISCONNECTED; static const struct _usb_mode_mapping_table { int mode_v; /* Integer defined by vconf */ unsigned int mode; /* Bitmap of usb function combination */ + struct usb_gadget_attrs attrs; } usb_mode_mapping_table[] = { /* Hack for performance. In most cases this is the value. */ {SET_USB_DEFAULT, USB_FUNCTION_MTP | USB_FUNCTION_ACM}, @@ -68,12 +73,43 @@ static const struct _usb_mode_mapping_table { {SET_USB_RNDIS_SDB_ACM, USB_FUNCTION_ACM | USB_FUNCTION_SDB | USB_FUNCTION_RNDIS}, }; +static const int mapping_table_len = sizeof(usb_mode_mapping_table) / sizeof(usb_mode_mapping_table[0]); + +/* + * Private, custom defined mode mapping. + * You can define custom mode_v with mode from /hal/etc/deviced/usb_gadget.conf + * A custom mapping precedes the above default mapping if the custom mode_v overlaps + * default mode_v. + * + * Do not declare it with static storage class as it will be exported as dynamic symbol + * so that dlopen-ed device-common can refer it. + */ +GList *usb_mode_mapping_table_custom; + +/* + * Do not declare it with static storage class as it will be exported as dynamic symbol + * so that dlopen-ed device-common can refer it. + */ +struct service_config { + char name[128]; + int remain_after_disable; /* do not stop the service on disabling usb-gadget function */ +}; +GList *service_config_list; + unsigned int get_mode_bitmap_from_vconf(int mode_v) { int i; - int array_len = sizeof(usb_mode_mapping_table)/sizeof(usb_mode_mapping_table[0]); + GList *elem; + struct _usb_mode_mapping_table *table; + + /* lookup from custom mapping table first */ + SYS_G_LIST_FOREACH(usb_mode_mapping_table_custom, elem, table) { + if (table->mode_v == mode_v) + return table->mode; + } - for (i = 0; i < array_len; i++) { + /* and then lookup the default mapping table */ + for (i = 0; i < mapping_table_len; i++) { if (usb_mode_mapping_table[i].mode_v == mode_v) return usb_mode_mapping_table[i].mode; } @@ -84,10 +120,17 @@ unsigned int get_mode_bitmap_from_vconf(int mode_v) static int get_mode_vconf_from_bitmap(unsigned int mode) { int i; - int array_len = sizeof(usb_mode_mapping_table)/sizeof(usb_mode_mapping_table[0]); + GList *elem; + struct _usb_mode_mapping_table *table; + + /* lookup from custom mapping table first */ + SYS_G_LIST_FOREACH(usb_mode_mapping_table_custom, elem, table) { + if (table->mode == mode) + return table->mode_v; + } /* Caution: The order to search the usb_mode_mapping_table must start with a low index. */ - for (i = 0; i < array_len; i++) { + for (i = 0; i < mapping_table_len; i++) { if (usb_mode_mapping_table[i].mode == mode) return usb_mode_mapping_table[i].mode_v; } @@ -125,6 +168,139 @@ static void usb_state_send_system_event(int status) bundle_free(b); } +static void parse_property_systemd_unit(gpointer data, gpointer udata) +{ + struct section_property *prop = (struct section_property *) data; + struct service_config *svc = (struct service_config *) udata; + + if (MATCH(prop->key, "Service")) { + strncpy(svc->name, prop->value, sizeof(svc->name)); + } else if (MATCH(prop->key, "RemainAfterDisable")) { + svc->remain_after_disable = MATCH(prop->value, "yes"); + } +} + +static unsigned int parse_usb_function(char *fstr) +{ + // Parse Function=, e.g., "Function=diag,acm" + unsigned int ret = USB_FUNCTION_NONE; + char *p, *saveptr; + + if (!fstr) + return ret; + + p = strtok_r(fstr, ",", &saveptr); + if (!p) + return ret; + + do { + if (strncasecmp(p, "mtp", sizeof("mtp")) == 0) { + ret |= USB_FUNCTION_MTP; + } else if (strncasecmp(p, "acm", sizeof("acm")) == 0) { + ret |= USB_FUNCTION_ACM; + } else if(strncasecmp(p, "sdb", sizeof("sdb")) == 0) { + ret |= USB_FUNCTION_SDB; + } else if (strncasecmp(p, "rndis", sizeof("rndis")) == 0) { + ret |= USB_FUNCTION_RNDIS; + } else if (strncasecmp(p, "diag", sizeof("diag")) == 0) { + ret |= USB_FUNCTION_DIAG; + } else if (strncasecmp(p, "conngadget", sizeof("conngadget")) == 0) { + ret |= USB_FUNCTION_CONN_GADGET; + } else if (strncasecmp(p, "dm", sizeof("dm")) == 0) { + ret |= USB_FUNCTION_DM; + } else if (strncasecmp(p, "rmnet", sizeof("rmnet")) == 0) { + ret |= USB_FUNCTION_RMNET; + } + } while ((p = strtok_r(NULL, ",", &saveptr))); + + return ret; +} + +static void parse_property_attribute(gpointer data, gpointer udata) +{ + struct section_property *prop = (struct section_property *) data; + struct _usb_mode_mapping_table *table = (struct _usb_mode_mapping_table *) udata; + unsigned int value; + + if (MATCH(prop->key, "Mode")) { + sscanf(prop->value, "%d", &table->mode_v); + } else if (MATCH(prop->key, "Function")) { + table->mode = parse_usb_function(prop->value); + } else if (MATCH(prop->key, "bDeviceClass")) { + sscanf(prop->value, "%x", &value); + table->attrs.bDeviceClass = (uint8_t) value; + } else if (MATCH(prop->key, "bDeviceSubClass")) { + sscanf(prop->value, "%x", &value); + table->attrs.bDeviceSubClass = (uint8_t) value; + } else if (MATCH(prop->key, "bDeviceProtocol")) { + sscanf(prop->value, "%x", &value); + table->attrs.bDeviceProtocol = (uint8_t) value; + } else if (MATCH(prop->key, "idVendor")) { + sscanf(prop->value, "%x", &value); + table->attrs.idVendor = (uint16_t) value; + } else if (MATCH(prop->key, "idProduct")) { + sscanf(prop->value, "%x", &value); + table->attrs.idProduct = (uint16_t) value; + } else if (MATCH(prop->key, "bcdDevice")) { + sscanf(prop->value, "%x", &value); + table->attrs.bcdDevice = (uint16_t) value; + } +} + +static int load_usb_gadget_config(const struct parse_result *result, void *data) +{ + if (MATCH(result->section, "SystemdUnit")) { + struct service_config svc = { 0, }; + void *entry = NULL; + + g_list_foreach(result->props, parse_property_systemd_unit, &svc); + + entry = malloc(sizeof(struct service_config)); + if (!entry) { + _E("Failed to alloc service config"); + return 0; + } + + _I("usb-gadget service config: name=%s, remain_after_disable=%d", + svc.name, svc.remain_after_disable); + service_config_list = g_list_prepend(service_config_list, memcpy(entry, &svc, sizeof(svc))); + + } else if (MATCH(result->section, "Attribute")) { + struct _usb_mode_mapping_table table = { 0, }; + void *entry = NULL; + + g_list_foreach(result->props, parse_property_attribute, &table); + + // if it hasn't defined mode, use default or pre-defined one + if (table.mode == USB_FUNCTION_NONE) + table.mode = get_mode_bitmap_from_vconf(table.mode_v); + + if (table.mode == USB_FUNCTION_INVALID) + return 0; + + if (table.mode_v >= SET_USB_NONE && table.mode_v <= SET_USB_RNDIS_SDB_ACM) + _W("The custom mode=%d replaces the predefined usb-gadget configuration", table.mode_v); + + entry = malloc(sizeof(struct _usb_mode_mapping_table)); + if (!entry) { + _E("Failed to alloc mapping table"); + return 0; + } + + _I("Custom usb-gadget: mode=%d, function=%#x, idVendor=%#x, idProduct=%#x", + table.mode_v, table.mode, table.attrs.idVendor, table.attrs.idProduct); + + usb_mode_mapping_table_custom = g_list_prepend(usb_mode_mapping_table_custom, memcpy(entry, &table, sizeof(table))); + } + + return 0; +} + +void usb_state_load_custom_mode(void) +{ + libsys_config_parse_by_section(PATH_USB_GADGET_CONF, load_usb_gadget_config, NULL); +} + void usb_state_retrieve_selected_mode(void) { int mode_v; diff --git a/src/usb/usb.c b/src/usb/usb.c index d1f9198..6792310 100644 --- a/src/usb/usb.c +++ b/src/usb/usb.c @@ -283,6 +283,7 @@ static void usb_init(void *data) { int ret; + usb_state_load_custom_mode(); usb_state_retrieve_selected_mode(); ret = hal_device_usb_gadget_get_backend(); diff --git a/src/usb/usb.h b/src/usb/usb.h index 204cadb..0e30b2e 100644 --- a/src/usb/usb.h +++ b/src/usb/usb.h @@ -28,6 +28,8 @@ int usb_dbus_init(void); +void usb_state_load_custom_mode(void); + int usb_change_mode(unsigned int mode, bool change_debug_mode); void usb_state_retrieve_selected_mode(void); unsigned int get_mode_bitmap_from_vconf(int mode_v); -- 2.7.4 From 33add101f3345ed53faeaaae5f4cf3d296fe3fe3 Mon Sep 17 00:00:00 2001 From: SangYoun Kwak Date: Tue, 15 Mar 2022 16:23:25 +0900 Subject: [PATCH 04/16] Add new command to manipulate the "cloned" flag Change-Id: I6dc81870f7769869f02b0dfaa6e2418179288ee2 Signed-off-by: SangYoun Kwak --- packaging/deviced.spec | 5 ++++- tools/board/CMakeLists.txt | 6 +++++- tools/board/clear-partition-ab-cloned.c | 25 +++++++++++++++++++++++++ tools/board/get-partition-ab-cloned.c | 33 +++++++++++++++++++++++++++++++++ tools/board/set-partition-ab-cloned.c | 25 +++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 tools/board/clear-partition-ab-cloned.c create mode 100644 tools/board/get-partition-ab-cloned.c create mode 100644 tools/board/set-partition-ab-cloned.c diff --git a/packaging/deviced.spec b/packaging/deviced.spec index 9a31220..595f28f 100644 --- a/packaging/deviced.spec +++ b/packaging/deviced.spec @@ -316,10 +316,13 @@ mv %{_libdir}/iot-headless-battery.so %{_libdir}/deviced/battery.so #if #{?usb_module} == on ==> always on %{_bindir}/direct_set_debug.sh %{TZ_SYS_DUMPGEN}/dump_pmstate_log.sh -%attr(2551,root,root) %{_bindir}/device_board_switch_partition %attr(2551,root,root) %{_bindir}/device_board_set_boot_success %attr(2551,root,root) %{_bindir}/device_board_clear_boot_mode %attr(2551,root,root) %{_bindir}/device_board_get_boot_mode +%attr(2551,root,root) %{_bindir}/device_board_switch_partition +%attr(2551,root,root) %{_bindir}/device_board_set_partition_ab_cloned +%attr(2551,root,root) %{_bindir}/device_board_clear_partition_ab_cloned +%attr(2551,root,root) %{_bindir}/device_board_get_partition_ab_cloned #endif %files auto-test diff --git a/tools/board/CMakeLists.txt b/tools/board/CMakeLists.txt index 2ac7eab..1ebb56e 100644 --- a/tools/board/CMakeLists.txt +++ b/tools/board/CMakeLists.txt @@ -15,7 +15,11 @@ MACRO(ADD_BOOT_EXECUTABLE BINARY_NAME SRCS) INSTALL(TARGETS ${BINARY_NAME} DESTINATION bin) ENDMACRO() -ADD_BOOT_EXECUTABLE(device_board_switch_partition switch-partition.c) ADD_BOOT_EXECUTABLE(device_board_set_boot_success set-boot-success.c) ADD_BOOT_EXECUTABLE(device_board_clear_boot_mode clear-boot-mode.c) ADD_BOOT_EXECUTABLE(device_board_get_boot_mode get-boot-mode.c) + +ADD_BOOT_EXECUTABLE(device_board_switch_partition switch-partition.c) +ADD_BOOT_EXECUTABLE(device_board_clear_partition_ab_cloned clear-partition-ab-cloned.c) +ADD_BOOT_EXECUTABLE(device_board_get_partition_ab_cloned get-partition-ab-cloned.c) +ADD_BOOT_EXECUTABLE(device_board_set_partition_ab_cloned set-partition-ab-cloned.c) diff --git a/tools/board/clear-partition-ab-cloned.c b/tools/board/clear-partition-ab-cloned.c new file mode 100644 index 0000000..36425fa --- /dev/null +++ b/tools/board/clear-partition-ab-cloned.c @@ -0,0 +1,25 @@ +/* + * device-board-get-boot-mode + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +int main(int argc, char *argv[]) +{ + return hal_device_board_clear_partition_ab_cloned(); +} diff --git a/tools/board/get-partition-ab-cloned.c b/tools/board/get-partition-ab-cloned.c new file mode 100644 index 0000000..fb55772 --- /dev/null +++ b/tools/board/get-partition-ab-cloned.c @@ -0,0 +1,33 @@ +/* + * device-board-get-boot-mode + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +int main(int argc, char *argv[]) +{ + int cloned; + int ret; + + ret = hal_device_board_get_partition_ab_cloned(&cloned); + if (ret == 0) + printf("%d", cloned); + + return ret; +} diff --git a/tools/board/set-partition-ab-cloned.c b/tools/board/set-partition-ab-cloned.c new file mode 100644 index 0000000..7bbc906 --- /dev/null +++ b/tools/board/set-partition-ab-cloned.c @@ -0,0 +1,25 @@ +/* + * device-board-get-boot-mode + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +int main(int argc, char *argv[]) +{ + return hal_device_board_set_partition_ab_cloned(); +} -- 2.7.4 From be1df8683e1726a2d60bda896ea488d8583dec5c Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Thu, 24 Mar 2022 15:45:47 +0900 Subject: [PATCH 05/16] power: change configuration section of TimeoutSleepSupport Change-Id: I9e534b858d7994182d994d9649d4f1e2375c32e9 Signed-off-by: Youngjae Cho --- conf/power.conf | 4 +--- src/power/power-control.c | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/conf/power.conf b/conf/power.conf index 60a66cc..57a49fa 100644 --- a/conf/power.conf +++ b/conf/power.conf @@ -5,8 +5,6 @@ Option=wdownload Option=debug Option=silent -[Sleep] -TimeoutSleepSupport=yes - [PowerState] +TimeoutSleepSupport=yes ChangeStateMaxWaitSecond=10 diff --git a/src/power/power-control.c b/src/power/power-control.c index c44d2de..91d07b9 100644 --- a/src/power/power-control.c +++ b/src/power/power-control.c @@ -332,7 +332,7 @@ static int __pm_power_unlock(void *data) static int load_sleep_config(struct parse_result *result, void *user_data) { - if (!MATCH(result->section, "Sleep")) + if (!MATCH(result->section, "PowerState")) return 0; if (MATCH(result->name, "TimeoutSleepSupport") && MATCH(result->value, "yes")) { -- 2.7.4 From 2a8ce43a4b7ff301378443f0de05c4e3d05d96b8 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Thu, 24 Mar 2022 13:56:26 +0900 Subject: [PATCH 06/16] power: add configuration for poweroff delay time Change-Id: I29fe716445cb197b66338d973c6acd1fc40890a8 Signed-off-by: Youngjae Cho --- conf/power.conf | 1 + src/power/power-handler.c | 33 ++++++++++++++------------------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/conf/power.conf b/conf/power.conf index 57a49fa..437c672 100644 --- a/conf/power.conf +++ b/conf/power.conf @@ -8,3 +8,4 @@ Option=silent [PowerState] TimeoutSleepSupport=yes ChangeStateMaxWaitSecond=10 +PowerOffDelaySecond=4 diff --git a/src/power/power-handler.c b/src/power/power-handler.c index b52bb6d..9e09401 100644 --- a/src/power/power-handler.c +++ b/src/power/power-handler.c @@ -51,7 +51,6 @@ #include "boot.h" #include "shared/plugin.h" -#define POWEROFF_DURATION 4 #define POWEROFF_WAIT_RESOURCED (0.5*1000) /* 0.5 seconds */ #define POWEROFF_WAIT_MAX 10 /* 10 seconds */ #define POWEROFF_WAIT_SYSTEMD_MS (30 * 1000/*ms*/) /* 30 seconds */ @@ -83,6 +82,7 @@ enum poweroff_stage { POWEROFF_WAIT_OTHERS, /* Wait for other processes to clean up their resources */ }; +static int poweroff_delay_second = 0; static enum poweroff_stage poweroff_stage; static const char *poweroff_type_to_name(enum poweroff_type type) @@ -202,21 +202,23 @@ void poweroff_request_shutdown(void) raise(SIGUSR1); } -static void poweroff_wait_for_seconds(void) +static void poweroff_delay_for_seconds(void) { static int wait; struct timeval now; - int poweroff_duration = POWEROFF_DURATION; int check_duration = 0; + if (poweroff_delay_second == 0) + return; + watchdog_notify(); gettimeofday(&now, NULL); check_duration = now.tv_sec - tv_start_poweroff.tv_sec; - while (check_duration < poweroff_duration) { + while (check_duration < poweroff_delay_second) { if (wait == 0) { - _I("Wait poweroff %d %d.", check_duration, poweroff_duration); + _I("Wait poweroff %d %d.", check_duration, poweroff_delay_second); wait = 1; } usleep(100000); @@ -244,7 +246,7 @@ void poweroff_prepare(void) disable_systemd_journald(); disable_coredump_handler(); - poweroff_wait_for_seconds(); + poweroff_delay_for_seconds(); disable_display(); @@ -728,22 +730,15 @@ static int add_poweroff_option(enum poweroff_type type, const char *option) static int load_config(struct parse_result *result, void *user_data) { enum poweroff_type type; - int ret_val; - if (MATCH(result->section, "PowerOff")) + if (MATCH(result->section, "PowerOff") && MATCH(result->name, "Option")) { type = POWEROFF_TYPE_DIRECT; - else if (MATCH(result->section, "Reboot")) + add_poweroff_option(type, result->value); + } else if (MATCH(result->section, "Reboot") && MATCH(result->name, "Option")) { type = POWEROFF_TYPE_RESTART; - else - return 0; - - if (!MATCH(result->name, "Option")) - return 0; - - ret_val = add_poweroff_option(type, result->value); - if (ret_val < 0) { - _E("Failed to add %s option=%s", result->section, result->value); - return ret_val; + add_poweroff_option(type, result->value); + } else if (MATCH(result->section, "PowerState") && MATCH(result->name, "PowerOffDelaySecond")) { + sscanf(result->value, "%d", &poweroff_delay_second); } return 0; -- 2.7.4 From 4ac5e7ffe949d231581c89febe86bbc9309716c7 Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Wed, 30 Mar 2022 14:33:26 +0900 Subject: [PATCH 07/16] Fix DAC performance for device_board tools Change-Id: I5c4cff6cef406aa4dcc798743bb8c3d3fd5a67f1 Signed-off-by: Hyotaek Shim --- packaging/deviced.spec | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packaging/deviced.spec b/packaging/deviced.spec index 595f28f..22f93f2 100644 --- a/packaging/deviced.spec +++ b/packaging/deviced.spec @@ -316,13 +316,13 @@ mv %{_libdir}/iot-headless-battery.so %{_libdir}/deviced/battery.so #if #{?usb_module} == on ==> always on %{_bindir}/direct_set_debug.sh %{TZ_SYS_DUMPGEN}/dump_pmstate_log.sh -%attr(2551,root,root) %{_bindir}/device_board_set_boot_success -%attr(2551,root,root) %{_bindir}/device_board_clear_boot_mode -%attr(2551,root,root) %{_bindir}/device_board_get_boot_mode -%attr(2551,root,root) %{_bindir}/device_board_switch_partition -%attr(2551,root,root) %{_bindir}/device_board_set_partition_ab_cloned -%attr(2551,root,root) %{_bindir}/device_board_clear_partition_ab_cloned -%attr(2551,root,root) %{_bindir}/device_board_get_partition_ab_cloned +%attr(2550,root,root) %{_bindir}/device_board_set_boot_success +%attr(2550,root,root) %{_bindir}/device_board_clear_boot_mode +%attr(2555,root,root) %{_bindir}/device_board_get_boot_mode +%attr(2550,root,root) %{_bindir}/device_board_switch_partition +%attr(2550,root,root) %{_bindir}/device_board_set_partition_ab_cloned +%attr(2550,root,root) %{_bindir}/device_board_clear_partition_ab_cloned +%attr(2555,root,root) %{_bindir}/device_board_get_partition_ab_cloned #endif %files auto-test -- 2.7.4 From b8fd400089dbad1e1c06a9e62ee49142cc69a97b Mon Sep 17 00:00:00 2001 From: SangYoun Kwak Date: Wed, 30 Mar 2022 18:20:59 +0900 Subject: [PATCH 08/16] Add new commands for upgrade status and change params in switch command Change-Id: Ib9de10fd0609cfa1eaa631e01f2a5eff756ff933 Signed-off-by: SangYoun Kwak --- packaging/deviced.spec | 2 ++ tools/board/CMakeLists.txt | 3 ++ tools/board/get-upgrade-status.c | 33 +++++++++++++++++++++ tools/board/set-upgrade-status.c | 64 ++++++++++++++++++++++++++++++++++++++++ tools/board/switch-partition.c | 13 +++++++- 5 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 tools/board/get-upgrade-status.c create mode 100644 tools/board/set-upgrade-status.c diff --git a/packaging/deviced.spec b/packaging/deviced.spec index 22f93f2..1331169 100644 --- a/packaging/deviced.spec +++ b/packaging/deviced.spec @@ -323,6 +323,8 @@ mv %{_libdir}/iot-headless-battery.so %{_libdir}/deviced/battery.so %attr(2550,root,root) %{_bindir}/device_board_set_partition_ab_cloned %attr(2550,root,root) %{_bindir}/device_board_clear_partition_ab_cloned %attr(2555,root,root) %{_bindir}/device_board_get_partition_ab_cloned +%attr(2550,root,root) %{_bindir}/device_board_set_upgrade_status +%attr(2555,root,root) %{_bindir}/device_board_get_upgrade_status #endif %files auto-test diff --git a/tools/board/CMakeLists.txt b/tools/board/CMakeLists.txt index 1ebb56e..533901d 100644 --- a/tools/board/CMakeLists.txt +++ b/tools/board/CMakeLists.txt @@ -23,3 +23,6 @@ ADD_BOOT_EXECUTABLE(device_board_switch_partition switch-partition.c) ADD_BOOT_EXECUTABLE(device_board_clear_partition_ab_cloned clear-partition-ab-cloned.c) ADD_BOOT_EXECUTABLE(device_board_get_partition_ab_cloned get-partition-ab-cloned.c) ADD_BOOT_EXECUTABLE(device_board_set_partition_ab_cloned set-partition-ab-cloned.c) + +ADD_BOOT_EXECUTABLE(device_board_set_upgrade_status set-upgrade-status.c) +ADD_BOOT_EXECUTABLE(device_board_get_upgrade_status get-upgrade-status.c) diff --git a/tools/board/get-upgrade-status.c b/tools/board/get-upgrade-status.c new file mode 100644 index 0000000..bf3da64 --- /dev/null +++ b/tools/board/get-upgrade-status.c @@ -0,0 +1,33 @@ +/* + * device-board-get-boot-mode + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +int main(int argc, char *argv[]) +{ + int status; + int ret; + + ret = hal_device_board_get_upgrade_status(&status); + if (ret == 0) + printf("%d", status); + + return ret; +} diff --git a/tools/board/set-upgrade-status.c b/tools/board/set-upgrade-status.c new file mode 100644 index 0000000..22876d7 --- /dev/null +++ b/tools/board/set-upgrade-status.c @@ -0,0 +1,64 @@ +/* + * device-board-switch-partition + * + * Copyright (c) 2022 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include + +#include + +static int parse_integer(const char *str, int *val) +{ + char *endptr = str; + long longval = 0; + + errno = 0; + longval = strtol(str, &endptr, 10); + + if(errno || *endptr) { + errno = 0; + return -EINVAL; + } + + if(longval > INT_MAX || longval < INT_MIN) { + return -EINVAL; + } + + *val = (int)longval; + + return 0; +} + +int main(int argc, char *argv[]) +{ + int status; + int parse_ret; + + if(argc < 2) { + return -EINVAL; + } + + parse_ret = parse_integer(argv[1], &status); + + if(parse_ret != 0) { + return -EINVAL; + } + + return hal_device_board_set_upgrade_status(argc, argv); +} diff --git a/tools/board/switch-partition.c b/tools/board/switch-partition.c index 6c8c580..bfdd5af 100644 --- a/tools/board/switch-partition.c +++ b/tools/board/switch-partition.c @@ -21,5 +21,16 @@ int main(int argc, char *argv[]) { - return hal_device_board_switch_partition(argc, argv); + char partition_ab; + + if(argc < 2) { + return -EINVAL; + } + + partition_ab = argv[1][0]; + if(partition_ab != 'a' && partition_ab != 'b') { + return -EINVAL; + } + + return hal_device_board_switch_partition(partition_ab); } -- 2.7.4 From af0a7f6275f7513bebc5c8470f4e35284fe63de8 Mon Sep 17 00:00:00 2001 From: SangYoun Kwak Date: Thu, 31 Mar 2022 14:05:03 +0900 Subject: [PATCH 09/16] Fix include and parameter Change-Id: I9ced21c55ce596087418a9f5f3867e42411e16c7 Signed-off-by: SangYoun Kwak --- tools/board/set-upgrade-status.c | 2 +- tools/board/switch-partition.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/board/set-upgrade-status.c b/tools/board/set-upgrade-status.c index 22876d7..e863d0a 100644 --- a/tools/board/set-upgrade-status.c +++ b/tools/board/set-upgrade-status.c @@ -60,5 +60,5 @@ int main(int argc, char *argv[]) return -EINVAL; } - return hal_device_board_set_upgrade_status(argc, argv); + return hal_device_board_set_upgrade_status(status); } diff --git a/tools/board/switch-partition.c b/tools/board/switch-partition.c index bfdd5af..69bf28a 100644 --- a/tools/board/switch-partition.c +++ b/tools/board/switch-partition.c @@ -17,6 +17,7 @@ * */ +#include #include int main(int argc, char *argv[]) -- 2.7.4 From 9b8cbc8167937d244e0f5529bcf00febe8ddc341 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Tue, 29 Mar 2022 18:28:05 -0700 Subject: [PATCH 10/16] hdmi: remove display control Controlling display from hdmi will be more discussed as multi-display concept would be introduced. Therefore, remove old fashioned display control policy. Change-Id: Iecd28b73491d6fcb565183196d2c9291720db23a Signed-off-by: Youngjae Cho --- src/extcon/hdmi.c | 43 ------------------------------------------- 1 file changed, 43 deletions(-) diff --git a/src/extcon/hdmi.c b/src/extcon/hdmi.c index 943f767..56ffea6 100644 --- a/src/extcon/hdmi.c +++ b/src/extcon/hdmi.c @@ -34,7 +34,6 @@ #define HDMI_NUMBER_MAX (64) // max number of supported hdmi static struct dd_bitmap *bm_hdmi; -static struct display_plugin *disp_plgn; static struct extcon_ops hdmi_extcon_ops; static void hdmi_send_broadcast(int status) @@ -110,8 +109,6 @@ static int hdmi_update(const char *index, int status) } _I("Hdmi changed"); - if (disp_plgn->pm_change_internal) - disp_plgn->pm_change_internal(INTERNAL_LOCK_HDMI, LCD_NORMAL); if (!index) update_all_hdmi_bitmap(status); @@ -132,35 +129,6 @@ static int hdmi_update(const char *index, int status) hdmi_extcon_ops.status = hdmi_status; hdmi_send_broadcast(hdmi_status); - if (hdmi_status == HDMI_CONNECTED) { - if (disp_plgn->pm_lock_internal) - disp_plgn->pm_lock_internal(INTERNAL_LOCK_HDMI, LCD_DIM, STAY_CUR_STATE, 0); - } else { - if (disp_plgn->pm_unlock_internal) - disp_plgn->pm_unlock_internal(INTERNAL_LOCK_HDMI, LCD_DIM, PM_SLEEP_MARGIN); - } - - return 0; -} - -static int display_changed(void *data) -{ - enum state_t state; - int hdmi; - - if (!data) - return 0; - - state = *(int *)data; - if (state != S_NORMAL) - return 0; - - hdmi = hdmi_extcon_ops.status; - if (hdmi == 0) { - if (disp_plgn->pm_lock_internal) - disp_plgn->pm_lock_internal(INTERNAL_LOCK_HDMI, LCD_DIM, STAY_CUR_STATE, 0); - _I("Hdmi is connected. Dim lock is on."); - } return 0; } @@ -187,8 +155,6 @@ static void hdmi_init(void *data) { int ret; - register_notifier(DEVICE_NOTIFIER_LCD, display_changed); - ret = gdbus_add_object(NULL, DEVICED_PATH_SYSNOTI, &dbus_interface); if (ret < 0) _E("Failed to init dbus method: %d", ret); @@ -198,8 +164,6 @@ static void hdmi_init(void *data) static void hdmi_exit(void *data) { - unregister_notifier(DEVICE_NOTIFIER_LCD, display_changed); - deinit_bitmap(bm_hdmi); } @@ -211,10 +175,3 @@ static struct extcon_ops hdmi_extcon_ops = { }; EXTCON_OPS_REGISTER(hdmi_extcon_ops) - -static void __CONSTRUCTOR__ initialize(void) -{ - disp_plgn = get_var_display_plugin(); - if (!disp_plgn) - _E("Failed to get display plugin variable."); -} -- 2.7.4 From 189ec95d3161aabdff5a7b9cd0851e3b80a6e640 Mon Sep 17 00:00:00 2001 From: SangYoun Kwak Date: Fri, 1 Apr 2022 16:07:13 +0900 Subject: [PATCH 11/16] Fix to initialize the char pointer to NULL Change-Id: I7144bf7646e813a905c3eae7fd209d342cabb450 Signed-off-by: SangYoun Kwak --- tools/board/set-upgrade-status.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/board/set-upgrade-status.c b/tools/board/set-upgrade-status.c index e863d0a..d1a9fe1 100644 --- a/tools/board/set-upgrade-status.c +++ b/tools/board/set-upgrade-status.c @@ -25,7 +25,7 @@ static int parse_integer(const char *str, int *val) { - char *endptr = str; + char *endptr = NULL; long longval = 0; errno = 0; -- 2.7.4 From 943e2f348215f1c60136909ecb640598c289c5d5 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Fri, 1 Apr 2022 15:30:23 +0900 Subject: [PATCH 12/16] power: separate power configuration for each profile Change-Id: Id24e09c02a3e4e706cbe95eeee351eb23c250273 Signed-off-by: Youngjae Cho --- CMakeLists.txt | 6 +++++- conf/power-profile-iot-headed.conf | 11 +++++++++++ conf/power-profile-iot-headless.conf | 11 +++++++++++ conf/{power.conf => power-profile-mobile.conf} | 0 conf/power-profile-tv.conf | 11 +++++++++++ conf/power-profile-wearable.conf | 11 +++++++++++ packaging/deviced.spec | 11 ++++++++++- 7 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 conf/power-profile-iot-headed.conf create mode 100644 conf/power-profile-iot-headless.conf rename conf/{power.conf => power-profile-mobile.conf} (100%) create mode 100644 conf/power-profile-tv.conf create mode 100644 conf/power-profile-wearable.conf diff --git a/CMakeLists.txt b/CMakeLists.txt index 49efd97..287aac9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -278,7 +278,11 @@ ENDIF() IF(POWER_MODULE STREQUAL on) INSTALL_CONF(conf init) - INSTALL_CONF(conf power) + INSTALL_CONF(conf power-profile-mobile) + INSTALL_CONF(conf power-profile-wearable) + INSTALL_CONF(conf power-profile-tv) + INSTALL_CONF(conf power-profile-iot-headed) + INSTALL_CONF(conf power-profile-iot-headless) ENDIF() # USB connection diff --git a/conf/power-profile-iot-headed.conf b/conf/power-profile-iot-headed.conf new file mode 100644 index 0000000..ce213be --- /dev/null +++ b/conf/power-profile-iot-headed.conf @@ -0,0 +1,11 @@ +[Reboot] +Option=recovery +Option=download +Option=wdownload +Option=debug +Option=silent + +[PowerState] +TimeoutSleepSupport=no +ChangeStateMaxWaitSecond=10 +PowerOffDelaySecond=4 diff --git a/conf/power-profile-iot-headless.conf b/conf/power-profile-iot-headless.conf new file mode 100644 index 0000000..27c6908 --- /dev/null +++ b/conf/power-profile-iot-headless.conf @@ -0,0 +1,11 @@ +[Reboot] +Option=recovery +Option=download +Option=wdownload +Option=debug +Option=silent + +[PowerState] +TimeoutSleepSupport=yes +ChangeStateMaxWaitSecond=10 +PowerOffDelaySecond=0 diff --git a/conf/power.conf b/conf/power-profile-mobile.conf similarity index 100% rename from conf/power.conf rename to conf/power-profile-mobile.conf diff --git a/conf/power-profile-tv.conf b/conf/power-profile-tv.conf new file mode 100644 index 0000000..437c672 --- /dev/null +++ b/conf/power-profile-tv.conf @@ -0,0 +1,11 @@ +[Reboot] +Option=recovery +Option=download +Option=wdownload +Option=debug +Option=silent + +[PowerState] +TimeoutSleepSupport=yes +ChangeStateMaxWaitSecond=10 +PowerOffDelaySecond=4 diff --git a/conf/power-profile-wearable.conf b/conf/power-profile-wearable.conf new file mode 100644 index 0000000..437c672 --- /dev/null +++ b/conf/power-profile-wearable.conf @@ -0,0 +1,11 @@ +[Reboot] +Option=recovery +Option=download +Option=wdownload +Option=debug +Option=silent + +[PowerState] +TimeoutSleepSupport=yes +ChangeStateMaxWaitSecond=10 +PowerOffDelaySecond=4 diff --git a/packaging/deviced.spec b/packaging/deviced.spec index 1331169..97860ae 100644 --- a/packaging/deviced.spec +++ b/packaging/deviced.spec @@ -223,6 +223,7 @@ update-alternatives --remove shutdown %{_sbindir}/deviced-power-command || : %post plugin-profile-mobile mv %{_sysconfdir}/deviced/display-profile-mobile.conf %{_sysconfdir}/deviced/display.conf +mv %{_sysconfdir}/deviced/power-profile-mobile.conf %{_sysconfdir}/deviced/power.conf mkdir -p %{_libdir}/deviced mv %{_libdir}/mobile-display.so %{_libdir}/deviced/display.so %if %{?battery_module} == on @@ -231,6 +232,7 @@ mv %{_libdir}/mobile-battery.so %{_libdir}/deviced/battery.so %post plugin-profile-wearable mv %{_sysconfdir}/deviced/display-profile-wearable.conf %{_sysconfdir}/deviced/display.conf +mv %{_sysconfdir}/deviced/power-profile-wearable.conf %{_sysconfdir}/deviced/power.conf mkdir -p %{_libdir}/deviced mv %{_libdir}/wearable-display.so %{_libdir}/deviced/display.so %if %{?battery_module} == on @@ -239,16 +241,19 @@ mv %{_libdir}/wearable-battery.so %{_libdir}/deviced/battery.so %post plugin-profile-tv mv %{_sysconfdir}/deviced/display-profile-tv.conf %{_sysconfdir}/deviced/display.conf +mv %{_sysconfdir}/deviced/power-profile-tv.conf %{_sysconfdir}/deviced/power.conf mkdir -p %{_libdir}/deviced mv %{_libdir}/tv-display.so %{_libdir}/deviced/display.so %post plugin-profile-iot-headed mv %{_sysconfdir}/deviced/display-profile-iot-headed.conf %{_sysconfdir}/deviced/display.conf +mv %{_sysconfdir}/deviced/power-profile-iot-headed.conf %{_sysconfdir}/deviced/power.conf mkdir -p %{_libdir}/deviced mv %{_libdir}/iot-headed-display.so %{_libdir}/deviced/display.so %post plugin-profile-iot-headless mv %{_sysconfdir}/deviced/input-profile-iot-headless.conf %{_sysconfdir}/deviced/input.conf +mv %{_sysconfdir}/deviced/power-profile-iot-headless.conf %{_sysconfdir}/deviced/power.conf mkdir -p %{_libdir}/deviced mv %{_libdir}/iot-headless-input-handler.so %{_libdir}/deviced/input-handler.so mv %{_libdir}/iot-headless-power.so %{_libdir}/deviced/power.so @@ -267,7 +272,6 @@ mv %{_libdir}/iot-headless-battery.so %{_libdir}/deviced/battery.so %{_unitdir}/basic.target.wants/sdb-prestart.service %endif %config %{_sysconfdir}/dbus-1/system.d/org.tizen.system.deviced.conf -%config %{_sysconfdir}/deviced/power.conf %config %{_sysconfdir}/deviced/init.conf %if %{?battery_module} == on %config %{_sysconfdir}/deviced/battery.conf @@ -337,6 +341,7 @@ mv %{_libdir}/iot-headless-battery.so %{_libdir}/deviced/battery.so %license LICENSE.Apache-2.0 %defattr(-,root,root,-) %config %{_sysconfdir}/deviced/display-profile-mobile.conf +%config %{_sysconfdir}/deviced/power-profile-mobile.conf %{_libdir}/mobile-display.so %if %{?battery_module} == on %{_libdir}/mobile-battery.so @@ -349,6 +354,7 @@ mv %{_libdir}/iot-headless-battery.so %{_libdir}/deviced/battery.so %license LICENSE.Apache-2.0 %defattr(-,root,root,-) %config %{_sysconfdir}/deviced/display-profile-wearable.conf +%config %{_sysconfdir}/deviced/power-profile-wearable.conf %{_libdir}/wearable-display.so %if %{?battery_module} == on %{_libdir}/wearable-battery.so @@ -361,6 +367,7 @@ mv %{_libdir}/iot-headless-battery.so %{_libdir}/deviced/battery.so %license LICENSE.Apache-2.0 %defattr(-,root,root,-) %config %{_sysconfdir}/deviced/display-profile-tv.conf +%config %{_sysconfdir}/deviced/power-profile-tv.conf %{_libdir}/tv-display.so %{_unitdir}/rndis.service %{_bindir}/rndis.sh @@ -370,6 +377,7 @@ mv %{_libdir}/iot-headless-battery.so %{_libdir}/deviced/battery.so %license LICENSE.Apache-2.0 %defattr(-,root,root,-) %config %{_sysconfdir}/deviced/display-profile-iot-headed.conf +%config %{_sysconfdir}/deviced/power-profile-iot-headed.conf %{_libdir}/iot-headed-display.so %{_unitdir}/rndis.service %{_bindir}/rndis.sh @@ -379,6 +387,7 @@ mv %{_libdir}/iot-headless-battery.so %{_libdir}/deviced/battery.so %license LICENSE.Apache-2.0 %defattr(-,root,root,-) %config %{_sysconfdir}/deviced/input-profile-iot-headless.conf +%config %{_sysconfdir}/deviced/power-profile-iot-headless.conf %{_libdir}/iot-headless-input-handler.so %{_libdir}/iot-headless-power.so %{_libdir}/iot-headless-battery.so -- 2.7.4 From c29ab86fae1e3e6e08b5ae76a9c51f35581e9e9e Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Tue, 5 Apr 2022 17:29:24 -0700 Subject: [PATCH 13/16] usb: prevent not null-terminated string Change-Id: I17b1d4c7753120dd09192523f75c8939ba96e184 Signed-off-by: Youngjae Cho --- src/usb/usb-state.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/usb/usb-state.c b/src/usb/usb-state.c index 77375c6..51fa4cb 100644 --- a/src/usb/usb-state.c +++ b/src/usb/usb-state.c @@ -174,7 +174,8 @@ static void parse_property_systemd_unit(gpointer data, gpointer udata) struct service_config *svc = (struct service_config *) udata; if (MATCH(prop->key, "Service")) { - strncpy(svc->name, prop->value, sizeof(svc->name)); + strncpy(svc->name, prop->value, sizeof(svc->name) - 1); + svc->name[sizeof(svc->name) - 1] = '\0'; } else if (MATCH(prop->key, "RemainAfterDisable")) { svc->remain_after_disable = MATCH(prop->value, "yes"); } -- 2.7.4 From 43658e8acdef4676c65bc1462f1306f5d3950587 Mon Sep 17 00:00:00 2001 From: SangYoun Kwak Date: Thu, 7 Apr 2022 16:32:35 +0900 Subject: [PATCH 14/16] Modify the return value and the output of deviced-tools Change-Id: Ic9070e2062f17b109a09791d38948e0aa7c20da9 Signed-off-by: SangYoun Kwak --- tools/board/clear-boot-mode.c | 11 ++++++++++- tools/board/clear-partition-ab-cloned.c | 11 ++++++++++- tools/board/get-boot-mode.c | 10 +++++++--- tools/board/get-partition-ab-cloned.c | 10 +++++++--- tools/board/get-upgrade-status.c | 10 +++++++--- tools/board/set-boot-success.c | 11 ++++++++++- tools/board/set-partition-ab-cloned.c | 11 ++++++++++- tools/board/set-upgrade-status.c | 21 ++++++++++++++++----- tools/board/switch-partition.c | 19 ++++++++++++++++--- 9 files changed, 93 insertions(+), 21 deletions(-) diff --git a/tools/board/clear-boot-mode.c b/tools/board/clear-boot-mode.c index 38075f9..7ae0704 100644 --- a/tools/board/clear-boot-mode.c +++ b/tools/board/clear-boot-mode.c @@ -17,9 +17,18 @@ * */ +#include #include int main(int argc, char *argv[]) { - return hal_device_board_clear_boot_mode(); + int ret = hal_device_board_clear_boot_mode(); + + if(ret < 0) { + printf("FAILURE\n"); + return 1; + } + + printf("SUCCESS\n"); + return 0; } diff --git a/tools/board/clear-partition-ab-cloned.c b/tools/board/clear-partition-ab-cloned.c index 36425fa..6c4437d 100644 --- a/tools/board/clear-partition-ab-cloned.c +++ b/tools/board/clear-partition-ab-cloned.c @@ -17,9 +17,18 @@ * */ +#include #include int main(int argc, char *argv[]) { - return hal_device_board_clear_partition_ab_cloned(); + int ret = hal_device_board_clear_partition_ab_cloned(); + + if(ret < 0) { + printf("FAILURE\n"); + return 1; + } + + printf("SUCCESS\n"); + return 0; } diff --git a/tools/board/get-boot-mode.c b/tools/board/get-boot-mode.c index 29ddde5..f72172c 100644 --- a/tools/board/get-boot-mode.c +++ b/tools/board/get-boot-mode.c @@ -26,8 +26,12 @@ int main(int argc, char *argv[]) int ret; ret = hal_device_board_get_boot_mode(buffer, sizeof(buffer)); - if (ret == 0) - printf("%s", buffer); - return ret; + if(ret < 0) { + printf("FAILURE\n"); + return 1; + } + + printf("%s\n", buffer); + return 0; } diff --git a/tools/board/get-partition-ab-cloned.c b/tools/board/get-partition-ab-cloned.c index fb55772..d843930 100644 --- a/tools/board/get-partition-ab-cloned.c +++ b/tools/board/get-partition-ab-cloned.c @@ -26,8 +26,12 @@ int main(int argc, char *argv[]) int ret; ret = hal_device_board_get_partition_ab_cloned(&cloned); - if (ret == 0) - printf("%d", cloned); - return ret; + if (ret < 0) { + printf("FAILURE\n"); + return 1; + } + + printf("%d\n", cloned); + return 0; } diff --git a/tools/board/get-upgrade-status.c b/tools/board/get-upgrade-status.c index bf3da64..f66ad36 100644 --- a/tools/board/get-upgrade-status.c +++ b/tools/board/get-upgrade-status.c @@ -26,8 +26,12 @@ int main(int argc, char *argv[]) int ret; ret = hal_device_board_get_upgrade_status(&status); - if (ret == 0) - printf("%d", status); - return ret; + if(ret < 0) { + printf("FAILURE\n"); + return 1; + } + + printf("%d\n", status); + return 0; } diff --git a/tools/board/set-boot-success.c b/tools/board/set-boot-success.c index 16ec3a5..5146149 100644 --- a/tools/board/set-boot-success.c +++ b/tools/board/set-boot-success.c @@ -17,9 +17,18 @@ * */ +#include #include int main(int argc, char *argv[]) { - return hal_device_board_set_boot_success(); + int ret = hal_device_board_set_boot_success(); + + if(ret < 0) { + printf("FAILURE\n"); + return 1; + } + + printf("SUCCESS\n"); + return 0; } diff --git a/tools/board/set-partition-ab-cloned.c b/tools/board/set-partition-ab-cloned.c index 7bbc906..941fe0d 100644 --- a/tools/board/set-partition-ab-cloned.c +++ b/tools/board/set-partition-ab-cloned.c @@ -17,9 +17,18 @@ * */ +#include #include int main(int argc, char *argv[]) { - return hal_device_board_set_partition_ab_cloned(); + int ret = hal_device_board_set_partition_ab_cloned(); + + if(ret < 0) { + printf("FAILURE\n"); + return 1; + } + + printf("SUCCESS\n"); + return 0; } diff --git a/tools/board/set-upgrade-status.c b/tools/board/set-upgrade-status.c index d1a9fe1..5bd1fb1 100644 --- a/tools/board/set-upgrade-status.c +++ b/tools/board/set-upgrade-status.c @@ -48,17 +48,28 @@ static int parse_integer(const char *str, int *val) int main(int argc, char *argv[]) { int status; - int parse_ret; + int parse_ret, ret; if(argc < 2) { - return -EINVAL; + goto err; } parse_ret = parse_integer(argv[1], &status); - if(parse_ret != 0) { - return -EINVAL; + if(parse_ret < 0) { + goto err; } - return hal_device_board_set_upgrade_status(status); + ret = hal_device_board_set_upgrade_status(status); + + if(ret < 0) { + goto err; + } + + printf("SUCCESS\n"); + return 0; + +err: + printf("FAILURE\n"); + return 1; } diff --git a/tools/board/switch-partition.c b/tools/board/switch-partition.c index 69bf28a..973e4ac 100644 --- a/tools/board/switch-partition.c +++ b/tools/board/switch-partition.c @@ -17,21 +17,34 @@ * */ +#include #include #include int main(int argc, char *argv[]) { char partition_ab; + int ret; if(argc < 2) { - return -EINVAL; + goto err; } partition_ab = argv[1][0]; if(partition_ab != 'a' && partition_ab != 'b') { - return -EINVAL; + goto err; } - return hal_device_board_switch_partition(partition_ab); + ret = hal_device_board_switch_partition(partition_ab); + + if(ret < 0) { + goto err; + } + + printf("SUCCESS\n"); + return 0; + +err: + printf("FAILURE\n"); + return 1; } -- 2.7.4 From fa58aae05a2915990380cdbd6cee7d557552282b Mon Sep 17 00:00:00 2001 From: SangYoun Kwak Date: Fri, 8 Apr 2022 17:29:15 +0900 Subject: [PATCH 15/16] Fix implicit declaration warning Change-Id: I9abfa31c34e01ed1796655cd86705430ab279d2f Signed-off-by: SangYoun Kwak --- tools/board/set-upgrade-status.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/board/set-upgrade-status.c b/tools/board/set-upgrade-status.c index 5bd1fb1..6080d63 100644 --- a/tools/board/set-upgrade-status.c +++ b/tools/board/set-upgrade-status.c @@ -17,6 +17,7 @@ * */ +#include #include #include #include -- 2.7.4 From 4f76e2b02b536704479168e7c8d68b02c671b857 Mon Sep 17 00:00:00 2001 From: Youngjae Cho Date: Wed, 6 Apr 2022 01:40:04 -0700 Subject: [PATCH 16/16] usb: move usb-gadget from device-common to deviced Change-Id: I3190fb3c7ff62aab41dc3f4959d26ce8647d03bc Signed-off-by: Youngjae Cho --- src/usb/usb-dbus.c | 1 - src/usb/usb-debug.c | 1 - src/usb/usb-gadget-cfs-gadget.c | 645 +++++++++++++++++++++++++++++++++++++ src/usb/usb-gadget-legacy-gadget.c | 358 ++++++++++++++++++++ src/usb/usb-gadget.c | 465 ++++++++++++++++++++++++++ src/usb/usb-gadget.h | 101 ++++++ src/usb/usb-state.c | 2 +- src/usb/usb-tethering.c | 1 - src/usb/usb.c | 16 +- 9 files changed, 1578 insertions(+), 12 deletions(-) create mode 100644 src/usb/usb-gadget-cfs-gadget.c create mode 100644 src/usb/usb-gadget-legacy-gadget.c create mode 100644 src/usb/usb-gadget.c create mode 100644 src/usb/usb-gadget.h diff --git a/src/usb/usb-dbus.c b/src/usb/usb-dbus.c index 700c86d..137a5e1 100644 --- a/src/usb/usb-dbus.c +++ b/src/usb/usb-dbus.c @@ -21,7 +21,6 @@ #include #include -#include #include "core/log.h" diff --git a/src/usb/usb-debug.c b/src/usb/usb-debug.c index 3f138d4..f6bfb23 100644 --- a/src/usb/usb-debug.c +++ b/src/usb/usb-debug.c @@ -21,7 +21,6 @@ #include #include -#include #include "core/log.h" #include "shared/device-notifier.h" diff --git a/src/usb/usb-gadget-cfs-gadget.c b/src/usb/usb-gadget-cfs-gadget.c new file mode 100644 index 0000000..61583e0 --- /dev/null +++ b/src/usb/usb-gadget-cfs-gadget.c @@ -0,0 +1,645 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include "usb-gadget.h" + +#define CONFIGFS_PATH "/sys/kernel/config" + +#define CONFIGFS_GADGET_NAME "hal-gadget" +#define CONFIGFS_CONFIG_LABEL "hal-config" + +#define NAME_INSTANCE_SEP '.' +#define MAX_INSTANCE_LEN 512 + +#define USB_FUNCS_PATH "/dev/usb-funcs" + +enum cfs_function_service_operation { + CFS_FUNCTION_SERVICE_START, + CFS_FUNCTION_SERVICE_STOP, + CFS_FUNCTION_SERVICE_POST_STOP, +}; + +struct cfs_client { + usbg_state *ctx; + usbg_gadget *gadget; + usbg_udc *udc; +}; + +/* Based on values in slp-gadget kernel module */ +struct usbg_gadget_attrs default_g_attrs = { + .idVendor = DEFAULT_VID, + .idProduct = DEFAULT_PID, + .bcdDevice = DEFAULT_BCD_DEVICE, +}; + +struct usbg_gadget_strs default_g_strs = { + .manufacturer = DEFAULT_MANUFACTURER, + .product = DEFAULT_PRODUCT, + .serial = DEFAULT_SERIAL, +}; + +struct cfs_client *g_cfs_client; + +static struct usb_function *cfs_find_usb_function(usbg_function *function) +{ + char *sep; + char buf[MAX_INSTANCE_LEN]; + const char *instance = usbg_get_function_instance(function); + const char *name = usbg_get_function_type_str(usbg_get_function_type(function)); + + /* Ex. name:"ffs", instance: "sdb.default" */ + if (strcmp(name, usbg_get_function_type_str(USBG_F_FFS)) == 0) { + strncpy(buf, instance, sizeof(buf) - 1); + buf[sizeof(buf) - 1] = '\0'; + + /* Ex. "sdb.default" ==> "sdb" + "default" */ + sep = strchr(buf, NAME_INSTANCE_SEP); + if (!sep || !sep[1]) + return NULL; + *sep = '\0'; + + name = buf; + instance = sep + 1; + } + + return find_usb_function_by_name_instance(name, instance); +} + +static bool cfs_is_function_supported(struct usb_function *func) +{ + char buf[PATH_MAX]; + + if (func->is_functionfs) { + /* functionfs must have a service */ + if (!func->service) + return false; + + snprintf(buf, sizeof(buf), "/usr/lib/systemd/system/%s.socket", func->service); + if (access(buf, F_OK)) + return false; + } else { + if (usbg_lookup_function_type(func->name) < 0) + return false; + } + + return true; +} + +static bool cfs_is_gadget_supported(struct usb_gadget *gadget) +{ + int i, j; + struct usb_configuration *config; + + if (!gadget || !gadget->configs || !gadget->configs[0] || !gadget->configs[0]->funcs[0]) + return false; + + if (!gadget->attrs.idVendor || !gadget->attrs.idProduct || !gadget->attrs.bcdDevice) + return false; + + /* only strings in US_en are allowed */ + if (gadget->strs.lang_code != DEFAULT_LANG) + return false; + + if (!gadget->strs.manufacturer || !gadget->strs.product || !gadget->strs.serial) + return false; + + for (j = 0; gadget->configs[j]; ++j) { + config = gadget->configs[j]; + + if (!config->funcs) + return false; + + for (i = 0; config->funcs[i]; ++i) + if (!cfs_is_function_supported(config->funcs[i])) + return false; + } + + return true; +} + +static int cfs_set_gadget_attrs(struct cfs_client *cfs_client, + struct usb_gadget_attrs *attrs) +{ + int ret; + struct usbg_gadget_attrs gadget_attrs; + + ret = usbg_get_gadget_attrs(cfs_client->gadget, &gadget_attrs); + if (ret) + return ret; + + gadget_attrs.bDeviceClass = attrs->bDeviceClass; + gadget_attrs.bDeviceSubClass = attrs->bDeviceSubClass; + gadget_attrs.bDeviceProtocol = attrs->bDeviceProtocol; + gadget_attrs.idVendor = attrs->idVendor; + gadget_attrs.idProduct = attrs->idProduct; + gadget_attrs.bcdDevice = attrs->bcdDevice; + + ret = usbg_set_gadget_attrs(cfs_client->gadget, &gadget_attrs); + + return ret; +} + +static int cfs_set_gadget_strs(struct cfs_client *cfs_client, struct usb_gadget_strings *strs) +{ + int ret; + + if (!strs->manufacturer || !strs->product || !strs->serial) + return -EINVAL; + + ret = usbg_set_gadget_str(cfs_client->gadget, USBG_STR_MANUFACTURER, strs->lang_code, strs->manufacturer); + if (ret) + return ret; + + ret = usbg_set_gadget_str(cfs_client->gadget, USBG_STR_PRODUCT, strs->lang_code, strs->product); + if (ret) + return ret; + + ret = usbg_set_gadget_str(cfs_client->gadget, USBG_STR_SERIAL_NUMBER, strs->lang_code, strs->serial); + if (ret) + return ret; + + return 0; +} + +static int cfs_ensure_dir(char *path) +{ + if (mkdir(path, 0770) < 0) + return (errno == EEXIST) ? 0 : -errno; + + return 0; +} + + +static int cfs_prep_ffs_service(struct usb_function *usb_func, usbg_function *function) +{ + int ret; + const char *name; + const char *service; + const char *instance; + const char *dev_name; + char buf[MAX_INSTANCE_LEN]; + + if (!usb_func || !function) + return -EINVAL; + + if (usbg_get_function_type(function) != USBG_F_FFS) + return -EINVAL; + + name = usb_func->name; + service = usb_func->service; + instance = usb_func->instance; + dev_name = usbg_get_function_instance(function); + + /* "/dev/usb-funcs" + "/" + "sdb" + "/" + "default" + '0' */ + if (strlen(USB_FUNCS_PATH) + strlen(name) + strlen(instance) + 3 > sizeof(buf)) + return -ENAMETOOLONG; + + /* mkdir /dev/usb-funcs */ + ret = cfs_ensure_dir(USB_FUNCS_PATH); + if (ret < 0) + return ret; + + /* mkdir /dev/usb-funcs/sdb */ + snprintf(buf, sizeof(buf), "%s/%s", USB_FUNCS_PATH, name); + ret = cfs_ensure_dir(buf); + if (ret < 0) + goto out_rmdir; + + /* mkdir /dev/usb-funcs/sdb/default */ + snprintf(buf, sizeof(buf), "%s/%s/%s", USB_FUNCS_PATH, name, instance); + ret = cfs_ensure_dir(buf); + if (ret < 0) + goto out_rmdir; + + /* mount -t functionfs sdb.default /dev/usb-funcs/sdb/default */ + ret = mount(dev_name, buf, "functionfs", 0, NULL); + if (ret < 0) + goto out_rmdir; + + /* start sdbd.socket */ + ret = systemd_start_unit_wait_started(service, ".socket", -1); + if (ret < 0) + goto out_unmount; + + return 0; + +out_unmount: + umount(buf); + +out_rmdir: + snprintf(buf, sizeof(buf), "%s/%s/%s", USB_FUNCS_PATH, name, instance); + rmdir(buf); + + snprintf(buf, sizeof(buf), "%s/%s", USB_FUNCS_PATH, name); + rmdir(buf); + + rmdir(USB_FUNCS_PATH); + + return ret; +} + +static int cfs_cleanup_ffs_service(usbg_function *function) +{ + int ret; + char buf[MAX_INSTANCE_LEN]; + struct usb_function *usb_function; + + if (!function) + return -EINVAL; + + usb_function = cfs_find_usb_function(function); + if (!usb_function) + return -ENOENT; + + /* stop .socket first and stop .service later becuase of socket activation */ + if (usb_function->service) { + (void)systemd_stop_unit_wait_stopped(usb_function->service, ".socket", -1); + (void)systemd_stop_unit_wait_stopped(usb_function->service, ".service", -1); + } + + /* umount /dev/usb-funcs/[sdb|mtp]/default and remove it's directory */ + ret = snprintf(buf, sizeof(buf), "%s/%s/%s", USB_FUNCS_PATH, usb_function->name, usb_function->instance); + if (ret < 0) + return ret; + + ret = umount(buf); + if (ret < 0) + return ret; + + ret = rmdir(buf); + if (ret < 0) + return ret; + + /* remove /dev/usb-funcs/[sdb|mtp] directory */ + ret = snprintf(buf, sizeof(buf), "%s/%s", USB_FUNCS_PATH, usb_function->name); + if (ret < 0) + return ret; + + ret = rmdir(buf); + if (ret < 0 && errno != ENOTEMPTY) + return ret; + + /* remove /dev/usb-funcs/ directory */ + ret = rmdir(USB_FUNCS_PATH); + if (ret < 0 && errno != ENOTEMPTY) + return ret; + + return 0; +} + + +static int cfs_set_rndis_mac_addr(usbg_gadget *gadget, usbg_function *func) +{ + int i, ret; + struct ether_addr ethaddr; + struct usbg_gadget_strs strs; + struct usbg_f_net *nf = usbg_to_net_function(func); + + if (!nf) + return -EINVAL; + + ret = usbg_get_gadget_strs(gadget, LANG_US_ENG, &strs); + if (ret != USBG_SUCCESS) + return ret; + + for (i = 0; i < ETHER_ADDR_LEN; i++) + ethaddr.ether_addr_octet[i] = 0; + + for (i = 0; (i < 256) && strs.serial[i]; i++) { + ethaddr.ether_addr_octet[i % (ETHER_ADDR_LEN - 1) + 1] ^= strs.serial[i]; + } + ethaddr.ether_addr_octet[0] &= 0xfe; /* clear multicast bit */ + ethaddr.ether_addr_octet[0] |= 0x02; /* set local assignment bit (IEEE802) */ + + usbg_free_gadget_strs(&strs); + + /* host_addr changes mac address */ + ret = usbg_f_net_set_host_addr(nf, ðaddr); + + return ret; +} + +static int cfs_cleanup_all_config_and_function(struct cfs_client *cfs_client) +{ + int ret; + usbg_config *config; + usbg_function *function; + + /* delete all configs */ +restart_rm_config: + usbg_for_each_config(config, cfs_client->gadget) { + ret = usbg_rm_config(config, USBG_RM_RECURSE); + if (ret) + return ret; + + goto restart_rm_config; /* You cannot delete a config directly in an iterator. */ + } + + /* delete all functions */ +restart_rm_function: + usbg_for_each_function(function, cfs_client->gadget) { + if (usbg_get_function_type(function) == USBG_F_FFS) { + ret = cfs_cleanup_ffs_service(function); + if (ret) + return ret; + } + + ret = usbg_rm_function(function, USBG_RM_RECURSE); + if (ret) + return ret; + + goto restart_rm_function; /* You cannot delete a function directly in an iterator. */ + } + + return 0; +} + +static int cfs_set_gadget_config(struct cfs_client *cfs_client, int config_id, struct usb_configuration *usb_config) +{ + int i; + int ret; + int function_type; + usbg_config *config; + usbg_function *function; + struct usb_function *usb_func; + char instance[MAX_INSTANCE_LEN]; + struct usbg_config_attrs cattrs = { + .bmAttributes = usb_config->attrs.bmAttributs, + .bMaxPower = usb_config->attrs.MaxPower/2, + }; + + if (!usb_config->funcs || !usb_config->funcs[0]) + return -EINVAL; + + ret = usbg_create_config(cfs_client->gadget, config_id, CONFIGFS_CONFIG_LABEL, &cattrs, NULL, &config); + if (ret) + return ret; + + if (usb_config->strs.config_str) { + ret = usbg_set_config_string(config, usb_config->strs.lang_code, usb_config->strs.config_str); + if (ret) + return ret; + } + + for (i = 0; usb_config->funcs[i]; ++i) { + usb_func = usb_config->funcs[i]; + + /* name("sdb") + NAME_INSTANCE_SEP(".") + instance("default") + '\0' */ + if (strlen(usb_func->name) + strlen(usb_func->instance) + 2 > sizeof(instance)) + return -ENAMETOOLONG; + + /* In functionfs, the instance is used in the format "[sdb|mtp].default" instead of "default" */ + if (usb_func->is_functionfs) { + function_type = USBG_F_FFS; + snprintf(instance, sizeof(instance), "%s%c%s", usb_func->name, NAME_INSTANCE_SEP, usb_func->instance); + } else { + function_type = usbg_lookup_function_type(usb_func->name); + strncpy(instance, usb_func->instance, sizeof(instance) - 1); + instance[sizeof(instance) - 1] = '\0'; + } + + function = usbg_get_function(cfs_client->gadget, function_type, instance); + if (!function) { + ret = usbg_create_function(cfs_client->gadget, function_type, instance, NULL, &function); + if (ret) + return ret; + + /* Setting rndis mac address. This should be done at this point, + * since the node host_addr changes to read only after the function + * is added to config. */ + if (usbg_get_function_type(function) == USBG_F_RNDIS) + (void)cfs_set_rndis_mac_addr(cfs_client->gadget, function); /* A random value is used if fails */ + + if (usbg_get_function_type(function) == USBG_F_FFS) { + ret = cfs_prep_ffs_service(usb_func, function); + if (ret) + return ret; + } + } + + ret = usbg_add_config_function(config, NULL, function); + if (ret) + return ret; + } + + return 0; +} + +static void cfs_start_stop_service_and_handler(usbg_gadget *gadget, enum cfs_function_service_operation operation) +{ + usbg_function *function; + struct usb_function *usb_function; + + usbg_for_each_function(function, gadget) { + usb_function = cfs_find_usb_function(function); + if (!usb_function) + continue; + + switch(operation) { + case CFS_FUNCTION_SERVICE_START: + if (usb_function->handler) + usb_function->handler(1); + + /* functionfs service is automatically started by socket activation */ + if (!usb_function->is_functionfs && usb_function->service) + (void)systemd_start_unit_wait_started(usb_function->service, ".service", -1); + break; + + case CFS_FUNCTION_SERVICE_STOP: + if (!usb_function->is_functionfs && usb_function->service && !usb_function->remain_after_disable) + (void)systemd_stop_unit_wait_stopped(usb_function->service, ".service", -1); + + if (usb_function->handler) + usb_function->handler(0); + break; + + case CFS_FUNCTION_SERVICE_POST_STOP: + if (usb_function->is_functionfs && usb_function->service && !usb_function->remain_after_disable) + (void)systemd_stop_unit_wait_stopped(usb_function->service, ".service", -1); + break; + + default: + break; + } + } +} + +static int usb_gadget_cfs_enable(void) +{ + int ret; + + if (!g_cfs_client) + return -EINVAL; + + ret = usbg_enable_gadget(g_cfs_client->gadget, g_cfs_client->udc); + if (ret) + return ret; + + cfs_start_stop_service_and_handler(g_cfs_client->gadget, CFS_FUNCTION_SERVICE_START); + + return 0; +} + +static int usb_gadget_cfs_disable(void) +{ + int ret; + + if (!g_cfs_client) + return -EINVAL; + + cfs_start_stop_service_and_handler(g_cfs_client->gadget, CFS_FUNCTION_SERVICE_STOP); + + ret = usbg_disable_gadget(g_cfs_client->gadget); /* ignore error checking */ + + /* + * Since functionfs service works with socket activation, you must stop it after disabling gadget. + * If usb data may come in after stopping functionfs service and before disabling gadget, + * functionfs service wakes up again by socket activation. + */ + cfs_start_stop_service_and_handler(g_cfs_client->gadget, CFS_FUNCTION_SERVICE_POST_STOP); + + return ret; +} + +static int usb_gadget_cfs_reconfigure_gadget(struct usb_gadget *gadget) +{ + int i; + int ret; + + if (!g_cfs_client || !gadget) + return -EINVAL; + + /* Verify the gadget and check if function is supported */ + if (!cfs_is_gadget_supported(gadget)) + return -ENOTSUP; + + ret = cfs_set_gadget_attrs(g_cfs_client, &gadget->attrs); + if (ret) + return ret; + + ret = cfs_set_gadget_strs(g_cfs_client, &gadget->strs); + if (ret) + return ret; + + ret = cfs_cleanup_all_config_and_function(g_cfs_client); + if (ret) + return ret; + + for (i = 0; gadget->configs[i]; ++i) { + ret = cfs_set_gadget_config(g_cfs_client, i + 1, gadget->configs[i]); + if (ret) + return ret; + } + + return 0; +} + +static int usb_gadget_cfs_open(void) +{ + int ret; + + g_cfs_client = calloc(1, sizeof(*g_cfs_client)); + if (!g_cfs_client) + return -ENOMEM; + + ret = usbg_init(CONFIGFS_PATH, &g_cfs_client->ctx); + if (ret) + goto err_usbg_init; + + g_cfs_client->udc = usbg_get_first_udc(g_cfs_client->ctx); + if (!g_cfs_client->udc) { + ret = -ENODEV; + goto err_no_udc; + } + + ret = usbg_create_gadget(g_cfs_client->ctx, CONFIGFS_GADGET_NAME, + &default_g_attrs, &default_g_strs, &g_cfs_client->gadget); + if (ret) + goto err_create_gadget; + + return 0; + +err_create_gadget: +err_no_udc: + usbg_cleanup(g_cfs_client->ctx); +err_usbg_init: + free(g_cfs_client); + + return ret; +} + +static int usb_gadget_cfs_close(void) +{ + usbg_function *function; + struct usb_function *usb_func; + + if (!g_cfs_client) + return -EINVAL; + + usbg_for_each_function(function, g_cfs_client->gadget) { + usb_func = cfs_find_usb_function(function); + if (!usb_func) + continue; + + if (usb_func->is_functionfs && usb_func->service) { + (void)systemd_stop_unit_wait_stopped(usb_func->service, ".socket", -1); + (void)systemd_stop_unit_wait_stopped(usb_func->service, ".service", -1); + } + } + + /* + * For now we don't check for errors + * but we should somehow handle them + */ + usbg_rm_gadget(g_cfs_client->gadget, USBG_RM_RECURSE); + usbg_cleanup(g_cfs_client->ctx); + free(g_cfs_client); + + return 0; +} + +int usb_gadget_cfs_supported(void) +{ + FILE *fp; + char *line = NULL; + size_t len = 0; + int configfs = 0; + + fp = fopen("/proc/filesystems", "r"); + if (!fp) + return 0; + + while (getline(&line, &len, fp) != -1) { + if (strstr(line, "configfs")) + configfs = 1; + } + + fclose(fp); + free(line); + + if (configfs) + CRITICAL_LOG("Usb-gadget is supported via configfs."); + + return configfs; +} + +void usb_gadget_bind_cfs_gadget(int (**open) (void), int (**close) (void), int (**enable) (void), + int (**disable) (void), int (**reconfigure) (struct usb_gadget *)) +{ + *open = usb_gadget_cfs_open; + *close = usb_gadget_cfs_close; + *enable = usb_gadget_cfs_enable; + *disable = usb_gadget_cfs_disable; + *reconfigure = usb_gadget_cfs_reconfigure_gadget; +} diff --git a/src/usb/usb-gadget-legacy-gadget.c b/src/usb/usb-gadget-legacy-gadget.c new file mode 100644 index 0000000..aa1f6b1 --- /dev/null +++ b/src/usb/usb-gadget-legacy-gadget.c @@ -0,0 +1,358 @@ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include "usb-gadget.h" + +#define MAX_GADGET_STR_LEN 256 + +#define LEGACY_ROOTPATH "/sys/class/usb_mode/usb0" + +/* Device descriptor values */ +#define LEGACY_ID_VENDOR_PATH LEGACY_ROOTPATH"/idVendor" +#define LEGACY_ID_PRODUCT_PATH LEGACY_ROOTPATH"/idProduct" +#define LEGACY_BCD_DEVICE_PATH LEGACY_ROOTPATH"/bcdDevice" +#define LEGACY_CLASS_PATH LEGACY_ROOTPATH"/bDeviceClass" +#define LEGACY_SUBCLASS_PATH LEGACY_ROOTPATH"/bDeviceSubClass" +#define LEGACY_PROTOCOL_PATH LEGACY_ROOTPATH"/bDeviceProtocol" + +/* Strings */ +#define LEGACY_IMANUFACTURER_PATH LEGACY_ROOTPATH"/iManufacturer" +#define LEGACY_IPRODUCT_PATH LEGACY_ROOTPATH"/iProduct" + +/* Functions in each config */ +#define LEGACY_CONFIG_1_PATH LEGACY_ROOTPATH"/funcs_fconf" +#define LEGACY_CONFIG_2_PATH LEGACY_ROOTPATH"/funcs_sconf" + +/* should be single char */ +#define LEGACY_FUNC_SEP "," + +/* ON/OFF switch */ +#define LEGACY_ENABLE_PATH LEGACY_ROOTPATH"/enable" +#define LEGACY_ENABLE "1" +#define LEGACY_DISABLE "0" + +static bool legacy_is_function_supported(struct usb_function *func) +{ + char buf[PATH_MAX]; + + snprintf (buf, sizeof(buf), "%s/f_%s", LEGACY_ROOTPATH, func->name); + if (access(buf, F_OK)) + return false; + + return true; +} + +static bool legacy_is_gadget_supported(struct usb_gadget *gadget) +{ + int i, j; + struct usb_configuration *config; + + if (!gadget || !gadget->configs || !gadget->configs[0] || !gadget->configs[0]->funcs[0]) + return false; + + if (!gadget->attrs.idVendor || !gadget->attrs.idProduct || !gadget->attrs.bcdDevice) + return false; + + /* only strings in US_en are allowed */ + if (gadget->strs.lang_code != DEFAULT_LANG) + return false; + + if (!gadget->strs.manufacturer || !gadget->strs.product) + return false; + + for (j = 0; gadget->configs[j]; ++j) { + config = gadget->configs[j]; + + if (!config->funcs) + return false; + + for (i = 0; config->funcs[i]; ++i) + if (!legacy_is_function_supported(config->funcs[i])) + return false; + } + + return true; +} + +/* TODO. Maybe move this to sys ? */ +static int legacy_set_int_hex(char *path, int val) +{ + int r; + char buf[MAX_GADGET_STR_LEN]; + + if (!path) + return -EINVAL; + + snprintf(buf, sizeof(buf), "%x", val); + r = sys_set_str(path, buf); + if (r < 0) + return r; + + return 0; +} + +static int legacy_set_gadget_attrs(struct usb_gadget_attrs *attrs) +{ + int ret; + + ret = sys_set_int(LEGACY_CLASS_PATH, attrs->bDeviceClass); + if (ret) + return ret; + + ret = sys_set_int(LEGACY_SUBCLASS_PATH, attrs->bDeviceSubClass); + if (ret) + return ret; + + ret = sys_set_int(LEGACY_PROTOCOL_PATH, attrs->bDeviceProtocol); + if (ret) + return ret; + + ret = legacy_set_int_hex(LEGACY_ID_VENDOR_PATH, attrs->idVendor); + if (ret) + return ret; + + ret = legacy_set_int_hex(LEGACY_ID_PRODUCT_PATH, attrs->idProduct); + if (ret) + return ret; + + ret = legacy_set_int_hex(LEGACY_BCD_DEVICE_PATH, attrs->bcdDevice); + if (ret) + return ret; + + return 0; +} + +static int legacy_set_gadget_strs(struct usb_gadget_strings *strs) +{ + int ret; + + if (!strs->manufacturer || !strs->product) + return -EINVAL; + + ret = sys_set_str(LEGACY_IMANUFACTURER_PATH, strs->manufacturer); + if (ret) + return ret; + + ret = sys_set_str(LEGACY_IPRODUCT_PATH, strs->product); + if (ret) + return ret; + + /* The serial is written by the slp gadget kernel driver */ + + return 0; +} + +static int legacy_set_gadget_config(char *cpath, + struct usb_configuration *config) +{ + char buf[MAX_GADGET_STR_LEN]; + int left = sizeof(buf); + char *pos = buf; + int ret; + int i; + + if (!config) { + buf[0] = '\n'; + buf[1] = '\0'; + goto empty_config; + } + + for (i = 0; config->funcs[i]; ++i) { + ret = snprintf(pos, left, "%s" LEGACY_FUNC_SEP, + config->funcs[i]->name); + if (ret >= left) + return -EOVERFLOW; + + pos += ret; + left -= ret; + } + + /* eliminate last separator */ + *(pos - 1) = '\0'; + +empty_config: + return sys_set_str(cpath, buf); +} + +static void legacy_start_stop_service_and_handler(bool start) +{ + int i; + int ret; + int n_func = 0; + char *ptr; + char *begin; + char *fname; + char *sep = LEGACY_FUNC_SEP; + char buf[MAX_GADGET_STR_LEN]; + struct usb_function *func; + struct usb_function *funcs[USB_FUNCTION_IDX_MAX]; + + /* SLP gadget uses two USB configuration. + * (/sys/class/usb_mode/usb0/funcs_fconf and /sys/class/usb_mode/usb0/funcs_sconf) + * + * One usb function can be included in two configurations simultaneously. + * In this situation, a handler associated with function can be called twice for a usb function. + * To prevent duplicate calls, + * Collect all functions and remove duplicates and process them. + */ + + /* First configuration */ + ret = sys_get_str(LEGACY_CONFIG_1_PATH, buf, sizeof(buf)); + if (ret) + goto second_configuration; + + /* Caution: buf ends with '\n' */ + ptr = strchr(buf, '\n'); + if (ptr) + *ptr = 0; + + begin = buf; + for (fname = strsep(&begin, sep); fname; fname = strsep(&begin, sep)) { + func = find_usb_function_by_name(fname); + if (!func) + continue; + + for (i = 0; i < n_func; i++) + if (funcs[i] == func) + continue; + + if(n_func >= USB_FUNCTION_IDX_MAX) /* What happen */ + break; + + funcs[n_func] = func; + n_func++; + } + + /* Second configuration */ +second_configuration: + ret = sys_get_str(LEGACY_CONFIG_2_PATH, buf, sizeof(buf)); + if (ret) + return; + + /* Caution: buf ends with '\n' */ + ptr = strchr(buf, '\n'); + if (ptr) + *ptr = 0; + + begin = buf; + for (fname = strsep(&begin, sep); fname; fname = strsep(&begin, sep)) { + func = find_usb_function_by_name(fname); + if (!func) + continue; + + for (i = 0; i < n_func; i++) + if (funcs[i] == func) + continue; + + if(n_func >= USB_FUNCTION_IDX_MAX) /* What happen */ + break; + + funcs[n_func] = func; + n_func++; + } + + for (i = 0; i < n_func; i++) { + if (start) { + if (funcs[i]->handler) + funcs[i]->handler(1); + + if (funcs[i]->service) + (void)systemd_start_unit_wait_started(funcs[i]->service, ".service", -1); + } else { + if (funcs[i]->service && !funcs[i]->remain_after_disable) + (void)systemd_stop_unit_wait_stopped(funcs[i]->service, ".service", -1); + + if (funcs[i]->handler) + funcs[i]->handler(0); + } + } +} + +static int usb_gadget_legacy_enable(void) +{ + int ret; + + ret = sys_set_str(LEGACY_ENABLE_PATH, LEGACY_ENABLE); + if (ret < 0) + return ret; + + legacy_start_stop_service_and_handler(true); + + return 0; +} + +static int usb_gadget_legacy_disable(void) +{ + legacy_start_stop_service_and_handler(false); + + return sys_set_str(LEGACY_ENABLE_PATH, LEGACY_DISABLE); +} + +static int usb_gadget_legacy_reconfigure_gadget(struct usb_gadget *gadget) +{ + int ret; + + if (!gadget) + return -EINVAL; + + /* Verify the gadget and check if function is supported */ + if (!legacy_is_gadget_supported(gadget)) + return -ENOTSUP; + + ret = legacy_set_gadget_attrs(&gadget->attrs); + if (ret) + return ret; + + ret = legacy_set_gadget_strs(&gadget->strs); + if (ret) + return ret; + + ret = legacy_set_gadget_config(LEGACY_CONFIG_1_PATH, gadget->configs[0]); + if (ret) + return ret; + + ret = legacy_set_gadget_config(LEGACY_CONFIG_2_PATH, gadget->configs[1]); + if (ret) + return ret; + + return 0; +} + +static int usb_gadget_legacy_open(void) +{ + return 0; +} + +static int usb_gadget_legacy_close(void) +{ + return 0; +} + +int usb_gadget_legacy_supported(void) +{ + int ret; + + ret = (access("/sys/class/usb_mode/usb0/enable", F_OK) == 0); + if (ret) + CRITICAL_LOG("Usb-gadget is supported via legacy samsung gadget."); + + return ret; +} + +void usb_gadget_bind_legacy_gadget(int (**open) (void), int (**close) (void), int (**enable) (void), + int (**disable) (void), int (**reconfigure) (struct usb_gadget *)) +{ + *open = usb_gadget_legacy_open; + *close = usb_gadget_legacy_close; + *enable = usb_gadget_legacy_enable; + *disable = usb_gadget_legacy_disable; + *reconfigure = usb_gadget_legacy_reconfigure_gadget; +} diff --git a/src/usb/usb-gadget.c b/src/usb/usb-gadget.c new file mode 100644 index 0000000..efa1da8 --- /dev/null +++ b/src/usb/usb-gadget.c @@ -0,0 +1,465 @@ +#include +#include + +#include +#include +#include + +#include + +#include "usb-gadget.h" + +static int (*__usb_gadget_open) (void); +static int (*__usb_gadget_close) (void); +static int (*__usb_gadget_enable) (void); +static int (*__usb_gadget_disable) (void); +static int (*__usb_gadget_reconfigure) (struct usb_gadget *gadget); + +/* temporary extern access */ +struct _usb_mode_mapping_table { + int mode_v; /* Integer defined by vconf */ + unsigned int mode; /* Bitmap of usb function combination */ + struct usb_gadget_attrs attrs; +}; +extern GList *usb_mode_mapping_table_custom; + +static void rndis_handler(int enable) +{ + if (enable) + (void)systemd_start_unit_wait_started("rndis.service", NULL, -1); + else + (void)systemd_stop_unit_wait_stopped("rndis.service", NULL, -1); +} + +#define DEFINE_USB_FUNCTION(_id, _name, _is_functionfs, _service, _handler) \ + static struct usb_function _##_name##_function = { \ + .id = _id, \ + .name = #_name, \ + .instance = "default", \ + .is_functionfs = _is_functionfs, \ + .service = _service, \ + .remain_after_disable = 0, \ + .handler = _handler, \ + } + +DEFINE_USB_FUNCTION(USB_FUNCTION_MTP, mtp, 1, "mtp-responder", NULL); +DEFINE_USB_FUNCTION(USB_FUNCTION_ACM, acm, 0, "data-router", NULL); +DEFINE_USB_FUNCTION(USB_FUNCTION_SDB, sdb, 1, "sdbd", NULL); +DEFINE_USB_FUNCTION(USB_FUNCTION_RNDIS, rndis, 0, "sshd", rndis_handler); +DEFINE_USB_FUNCTION(USB_FUNCTION_DIAG, diag, 1, "diag", NULL); +DEFINE_USB_FUNCTION(USB_FUNCTION_CONN_GADGET, conn_gadget, 0, NULL, NULL); +DEFINE_USB_FUNCTION(USB_FUNCTION_DM, dm, 0, NULL, NULL); +DEFINE_USB_FUNCTION(USB_FUNCTION_RMNET, rmnet, 0, NULL, NULL); + +#undef DEFINE_USB_FUNCTION + +/* Caution: index order of arrary is important, because simple_translator_open() uses it. */ +static struct usb_function *_available_funcs[] = { + [USB_FUNCTION_IDX_MTP] = &_mtp_function, + [USB_FUNCTION_IDX_ACM] = &_acm_function, + [USB_FUNCTION_IDX_SDB] = &_sdb_function, + [USB_FUNCTION_IDX_RNDIS] = &_rndis_function, + [USB_FUNCTION_IDX_DIAG] = &_diag_function, + [USB_FUNCTION_IDX_CONN_GADGET] = &_conn_gadget_function, + [USB_FUNCTION_IDX_DM] = &_dm_function, + [USB_FUNCTION_IDX_RMNET] = &_rmnet_function, + [USB_FUNCTION_IDX_MAX] = NULL /* An indicator to end the array */ +}; +static struct usb_function *find_usb_function_by_id(int id); + +struct usb_function *find_usb_function_by_name(const char *name) +{ + int i; + + if(!name || !name[0]) + return NULL; + + for (i = 0; _available_funcs[i]; i++) + if (!strcmp(name, _available_funcs[i]->name)) + return _available_funcs[i]; + + return NULL; +} + +struct usb_function *find_usb_function_by_name_instance(const char *name, const char *instance) +{ + int i; + + if(!name || !name[0] || !instance || !instance[0]) + return NULL; + + for (i = 0; _available_funcs[i]; ++i) + if (!strcmp(name, _available_funcs[i]->name) && !strcmp(instance, _available_funcs[i]->instance)) + return _available_funcs[i]; + + return NULL; +} + +static void simple_cleanup_config(struct usb_configuration *config) +{ + if (!config) + return; + + free(config->strs.config_str); + + if (config->funcs) + free(config->funcs); + + free(config); +} + +static void cleanup_gadget(struct usb_gadget *gadget) +{ + int i; + + if (!gadget) + return; + + free(gadget->strs.manufacturer); + free(gadget->strs.product); + free(gadget->strs.serial); + + if (gadget->configs) { + for (i = 0; gadget->configs[i]; ++i) + simple_cleanup_config(gadget->configs[i]); + + free(gadget->configs); + } + + free(gadget); +} + +static int alloc_default_config(struct usb_configuration **_config) +{ + struct usb_configuration *config; + + config = calloc(1, sizeof(*config)); + if (!config) + return -ENOMEM; + + config->attrs.bmAttributs = DEFAULT_BMATTRIBUTES; + config->attrs.MaxPower = DEFAULT_MAX_POWER; + + /* TODO. Here is where to set the string used in config of configfs */ + + *_config = config; + + return 0; +} + +static int alloc_default_gadget(char *serial, struct usb_gadget **_gadget) +{ + struct usb_gadget *gadget; + struct usb_configuration **configs; + + gadget = calloc(1, sizeof(*gadget)); + if (!gadget) + goto out; + + gadget->attrs.idVendor = DEFAULT_VID; + gadget->attrs.idProduct = DEFAULT_PID; + gadget->attrs.bcdDevice = DEFAULT_BCD_DEVICE; + + gadget->strs.lang_code = DEFAULT_LANG; + gadget->strs.manufacturer = strdup(DEFAULT_MANUFACTURER); + gadget->strs.product = strdup(DEFAULT_PRODUCT); + gadget->strs.serial = strdup(serial); + + if (!gadget->strs.manufacturer || !gadget->strs.product || !gadget->strs.serial) + goto free_strs; + + /* slp-gadget use max 2 confiuration and NULL termination */ + configs = calloc(3, sizeof(*configs)); + if (!configs) + goto free_strs; + + gadget->configs = configs; + *_gadget = gadget; + + return 0; + +free_strs: + free(gadget->strs.manufacturer); + free(gadget->strs.product); + free(gadget->strs.serial); + free(gadget); +out: + return -ENOMEM; +} + +static int id_to_gadget(struct usb_gadget_id *gadget_id, char *serial, struct usb_gadget **_gadget) +{ + int ret; + int i, j; + int n_configs; + struct usb_gadget *gadget; + int functions[2][sizeof(gadget_id->function_mask)*8]; /* zero terminates */ + + GList *elem; + const struct _usb_mode_mapping_table *cm = NULL; + + if (!gadget_id || !serial || !_gadget) + return -EINVAL; + + ret = alloc_default_gadget(serial, &gadget); + if (ret) + goto out; + + /* find custom mode */ + SYS_G_LIST_FOREACH(usb_mode_mapping_table_custom, elem, cm) { + if (cm->mode == gadget_id->function_mask) + break; + } + + if (cm) { + int i, j; + + j = 0; + n_configs = 1; + for (i = 0; i < USB_FUNCTION_IDX_MAX; ++i) { + if (cm->mode & (1 << i)) + functions[0][j++] = (1 << i); + } + functions[0][j] = 0; + + if (cm->attrs.idVendor) + gadget->attrs.idVendor = cm->attrs.idVendor; + if (cm->attrs.idProduct) + gadget->attrs.idProduct = cm->attrs.idProduct; + + } else { + /* + * Currently all gadgets use inly single configuration but + * slp-gadget is capable to handle two of them + * + * Order of interfaces in configuration is significant + * so in this switch we sort our functions in a correct order + */ + switch (gadget_id->function_mask) { + /* MTP, ACM, SDB */ + case USB_FUNCTION_MTP | USB_FUNCTION_ACM: + n_configs = 1; + functions[0][0] = USB_FUNCTION_MTP; + functions[0][1] = USB_FUNCTION_ACM; + functions[0][2] = 0; + gadget->attrs.idProduct = 0x6860; + break; + + case USB_FUNCTION_MTP | USB_FUNCTION_ACM | USB_FUNCTION_SDB: + n_configs = 1; + functions[0][0] = USB_FUNCTION_MTP; + functions[0][1] = USB_FUNCTION_ACM; + functions[0][2] = USB_FUNCTION_SDB; + functions[0][3] = 0; + gadget->attrs.idProduct = 0x6860; + break; + + /* DIAG */ + case USB_FUNCTION_MTP | USB_FUNCTION_ACM | USB_FUNCTION_SDB | USB_FUNCTION_DIAG: + n_configs = 1; + functions[0][0] = USB_FUNCTION_MTP; + functions[0][1] = USB_FUNCTION_ACM; + functions[0][2] = USB_FUNCTION_SDB; + functions[0][3] = USB_FUNCTION_DIAG; + functions[0][4] = 0; + gadget->attrs.idProduct = 0x6860; + break; + + /* RNDIS */ + case USB_FUNCTION_RNDIS: + n_configs = 1; + functions[0][0] = USB_FUNCTION_RNDIS; + functions[0][1] = 0; + gadget->attrs.idProduct = 0x6863; + break; + + case USB_FUNCTION_RNDIS | USB_FUNCTION_DIAG: + n_configs = 1; + functions[0][0] = USB_FUNCTION_RNDIS; + functions[0][1] = USB_FUNCTION_DIAG; + functions[0][2] = 0; + gadget->attrs.idProduct = 0x6864; + break; + + case USB_FUNCTION_ACM | USB_FUNCTION_SDB | USB_FUNCTION_RNDIS: + n_configs = 1; + functions[0][0] = USB_FUNCTION_RNDIS; + functions[0][1] = USB_FUNCTION_ACM; + functions[0][2] = USB_FUNCTION_SDB; + functions[0][3] = 0; + gadget->attrs.idProduct = 0x6864; + break; + + /* RMNET */ + case USB_FUNCTION_DIAG | USB_FUNCTION_RMNET: + n_configs = 1; + functions[0][0] = USB_FUNCTION_DIAG; + functions[0][1] = USB_FUNCTION_RMNET; + functions[0][2] = 0; + gadget->attrs.idProduct = 0x685d; + break; + + /* DM */ + case USB_FUNCTION_ACM | USB_FUNCTION_SDB | USB_FUNCTION_DM: + n_configs = 1; + functions[0][0] = USB_FUNCTION_ACM; + functions[0][1] = USB_FUNCTION_SDB; + functions[0][2] = USB_FUNCTION_DM; + functions[0][3] = 0; + gadget->attrs.idProduct = 0x6860; + break; + + default: + ret = -EINVAL; + goto free_gadget; + }; + } + + for (j = 0; j < n_configs; ++j) { + int n_funcs_in_config; + struct usb_configuration *config; + + for (i = 0; functions[j][i]; ++i); + n_funcs_in_config = i; + + ret = alloc_default_config(&config); + if (ret) + goto free_configs; + + gadget->configs[j] = config; + config->funcs = calloc(n_funcs_in_config + 1, sizeof(void *)); + if (!config->funcs) + goto free_configs; + + for (i = 0; functions[j][i]; ++i) { + config->funcs[i] = find_usb_function_by_id(functions[j][i]); + if (!config->funcs[i]) + goto free_configs; + } + } + + *_gadget = gadget; + + return 0; + +free_configs: +free_gadget: + cleanup_gadget(gadget); +out: + return ret; +} + + +static struct usb_function *find_usb_function_by_id(int id) +{ + int i; + + for (i = 0; _available_funcs[i]; i++) + if (_available_funcs[i]->id == id) + return _available_funcs[i]; + + return NULL; +} + + +int usb_gadget_enable(void) +{ + if (!__usb_gadget_enable) { + _E("Not supported usb_gadget_enable."); + return -ENOTSUP; + } + + return __usb_gadget_enable(); +} + +int usb_gadget_disable(void) +{ + if (!__usb_gadget_disable) { + _E("Not supported usb_gadget_disable."); + return -ENOTSUP; + } + + return __usb_gadget_disable(); +} + +int usb_gadget_change_mode(unsigned int mode) +{ + struct usb_gadget *gadget; + struct usb_gadget_id gadget_id = {0, }; + char serial[] = "123456"; + int ret; + + if (!__usb_gadget_reconfigure) { + _E("Not supported usb_gadget_reconfigure."); + return -ENOTSUP; + } + + gadget_id.function_mask = mode; + + ret = id_to_gadget(&gadget_id, serial, &gadget); + if (ret) { + _E("Failed to id_to_gadget, %d", ret); + return ret; + } + + ret = __usb_gadget_reconfigure(gadget); + cleanup_gadget(gadget); + if (ret) { + _E("Failed to reconfigure gadget, %d", ret); + return ret; + } + + return 0; +} + +int usb_gadget_init(void) +{ + if (usb_gadget_legacy_supported()) { + /* legacy samsung gadget */ + usb_gadget_bind_legacy_gadget(&__usb_gadget_open, + &__usb_gadget_close, + &__usb_gadget_enable, + &__usb_gadget_disable, + &__usb_gadget_reconfigure); + } else if (usb_gadget_cfs_supported()) { + /* configfs/functionfs gadget */ + usb_gadget_bind_cfs_gadget(&__usb_gadget_open, + &__usb_gadget_close, + &__usb_gadget_enable, + &__usb_gadget_disable, + &__usb_gadget_reconfigure); + } else { + CRITICAL_LOG("Usb-gadget is not supported."); + return -ENOTSUP; + } + + /* open supported usb-gadget */ + __usb_gadget_open(); + + /* Use mtp-responder-dummy.socket when there is no mtp-responser.socket. + * + * The mtp-responder.socket is special in the configfs environment. + * If mtp-responder.socket is missing, gadget configuration will fail. + * As a result, all usb operations do not work properly. + * So in environments that mtp doesn't support, use dummy mtp. + */ + if (access("/usr/lib/systemd/system/mtp-responder.socket", F_OK)) { + _available_funcs[USB_FUNCTION_IDX_MTP]->service = "mtp-responder-dummy"; + } + + return 0; +} + +int usb_gadget_exit(void) +{ + if (__usb_gadget_close) + __usb_gadget_close(); + + __usb_gadget_open = NULL; + __usb_gadget_close = NULL; + __usb_gadget_enable = NULL; + __usb_gadget_disable = NULL; + __usb_gadget_reconfigure = NULL; + + return 0; +} diff --git a/src/usb/usb-gadget.h b/src/usb/usb-gadget.h new file mode 100644 index 0000000..161be96 --- /dev/null +++ b/src/usb/usb-gadget.h @@ -0,0 +1,101 @@ +#ifndef __USB_GADGET_H__ +#define __USB_GADGET_H__ + +#include +#include + +/*The default USB configuration */ +#define DEFAULT_VID 0x04e8 +#define DEFAULT_PID 0x6860 +#define DEFAULT_BCD_DEVICE 0x0100 + +#define DEFAULT_LANG 0x409 /* US_en */ +#define DEFAULT_MANUFACTURER "Samsung" +#define DEFAULT_PRODUCT "TIZEN" +#define DEFAULT_SERIAL "01234TEST" + +#define DEFAULT_BMATTRIBUTES ((1 << 7) | (1 << 6)) +#define DEFAULT_MAX_POWER 500 + +struct usb_function { + int id; + const char *name; + const char *instance; + + int is_functionfs; + const char *service; + + /* do not stop the service on disabling usb-gadget function */ + int remain_after_disable; + + void (*handler)(int enable); +}; + +struct usb_configuration_attributes { + uint8_t bmAttributs; + int MaxPower; +}; + +struct usb_configuration_strings { + uint16_t lang_code; + char *config_str; +}; + +struct usb_configuration { + struct usb_configuration_attributes attrs; + struct usb_configuration_strings strs; + struct usb_function **funcs; +}; + +struct usb_gadget_attrs { + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; +}; + +struct usb_gadget_strings { + uint16_t lang_code; + char *manufacturer; + char *product; + char *serial; +}; + +struct usb_gadget { + struct usb_gadget_attrs attrs; + struct usb_gadget_strings strs; + struct usb_configuration **configs; +}; + +struct usb_gadget_id { + unsigned int function_mask; +}; + +struct usb_function *find_usb_function_by_name(const char *name); +struct usb_function *find_usb_function_by_name_instance(const char *name, const char *instance); + +int usb_gadget_enable(void); +int usb_gadget_disable(void); +int usb_gadget_change_mode(unsigned int mode); +int usb_gadget_init(void); +int usb_gadget_exit(void); + +/* legacy samsung gadget */ +int usb_gadget_legacy_supported(void); +void usb_gadget_bind_legacy_gadget(int (**open) (void), + int (**close) (void), + int (**enable) (void), + int (**disable) (void), + int (**reconfigure) (struct usb_gadget *)); + +/* configfs/functionfs gadget */ +int usb_gadget_cfs_supported(void); +void usb_gadget_bind_cfs_gadget(int (**open) (void), + int (**close) (void), + int (**enable) (void), + int (**disable) (void), + int (**reconfigure) (struct usb_gadget *)); + +#endif //__USB_GADGET_H__ diff --git a/src/usb/usb-state.c b/src/usb/usb-state.c index 51fa4cb..d05f9a3 100644 --- a/src/usb/usb-state.c +++ b/src/usb/usb-state.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include "core/log.h" @@ -30,6 +29,7 @@ #include "usb.h" #include "usb-debug.h" +#include "usb-gadget.h" #define PATH_USB_GADGET_CONF "/hal/etc/deviced/usb_gadget.conf" diff --git a/src/usb/usb-tethering.c b/src/usb/usb-tethering.c index e0ed34f..f0d7142 100644 --- a/src/usb/usb-tethering.c +++ b/src/usb/usb-tethering.c @@ -20,7 +20,6 @@ #include #include -#include #include "core/log.h" #include "shared/device-notifier.h" diff --git a/src/usb/usb.c b/src/usb/usb.c index 6792310..c71da85 100644 --- a/src/usb/usb.c +++ b/src/usb/usb.c @@ -19,8 +19,6 @@ #include #include -#include -#include #include "core/log.h" #include "core/udev.h" @@ -29,6 +27,7 @@ #include "shared/plugin.h" #include "usb.h" +#include "usb-gadget.h" #include "usb-debug.h" #include "usb-tethering.h" @@ -48,7 +47,7 @@ static int usb_change_gadget(unsigned mode) { int ret; - ret = hal_device_usb_gadget_change_mode(mode); + ret = usb_gadget_change_mode(mode); if (ret) { /* because usb does not work properly */ (void)usb_state_set_current_mode(USB_FUNCTION_NONE); @@ -65,7 +64,7 @@ static int usb_enable(unsigned int mode) { int ret; - ret = hal_device_usb_gadget_enable(); + ret = usb_gadget_enable(); if (ret < 0) { _E("Failed to enable USB config: %d", ret); goto out; @@ -91,7 +90,7 @@ static int usb_disable(void) (void)usb_state_set_current_mode(USB_FUNCTION_NONE); change_usb_state_notification_handler(USB_FUNCTION_NONE); - ret = hal_device_usb_gadget_disable(); + ret = usb_gadget_disable(); if (ret < 0) { _E("Failed to disable USB config: %d", ret); return ret; @@ -286,7 +285,7 @@ static void usb_init(void *data) usb_state_load_custom_mode(); usb_state_retrieve_selected_mode(); - ret = hal_device_usb_gadget_get_backend(); + ret = usb_gadget_init(); if (ret < 0) { _E("USB client cannot be used: %d", ret); return; @@ -319,8 +318,9 @@ static void usb_exit(void *data) change_usb_state_notification_handler(USB_FUNCTION_NONE); unregister_udev_uevent_control(&uh); - (void)hal_device_usb_gadget_disable(); - hal_device_usb_gadget_put_backend(); + usb_gadget_disable(); + usb_gadget_exit(); + } static struct extcon_ops extcon_usb_ops = { -- 2.7.4