File indexing completed on 2024-12-01 04:33:08
0001 /** 0002 * SPDX-FileCopyrightText: 2013 Albert Vaca <albertvaka@gmail.com> 0003 * SPDX-FileCopyrightText: 2018 Simon Redman <simon@ergotech.com> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0006 */ 0007 0008 #pragma once 0009 0010 #include <QObject> 0011 0012 #include <core/kdeconnectplugin.h> 0013 0014 #include "conversationsdbusinterface.h" 0015 #include "interfaces/conversationmessage.h" 0016 0017 /** 0018 * Packet used to indicate a batch of messages has been pushed from the remote device 0019 * 0020 * The body should contain the key "messages" mapping to an array of messages 0021 * 0022 * For example: 0023 * { 0024 * "version": 2 // This is the second version of this packet type and 0025 * // version 1 packets (which did not carry this flag) 0026 * // are incompatible with the new format 0027 * "messages" : [ 0028 * { "event" : 1, // 32-bit field containing a bitwise-or of event flags 0029 * // See constants declared in SMSHelper.Message for defined 0030 * // values and explanations 0031 * "body" : "Hello", // Text message body 0032 * "addresses": <List<Address>> // List of Address objects, one for each participant of the conversation 0033 * // The user's Address is excluded so: 0034 * // If this is a single-target message, there will only be one 0035 * // Address (the other party) 0036 * // If this is an incoming multi-target message, the first Address is the 0037 * // sender and all other addresses are other parties to the conversation 0038 * // If this is an outgoing multi-target message, the sender is implicit 0039 * // (the user's phone number) and all Addresses are recipients 0040 * "date" : "1518846484880", // Timestamp of the message 0041 * "type" : "2", // Compare with Android's 0042 * // Telephony.TextBasedSmsColumns.MESSAGE_TYPE_* 0043 * "thread_id" : 132 // Thread to which the message belongs 0044 * "read" : true // Boolean representing whether a message is read or unread 0045 * }, 0046 * { ... }, 0047 * ... 0048 * ] 0049 * 0050 * The following optional fields of a message object may be defined 0051 * "sub_id": <int> // Android's subscriber ID, which is basically used to determine which SIM card the message 0052 * // belongs to. This is mostly useful when attempting to reply to an SMS with the correct 0053 * // SIM card using PACKET_TYPE_SMS_REQUEST. 0054 * // If this value is not defined or if it does not match a valid subscriber_id known by 0055 * // Android, we will use whatever subscriber ID Android gives us as the default 0056 * 0057 * "attachments": <List<Attachment>> // List of Attachment objects, one for each attached file in the message. 0058 * 0059 * An Attachment object looks like: 0060 * { 0061 * "part_id": <long> // part_id of the attachment used to read the file from MMS database 0062 * "mime_type": <int> // contains the mime type of the file (image, video, audio, etc.) 0063 * "encoded_thumbnail": <String> // Optional base64-encoded thumbnail preview of the content for types which support it 0064 * "unique_identifier": <String> // Unique name of te file 0065 * } 0066 * 0067 * An Address object looks like: 0068 * { 0069 * "address": <String> // Address (phone number, email address, etc.) of this object 0070 * } 0071 */ 0072 #define PACKET_TYPE_SMS_MESSAGES QStringLiteral("kdeconnect.sms.messages") 0073 0074 /** 0075 * Packet sent to request a message be sent 0076 * 0077 * The body should look like so: 0078 * { 0079 * "version": 2, // The version of the packet being sent. Compare to SMS_REQUEST_PACKET_VERSION before attempting to handle. 0080 * "addresses": <List<Addresses>>, // The one or many targets of this message 0081 * "messageBody": "Hi mom!", // Plain-text string to be sent as the body of the message 0082 * "attachments": <List<Attachment>>,// Send one or more attachments with this message. See AttachmentContainer documentation for formatting. (Optional) 0083 * "sub_id": 3859358340534 // Some magic number which tells Android which SIM card to use (Optional, if omitted, sends with the default SIM card) 0084 * } 0085 * 0086 * An AttachmentContainer object looks like: 0087 * { 0088 * "fileName": <String> // Name of the file 0089 * "base64EncodedFile": <String> // Base64 encoded file 0090 * "mimeType": <String> // File type (eg: image/jpg, video/mp4 etc.) 0091 * } 0092 * 0093 */ 0094 #define PACKET_TYPE_SMS_REQUEST QStringLiteral("kdeconnect.sms.request") 0095 #define SMS_REQUEST_PACKET_VERSION 2 // We *send* packets of this version 0096 0097 /** 0098 * Packet sent to request the most-recent message in each conversations on the device 0099 * 0100 * The request packet shall contain no body 0101 */ 0102 #define PACKET_TYPE_SMS_REQUEST_CONVERSATIONS QStringLiteral("kdeconnect.sms.request_conversations") 0103 0104 /** 0105 * Packet sent to request all the messages in a particular conversation 0106 * 0107 * The following fields are available: 0108 * "threadID": <long> // (Required) ThreadID to request 0109 * "rangeStartTimestamp": <long> // (Optional) Millisecond epoch timestamp indicating the start of the range from which to return messages 0110 * "numberToRequest": <long> // (Optional) Number of messages to return, starting from rangeStartTimestamp. 0111 * // May return fewer than expected if there are not enough or more than expected if many 0112 * // messages have the same timestamp. 0113 */ 0114 #define PACKET_TYPE_SMS_REQUEST_CONVERSATION QStringLiteral("kdeconnect.sms.request_conversation") 0115 0116 /** 0117 * Packet sent to request an attachment file in a particular message of a conversation 0118 * 0119 * The body should look like so: 0120 * "part_id": <long> // Part id of the attachment 0121 * "unique_identifier": <String> // It can be any hash code or unique name of the file 0122 */ 0123 #define PACKET_TYPE_SMS_REQUEST_ATTACHMENT QStringLiteral("kdeconnect.sms.request_attachment") 0124 0125 /** 0126 * Packet used to send original attachment file from mms database to desktop 0127 * <p> 0128 * The following fields are available: 0129 * "thread_id": <long> // Thread to which the attachment belongs 0130 * "filename": <String> // Name of the attachment file in the database 0131 */ 0132 #define PACKET_TYPE_SMS_ATTACHMENT_FILE QStringLiteral("kdeconnect.sms.attachment_file") 0133 0134 Q_DECLARE_LOGGING_CATEGORY(KDECONNECT_PLUGIN_SMS) 0135 0136 #define CODEC_NAME "CP1251" 0137 0138 class QTextCodec; 0139 0140 class SmsPlugin : public KdeConnectPlugin 0141 { 0142 Q_OBJECT 0143 Q_CLASSINFO("D-Bus Interface", "org.kde.kdeconnect.device.sms") 0144 0145 public: 0146 explicit SmsPlugin(QObject *parent, const QVariantList &args); 0147 ~SmsPlugin() override; 0148 0149 void receivePacket(const NetworkPacket &np) override; 0150 0151 QString dbusPath() const override; 0152 0153 public Q_SLOTS: 0154 Q_SCRIPTABLE void sendSms(const QVariantList &addresses, const QString &textMessage, const QVariantList &attachmentUrls, const qint64 subID = -1); 0155 0156 /** 0157 * Send a request to the remote for all of its conversations 0158 */ 0159 Q_SCRIPTABLE void requestAllConversations(); 0160 0161 /** 0162 * Send a request to the remote for a particular conversation 0163 * 0164 * @param conversationID The conversation to query 0165 * @param rangeStartTimestamp Return messages with timestamp >= this value. Value <= 0 indicates no limit. 0166 * @param numberToRequest Request this many messages. May return more, may return less. Value <= 0 indicates no limit. 0167 */ 0168 Q_SCRIPTABLE void requestConversation(const qint64 conversationID, const qint64 rangeStartTimestamp = -1, const qint64 numberToRequest = -1) const; 0169 0170 Q_SCRIPTABLE void launchApp(); 0171 0172 /** 0173 * Send a request to the remote device for a particulr attachment file 0174 */ 0175 Q_SCRIPTABLE void requestAttachment(const qint64 &partID, const QString &uniqueIdentifier); 0176 0177 /** 0178 * Searches the requested file in the application's cache directory, 0179 * if not found then sends the request to remote device 0180 */ 0181 Q_SCRIPTABLE void getAttachment(const qint64 &partID, const QString &uniqueIdentifier); 0182 0183 private: 0184 /** 0185 * Send to the telepathy plugin if it is available 0186 */ 0187 void forwardToTelepathy(const ConversationMessage &message); 0188 0189 /** 0190 * Handle a packet which contains many messages, such as PACKET_TYPE_TELEPHONY_MESSAGE 0191 */ 0192 bool handleBatchMessages(const NetworkPacket &np); 0193 0194 /** 0195 * Handle a packet of type PACKET_TYPE_SMS_ATTACHMENT_FILE which contains an attachment file 0196 */ 0197 bool handleSmsAttachmentFile(const NetworkPacket &np); 0198 0199 /** 0200 * Encode a local file so it can be sent to the remote device as part of an MMS message. 0201 */ 0202 Attachment createAttachmentFromUrl(const QString &url); 0203 0204 QDBusInterface m_telepathyInterface; 0205 ConversationsDbusInterface *m_conversationInterface; 0206 QTextCodec *m_codec; 0207 };