static bool jobject_to_string_append (jvalue_ref jref, JStreamRef generating) { SANITY_CHECK_POINTER(jref); if (UNLIKELY(!generating->o_begin (generating))) { PJ_LOG_ERR("Schema validation error, objects are not allowed."); return false; } if (!jis_object (jref)) { const char *asStr = jvalue_tostring_internal_layer2 (jref, NULL, false); generating->string (generating, J_CSTR_TO_BUF("Internal error - not an object")); generating->string (generating, j_cstr_to_buffer(asStr)); // create invalid JSON on purpose return false; } jobject_iter it; jobject_iter_init(&it, jref); jobject_key_value key_value; while (jobject_iter_next(&it, &key_value)) { assert(jis_string(key_value.key)); if(UNLIKELY(!key_value_to_string_append(key_value, generating))) { return false; } } if (UNLIKELY(!generating->o_end (generating))) { PJ_LOG_ERR("Schema validation error, object did not validate against schema"); return false; } return true; }
bool luna_service_message_validate_and_send(LSHandle *handle, LSMessage *message, jvalue_ref reply_obj) { jschema_ref response_schema = NULL; LSError lserror; bool success = true; LSErrorInit(&lserror); response_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL); if(!response_schema) { luna_service_message_reply_error_internal(handle, message); return false; } if (!LSMessageReply(handle, message, jvalue_tostring(reply_obj, response_schema), &lserror)) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); success = false; } jschema_release(&response_schema); return success; }
jvalue_ref luna_service_message_parse_and_validate(const char *payload) { jschema_ref input_schema = NULL; jvalue_ref parsed_obj = NULL; JSchemaInfo schema_info; input_schema = jschema_parse(j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL); jschema_info_init(&schema_info, input_schema, NULL, NULL); parsed_obj = jdom_parse(j_cstr_to_buffer(payload), DOMOPT_NOOPT, &schema_info); jschema_release(&input_schema); if (jis_null(parsed_obj)) return NULL; return parsed_obj; }
/** * @brief If message contains subscribe:true, add the message to subscription list using the default key '/category/method'. * * This is equivalent to LSSubscriptionAdd(sh, key, message, lserror) * where the key is LSMessageGetKind(message). * * @param sh * @param message * @param subscribed * @param lserror * * @retval */ bool LSSubscriptionProcess (LSHandle *sh, LSMessage *message, bool *subscribed, LSError *lserror) { JSchemaInfo schemaInfo; jschema_info_init(&schemaInfo, jschema_all(), NULL, NULL); bool retVal = false; bool subscribePayload = false; jvalue_ref subObj = NULL; const char *payload = LSMessageGetPayload(message); jvalue_ref object = jdom_parse(j_cstr_to_buffer(payload), DOMOPT_NOOPT, &schemaInfo); if (jis_null(object)) { _LSErrorSet(lserror, MSGID_LS_INVALID_JSON, -1, "Unable to parse JSON: %s", payload); goto exit; } if (!jobject_get_exists(object, J_CSTR_TO_BUF("subscribe"), &subObj) || subObj == NULL || !jis_boolean(subObj)) { subscribePayload = false; /* FIXME: I think retVal should be false, but I don't know if anyone * is relying on this behavior. If set to false, make sure to set * LSError */ retVal = true; } else { (void)jboolean_get(subObj, &subscribePayload);/* TODO: handle appropriately */ retVal = true; } if (subscribePayload) { const char *key = LSMessageGetKind(message); retVal = LSSubscriptionAdd(sh, key, message, lserror); } if (retVal && subscribePayload) { *subscribed = true; } else { *subscribed = false; } exit: j_release(&object); return retVal; }
static bool handle_get_info_command(LSHandle *sh, LSMessage *message, void* context) { jvalue_ref reply = jobject_create(); LSError lserror; LSErrorInit(&lserror); char wifi_mac_address[32]={0}, wired_mac_address[32]={0}; jobject_put(reply, J_CSTR_TO_JVAL("returnValue"), jboolean_create(true)); if(get_wifi_mac_address(CONNMAN_WIFI_INTERFACE_NAME, wifi_mac_address) == 0) { jvalue_ref wifi_info = jobject_create(); jobject_put(wifi_info, J_CSTR_TO_JVAL("macAddress"),jstring_create(wifi_mac_address)); jobject_put(reply, J_CSTR_TO_JVAL("wifiInfo"), wifi_info); } else WCA_LOG_ERROR("Error in fetching mac address for wifi interface"); if(get_wifi_mac_address(CONNMAN_WIRED_INTERFACE_NAME, wired_mac_address) == 0) { jvalue_ref wired_info = jobject_create(); jobject_put(wired_info, J_CSTR_TO_JVAL("macAddress"),jstring_create(wired_mac_address)); jobject_put(reply, J_CSTR_TO_JVAL("wiredInfo"), wired_info); } else WCA_LOG_ERROR("Error in fetching mac address for wired interface"); jschema_ref response_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL); if(!response_schema) { LSMessageReplyErrorUnknown(sh,message); goto cleanup; } if (!LSMessageReply(sh, message, jvalue_tostring(reply, response_schema), &lserror)) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } jschema_release(&response_schema); cleanup: if (LSErrorIsSet(&lserror)) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } j_release(&reply); return true; }
bool _CatalogHandleCancel(_Catalog *catalog, LSMessage *cancelMsg, LSError *lserror) { JSchemaInfo schemaInfo; jschema_info_init(&schemaInfo, jschema_all(), NULL, NULL); const char *sender; int token; jvalue_ref tokenObj = NULL; const char *payload = LSMessageGetPayload(cancelMsg); jvalue_ref object = jdom_parse(j_cstr_to_buffer(payload), DOMOPT_NOOPT, &schemaInfo); if (jis_null(object)) { _LSErrorSet(lserror, MSGID_LS_INVALID_JSON, -EINVAL, "Invalid json"); goto error; } sender = LSMessageGetSender(cancelMsg); if (!jobject_get_exists(object, J_CSTR_TO_BUF("token"), &tokenObj) || tokenObj == NULL || !jis_number(tokenObj)) { _LSErrorSet(lserror, MSGID_LS_INVALID_JSON, -EINVAL, "Invalid json"); goto error; } (void)jnumber_get_i32(tokenObj, &token);/* TODO: handle appropriately */ char *uniqueToken = g_strdup_printf("%s.%d", sender, token); _CatalogCallCancelNotifications(catalog, uniqueToken); _CatalogRemoveToken(catalog, uniqueToken, true); g_free(uniqueToken); j_release(&object); return true; error: j_release(&object); return false; }
static bool handle_get_status_command(LSHandle* sh, LSMessage *message, void* context) { jvalue_ref reply = jobject_create(); LSError lserror; LSErrorInit(&lserror); bool subscribed = false; if (LSMessageIsSubscription(message)) { if (!LSSubscriptionProcess(sh, message, &subscribed, &lserror)) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } jobject_put(reply, J_CSTR_TO_JVAL("subscribed"), jboolean_create(subscribed)); if(!connman_manager_is_manager_available(manager)) goto response; } if(!connman_status_check(manager, sh, message)) goto cleanup; send_connection_status(&reply); response: { jschema_ref response_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL); if(!response_schema) { LSMessageReplyErrorUnknown(sh,message); goto cleanup; } if (!LSMessageReply(sh, message, jvalue_tostring(reply, response_schema), &lserror)) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } jschema_release(&response_schema); } cleanup: j_release(&reply); return true; }
/** ******************************************************************************* * @brief Get the service name from a "ServceStatus" message. The name is * allocated and should be freed. * * @param message IN message * * @retval name string on success * @retval NULL on error ******************************************************************************* */ char* LSTransportServiceStatusSignalGetServiceName(_LSTransportMessage *message) { JSchemaInfo schemaInfo; jschema_info_init(&schemaInfo, jschema_all(), NULL, NULL); LS_ASSERT(_LSTransportMessageGetType(message) == _LSTransportMessageTypeServiceDownSignal || _LSTransportMessageGetType(message) == _LSTransportMessageTypeServiceUpSignal); char *service_name = NULL; jvalue_ref service_name_obj = NULL; const char *payload = _LSTransportMessageGetPayload(message); if (!payload) { LOG_LS_ERROR(MSGID_LS_INVALID_JSON, 0, "Unable to get payload from message"); return NULL; } /* get the serviceName part of the JSON object */ jvalue_ref payload_json = jdom_parse(j_cstr_to_buffer(payload), DOMOPT_NOOPT, &schemaInfo); bool ret = jobject_get_exists(payload_json, J_CSTR_TO_BUF(SERVICE_STATUS_SERVICE_NAME), &service_name_obj); if (ret) { raw_buffer service_name_buf = jstring_get_fast(service_name_obj); service_name = g_strndup(service_name_buf.m_str, service_name_buf.m_len); } else { LOG_LS_ERROR(MSGID_LS_INVALID_JSON, 0, "Unable to get service name string from payload: %s", payload); } j_release(&payload_json); return service_name; }
void luna_service_post_subscription(LSHandle *handle, const char *path, const char *method, jvalue_ref reply_obj) { jschema_ref response_schema = NULL; LSError lserror; LSErrorInit(&lserror); response_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL); if(!response_schema) goto cleanup; if (!LSSubscriptionPost(handle, path, method, jvalue_tostring(reply_obj, response_schema), &lserror)) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } cleanup: if (response_schema) jschema_release(&response_schema); }
void connectionmanager_send_status(void) { jvalue_ref reply = jobject_create(); jobject_put(reply, J_CSTR_TO_JVAL("returnValue"), jboolean_create(true)); send_connection_status(&reply); jschema_ref response_schema = jschema_parse (j_cstr_to_buffer("{}"), DOMOPT_NOOPT, NULL); if(response_schema) { const char *payload = jvalue_tostring(reply, response_schema); LSError lserror; LSErrorInit(&lserror); WCA_LOG_INFO("Sending payload %s",payload); if (!LSSubscriptionPost(pLsHandle, "/", "getstatus", payload, &lserror)) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } jschema_release(&response_schema); } j_release(&reply); }
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; }
bool _LSSubscriptionGetJson(LSHandle *sh, jvalue_ref *ret_obj, LSError *lserror) { _Catalog *catalog = sh->catalog; const char *key = NULL; _SubList *sub_list = NULL; GHashTableIter iter; jvalue_ref true_obj = NULL; jvalue_ref array = NULL; jvalue_ref cur_obj = NULL; jvalue_ref sub_array = NULL; jvalue_ref key_name = NULL; jvalue_ref message_obj = NULL; jvalue_ref sub_array_item = NULL; jvalue_ref unique_name_obj = NULL; jvalue_ref service_name_obj = NULL; *ret_obj = jobject_create(); if (*ret_obj == NULL) goto error; true_obj = jboolean_create(true); if (true_obj == NULL) goto error; array = jarray_create(NULL); if (array == NULL) goto error; /* returnValue: true, * subscriptions: [ * { key: key_name, subscribers: [{unique_name: , service_name: }, ...] }, * ... * ] */ _CatalogLock(catalog); g_hash_table_iter_init(&iter, catalog->subscription_lists); while (g_hash_table_iter_next(&iter, (gpointer)&key, (gpointer)&sub_list)) { cur_obj = jobject_create(); if (cur_obj == NULL) goto error; sub_array = jarray_create(NULL); if (sub_array == NULL) goto error; key_name = jstring_create_copy(j_cstr_to_buffer(key)); if (key_name == NULL) goto error; /* iterate over SubList */ int i = 0; const char *token = NULL; const int len = _SubListLen(sub_list); for (i = 0; i < len; i++) { token = _SubListGet(sub_list, i); if (token) { _Subscription *sub = g_hash_table_lookup(catalog->token_map, token); if (!sub) continue; LSMessage *msg = sub->message; const char *unique_name = LSMessageGetSender(msg); const char *service_name = LSMessageGetSenderServiceName(msg); const char *message_body = LSMessageGetPayload(msg); /* create subscribers item and add to sub_array */ sub_array_item = jobject_create(); if (sub_array_item == NULL) goto error; unique_name_obj = unique_name ? jstring_create_copy(j_cstr_to_buffer(unique_name)) : jstring_empty(); if (unique_name_obj == NULL) goto error; service_name_obj = service_name ? jstring_create_copy(j_cstr_to_buffer(service_name)) : jstring_empty(); if (service_name_obj == NULL) goto error; message_obj = message_body ? jstring_create_copy(j_cstr_to_buffer(message_body)) : jstring_empty(); if (message_obj == NULL) goto error; jobject_put(sub_array_item, J_CSTR_TO_JVAL("unique_name"), unique_name_obj); jobject_put(sub_array_item, J_CSTR_TO_JVAL("service_name"), service_name_obj); jobject_put(sub_array_item, J_CSTR_TO_JVAL("subscription_message"), message_obj); jarray_append(sub_array, sub_array_item); sub_array_item = NULL; unique_name_obj = NULL; service_name_obj = NULL; message_obj = NULL; } } jobject_put(cur_obj, J_CSTR_TO_JVAL("key"), key_name); jobject_put(cur_obj, J_CSTR_TO_JVAL("subscribers"), sub_array); jarray_append(array, cur_obj); key_name = NULL; cur_obj = NULL; sub_array = NULL; } jobject_put(*ret_obj, J_CSTR_TO_JVAL("returnValue"), true_obj); jobject_put(*ret_obj, J_CSTR_TO_JVAL("subscriptions"), array); _CatalogUnlock(catalog); return true; error: _CatalogUnlock(catalog); j_release(ret_obj); j_release(&true_obj); j_release(&array); j_release(&cur_obj); j_release(&sub_array); j_release(&key_name); j_release(&sub_array_item); j_release(&unique_name_obj); j_release(&service_name_obj); return false; }