/** * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * AUTHORS * Maciek Borzecki <maciek.borzecki (at] gmail.com> * gyan000 <gyan000 (at] ijaz.fr> */ using EOSConnect; using EOSConnect.Plugin; namespace MConnect { class TelephonyHandler : Object, PacketHandlerInterface { public signal void telephony_update (); public const string TELEPHONY = "kdeconnect.telephony"; public const string SMS_REQUEST = "kdeconnect.sms.request"; public DateTime last_sms_received_date_time { get; private set; } public string get_pkt_type () { return TELEPHONY; } private TelephonyHandler () { } public static TelephonyHandler instance () { return new TelephonyHandler (); } public void use_device (Device dev) { debug ("Use device %s for telephony.", dev.to_string ()); dev.message.connect (this.message); } public void release_device (Device dev) { debug ("Release device %s", dev.to_string ()); dev.message.disconnect (this.message); } public void message (Device device, Packet pkt) { if (pkt.pkt_type != TELEPHONY || device.is_capabality_activated (TELEPHONY) == false) { return; } info ("Got telephony packet."); if (pkt.body.has_member ("phoneNumber") == false || pkt.body.has_member ("event") == false) { return; } string id = pkt.id.to_string (); string event = pkt.body.get_string_member ("event"); string message_body = pkt.body.get_string_member ("messageBody"); string phone_thumbnail = pkt.body.get_string_member ("phoneThumbnail"); string phone_number = pkt.body.get_string_member ("phoneNumber"); string contact_name = pkt.body.has_member ("contactName") ? pkt.body.get_string_member ("contactName") : phone_number; string device_name = (device.custom_name.length > 0) ? device.custom_name : device.name; string notif_summary = ""; string notif_body = ""; bool set_notification_icon = false; string notification_icon_pathname = ""; if (event == "sms") { last_sms_received_date_time = new DateTime.now_utc (); SMSContact sms_contact = new SMSContact (phone_number, contact_name, device.id, phone_thumbnail, contact_name); SMSStore.instance ().add_sms ( device, new SMS ( message_body, SMS.FROM_CONTACT, SMS.FROM_TYPE_TELEPHONY, last_sms_received_date_time), sms_contact); notif_summary = "SMS\u0040" + device_name; notif_body = "<i>" + contact_name + "</i>\n"; notif_body += message_body; if (sms_contact.contact_image_path.length > 10) { notification_icon_pathname = sms_contact.contact_image_path; set_notification_icon = true; } } if (device.is_capabality_activated (NotificationHandler.NOTIFICATION) == false || ((Plugin.Notification)device.get_plugin (NotificationHandler.NOTIFICATION)).settings_receive_is_active == false) { debug ("Notification deactivated for device %s", device.custom_name); return; } var notification = new GLib.Notification (notif_summary); notification.set_body (notif_body); if (event == "sms") { // Action defined in EOSConnect._init_sms_history_view () notification.set_default_action ("app.telephony-open-sms-tab"); } if (set_notification_icon == true) { notification.set_icon (new FileIcon (File.new_for_path (notification_icon_pathname))); } try { Core.instance ().application.send_notification (id, notification); } catch (Error e) { warning ("Unable to send the telephony notification. :/"); } //const string[] accepted_events = { "event" "ringing", "missedCall" }; //debug ("Call from %s, status %s", number, event); // // if (event in accepted_events) { // string summary = "Other event"; // // if (ev == "ringing") // summary = "Incoming call"; // if (ev == "missedCall") // summary = "Missed call"; // // // check if ringing was cancelled // if (ev == "missedCall" && pkt.body.has_member ("isCancel")) { // bool cancelled = pkt.body.get_boolean_member ("isCancel"); // if (cancelled == true) { // debug ("call cancelled"); // return; // } // } // // // telephony packets have no time information // var time = new DateTime.now_local (); // number = "%s %s".printf (time.format ("%X"), number); // // var notif = new Notify.Notification (summary, number, // "phone"); // try { // notif.show (); // } catch (Error e) { // critical ("failed to show notification: %s", e.message); // } // } } public void handle_sms_notification (Device device, Packet pkt) { debug ("Handling missed SMS from notifiation."); // TOCHECK There's' a "time" field, but, does not seems to be a unix timestamp. And no mention in kdeconnect. //DateTime glop = new DateTime.from_unix_local (pkt.body.get_string_member ("time").to_int()); //print (">> %s -> %s", pkt.body.get_string_member ("time").to_string (), glop.to_string ()); //return; SMSStore.instance ().handle_missed_sms ( device, new SMS ( pkt.body.get_string_member ("text"), SMS.FROM_CONTACT, SMS.FROM_TYPE_NOTIFICATION, new DateTime.now_utc () ), pkt.body.get_string_member ("title")); } /** * make_sms_packet: * @number: recipient's number * @message: message * * @return allocated packet */ private Packet _make_sms_packet (string number, string message) { var builder = new Json.Builder (); builder.begin_object (); builder.set_member_name ("sendSms"); builder.add_boolean_value (true); builder.set_member_name ("phoneNumber"); builder.add_string_value (number); builder.set_member_name ("messageBody"); builder.add_string_value (message); builder.end_object (); return new Packet (SMS_REQUEST, builder.get_root ().get_object ()); } /** * send_sms: * * Reques to send an SMS to @number with message @message. */ public void send_sms (Device device, string number, string message) { device.send (_make_sms_packet (number, message)); } } }