/** ******************************************************************************* * @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; }
/** * @brief Send a reply to a message using the bus identified by LSHandle. * * To use the same bus upon which the message arrived, it is * recommended to use LSMessageRespond(). * * @param sh * @param lsmsg * @param replyPayload * @param lserror * * @retval */ bool LSMessageReply(LSHandle *sh, LSMessage *lsmsg, const char *replyPayload, LSError *lserror) { _LSErrorIfFail (sh != NULL, lserror); _LSErrorIfFail (lsmsg != NULL, lserror); _LSErrorIfFail (replyPayload != NULL, lserror); LSHANDLE_VALIDATE(sh); if (unlikely(_ls_enable_utf8_validation)) { if (!g_utf8_validate (replyPayload, -1, NULL)) { _LSErrorSet(lserror, -EINVAL, "%s: payload is not utf-8", __FUNCTION__); return false; } } if (unlikely(strcmp(replyPayload, "") == 0)) { _LSErrorSet(lserror, -EINVAL, "Empty payload is not valid JSON. Use {}"); return false; } if (DEBUG_TRACING) { if (DEBUG_VERBOSE) { g_debug("TX: LSMessageReply token <<%ld>> %s", LSMessageGetToken(lsmsg), replyPayload); } else { g_debug("TX: LSMessageReply token <<%ld>>", LSMessageGetToken(lsmsg)); } } if (_LSTransportMessageGetType(lsmsg->transport_msg) == _LSTransportMessageTypeReply) { g_warning("%s: \nYou are attempting to send a reply to a reply message. \n" "I'm going to allow this for now to more easily reproduce some bugs \n" "we encountered with services using LSCustomWaitForMessage \n" "receiving a reply-to-a-reply, but soon this will return an error.", __FUNCTION__); } if (unlikely(LSMessageGetConnection(lsmsg) != sh)) { _LSErrorSet(lserror, -EINVAL, "%s: You are replying to message on different bus.\n" " If you can't identify which bus, " "try LSMessageRespond() instead.", __FUNCTION__); return false; } bool retVal = _LSTransportSendReply(lsmsg->transport_msg, replyPayload, lserror); return retVal; }
static LSMessageHandlerResult _LSMonitorListMessageHandler(_LSTransportMessage *message, void *context) { LS_ASSERT(_LSTransportMessageGetType(message) == _LSTransportMessageTypeListClientsReply); static int call_count = 0; const char *unique_name = NULL; const char *service_name = NULL; int32_t pid = 0; const char *exe_path = NULL; const char *service_type = NULL; static int total_sub_services = 0; int type = *(int*)context; bool iter_ret = false; static GSList *public_monitor_info = NULL; static GSList *private_monitor_info = NULL; GSList **cur_list = NULL; _LSTransportMessageIter iter; if (type == HUB_TYPE_PUBLIC) { cur_list = &public_monitor_info; } else { cur_list = &private_monitor_info; } _LSTransportMessageIterInit(message, &iter); while (_LSTransportMessageIterHasNext(&iter)) { _LSMonitorListInfo *info = g_malloc(sizeof(_LSMonitorListInfo)); if (!info) { g_critical("Out of memory when allocating list info"); exit(EXIT_FAILURE); } iter_ret = _LSTransportMessageGetString(&iter, &unique_name); if (!iter_ret) break; info->unique_name = g_strdup(unique_name); _LSTransportMessageIterNext(&iter); iter_ret = _LSTransportMessageGetString(&iter, &service_name); if (!iter_ret) break; info->service_name = g_strdup(service_name); _LSTransportMessageIterNext(&iter); iter_ret = _LSTransportMessageGetInt32(&iter, &pid); if (!iter_ret) break; info->pid = pid; _LSTransportMessageIterNext(&iter); iter_ret = _LSTransportMessageGetString(&iter, &exe_path); if (!iter_ret) break; info->exe_path = g_strdup(exe_path); _LSTransportMessageIterNext(&iter); iter_ret = _LSTransportMessageGetString(&iter, &service_type); if (!iter_ret) break; info->service_type = g_strdup(service_type); _LSTransportMessageIterNext(&iter); if (_CanGetSubscriptionInfo(info)) { total_sub_services++; } *cur_list = g_slist_prepend(*cur_list, info); } /* Process and display when we receive public and private responses */ if (++call_count == 2) { if (list_subscriptions || list_malloc) { LSError lserror; LSErrorInit(&lserror); LSHandle *private_sh = NULL; LSHandle *public_sh = NULL; _DisconnectCustomTransport(); if (total_sub_services == 0) { _PrintSubscriptionResults(); g_main_loop_quit(mainloop); goto Done; } /* register as a "high-level" client */ if (!LSRegisterPubPriv(MONITOR_NAME, &private_sh, false, &lserror)) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } else { LSGmainAttach(private_sh, mainloop, &lserror); _ListServiceSubscriptions(private_sh, _SubscriptionResultsCallback, private_monitor_info, total_sub_services, &private_sub_replies); } /* Same for the public hub */ if (!LSRegisterPubPriv(MONITOR_NAME, &public_sh, true, &lserror)) { LSErrorPrint(&lserror, stderr); LSErrorFree(&lserror); } else { LSGmainAttach(public_sh, mainloop, &lserror); _ListServiceSubscriptions(public_sh, _SubscriptionResultsCallback, public_monitor_info, total_sub_services, &public_sub_replies); } } else if (list_clients) { fprintf(stdout, "PRIVATE HUB CLIENTS:\n"); fprintf(stdout, "%-10s\t%-30s\t%-35s\t%-20s\t%-20s\n", "PID", "SERVICE NAME", "EXE", "TYPE", "UNIQUE NAME"); _PrintMonitorListInfo(private_monitor_info); fprintf(stdout, "\n"); _FreeMonitorListInfo(&private_monitor_info); fprintf(stdout, "PUBLIC HUB CLIENTS:\n"); fprintf(stdout, "%-10s\t%-30s\t%-35s\t%-20s\t%-20s\n", "PID", "SERVICE NAME", "EXE", "TYPE", "UNIQUE NAME"); _PrintMonitorListInfo(public_monitor_info); fprintf(stdout, "\n"); _FreeMonitorListInfo(&public_monitor_info); g_main_loop_quit(mainloop); } } Done: return LSMessageHandlerResultHandled; }