/** * @brief Set the network the modem should connect to. * * JSON format: * request: * { * "automatic": <boolean>, * "id": <string>, * } * response: * { * "returnValue": <boolean>, * "errorCode": <integer>, * "errorString": <string>, * } **/ bool _service_network_set_cb(LSHandle *handle, LSMessage *message, void *user_data) { struct telephony_service *service = user_data; struct luna_service_req_data *req_data = NULL; jvalue_ref parsed_obj = NULL; jvalue_ref automatic_obj = NULL; jvalue_ref id_obj = NULL; const char *payload; raw_buffer id_buf; const char *id = NULL; bool automatic = false; if (!service->initialized) { luna_service_message_reply_custom_error(handle, message, "Backend not initialized"); return true; } if (!service->driver || !service->driver->network_set) { g_warning("No implementation available for service networkSet API method"); luna_service_message_reply_error_not_implemented(handle, message); goto cleanup; } payload = LSMessageGetPayload(message); parsed_obj = luna_service_message_parse_and_validate(payload); if (jis_null(parsed_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } if (!jobject_get_exists(parsed_obj, J_CSTR_TO_BUF("automatic"), &automatic_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } jboolean_get(automatic_obj, &automatic); if (!automatic) { if (!jobject_get_exists(parsed_obj, J_CSTR_TO_BUF("id"), &id_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } id_buf = jstring_get(id_obj); id = id_buf.m_str; } req_data = luna_service_req_data_new(handle, message); service->driver->network_set(service, automatic, id, telephonyservice_common_finish, req_data); cleanup: if (!jis_null(parsed_obj)) j_release(&parsed_obj); return true; }
/** * @brief Set the radio access technology mode * * JSON format: * request: * { * "mode": <string>, * } * response: * { * "returnValue": <boolean>, * "errorCode": <integer>, * "errorString": <string>, * } **/ bool _service_rat_set_cb(LSHandle *handle, LSMessage *message, void *user_data) { struct telephony_service *service = user_data; struct luna_service_req_data *req_data = NULL; jvalue_ref parsed_obj = NULL; jvalue_ref mode_obj = NULL; const char *payload; raw_buffer mode_buf; enum telephony_radio_access_mode mode; if (!service->initialized) { luna_service_message_reply_custom_error(handle, message, "Backend not initialized"); return true; } if (!service->driver || !service->driver->rat_set) { g_warning("No implementation available for service ratSet API method"); luna_service_message_reply_error_not_implemented(handle, message); goto cleanup; } payload = LSMessageGetPayload(message); parsed_obj = luna_service_message_parse_and_validate(payload); if (jis_null(parsed_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } if (!jobject_get_exists(parsed_obj, J_CSTR_TO_BUF("mode"), &mode_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } mode_buf = jstring_get(mode_obj); mode = telephony_radio_access_mode_from_string(mode_buf.m_str); if (mode < 0) { luna_service_message_reply_error_invalid_params(handle, message); goto cleanup; } req_data = luna_service_req_data_new(handle, message); service->driver->rat_set(service, mode, telephonyservice_common_finish, req_data); cleanup: if (!jis_null(parsed_obj)) j_release(&parsed_obj); return true; }
static bool set_volume_cb(LSHandle *handle, LSMessage *message, void *user_data) { struct audio_service *service = user_data; const char *payload; jvalue_ref parsed_obj = NULL; jvalue_ref volume_obj = NULL; struct luna_service_req_data *req; int new_volume = 0; if (!service->context_initialized) { luna_service_message_reply_custom_error(handle, message, "Not yet initialized"); return true; } payload = LSMessageGetPayload(message); parsed_obj = luna_service_message_parse_and_validate(payload); if (jis_null(parsed_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } if (!jobject_get_exists(parsed_obj, J_CSTR_TO_BUF("volume"), &volume_obj) || !jis_number(volume_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } jnumber_get_i32(volume_obj, &new_volume); if (new_volume < 0 || new_volume > 100) { luna_service_message_reply_custom_error(handle, message, "Volume out of range. Must be in [0;100]"); goto cleanup; } if (service->new_volume == service->volume) { luna_service_message_reply_custom_error(handle, message, "Provided volume doesn't differ from current one"); goto cleanup; } req = luna_service_req_data_new(handle, message); req->user_data = service; set_volume(service, service->new_volume, req); cleanup: if (!jis_null(parsed_obj)) j_release(&parsed_obj); return true; }
static bool set_mic_mute_cb(LSHandle *handle, LSMessage *message, void *user_data) { struct audio_service *service = user_data; const char *payload; jvalue_ref parsed_obj = NULL; struct luna_service_req_data *req; pa_operation *op; if (!service->context_initialized) { luna_service_message_reply_custom_error(handle, message, "Not yet initialized"); return true; } payload = LSMessageGetPayload(message); parsed_obj = luna_service_message_parse_and_validate(payload); if (jis_null(parsed_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } service->mic_mute = luna_service_message_get_boolean(parsed_obj, "micMute", service->mic_mute); req = luna_service_req_data_new(handle, message); req->user_data = service; op = pa_context_get_source_info_list(service->context, mm_sourceinfo_cb, req); pa_operation_unref(op); cleanup: if (!jis_null(parsed_obj)) j_release(&parsed_obj); return true; }
static bool play_feedback_cb(LSHandle *handle, LSMessage *message, void *user_data) { struct audio_service *service = user_data; struct play_feedback_data *pfd; const char *payload; jvalue_ref parsed_obj; char *name, *sink; bool play; if (!service->context_initialized) { luna_service_message_reply_custom_error(handle, message, "Not yet initialized"); return true; } payload = LSMessageGetPayload(message); parsed_obj = luna_service_message_parse_and_validate(payload); if (jis_null(parsed_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } name = luna_service_message_get_string(parsed_obj, "name", NULL); if (!name) { luna_service_message_reply_custom_error(handle, message, "Invalid parameters: name parameter is required"); goto cleanup; } play = luna_service_message_get_boolean(parsed_obj, "play", true); sink = luna_service_message_get_string(parsed_obj, "sink", NULL); pfd = g_new0(struct play_feedback_data, 1); pfd->service = service; pfd->handle = handle; pfd->message = message; pfd->name = name; pfd->sink = sink; pfd->play = play; LSMessageRef(message); if (!preload_sample(service, pfd)) { luna_service_message_reply_custom_error(handle, message, "Could not preload sample"); LSMessageUnref(message); g_free(pfd); g_free(name); g_free(sink); goto cleanup; } cleanup: if (!jis_null(parsed_obj)) j_release(&parsed_obj); return true; }
bool service_retrieve_package_info_cb(LSHandle *handle, LSMessage *message, void *user_data) { jvalue_ref reply_obj; jvalue_ref parsed_obj; jvalue_ref name_obj; jvalue_ref depends_obj; jvalue_ref recommends_obj; jvalue_ref conflicts_obj; pkg_t *package = NULL; const char *payload = NULL; const char *pkgname = NULL; raw_buffer name_buf; int n; payload = LSMessageGetPayload(message); parsed_obj = luna_service_message_parse_and_validate(payload); if (jis_null(parsed_obj)) { luna_service_message_reply_error_bad_json(handle, message); return true; } if (!jobject_get_exists(parsed_obj, J_CSTR_TO_BUF("name"), &name_obj)) { luna_service_message_reply_error_bad_json(handle, message); return true; } if (opkg_new()) { luna_service_message_reply_error_internal(handle, message); return true; } name_buf = jstring_get(name_obj); package = opkg_find_package(name_buf.m_str, NULL, NULL, NULL); if (!package) { luna_service_message_reply_custom_error(handle, message, "Package does not exist"); goto cleanup; } set_flags_from_control(package); reply_obj = jobject_create(); jobject_put(reply_obj, J_CSTR_TO_JVAL("returnValue"), jboolean_create(true)); jobject_put(reply_obj, J_CSTR_TO_JVAL("version"), jstring_create(package->version ? package->version : "")); jobject_put(reply_obj, J_CSTR_TO_JVAL("revision"), jstring_create(package->revision ? package->revision : "")); jobject_put(reply_obj, J_CSTR_TO_JVAL("architecture"), jstring_create(package->architecture ? package->architecture : "")); jobject_put(reply_obj, J_CSTR_TO_JVAL("section"), jstring_create(package->section ? package->section : "")); jobject_put(reply_obj, J_CSTR_TO_JVAL("maintainer"), jstring_create(package->maintainer ? package->maintainer : "")); jobject_put(reply_obj, J_CSTR_TO_JVAL("description"), jstring_create(package->description ? package->description : "")); jobject_put(reply_obj, J_CSTR_TO_JVAL("tags"), jstring_create(package->tags ? package->tags : "")); jobject_put(reply_obj, J_CSTR_TO_JVAL("size"), jnumber_create_i32(package->size)); jobject_put(reply_obj, J_CSTR_TO_JVAL("installed_size"), jnumber_create_i32(package->installed_size)); jobject_put(reply_obj, J_CSTR_TO_JVAL("auto_installed"), jboolean_create(package->auto_installed > 0 ? true : false)); if (!luna_service_message_validate_and_send(handle, message, reply_obj)) { luna_service_message_reply_error_internal(handle, message); goto cleanup; } cleanup: opkg_free(); return true; }
bool get_property_cb(LSHandle *handle, LSMessage *message, void *user_data) { jvalue_ref parsed_obj = NULL; jvalue_ref keys_obj = NULL; jvalue_ref reply_obj = NULL; jvalue_ref props_obj = NULL; jvalue_ref prop_obj = NULL; char *payload, value[PROP_VALUE_MAX]; int n; raw_buffer key_buf; payload = LSMessageGetPayload(message); parsed_obj = luna_service_message_parse_and_validate(payload); if (jis_null(parsed_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } if (!jobject_get_exists(parsed_obj, J_CSTR_TO_BUF("keys"), &keys_obj) || !jis_array(keys_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } reply_obj = jobject_create(); props_obj = jarray_create(NULL); for (n = 0; n < jarray_size(keys_obj); n++) { jvalue_ref key_obj = jarray_get(keys_obj, n); if (!jis_string(key_obj)) continue; key_buf = jstring_get(key_obj); if (strlen(key_buf.m_str) == 0) continue; property_get(key_buf.m_str, value, ""); prop_obj = jobject_create(); jobject_put(prop_obj, jstring_create(key_buf.m_str), jstring_create(value)); jarray_append(props_obj, prop_obj); } jobject_put(reply_obj, J_CSTR_TO_JVAL("properties"), props_obj); jobject_put(reply_obj, J_CSTR_TO_JVAL("returnValue"), jboolean_create(true)); if (!luna_service_message_validate_and_send(handle, message, reply_obj)) goto cleanup; cleanup: if (!jis_null(parsed_obj)) j_release(&parsed_obj); if (!jis_null(reply_obj)) j_release(&reply_obj); return true; }
/** * @brief Subscribe for a specific group of events * * JSON format: * {"events":"<type>"} **/ bool _service_subscribe_cb(LSHandle *handle, LSMessage *message, void *user_data) { jvalue_ref parsed_obj = NULL; jvalue_ref events_obj = NULL; jvalue_ref reply_obj = NULL; bool result = false; LSError lserror; const char *payload; bool subscribed = false; payload = LSMessageGetPayload(message); parsed_obj = luna_service_message_parse_and_validate(payload); if (jis_null(parsed_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } if (!jobject_get_exists(parsed_obj, J_CSTR_TO_BUF("events"), &events_obj)) { luna_service_message_reply_error_invalid_params(handle, message); goto cleanup; } if (jstring_equal2(events_obj, J_CSTR_TO_BUF("network"))) { result = LSSubscriptionAdd(handle, "/networkStatusQuery", message, &lserror); if (!result) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); luna_service_message_reply_error_internal(handle, message); goto cleanup; } subscribed = true; } else if (jstring_equal2(events_obj, J_CSTR_TO_BUF("signal"))) { result = LSSubscriptionAdd(handle, "/signalStrengthQuery", message, &lserror); if (!result) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); luna_service_message_reply_error_internal(handle, message); goto cleanup; } subscribed = true; } reply_obj = jobject_create(); jobject_put(reply_obj, J_CSTR_TO_JVAL("returnValue"), jboolean_create(true)); jobject_put(reply_obj, J_CSTR_TO_JVAL("errorCode"), jnumber_create_i32(0)); jobject_put(reply_obj, J_CSTR_TO_JVAL("errorText"), jstring_create("success")); jobject_put(reply_obj, J_CSTR_TO_JVAL("subscribed"), jboolean_create(subscribed)); if (!luna_service_message_validate_and_send(handle, message, reply_obj)) { luna_service_message_reply_error_internal(handle, message); goto cleanup; } cleanup: j_release(&parsed_obj); return true; }
bool _service_power_set_cb(LSHandle *handle, LSMessage *message, void *user_data) { struct telephony_service *service = user_data; struct luna_service_req_data *req_data = NULL; bool power = false; jvalue_ref parsed_obj = NULL; jvalue_ref state_obj = NULL; jvalue_ref save_obj = NULL; const char *payload; bool should_save = false; if (!service->initialized) { luna_service_message_reply_custom_error(handle, message, "Backend not initialized"); return true; } if (!service->driver || !service->driver->power_set) { g_warning("No implementation available for service powerSet API method"); luna_service_message_reply_error_not_implemented(handle, message); goto cleanup; } payload = LSMessageGetPayload(message); parsed_obj = luna_service_message_parse_and_validate(payload); if (jis_null(parsed_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } if (!jobject_get_exists(parsed_obj, J_CSTR_TO_BUF("state"), &state_obj)) { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } if (jstring_equal2(state_obj, J_CSTR_TO_BUF("on"))) power = true; else if (jstring_equal2(state_obj, J_CSTR_TO_BUF("off"))) power = false; else if (jstring_equal2(state_obj, J_CSTR_TO_BUF("default"))) { power = true; } else { luna_service_message_reply_error_bad_json(handle, message); goto cleanup; } if (jobject_get_exists(parsed_obj, J_CSTR_TO_BUF("save"), &save_obj)) { jboolean_get(save_obj, &should_save); if (should_save) telephony_settings_store(TELEPHONY_SETTINGS_TYPE_POWER_STATE, power ? "{\"state\":true}" : "{\"state\":false}"); } service->power_off_pending = !power; req_data = luna_service_req_data_new(handle, message); req_data->user_data = service; service->driver->power_set(service, power, _service_power_set_finish, req_data); cleanup: if (!jis_null(parsed_obj)) j_release(&parsed_obj); return true; }