Esempio n. 1
0
static void
_activity_print(struct timespec *from, struct timespec *now)
{
    struct timespec diff;
    int diff_ms;

    pthread_mutex_lock(&activity_mutex);

    GList *iter;
    for (iter = activity_roster->head; iter != NULL; iter = iter->next)
    {
        Activity *a = (Activity*)iter->data;

         // now > activity.end_time
        if (ClockTimeIsGreater(from, &a->end_time))
        {
            continue;
        }

        // end_time - now
        ClockDiff(&diff, &a->end_time, now);

        diff_ms = diff.tv_sec * 1000 + diff.tv_nsec / 1000000;
       
        SLEEPDLOG(LOG_INFO, "(%s) for %d ms, expiry in %d ms",
               a->activity_id, a->duration_ms,
               diff_ms);
    }
    pthread_mutex_unlock(&activity_mutex);
}
Esempio n. 2
0
/**
 * @brief Log the client's response for the current shutdown voting process
 */
static void
client_vote_print(const char *key, ShutdownClient *client, void *data)
{
    SLEEPDLOG(LOG_INFO, "    %s %s %s @ %fs", client->id, client->name,
            shutdown_reply_to_string(client->ack_shutdown),
            client->elapsed);
}
Esempio n. 3
0
/** 
* @brief Stop an activity
*
* @param activity_id of the activity than needs to be stopped
* 
* @param  activity_id 
*/
void
PwrEventActivityStop(const char *activity_id)
{
    SLEEPDLOG(LOG_INFO, "%s: (%s)", __FUNCTION__, activity_id);
    _activity_stop(activity_id);

    ScheduleIdleCheck(0, false);
}
Esempio n. 4
0
static void
client_list_print(GHashTable *client_table)
{
    int size = g_hash_table_size(client_table);

    SLEEPDLOG(LOG_INFO, "clients:");

    if (size > 0)
    {
        g_hash_table_foreach(client_table,
                (GHFunc)client_vote_print, NULL);
    }
    else
    {
        SLEEPDLOG(LOG_INFO, "    No clients registered.");
    }
}
Esempio n. 5
0
/**
 * @brief Check the client response for the "shutdownApplications" signal. We get to this state either when
 * a client ACKs or we have timed out.
 */
static bool 
state_shutdown_apps_process(ShutdownEvent *event, ShutdownState *next)
{
    bool timeout = false;

    switch (event->id)
    {
    case kShutdownEventAck:
        client_vote(event->client, true);
        break;
    case kShutdownEventTimeout:
        timeout = true;
        break;
    default:
        break;
    }

    int readiness = shutdown_apps_ready();
    if (readiness > 0 || timeout)
    {
        if (timeout)
        {
            SLEEPDLOG(LOG_CRIT, "Shutdown apps timed out: ");
        }
        client_list_print(sClientList->applications);

        g_source_remove(shutdown_apps_timeout_id);

        *next = kPowerShutdownServices;
        return true;
    }
    else if (readiness < 0)
    {
        *next = kPowerShutdownNone;
        return false;
    }
    else
    {
        *next = kPowerShutdownAppsProcess;
        return false;
    }
}
Esempio n. 6
0
/** 
* @brief Start an activity by the name of 'activity_id'.
* 
* @param  activity_id  Should be in format com.domain.reverse-serial.
* @param  duration_ms 
*
* @return false if the activity could not be created... (activities may be frozen).
*/
bool
PwrEventActivityStart(const char *activity_id, int duration_ms)
{
    bool retVal;

    retVal = _activity_start(activity_id, duration_ms);

    SLEEPDLOG(LOG_INFO, "%s: (%s) for %dms => %s",
        __FUNCTION__, activity_id, duration_ms, retVal ? "true" : "false");

    if (retVal)
    {
        /*
            Force IdleCheck to run in case this activity is the same as
            the current "long pole" activity but with a shorter life.
        */
        ScheduleIdleCheck(0, false);
    }

    return retVal;
}
Esempio n. 7
0
/** 
* @brief Remove all expired activities...
*        This assumes the list is sorted.
* 
* @param  now 
*/
void
PwrEventActivityRemoveExpired(struct timespec *now)
{
    pthread_mutex_lock(&activity_mutex);

    GList *iter;
    for (iter = activity_roster->head; iter != NULL; )
    {
        Activity *a = (Activity*)iter->data;

        // remove expired
        if (_activity_expired(a, now))
        {
            GList *current_iter = iter;
            iter = iter->next;

            if (a->duration_ms >= ACTIVITY_HIGH_DURATION_MS)
            {
                LSError lserror;
                LSErrorInit(&lserror);

                SLEEPDLOG(LOG_WARNING,
                    "%s Long activity %s of duration %d ms expired... sending RDX report.",
                    __FUNCTION__,
                    a->activity_id, a->duration_ms);
            }

            _activity_stop_activity(a);

            g_queue_delete_link(activity_roster, current_iter);
        }
        else
        {
            break;
        }
    }

    pthread_mutex_unlock(&activity_mutex);
}
Esempio n. 8
0
static void
shutdown_state_dispatch(ShutdownEvent *event)
{
    ShutdownState next_state = gCurrentState->state;
    bool running = true;

    while (running)
    {
        running = gCurrentState->function(event, &next_state);

        _assert(next_state >= gCurrentState->state);

        if (next_state != gCurrentState->state)
        {
            SLEEPDLOG(LOG_DEBUG, "Shutdown: entering state: %s @ %fs",
                    kStateMachine[next_state].name,
                    g_timer_elapsed(shutdown_timer, NULL));
        }

        gCurrentState = &kStateMachine[next_state];
    }
}
Esempio n. 9
0
int
main(int argc, char **argv)
{
    bool retVal;

    // FIXME integrate this into TheOneInit()
    LOGInit();
    LOGSetHandler(LOGSyslog);

    signal(SIGTERM, term_handler);
    signal(SIGINT, term_handler);

    if (!g_thread_supported ()) g_thread_init (NULL);

    mainloop = g_main_loop_new(NULL, FALSE);

    /**
     *  initialize the lunaservice and we want it before all the init
     *  stuff happening.
     */
    LSError lserror;
    LSErrorInit(&lserror);

    retVal = LSRegisterPalmService("com.palm.sleep", &psh, &lserror);
    if (!retVal)
    {
        goto ls_error;
    }

    retVal = LSGmainAttachPalmService(psh, mainloop, &lserror);
    if (!retVal)
    {
        goto ls_error;
    }

    private_sh = LSPalmServiceGetPrivateConnection(psh);

    retVal = LSCall(private_sh,"luna://com.palm.lunabus/signal/addmatch","{\"category\":\"/com/palm/power\","
              "\"method\":\"USBDockStatus\"}", ChargerStatus, NULL, NULL, &lserror);
    if (!retVal) {
		SLEEPDLOG(LOG_CRIT,"Error in registering for luna-signal \"chargerStatus\"");
		goto ls_error;
	}

 	int ret = nyx_device_open(NYX_DEVICE_SYSTEM, "Main", &nyxSystem);
 	if(ret != NYX_ERROR_NONE)
 	{
 		SLEEPDLOG(LOG_CRIT,"Sleepd: Unable to open the nyx device system");
 		abort();
 	}


    TheOneInit();

 	LSCall(private_sh,"luna://com.palm.power/com/palm/power/chargerStatusQuery","{}",ChargerStatus,NULL,NULL,&lserror);

    SLEEPDLOG(LOG_INFO,"Sleepd daemon started\n");

    g_main_loop_run(mainloop);

end:
    g_main_loop_unref(mainloop);

     return 0;
ls_error:
	SLEEPDLOG(LOG_CRIT,"Fatal - Could not initialize sleepd.  Is LunaService Down?. %s",
        lserror.message);
    LSErrorFree(&lserror);
    goto end;
}
Esempio n. 10
0
/**
* @brief Sends a "/alarm" message to the service associated with this alarm.
*
* {"alarmId":1,"fired":true,"key":"appkey"}
*
* @param  alarm
*/
static void
fire_alarm(_Alarm *alarm)
{
    bool retVal;
    char buf_alarm[STD_ASCTIME_BUF_SIZE];

    struct tm tm_alarm;
    time_t rtctime = 0;

    gmtime_r(&alarm->expiry, &tm_alarm);
    asctime_r(&tm_alarm, buf_alarm);

    nyx_system_query_rtc_time(GetNyxSystemDevice(),&rtctime);

    SLEEPDLOG(LOG_INFO, "Alarm (%s %s %s) fired at %s (rtc %ld)",
              alarm->serviceName, alarm->applicationName, alarm->key, buf_alarm, rtctime);

    GString *payload = g_string_sized_new(255);
    g_string_append_printf(payload, "{\"alarmId\":%d,\"fired\":true", alarm->id);

    if (alarm->key)
    {
        g_string_append_printf(payload, ",\"key\":\"%s\"", alarm->key);
    }

    if (alarm->applicationName && strcmp(alarm->applicationName, "") != 0)
    {
        g_string_append_printf(payload, ",\"applicationName\":\"%s\"",
                               alarm->applicationName);
    }
    g_string_append_printf(payload, "}");

    LSError lserror;
    LSErrorInit(&lserror);

    if (alarm->serviceName && strcmp(alarm->serviceName, "") != 0)
    {
        char *uri = g_strdup_printf("luna://%s/alarm", alarm->serviceName);
        retVal = LSCall(GetLunaServiceHandle(), uri, payload->str,
                        NULL, NULL, NULL, &lserror);
        if (!retVal)
        {
            LSErrorPrint(&lserror, stderr);
            LSErrorFree(&lserror);
        }

        g_free(uri);
    }

    if (alarm->message)
    {
        retVal = LSMessageReply(GetLunaServiceHandle(), alarm->message,
                                payload->str, &lserror);
        if (!retVal)
        {
            LSErrorPrint(&lserror, stderr);
            LSErrorFree(&lserror);
        }
    }

    g_string_free(payload, TRUE);
}
Esempio n. 11
0
/**
* @brief Remove an alarm by id.
*
* {"alarmId":1}
*
* Response:
*
* {"returnValue":true}
*
* @param  sh
* @param  message
* @param  ctx
*
* @retval
*/
static bool
alarmRemove(LSHandle *sh, LSMessage *message, void *ctx)
{
    LSError lserror;
    LSErrorInit(&lserror);

    bool found = false;
    bool retVal;

    const char *payload = LSMessageGetPayload(message);
    struct json_object *object = json_tokener_parse(payload);
    if (is_error(object))
    {
        goto malformed_json;
    }

    SLEEPDLOG(LOG_DEBUG, "%s: %s", __FUNCTION__, LSMessageGetPayload(message));

    int alarmId =
        json_object_get_int(json_object_object_get(object, "alarmId"));

    GSequenceIter *iter = g_sequence_get_begin_iter(gAlarmQueue->alarms);
    while (!g_sequence_iter_is_end (iter))
    {
        _Alarm *alarm = (_Alarm*)g_sequence_get(iter);
        GSequenceIter *next = g_sequence_iter_next(iter);

        if (alarm && alarm->id == alarmId)
        {
            char *timeout_key = g_strdup_printf("%s-%d", alarm->key, alarm->id);
            _timeout_clear("com.palm.sleep", timeout_key,
                           false /*public_bus*/);
            g_free(timeout_key);

            g_sequence_remove(iter);
            found = true;
        }

        iter = next;
    }

    const char *response;
    if (found)
    {
        alarm_write_db();
        response = "{\"returnValue\":true}";
    }
    else
    {
        response = "{\"returnValue\":false}";
    }

    retVal = LSMessageReply(sh, message, response, &lserror);
    if (!retVal)
    {
        LSErrorPrint(&lserror,stderr);
        LSErrorFree(&lserror);
    }

    goto cleanup;
malformed_json:
    LSMessageReplyErrorBadJSON(sh, message);
    goto cleanup;
cleanup:
    if (!is_error(object)) json_object_put(object);
    return true;
}
Esempio n. 12
0
/**
* @brief Set a calendar event.
*
* luna://com.palm.sleep/time/alarmAddCalendar
*
* Message:
* Set alarm to expire at a fixed calendar time in UTC. Response will be sent
* as a call to "luna://com.palm.X/alarm".
*
* {"key":"calendarAlarm", "serviceName":"com.palm.X",
*  "date":"01-02-2009", "time":"13:40:03"}
*
* Subscribing indicates that you want the alarm message as a response to
* the current call.
*
* {"subscribe":true, "key":"calendarAlarm", "serviceName":"com.palm.X",
*  "date":"01-02-2009", "time":"13:40:03"}
*
* Response:
*
* Alarm is sucessfully registered for calendar date
* {"alarmId":1}
*
* Subscribe case:
* {"alarmId":1,"subscribed":true}
* {"alarmId":1,"fired":true}
*
* Alarm failed to be registered:
*
* {"returnValue":false, ...}
* {"returnValue":false,"serivceName":"com.palm.sleep",
*  "errorText":"com.palm.sleep is not running"}
*
* @param  sh
* @param  message
* @param  ctx
*
* @retval
*/
static bool
alarmAddCalendar(LSHandle *sh, LSMessage *message, void *ctx)
{
    int alarm_id;
    struct json_object *object;
    const char *key, *serviceName, *applicationName, *cal_date, *cal_time;
    struct tm gm_time;
    bool subscribe;
    bool retVal = false;

    time_t alarm_time = 0;

    LSError lserror;
    LSErrorInit(&lserror);

    object = json_tokener_parse(LSMessageGetPayload(message));
    if ( is_error(object) )
    {
        goto malformed_json;
    }

    SLEEPDLOG(LOG_DEBUG, "%s: %s", __FUNCTION__, LSMessageGetPayload(message));

    serviceName = json_object_get_string(
                      json_object_object_get(object, "serviceName"));

    applicationName = LSMessageGetApplicationID(message);

    key = json_object_get_string(json_object_object_get(object, "key"));

    cal_date = json_object_get_string(
                   json_object_object_get(object, "date"));
    cal_time = json_object_get_string(
                   json_object_object_get(object, "time"));


    if (!cal_date || !cal_time)
    {
        goto invalid_format;
    }

    int hour, min, sec;
    int month, day, year;

    if (sscanf(cal_time, "%02d:%02d:%02d", &hour, &min, &sec) != 3)
    {
        goto invalid_format;
    }
    if (sscanf(cal_date, "%02d-%02d-%04d", &month, &day, &year) != 3)
    {
        goto invalid_format;
    }

    if (hour < 0 || hour > 24 || min < 0 || min > 60 ||
            sec < 0 || sec > 60 ||
            month < 1 || month > 12 || day < 1 || day > 31 || year < 0)
    {
        goto invalid_format;
    }

    SLEEPDLOG(LOG_INFO, "%s: (%s %s %s) at %s %s", __FUNCTION__,
              serviceName, applicationName, key, cal_date, cal_time);

    struct json_object *subscribe_json =
        json_object_object_get(object, "subscribe");

    subscribe = json_object_get_boolean(subscribe_json);

    memset(&gm_time, 0, sizeof(struct tm));

    gm_time.tm_hour = hour;
    gm_time.tm_min = min;
    gm_time.tm_sec = sec;
    gm_time.tm_mon = month - 1; // month-of-year [0-11]
    gm_time.tm_mday = day;      // day-of-month [1-31]
    gm_time.tm_year = year - 1900;

    /* timegm converts time(GMT) -> seconds since epoch */
    alarm_time = timegm(&gm_time);
    if (alarm_time < 0)
    {
        goto invalid_format;
    }

    retVal = alarm_queue_new(key, true, alarm_time,
                             serviceName, applicationName, subscribe, message, &alarm_id);
    if (!retVal) goto error;

    /*****************
     * Use new timeout API
     */
    {
        char *timeout_key = g_strdup_printf("%s-%d", key, alarm_id);
        _AlarmTimeout timeout;
        _timeout_create(&timeout, "com.palm.sleep", timeout_key,
                        "luna://com.palm.sleep/time/internalAlarmFired",
                        "{}",
                        false /*public bus*/,
                        true /*wakeup*/,
                        "" /*activity_id*/,
                        0 /*activity_duration_ms*/,
                        true /*calendar*/,
                        alarm_time);

        retVal = _timeout_set(&timeout);

        g_free(timeout_key);
        if (!retVal) goto error;
    }
    /*****************/

    /* Send alarm id of sucessful alarm add. */
    GString *reply = g_string_sized_new(512);
    g_string_append_printf(reply, "{\"alarmId\":%d", alarm_id);
    if (subscribe_json)
    {
        g_string_append_printf(reply, ",\"subscribed\":%s",
                               subscribe ? "true":"false");
    }
    g_string_append_printf(reply, "}");

    retVal = LSMessageReply(sh, message, reply->str, &lserror);

    g_string_free(reply, TRUE);

    goto cleanup;
error:
    retVal = LSMessageReply(sh, message, "{\"returnValue\":false,"
                            "\"errorText\":\"Unknown error\"}", &lserror);
    goto cleanup;
invalid_format:
    retVal = LSMessageReply(sh, message, "{\"returnValue\":false,"
                            "\"errorText\":\"Invalid format for alarm time.\"}", &lserror);
    goto cleanup;
malformed_json:
    LSMessageReplyErrorBadJSON(sh, message);
    goto cleanup;
cleanup:
    if (!is_error(object)) json_object_put(object);
    if (!retVal && LSErrorIsSet(&lserror))
    {
        LSErrorPrint(&lserror, stderr);
        LSErrorFree(&lserror);
    }

    return true;
}
Esempio n. 13
0
/**
* @brief  Set alarm to fire in a fixed time in the future.
*
* luna://com.palm.sleep/time/alarmAdd
*
* Set alarm to expire in T+5hrs. Response will be sent
* as a call to "luna://com.palm.X/alarm".
*
* {"key":"calendarAlarm", "serviceName":"com.palm.X",
*  "relative_time":"05:00:00"}
*
* Subscribing indicates that you want the alarm message as a response to
* the current call.
*
* {"subscribe":true, "key":"calendarAlarm", "serviceName":"com.palm.X",
*  "relative_time":"05:00:00"}
*
* Alarm is sucessfully registered.
* {"alarmId":1}
*
* Alarm failed to be registered:
*
* {"returnValue":false, ...}
* {"returnValue":false,"serivceName":"com.palm.sleep",
*  "errorText":"com.palm.sleep is not running"}
*
* @param  sh
* @param  message
* @param  ctx
*
* @retval
*/
static bool
alarmAdd(LSHandle *sh, LSMessage *message, void *ctx)
{
    time_t alarm_time = 0;
    int rel_hour, rel_min, rel_sec;

    const char *key, *serviceName, *applicationName, *rel_time;
    bool subscribe;

    struct json_object *object;

    int alarm_id;
    bool retVal = false;

    LSError lserror;
    LSErrorInit(&lserror);
    time_t rtctime = 0;

    object = json_tokener_parse(LSMessageGetPayload(message));
    if ( is_error(object) )
    {
        goto malformed_json;
    }

    SLEEPDLOG(LOG_DEBUG, "%s: %s", __FUNCTION__, LSMessageGetPayload(message));

    serviceName = json_object_get_string(
                      json_object_object_get(object, "serviceName"));

    applicationName = LSMessageGetApplicationID(message);

    key = json_object_get_string(json_object_object_get(object, "key"));

    rel_time = json_object_get_string(
                   json_object_object_get(object, "relative_time"));
    if (!rel_time)
    {
        goto invalid_format;
    }

    if (sscanf(rel_time, "%02d:%02d:%02d", &rel_hour, &rel_min, &rel_sec) != 3)
    {
        goto invalid_format;
    }

    nyx_system_query_rtc_time(GetNyxSystemDevice(),&rtctime);

    SLEEPDLOG(LOG_INFO, "%s: (%s %s %s) in %s (rtc %ld)", __FUNCTION__,
              serviceName, applicationName, key, rel_time, rtctime);

    struct json_object *subscribe_json =
        json_object_object_get(object, "subscribe");

    subscribe = json_object_get_boolean(subscribe_json);


    alarm_time = rtc_wall_time();
    alarm_time += rel_sec;
    alarm_time += rel_min * 60;
    alarm_time += rel_hour * 60 * 60;

    retVal = alarm_queue_new(key, false, alarm_time,
                             serviceName, applicationName, subscribe, message, &alarm_id);
    if (!retVal) goto error;

    /*****************
     * Use new timeout API
     */
    {
        char *timeout_key = g_strdup_printf("%s-%d", key, alarm_id);
        _AlarmTimeout timeout;
        _timeout_create(&timeout, "com.palm.sleep", timeout_key,
                        "luna://com.palm.sleep/time/internalAlarmFired",
                        "{}",
                        false /*public bus*/,
                        true /*wakeup*/,
                        "" /*activity_id*/,
                        0 /*activity_duration_ms*/,
                        false /*calendar*/,
                        alarm_time);

        retVal = _timeout_set(&timeout);

        g_free(timeout_key);
        if (!retVal) goto error;
    }
    /*****************/

    /* Send alarm id of sucessful alarm add. */
    GString *reply = g_string_sized_new(512);
    g_string_append_printf(reply, "{\"alarmId\":%d", alarm_id);
    if (subscribe_json)
    {
        g_string_append_printf(reply, ",\"subscribed\":%s",
                               subscribe ? "true":"false");
    }
    g_string_append_printf(reply, "}");

    retVal = LSMessageReply(sh, message, reply->str, &lserror);

    g_string_free(reply, TRUE);
    goto cleanup;
error:
    retVal = LSMessageReply(sh, message, "{\"returnValue\":false,"
                            "\"errorText\":\"Unknown error\"}", &lserror);
    goto cleanup;
invalid_format:
    retVal = LSMessageReply(sh, message, "{\"returnValue\":false,"
                            "\"errorText\":\"Invalid format for alarm time.\"}", &lserror);
    goto cleanup;
malformed_json:
    LSMessageReplyErrorBadJSON(sh, message);
    goto cleanup;
cleanup:
    if (!is_error(object)) json_object_put(object);
    if (!retVal && LSErrorIsSet(&lserror))
    {
        LSErrorPrint(&lserror, stderr);
        LSErrorFree(&lserror);
    }
    return true;
}