/** * @brief Shutdown the machine forcefully by calling "tellbootie" * * @param sh * @param message with "reason" field for shutdown reason. * @param user_data */ static bool machineOff(LSHandle *sh, LSMessage *message, void *user_data) { struct json_object *object = json_tokener_parse( LSMessageGetPayload(message)); if (is_error(object)) { LSMessageReplyErrorBadJSON(sh, message); goto cleanup; } const char *reason = json_object_get_string( json_object_object_get(object, "reason")); if (!reason) { LSMessageReplyErrorInvalidParams(sh, message); goto cleanup; } MachineForceShutdown(reason); LSMessageReplySuccess(sh, message); cleanup: if (!is_error(object)) json_object_put(object); return true; }
static bool shutdownServicesAck(LSHandle *sh, LSMessage *message, void *user_data) { struct json_object *object = json_tokener_parse( LSMessageGetPayload(message)); if (is_error(object)) { LSMessageReplyErrorBadJSON(sh, message); goto cleanup; } const char *clientId = json_object_get_string( json_object_object_get(object, "clientId")); if (!clientId) { LSMessageReplyErrorInvalidParams(sh, message); goto cleanup; } ShutdownEvent event; event.id = kShutdownEventAck; event.client = client_lookup_service(clientId); shutdown_state_dispatch(&event); cleanup: if (!is_error(object)) json_object_put(object); return true; }
/** * @brief Add a new alarm based on calender time. Sets the callback function based on the "subscribe" option value. */ static bool alarmAddCalendar(LSHandle *sh, LSMessage *message, void *ctx) { struct json_object *object=NULL; object = json_tokener_parse(LSMessageGetPayload(message)); if ( is_error(object) ) { goto malformed_json; } struct json_object *subscribe_json = json_object_object_get(object, "subscribe"); bool subscribe = json_object_get_boolean(subscribe_json); LSMessageRef(message); if(subscribe) { struct context *alrm_ctx=NULL; alrm_ctx = malloc(sizeof(struct context)); if(!alrm_ctx) goto error; memset(alrm_ctx,0,sizeof(struct context)); alrm_ctx->replyMessage = message; LSCall(GetLunaServiceHandle(), "palm://com.palm.sleep/time/alarmAddCalender", LSMessageGetPayload(message), alarms_timeout_subscribe_cb, (void *)alrm_ctx, &alrm_ctx->call_token, NULL); } else LSCallOneReply(GetLunaServiceHandle(), "palm://com.palm.sleep/time/alarmAddCalender", LSMessageGetPayload(message), alarms_timeout_cb, (void *)message, NULL, NULL); goto cleanup; malformed_json: LSMessageReplyErrorBadJSON(sh, message); goto cleanup; error: POWERDLOG(LOG_ERR,"Failed to allocate memory"); LSMessageReplyErrorUnknown(sh, message); cleanup: if (!is_error(object)) json_object_put(object); return true; }
/** * @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_DEBUG("alarmRemove() : %s", 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; }
/** * @brief Query for set of alarms identified by 'serviceName' & 'key'. * * {"serviceName":"com.palm.X", "key":"calendarAlarm"} * * Response: * * {"alarms": * [{"alarmId":1,"key":"calendarAlarm"}, * {"alarmId":2,"key":"calendarAlarm"}, * ]} * * @param sh * @param message * @param ctx * * @retval */ static bool alarmQuery(LSHandle *sh, LSMessage *message, void *ctx) { bool retVal; const char *serviceName, *key; struct json_object *object; GString *alarm_str = NULL; GString *buf = NULL; object = json_tokener_parse(LSMessageGetPayload(message)); if (is_error(object)) { goto malformed_json; } serviceName = json_object_get_string( json_object_object_get(object, "serviceName")); key = json_object_get_string( json_object_object_get(object, "key")); if (!serviceName || !key) { goto invalid_format; } alarm_str = g_string_sized_new(512); if (!alarm_str) { goto cleanup; } bool first = true; 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->serviceName && alarm->key && (strcmp(alarm->serviceName, serviceName) == 0) && (strcmp(alarm->key, key) == 0)) { g_string_append_printf(alarm_str, "%s{\"alarmId\":%d,\"key\":\"%s\"}", first ? "" : "\n,", alarm->id, alarm->key); first = false; } iter = next; } buf = g_string_sized_new(512); g_string_append_printf(buf, "{\"alarms\": [%s]}", alarm_str->str); LSError lserror; LSErrorInit(&lserror); retVal = LSMessageReply(sh, message, buf->str, &lserror); if (!retVal) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } goto cleanup; invalid_format: retVal = LSMessageReply(sh, message, "{\"returnValue\":false," "\"errorText\":\"alarmQuery parameters are missing.\"}", &lserror); goto cleanup; malformed_json: LSMessageReplyErrorBadJSON(sh, message); goto cleanup; cleanup: if (alarm_str) { g_string_free(alarm_str, TRUE); } if (buf) { g_string_free(buf, TRUE); } if (!is_error(object)) { json_object_put(object); } return true; }
/** * @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; gchar **cal_date_str; time_t alarm_time = 0; LSError lserror; LSErrorInit(&lserror); object = json_tokener_parse(LSMessageGetPayload(message)); if (is_error(object)) { goto malformed_json; } SLEEPDLOG_DEBUG("alarmAddCalendar() : %s", 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 (!ConvertJsonTime(cal_time, &hour, &min, &sec)) { goto invalid_format; } cal_date_str = g_strsplit(cal_date, "-", 3); if ((NULL == cal_date_str[0]) || (NULL == cal_date_str[1]) || (NULL == cal_date_str[2])) { goto invalid_format; } month = atoi(cal_date_str[0]); day = atoi(cal_date_str[1]); year = atoi(cal_date_str[2]); g_strfreev(cal_date_str); if (hour < 0 || hour > 24 || min < 0 || min > 59 || sec < 0 || sec > 59 || month < 1 || month > 12 || day < 1 || day > 31 || year < 0) { goto invalid_format; } SLEEPDLOG_DEBUG("alarmAddCalendar() : (%s %s %s) at %s %s", 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; }
/** * @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_DEBUG("%s", 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 (!ConvertJsonTime(rel_time, &rel_hour, &rel_min, &rel_sec) || (rel_hour < 0 || rel_hour > 24 || rel_min < 0 || rel_min > 59 || rel_sec < 0 || rel_sec > 59)) { goto invalid_format; } nyx_system_query_rtc_time(GetNyxSystemDevice(), &rtctime); SLEEPDLOG_DEBUG("alarmAdd(): (%s %s %s) in %s (rtc %ld)", 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 = reference_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; }
static bool handle_set_state_command(LSHandle *sh, LSMessage *message, void* context) { if(!connman_status_check(manager, sh, message)) return true; jvalue_ref parsedObj = {0}; jschema_ref input_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL); if(!input_schema) return false; JSchemaInfo schemaInfo; jschema_info_init(&schemaInfo, input_schema, NULL, NULL); // no external refs & no error handlers parsedObj = jdom_parse(j_cstr_to_buffer(LSMessageGetPayload(message)), DOMOPT_NOOPT, &schemaInfo); jschema_release(&input_schema); if (jis_null(parsedObj)) { LSMessageReplyErrorBadJSON(sh, message); return true; } jvalue_ref wifiObj = {0}, wiredObj = {0}; gboolean enable_wifi = FALSE, enable_wired = FALSE; gboolean invalidArg = TRUE; if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("wifi"), &wifiObj)) { if (jstring_equal2(wifiObj, J_CSTR_TO_BUF("enabled"))) { enable_wifi = TRUE; } else if (jstring_equal2(wifiObj, J_CSTR_TO_BUF("disabled"))) { enable_wifi = FALSE; } else { goto invalid_params; } /* * Check if we are enabling an already enabled service, * or disabling an already disabled service */ if((enable_wifi && is_wifi_powered()) || (!enable_wifi && !is_wifi_powered())) { WCA_LOG_DEBUG("Wifi technology already enabled/disabled"); } else { set_wifi_state(enable_wifi); } invalidArg = FALSE; } if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("wired"), &wiredObj)) { if (jstring_equal2(wiredObj, J_CSTR_TO_BUF("enabled"))) { enable_wired = TRUE; } else if (jstring_equal2(wiredObj, J_CSTR_TO_BUF("disabled"))) { enable_wired = FALSE; } else { goto invalid_params; } /* * Check if we are enabling an already enabled service, * or disabling an already disabled service */ if((enable_wired && is_ethernet_powered()) || (!enable_wired && !is_ethernet_powered())) { WCA_LOG_DEBUG("Wired technology already enabled/disabled"); } else { set_ethernet_state(enable_wired); } invalidArg = FALSE; } if(invalidArg == TRUE) { goto invalid_params; } LSMessageReplySuccess(sh,message); goto cleanup; invalid_params: LSMessageReplyErrorInvalidParams(sh, message); cleanup: j_release(&parsedObj); return true; }
static bool handle_set_dns_command(LSHandle *sh, LSMessage *message, void* context) { if(!connman_status_check(manager, sh, message)) return true; jvalue_ref parsedObj = {0}; jschema_ref input_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL); if(!input_schema) return false; JSchemaInfo schemaInfo; jschema_info_init(&schemaInfo, input_schema, NULL, NULL); // no external refs & no error handlers parsedObj = jdom_parse(j_cstr_to_buffer(LSMessageGetPayload(message)), DOMOPT_NOOPT, &schemaInfo); jschema_release(&input_schema); if (jis_null(parsedObj)) { LSMessageReplyErrorBadJSON(sh, message); return true; } jvalue_ref ssidObj = {0}, dnsObj = {0}; GStrv dns = NULL; gchar *ssid = NULL; if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("dns"), &dnsObj)) { int i, dns_arrsize = jarray_size(dnsObj); dns = (GStrv) g_new0(GStrv, 1); for(i = 0; i < dns_arrsize; i++) { raw_buffer dns_buf = jstring_get(jarray_get(dnsObj, i)); dns[i] = g_strdup(dns_buf.m_str); jstring_free_buffer(dns_buf); } } else { LSMessageReplyErrorInvalidParams(sh, message); goto Exit; } if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("ssid"), &ssidObj)) { raw_buffer ssid_buf = jstring_get(ssidObj); ssid = g_strdup(ssid_buf.m_str); jstring_free_buffer(ssid_buf); } connman_service_t *service = get_connman_service(ssid); if(NULL != service) { if(connman_service_set_nameservers(service, dns)) LSMessageReplySuccess(sh, message); else LSMessageReplyErrorUnknown(sh, message); goto Exit; } else LSMessageReplyCustomError(sh, message, "No connected network"); Exit: g_strfreev(dns); g_free(ssid); j_release(&parsedObj); return true; }
static bool handle_set_ipv4_command(LSHandle *sh, LSMessage *message, void* context) { if(!connman_status_check(manager, sh, message)) return true; jvalue_ref parsedObj = {0}; jschema_ref input_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL); if(!input_schema) return false; JSchemaInfo schemaInfo; jschema_info_init(&schemaInfo, input_schema, NULL, NULL); // no external refs & no error handlers parsedObj = jdom_parse(j_cstr_to_buffer(LSMessageGetPayload(message)), DOMOPT_NOOPT, &schemaInfo); jschema_release(&input_schema); if (jis_null(parsedObj)) { LSMessageReplyErrorBadJSON(sh, message); return true; } jvalue_ref ssidObj = {0}, methodObj = {0}, addressObj = {0}, netmaskObj = {0}, gatewayObj = {0}; ipv4info_t ipv4 = {0}; gchar *ssid = NULL; gboolean invalidArg = TRUE; if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("method"), &methodObj)) { raw_buffer method_buf = jstring_get(methodObj); ipv4.method = g_strdup(method_buf.m_str); jstring_free_buffer(method_buf); invalidArg = FALSE; } if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("address"), &addressObj)) { raw_buffer address_buf = jstring_get(addressObj); ipv4.address = g_strdup(address_buf.m_str); jstring_free_buffer(address_buf); invalidArg = FALSE; } if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("netmask"), &netmaskObj)) { raw_buffer netmask_buf = jstring_get(netmaskObj); ipv4.netmask = g_strdup(netmask_buf.m_str); jstring_free_buffer(netmask_buf); invalidArg = FALSE; } if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("gateway"), &gatewayObj)) { raw_buffer gateway_buf = jstring_get(gatewayObj); ipv4.gateway = g_strdup(gateway_buf.m_str); jstring_free_buffer(gateway_buf); invalidArg = FALSE; } if(jobject_get_exists(parsedObj, J_CSTR_TO_BUF("ssid"), &ssidObj)) { raw_buffer ssid_buf = jstring_get(ssidObj); ssid = g_strdup(ssid_buf.m_str); jstring_free_buffer(ssid_buf); invalidArg = FALSE; } if(invalidArg == TRUE) { LSMessageReplyErrorInvalidParams(sh, message); goto Exit; } connman_service_t *service = get_connman_service(ssid); if(NULL != service) { if(connman_service_set_ipv4(service, &ipv4)) LSMessageReplySuccess(sh, message); else LSMessageReplyErrorUnknown(sh, message); goto Exit; } else { LSMessageReplyCustomError(sh, message, "Network not found"); } Exit: g_free(ipv4.method); g_free(ipv4.address); g_free(ipv4.netmask); g_free(ipv4.gateway); g_free(ssid); j_release(&parsedObj); return true; }