2 * This file is part of TimedSilencer.
4 * TimedSilencer is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * TimedSilencer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with TimedSilencer. If not, see <http://www.gnu.org/licenses/>.
18 #ifndef ALARMD_TALKER_H
19 #define ALARMD_TALKER_H
25 #include <alarmd/libalarm.h>
26 #include <dbus-1.0/dbus/dbus-protocol.h>
29 #include "phone_profile.h"
30 #include "dbus_backend.h"
31 #include "profileevent.h"
33 // Alarmd documentation found at:
34 // http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Using_Generic_Platform_Components/Alarm_Framework
35 class AlarmdBackend : public QObject {
38 static time_t toTime_t(const QTime &t) {
39 int time_diff = QTime::currentTime().secsTo(t);
44 qDebug("time diff: %d", time_diff);
45 return (time_t) time(0) + time_diff;
48 static uint32_t daysToMask(QList<int> days) {
50 foreach(const int& d, days) {
53 mask |= ALARM_RECUR_WDAY_MON;
56 mask |= ALARM_RECUR_WDAY_TUE;
59 mask |= ALARM_RECUR_WDAY_WED;
62 mask |= ALARM_RECUR_WDAY_THU;
65 mask |= ALARM_RECUR_WDAY_FRI;
68 mask |= ALARM_RECUR_WDAY_SAT;
71 mask |= ALARM_RECUR_WDAY_SUN;
74 Q_ASSERT(0); // Should never go here
75 mask |= ALARM_RECUR_WDAY_ALL;
83 // Is only called on program uninstall
84 static void deleteAllEvents() {
85 QSettings settings("TimedSilencer", "TimedSilencer");
86 QHash<QString, QVariant> events = settings.value("events").toHash();
87 foreach(QVariant var_ev, events) {
88 ProfileEvent *pe = ProfileEvent::load(var_ev);
89 foreach(const long &cookie, pe->alarmd_cookies) {
90 qDebug("Unregistering event with cookie %ld", cookie);
91 alarmd_event_del(cookie);
97 settings.setValue("events", events);
100 static void deleteEvents(QByteArray event_id) {
101 deleteEvents(ProfileEvent::findByID(event_id));
104 static void deleteEvents(ProfileEvent *pe) {
105 // unregistering events
106 foreach(const long &cookie, pe->alarmd_cookies) {
107 qDebug("Unregistering event with cookie %ld", cookie);
108 alarmd_event_del(cookie);
110 pe->alarmd_cookies.clear();
111 ProfileEvent::clearCookies(pe->getID());
114 static void setProfileEvents(QByteArray event_id) {
115 setProfileEvents(ProfileEvent::findByID(event_id));
118 static bool checkIfStillActive(ProfileEvent *pe) {
119 Q_ASSERT(pe->activated);
120 foreach(const long &cookie, pe->alarmd_cookies) {
121 alarm_event_t *eve = 0;
122 if((eve = alarmd_event_get(cookie)) != 0) {
123 // Free all dynamic memory associated with the alarm event
124 alarm_event_delete(eve);
131 static void setProfileEvents(ProfileEvent *pe) {
132 Q_ASSERT(pe->activated);
133 // First clear old alarmd events
134 foreach(const long &cookie, pe->alarmd_cookies) {
135 qDebug("Unregistering event with cookie %ld", cookie);
136 alarmd_event_del(cookie);
138 pe->alarmd_cookies.clear();
139 // Then setting new events
140 long c1 = newProfileEvent(SILENT, pe->from_time, pe->days);
143 pe->alarmd_cookies << c1;
144 long c2 = newProfileEvent(GENERAL, pe->to_time, pe->days);
147 pe->alarmd_cookies << c2;
149 ProfileEvent::setCookies(pe->getID(), pe->alarmd_cookies);
150 // Set Profile to SILENT if we are currently in the silent time slot
151 if(pe->affectsCurrentTime())
152 DBusBackend::setProfile(SILENT);
156 static long newProfileEvent(Profile p, const QTime &event_time, QList<int> days) {
157 Q_ASSERT(!days.empty());
158 if(days.empty()) days << NEVER;
159 // Create the default alarm struct.
160 alarm_event_t *newEvent = alarm_event_create();
162 alarm_event_set_alarm_appid(newEvent, "TimedSilencer");
165 alarm_event_set_title(newEvent, "silent_profile");
167 alarm_event_set_title(newEvent, "general_profile");
169 if(days.first() == EVERY_DAY) {
170 newEvent->recur_secs = 86400; // 24 hours
171 newEvent->recur_count = -1; // Reoccur infinitely
172 newEvent->alarm_time = toTime_t(event_time); // Set event time
174 if(days.first() == NEVER) {
175 newEvent->alarm_time = toTime_t(event_time); // Set event time
177 newEvent->recur_secs = 0; // We re not using this way for recurrence
178 alarm_recur_t* recur = alarm_event_add_recurrences(newEvent, 1);
180 recur->mask_hour |= (1ul << event_time.hour());
181 recur->mask_min |= (1ull << event_time.minute());
182 recur->mask_wday |= daysToMask(days);
185 //Add 1 action to our alarm event, and assign it to the "act" variable
186 alarm_action_t *act = alarm_event_add_actions(newEvent, 1);
187 // Actions are documented here:
188 // http://maemo.org/api_refs/5.0/5.0-final/libalarm/libalarm_8h.html#cc8e6f439d134448001132132476683c910f7626ec85a4170659b53fa2f0abc7
189 //Setup this action to be an "DBus command" one; also set it up to use DBUS auto-activation.
190 act->flags = ALARM_ACTION_WHEN_TRIGGERED | ALARM_ACTION_DBUS_USE_ACTIVATION | ALARM_ACTION_TYPE_DBUS;
192 //Setup the DBus params for this action
193 alarm_action_set_dbus_interface(act, "com.nokia.profiled");
194 alarm_action_set_dbus_service(act, "com.nokia.profiled");
195 alarm_action_set_dbus_path(act, "/com/nokia/profiled");
196 alarm_action_set_dbus_name(act, "set_profile");
199 const char* param = "silent";
200 alarm_action_set_dbus_args(act, DBUS_TYPE_STRING, ¶m, DBUS_TYPE_INVALID);
202 const char* param = "general";
203 alarm_action_set_dbus_args(act, DBUS_TYPE_STRING, ¶m, DBUS_TYPE_INVALID);
206 // Finally with everything setup, try to add your event to the alarm queue
207 long cookie = alarmd_event_add(newEvent);
208 // Free all dynamic memory associated with the alarm event
209 alarm_event_delete(newEvent);
214 #endif // ALARMD_TALKER_H