mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-25 11:26:47 +01:00
Xiaomi: Refactor to install firmware (untested)
This commit is contained in:
parent
c47e830056
commit
29c183b88a
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.miband8;
|
package nodomain.freeyourgadget.gadgetbridge.devices.xiaomi;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@ -36,9 +36,12 @@ public class XiaomiFWHelper {
|
|||||||
private final Uri uri;
|
private final Uri uri;
|
||||||
private byte[] fw;
|
private byte[] fw;
|
||||||
private boolean valid;
|
private boolean valid;
|
||||||
|
private boolean typeFirmware;
|
||||||
|
private boolean typeWatchface;
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
private String name;
|
private String name;
|
||||||
|
private String version;
|
||||||
|
|
||||||
public XiaomiFWHelper(final Uri uri, final Context context) {
|
public XiaomiFWHelper(final Uri uri, final Context context) {
|
||||||
this.uri = uri;
|
this.uri = uri;
|
||||||
@ -65,15 +68,23 @@ public class XiaomiFWHelper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
valid = parseFirmware();
|
parseBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isWatchface() {
|
||||||
|
return typeWatchface;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFirmware() {
|
||||||
|
return typeFirmware;
|
||||||
|
}
|
||||||
|
|
||||||
public String getDetails() {
|
public String getDetails() {
|
||||||
return name != null ? name : "UNKNOWN WATCHFACE";
|
return name != null ? name : (version != null ? version : "UNKNOWN");
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getBytes() {
|
public byte[] getBytes() {
|
||||||
@ -88,11 +99,29 @@ public class XiaomiFWHelper {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
public void unsetFwBytes() {
|
public void unsetFwBytes() {
|
||||||
this.fw = null;
|
this.fw = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean parseFirmware() {
|
private void parseBytes() {
|
||||||
|
if (parseAsWatchface()) {
|
||||||
|
assert id != null;
|
||||||
|
valid = true;
|
||||||
|
typeWatchface = true;
|
||||||
|
} else if (parseAsFirmware()) {
|
||||||
|
assert version != null;
|
||||||
|
valid = true;
|
||||||
|
typeFirmware = true;
|
||||||
|
} else {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean parseAsWatchface() {
|
||||||
if (fw[0] != (byte) 0x5A || fw[1] != (byte) 0xA5) {
|
if (fw[0] != (byte) 0x5A || fw[1] != (byte) 0xA5) {
|
||||||
LOG.warn("File header not a watchface");
|
LOG.warn("File header not a watchface");
|
||||||
return false;
|
return false;
|
||||||
@ -120,4 +149,9 @@ public class XiaomiFWHelper {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean parseAsFirmware() {
|
||||||
|
// TODO parse and set version
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
@ -22,7 +22,6 @@ import android.net.Uri;
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.InstallActivity;
|
import nodomain.freeyourgadget.gadgetbridge.activities.InstallActivity;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.miband8.XiaomiFWHelper;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
import nodomain.freeyourgadget.gadgetbridge.model.GenericItem;
|
||||||
|
|
||||||
@ -63,8 +62,17 @@ public class XiaomiInstallHandler implements InstallHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final GenericItem installItem = new GenericItem();
|
final GenericItem installItem = new GenericItem();
|
||||||
|
if (helper.isWatchface()) {
|
||||||
installItem.setIcon(R.drawable.ic_watchface);
|
installItem.setIcon(R.drawable.ic_watchface);
|
||||||
installItem.setName(mContext.getString(R.string.kind_watchface));
|
installItem.setName(mContext.getString(R.string.kind_watchface));
|
||||||
|
} else if (helper.isFirmware()) {
|
||||||
|
installItem.setIcon(R.drawable.ic_firmware);
|
||||||
|
installItem.setName(mContext.getString(R.string.kind_firmware));
|
||||||
|
} else {
|
||||||
|
installItem.setIcon(R.drawable.ic_device_unknown);
|
||||||
|
installItem.setName(mContext.getString(R.string.kind_invalid));
|
||||||
|
}
|
||||||
|
|
||||||
installItem.setDetails(helper.getDetails());
|
installItem.setDetails(helper.getDetails());
|
||||||
|
|
||||||
installActivity.setInfoText(mContext.getString(R.string.firmware_install_warning, "(unknown)"));
|
installActivity.setInfoText(mContext.getString(R.string.firmware_install_warning, "(unknown)"));
|
||||||
|
@ -27,7 +27,6 @@ import android.net.Uri;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -35,6 +34,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.XiaomiCoordinator;
|
import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.XiaomiCoordinator;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.XiaomiFWHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
import nodomain.freeyourgadget.gadgetbridge.model.Alarm;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
import nodomain.freeyourgadget.gadgetbridge.model.CalendarEventSpec;
|
||||||
@ -319,8 +319,20 @@ public abstract class XiaomiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInstallApp(final Uri uri) {
|
public void onInstallApp(final Uri uri) {
|
||||||
// TODO distinguish between fw and watchface
|
final XiaomiFWHelper fwHelper = new XiaomiFWHelper(uri, getContext());
|
||||||
watchfaceService.installWatchface(uri);
|
|
||||||
|
if (!fwHelper.isValid()) {
|
||||||
|
LOG.warn("Uri {} is not valid", uri);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwHelper.isFirmware()) {
|
||||||
|
systemService.installFirmware(fwHelper);
|
||||||
|
} else if (fwHelper.isWatchface()) {
|
||||||
|
watchfaceService.installWatchface(fwHelper);
|
||||||
|
} else {
|
||||||
|
LOG.warn("Unknown fwhelper for {}", uri);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -30,6 +30,7 @@ import java.util.Map;
|
|||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
import nodomain.freeyourgadget.gadgetbridge.activities.devicesettings.DeviceSettingsPreferenceConst;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.capabilities.password.PasswordCapabilityImpl;
|
import nodomain.freeyourgadget.gadgetbridge.capabilities.password.PasswordCapabilityImpl;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventBatteryInfo;
|
||||||
@ -38,15 +39,21 @@ import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdateDevi
|
|||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePreferences;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventUpdatePreferences;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventVersionInfo;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
import nodomain.freeyourgadget.gadgetbridge.devices.huami.HuamiConst;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.XiaomiFWHelper;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
|
import nodomain.freeyourgadget.gadgetbridge.model.BatteryState;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto;
|
import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.TransactionBuilder;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.SetProgressAction;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiPreferences;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiPreferences;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiSupport;
|
import nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.XiaomiSupport;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.CheckSums;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
import nodomain.freeyourgadget.gadgetbridge.util.StringUtils;
|
||||||
|
|
||||||
public class XiaomiSystemService extends AbstractXiaomiService {
|
public class XiaomiSystemService extends AbstractXiaomiService implements XiaomiDataUploadService.Callback {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(XiaomiSystemService.class);
|
private static final Logger LOG = LoggerFactory.getLogger(XiaomiSystemService.class);
|
||||||
|
|
||||||
public static final int COMMAND_TYPE = 2;
|
public static final int COMMAND_TYPE = 2;
|
||||||
@ -54,6 +61,7 @@ public class XiaomiSystemService extends AbstractXiaomiService {
|
|||||||
public static final int CMD_BATTERY = 1;
|
public static final int CMD_BATTERY = 1;
|
||||||
public static final int CMD_DEVICE_INFO = 2;
|
public static final int CMD_DEVICE_INFO = 2;
|
||||||
public static final int CMD_CLOCK = 3;
|
public static final int CMD_CLOCK = 3;
|
||||||
|
public static final int CMD_FIRMWARE_INSTALL = 5;
|
||||||
public static final int CMD_LANGUAGE = 6;
|
public static final int CMD_LANGUAGE = 6;
|
||||||
public static final int CMD_PASSWORD_GET = 9;
|
public static final int CMD_PASSWORD_GET = 9;
|
||||||
public static final int CMD_FIND_PHONE = 17;
|
public static final int CMD_FIND_PHONE = 17;
|
||||||
@ -63,6 +71,9 @@ public class XiaomiSystemService extends AbstractXiaomiService {
|
|||||||
public static final int CMD_DISPLAY_ITEMS_SET = 30;
|
public static final int CMD_DISPLAY_ITEMS_SET = 30;
|
||||||
public static final int CMD_CHARGER = 79;
|
public static final int CMD_CHARGER = 79;
|
||||||
|
|
||||||
|
// Not null if we're installing a firmware
|
||||||
|
private XiaomiFWHelper fwHelper = null;
|
||||||
|
|
||||||
public XiaomiSystemService(final XiaomiSupport support) {
|
public XiaomiSystemService(final XiaomiSupport support) {
|
||||||
super(support);
|
super(support);
|
||||||
}
|
}
|
||||||
@ -86,6 +97,18 @@ public class XiaomiSystemService extends AbstractXiaomiService {
|
|||||||
case CMD_BATTERY:
|
case CMD_BATTERY:
|
||||||
handleBattery(cmd.getSystem().getPower().getBattery());
|
handleBattery(cmd.getSystem().getPower().getBattery());
|
||||||
return;
|
return;
|
||||||
|
case CMD_FIRMWARE_INSTALL:
|
||||||
|
final int installStatus = cmd.getSystem().getFirmwareInstallResponse().getStatus();
|
||||||
|
if (installStatus != 0) {
|
||||||
|
LOG.warn("Invalid firmware install status {} for {}", installStatus, fwHelper.getId());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG.debug("Firmware install status 0, uploading");
|
||||||
|
setDeviceBusy();
|
||||||
|
getSupport().getDataUploader().setCallback(this);
|
||||||
|
getSupport().getDataUploader().requestUpload(XiaomiDataUploadService.TYPE_FIRMWARE, fwHelper.getBytes());
|
||||||
|
return;
|
||||||
case CMD_PASSWORD_GET:
|
case CMD_PASSWORD_GET:
|
||||||
handlePassword(cmd.getSystem().getPassword());
|
handlePassword(cmd.getSystem().getPassword());
|
||||||
return;
|
return;
|
||||||
@ -400,6 +423,82 @@ public class XiaomiSystemService extends AbstractXiaomiService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void installFirmware(final XiaomiFWHelper fwHelper) {
|
||||||
|
assert fwHelper.isValid();
|
||||||
|
assert fwHelper.isFirmware();
|
||||||
|
|
||||||
|
this.fwHelper = fwHelper;
|
||||||
|
|
||||||
|
getSupport().sendCommand(
|
||||||
|
"install firmware " + fwHelper.getVersion(),
|
||||||
|
XiaomiProto.Command.newBuilder()
|
||||||
|
.setType(COMMAND_TYPE)
|
||||||
|
.setSubtype(CMD_FIRMWARE_INSTALL)
|
||||||
|
.setSystem(XiaomiProto.System.newBuilder().setFirmwareInstallRequest(
|
||||||
|
XiaomiProto.FirmwareInstallRequest.newBuilder()
|
||||||
|
.setUnknown1(0)
|
||||||
|
.setUnknown2(0)
|
||||||
|
.setVersion(fwHelper.getVersion())
|
||||||
|
.setMd5(GB.hexdump(CheckSums.md5(fwHelper.getBytes())).toLowerCase(Locale.ROOT))
|
||||||
|
))
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDeviceBusy() {
|
||||||
|
final GBDevice device = getSupport().getDevice();
|
||||||
|
device.setBusyTask(getSupport().getContext().getString(R.string.updating_firmware));
|
||||||
|
device.sendDeviceUpdateIntent(getSupport().getContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unsetDeviceBusy() {
|
||||||
|
final GBDevice device = getSupport().getDevice();
|
||||||
|
if (device != null && device.isConnected()) {
|
||||||
|
if (device.isBusy()) {
|
||||||
|
device.unsetBusyTask();
|
||||||
|
device.sendDeviceUpdateIntent(getSupport().getContext());
|
||||||
|
}
|
||||||
|
device.sendDeviceUpdateIntent(getSupport().getContext());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUploadFinish(final boolean success) {
|
||||||
|
LOG.debug("Firmware upload finished: {}", success);
|
||||||
|
|
||||||
|
getSupport().getDataUploader().setCallback(null);
|
||||||
|
|
||||||
|
final String notificationMessage = success ?
|
||||||
|
getSupport().getContext().getString(R.string.updatefirmwareoperation_update_complete) :
|
||||||
|
getSupport().getContext().getString(R.string.updatefirmwareoperation_write_failed);
|
||||||
|
|
||||||
|
GB.updateInstallNotification(notificationMessage, false, 100, getSupport().getContext());
|
||||||
|
|
||||||
|
unsetDeviceBusy();
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
// TODO do we need to reboot?
|
||||||
|
}
|
||||||
|
|
||||||
|
fwHelper = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUploadProgress(final int progressPercent) {
|
||||||
|
try {
|
||||||
|
final TransactionBuilder builder = getSupport().createTransactionBuilder("send data upload progress");
|
||||||
|
builder.add(new SetProgressAction(
|
||||||
|
getSupport().getContext().getString(R.string.updatefirmwareoperation_update_in_progress),
|
||||||
|
true,
|
||||||
|
progressPercent,
|
||||||
|
getSupport().getContext()
|
||||||
|
));
|
||||||
|
builder.queue(getSupport().getQueue());
|
||||||
|
} catch (final Exception e) {
|
||||||
|
LOG.error("Failed to update progress notification", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final Map<String, String> DISPLAY_ITEM_NAMES = new HashMap<String, String>() {{
|
private static final Map<String, String> DISPLAY_ITEM_NAMES = new HashMap<String, String>() {{
|
||||||
put("today_act", "Stats");
|
put("today_act", "Stats");
|
||||||
put("sport", "Workout");
|
put("sport", "Workout");
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||||
package nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services;
|
package nodomain.freeyourgadget.gadgetbridge.service.devices.xiaomi.services;
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -29,7 +27,7 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventAppInfo;
|
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventAppInfo;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.miband8.XiaomiFWHelper;
|
import nodomain.freeyourgadget.gadgetbridge.devices.xiaomi.XiaomiFWHelper;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
|
import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp;
|
||||||
import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto;
|
import nodomain.freeyourgadget.gadgetbridge.proto.xiaomi.XiaomiProto;
|
||||||
@ -190,13 +188,11 @@ public class XiaomiWatchfaceService extends AbstractXiaomiService implements Xia
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void installWatchface(final Uri uri) {
|
public void installWatchface(final XiaomiFWHelper fwHelper) {
|
||||||
fwHelper = new XiaomiFWHelper(uri, getSupport().getContext());
|
assert fwHelper.isValid();
|
||||||
if (!fwHelper.isValid()) {
|
assert fwHelper.isWatchface();
|
||||||
fwHelper = null;
|
|
||||||
LOG.warn("watchface is not valid");
|
this.fwHelper = fwHelper;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
getSupport().sendCommand(
|
getSupport().sendCommand(
|
||||||
"install watchface " + fwHelper.getId(),
|
"install watchface " + fwHelper.getId(),
|
||||||
|
@ -88,6 +88,10 @@ message System {
|
|||||||
// 2, 34
|
// 2, 34
|
||||||
optional DoNotDisturb dndStatus = 11;
|
optional DoNotDisturb dndStatus = 11;
|
||||||
|
|
||||||
|
// 2, 5
|
||||||
|
optional FirmwareInstallRequest firmwareInstallRequest = 16;
|
||||||
|
optional FirmwareInstallResponse firmwareInstallResponse = 17;
|
||||||
|
|
||||||
// 2, 9 get | 2, 21 set
|
// 2, 9 get | 2, 21 set
|
||||||
optional Password password = 19;
|
optional Password password = 19;
|
||||||
|
|
||||||
@ -236,6 +240,17 @@ message DoNotDisturb2 {
|
|||||||
message DndSync {
|
message DndSync {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message FirmwareInstallRequest {
|
||||||
|
optional uint32 unknown1 = 1; // 0
|
||||||
|
optional uint32 unknown2 = 2; // 0
|
||||||
|
optional string version = 3;
|
||||||
|
optional string md5 = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message FirmwareInstallResponse {
|
||||||
|
optional uint32 status = 1; // 0
|
||||||
|
}
|
||||||
|
|
||||||
message Password {
|
message Password {
|
||||||
optional uint32 state = 1; // 1 disabled, 2 enabled
|
optional uint32 state = 1; // 1 disabled, 2 enabled
|
||||||
optional string password = 2;
|
optional string password = 2;
|
||||||
|
Loading…
Reference in New Issue
Block a user