/* Copyright (C) 2019-2024 Andreas Shimokawa, Arjan Schrijver, Daniel Dakhno, hackoder This file is part of Gadgetbridge. Gadgetbridge is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Gadgetbridge is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.notification; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.Charset; import java.util.Arrays; import java.util.zip.CRC32; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.file.FilePutRequest; import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; public abstract class PlayNotificationRequest extends FilePutRequest { public PlayNotificationRequest(NotificationType notificationType, int flags, String packageName, FossilWatchAdapter adapter) { super(FileHandle.NOTIFICATION_PLAY, createFile(notificationType, flags, packageName, packageName, packageName, getCurrentMessageId()), adapter); } public PlayNotificationRequest(NotificationType notificationType, int flags, String packageName, String sender, String message, int notificationId, FossilWatchAdapter adapter) { super(FileHandle.NOTIFICATION_PLAY, createFile(notificationType, flags, packageName, sender, message, notificationId), adapter); } public PlayNotificationRequest(NotificationType notificationType, int flags, int packageCRC, String sender, String message, int messageId, FossilWatchAdapter adapter) { super(FileHandle.NOTIFICATION_PLAY, createFile(notificationType, flags, "whatever", sender, message, packageCRC, messageId), adapter); } private static int getCurrentMessageId(){ return (int) System.currentTimeMillis(); } private static byte[] createFile(NotificationType notificationType, int flags, String packageName, String sender, String message, int messageId){ CRC32 crc = new CRC32(); crc.update(packageName.getBytes()); return createFile(notificationType, flags, packageName, sender, message, (int)crc.getValue(), messageId); } private static byte[] createFile(NotificationType notificationType, int flags, String title, String sender, String message, int packageCrc, int messageId) { byte lengthBufferLength = (byte) 10; byte uidLength = (byte) 4; byte appBundleCRCLength = (byte) 4; Charset charsetUTF8 = Charset.forName("UTF-8"); String nullTerminatedTitle = StringUtils.terminateNull(title); byte[] titleBytes = nullTerminatedTitle.getBytes(charsetUTF8); String nullTerminatedSender = StringUtils.terminateNull(sender); byte[] senderBytes = nullTerminatedSender.getBytes(charsetUTF8); if (message.length() > 475) { message = message.substring(0, 475); } String nullTerminatedMessage = StringUtils.terminateNull(message); byte[] messageBytes = nullTerminatedMessage.getBytes(charsetUTF8); short mainBufferLength = (short) (lengthBufferLength + uidLength + appBundleCRCLength + titleBytes.length + senderBytes.length + messageBytes.length); ByteBuffer mainBuffer = ByteBuffer.allocate(mainBufferLength); mainBuffer.order(ByteOrder.LITTLE_ENDIAN); mainBuffer.putShort(mainBufferLength); mainBuffer.put(lengthBufferLength); mainBuffer.put((byte) notificationType.getType()); mainBuffer.put((byte) flags); mainBuffer.put(uidLength); mainBuffer.put(appBundleCRCLength); mainBuffer.put((byte) titleBytes.length); mainBuffer.put((byte) senderBytes.length); mainBuffer.put((byte) messageBytes.length); mainBuffer.putInt(messageId); mainBuffer.putInt(packageCrc); mainBuffer.put(titleBytes); mainBuffer.put(senderBytes); mainBuffer.put(messageBytes); return mainBuffer.array(); } }