/**
 *******************************************************************************
 * @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;
}
Beispiel #3
0
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;
}