File indexing completed on 2025-02-02 05:16:30
0001 // SPDX-FileCopyrightText: 2021 Alexey Andreyev <aa13q@ya.ru> 0002 // 0003 // SPDX-License-Identifier: LicenseRef-KDE-Accepted-GPL 0004 0005 #pragma once 0006 0007 #include <type_traits> 0008 0009 #include <QDBusArgument> 0010 #include <QDBusMetaType> 0011 #include <QDateTime> 0012 #include <QObject> 0013 #include <QString> 0014 0015 namespace DialerTypes 0016 { 0017 Q_NAMESPACE 0018 0019 enum class CallState { Unknown, Dialing, RingingOut, RingingIn, Active, Held, Waiting, Terminated }; 0020 0021 enum class CallStateReason { 0022 Unknown, 0023 OutgoingStarted, 0024 IncomingNew, 0025 Accepted, 0026 TerminatedReason, 0027 RefusedOrBusy, 0028 Error, 0029 AudioSetupFailed, 0030 Transferred, 0031 Deflected 0032 }; 0033 0034 enum class CallDirection { 0035 Unknown, 0036 Incoming, 0037 Outgoing, 0038 }; 0039 0040 Q_ENUM_NS(CallState) 0041 Q_ENUM_NS(CallStateReason) 0042 Q_ENUM_NS(CallDirection) 0043 0044 struct CallData { 0045 QString id; // event id 0046 0047 QString protocol; // protocol id: tel, mtx, tg 0048 QString provider; // provider id: sim value displayed with sim name/icon or homeserver id) 0049 QString account; // account id: phone number or mtx id) 0050 0051 QString communicationWith; // interlocutor: a phone number or room id 0052 DialerTypes::CallDirection direction; // direction (incoming/outgoing/unknown) 0053 DialerTypes::CallState state; // call state 0054 DialerTypes::CallStateReason stateReason; // call state reason 0055 0056 int callAttemptDuration; // call attempt duration 0057 QDateTime startedAt; // started at 0058 int duration; // call duration 0059 }; 0060 0061 // Marshalling for CallState, CallStateReason and CallDirection enums: 0062 0063 template<typename T, typename TEnum> 0064 struct QDBusEnumMarshal; 0065 0066 template<typename T> 0067 struct QDBusEnumMarshal<T, std::true_type> { 0068 static QDBusArgument &marshal(QDBusArgument &argument, const T &source) 0069 { 0070 argument.beginStructure(); 0071 argument << static_cast<int>(source); 0072 argument.endStructure(); 0073 return argument; 0074 } 0075 0076 static const QDBusArgument &unmarshal(const QDBusArgument &argument, T &source) 0077 { 0078 int a; 0079 argument.beginStructure(); 0080 argument >> a; 0081 argument.endStructure(); 0082 0083 source = static_cast<T>(a); 0084 return argument; 0085 } 0086 }; 0087 0088 // Marshalling for CallData struct: 0089 0090 template<typename T> 0091 struct QDBusCallDataMarshal; 0092 0093 template<> 0094 struct QDBusCallDataMarshal<CallData> { 0095 static QDBusArgument &marshal(QDBusArgument &argument, const CallData &source) 0096 { 0097 QVariantMap dict; 0098 dict.insert(QStringLiteral("id"), source.id); 0099 dict.insert(QStringLiteral("protocol"), source.protocol); 0100 dict.insert(QStringLiteral("account"), source.account); 0101 dict.insert(QStringLiteral("provider"), source.provider); 0102 dict.insert(QStringLiteral("communicationWith"), source.communicationWith); 0103 dict.insert(QStringLiteral("direction"), static_cast<int>(source.direction)); 0104 dict.insert(QStringLiteral("state"), static_cast<int>(source.state)); 0105 dict.insert(QStringLiteral("stateReason"), static_cast<int>(source.stateReason)); 0106 dict.insert(QStringLiteral("callAttemptDuration"), source.callAttemptDuration); 0107 dict.insert(QStringLiteral("startedAt"), source.startedAt.toSecsSinceEpoch()); 0108 dict.insert(QStringLiteral("duration"), source.duration); 0109 0110 argument.beginStructure(); 0111 argument << dict; 0112 argument.endStructure(); 0113 return argument; 0114 }; 0115 0116 static const QDBusArgument &unmarshal(const QDBusArgument &argument, CallData &source) 0117 { 0118 QVariantMap dict; 0119 argument.beginStructure(); 0120 argument >> dict; 0121 argument.endStructure(); 0122 0123 source.id = dict.value(QStringLiteral("id")).toString(); 0124 source.protocol = dict.value(QStringLiteral("protocol")).toString(); 0125 source.account = dict.value(QStringLiteral("account")).toString(); 0126 source.provider = dict.value(QStringLiteral("provider")).toString(); 0127 source.communicationWith = dict.value(QStringLiteral("communicationWith")).toString(); 0128 0129 source.direction = dict.value(QStringLiteral("direction"), 0).value<DialerTypes::CallDirection>(); 0130 source.state = dict.value(QStringLiteral("state"), 0).value<DialerTypes::CallState>(); 0131 source.stateReason = dict.value(QStringLiteral("stateReason"), 0).value<DialerTypes::CallStateReason>(); 0132 0133 source.callAttemptDuration = dict.value(QStringLiteral("callAttemptDuration"), 0).toInt(); 0134 source.startedAt = QDateTime::fromSecsSinceEpoch((uint)dict.value(QStringLiteral("startedAt"), 0).toLongLong()); 0135 source.duration = dict.value(QStringLiteral("duration"), 0).toInt(); 0136 0137 return argument; 0138 }; 0139 }; 0140 0141 template<typename T> 0142 QDBusArgument &operator<<(QDBusArgument &argument, const T &source) 0143 { 0144 if constexpr (std::is_same_v<T, CallData>) { 0145 return QDBusCallDataMarshal<CallData>::marshal(argument, source); 0146 } else { 0147 return QDBusEnumMarshal<T, typename std::is_enum<T>::type>::marshal(argument, source); 0148 } 0149 } 0150 0151 template<typename T> 0152 const QDBusArgument &operator>>(const QDBusArgument &argument, T &source) 0153 { 0154 if constexpr (std::is_same_v<T, CallData>) { 0155 return QDBusCallDataMarshal<CallData>::unmarshal(argument, source); 0156 } else { 0157 return QDBusEnumMarshal<T, typename std::is_enum<T>::type>::unmarshal(argument, source); 0158 }; 0159 } 0160 0161 using CallDataVector = QVector<DialerTypes::CallData>; 0162 0163 } // namespace DialerTypes 0164 0165 Q_DECLARE_METATYPE(DialerTypes::CallState) 0166 Q_DECLARE_METATYPE(DialerTypes::CallStateReason) 0167 Q_DECLARE_METATYPE(DialerTypes::CallDirection) 0168 Q_DECLARE_METATYPE(DialerTypes::CallData) 0169 Q_DECLARE_METATYPE(DialerTypes::CallDataVector) 0170 0171 namespace DialerTypes 0172 { 0173 inline void registerMetaTypes() 0174 { 0175 qRegisterMetaType<DialerTypes::CallState>("DialerTypesCallState"); 0176 qDBusRegisterMetaType<DialerTypes::CallState>(); 0177 0178 qRegisterMetaType<DialerTypes::CallStateReason>("DialerTypesCallStateReason"); 0179 qDBusRegisterMetaType<DialerTypes::CallStateReason>(); 0180 0181 qRegisterMetaType<DialerTypes::CallDirection>("DialerTypesCallDirection"); 0182 qDBusRegisterMetaType<DialerTypes::CallDirection>(); 0183 0184 qRegisterMetaType<DialerTypes::CallData>("DialerTypesCallData"); 0185 qDBusRegisterMetaType<DialerTypes::CallData>(); 0186 0187 qRegisterMetaType<DialerTypes::CallDataVector>("DialerTypesCallDataVector"); 0188 qDBusRegisterMetaType<DialerTypes::CallDataVector>(); 0189 } 0190 }