Beispiel #1
0
static void on_di_data_available(const qeocore_reader_t *reader,
                                            const qeocore_data_t *data,
                                            uintptr_t userdata){

    
    qeo_retcode_t ret = QEO_OK;
    switch (qeocore_data_get_status(data)) {
        case QEOCORE_NOTIFY:
            qeo_log_d("Notify received");
            break;
        case QEOCORE_DATA:
            qeo_log_d("Data received");
            ret = qeo_walk_tsm_for_unmarshal(_types, org_qeo_system_DeviceInfo_type, data, (uintptr_t)&_rcvd_di, QEO_T2D_FLAGS_ALL, &_di_ucbs);
            break;
        case QEOCORE_NO_MORE_DATA:
            qeo_log_d("No more data received");
            break;
        case QEOCORE_REMOVE:
            qeo_log_d("remove received");
            break;
        case QEOCORE_ERROR:
            qeo_log_e("no callback called due to prior error");
            break;
    }
    ck_assert_int_eq(ret, QEO_OK);

}
Beispiel #2
0
X509_NAME* cnhelper_create_dn(const qeo_platform_device_info *info)
{
    X509_NAME* dn = NULL;

    do {
        dn = X509_NAME_new();
        if (dn) {
            char devicename[MAX_CN_LENGTH];

            strncpy(devicename, info->userFriendlyName, sizeof(devicename));
            if (devicename[sizeof(devicename)-1] != '\0'){
                strncpy(&devicename[sizeof(devicename)-4], "...", 4);
                qeo_log_w("Device name exceeds the maximal allowed length of <%d> characters, cutting it off to <%s>.", sizeof(devicename)-1, devicename);
            }
            //TODO: now only the friendly name is forwarded to the server, in the future this needs to be extended
            if (!X509_NAME_add_entry_by_NID(dn, NID_commonName, MBSTRING_ASC, (unsigned char* ) devicename, -1, -1, 0)) {
                X509_NAME_free(dn);
                dn = NULL;
                break;
            }
        }
        qeo_log_d("created DN for device");
    } while (0);

    return dn;
}
curl_socket_t qmcu_socket_open_function(void *clientp, curlsocktype purpose, struct curl_sockaddr *addr) {
    curl_socket_t sock = socket(addr->family, addr->socktype, addr->protocol);
    if (sock >= 0 && clientp) {
        qeo_mgmt_client_ctx_t* ctx = (qeo_mgmt_client_ctx_t*) clientp;
        if (_lock_fd_mutex(ctx)) {
            if (ctx->is_closed) {
                qeo_log_d("management thread shutdown requested, not creating socket");
                close(sock);
                _unlock_fd_mutex(ctx);
                return CURL_SOCKET_BAD;
            }
            qeo_mgmt_fd_link_t* new_fd_link = malloc(sizeof(qeo_mgmt_fd_link_t));
            if (new_fd_link) {
                new_fd_link->fd = sock;
                new_fd_link->next = NULL;
                if (ctx->fd_list == NULL) {
                    ctx->fd_list = new_fd_link;
                } else {
                    qeo_mgmt_fd_link_t* link = ctx->fd_list;
                    while (link->next) {
                        link = link->next;
                    }
                    link->next = new_fd_link;
                }
            }
            _unlock_fd_mutex(ctx);
        }
    }
    return sock;
}
Beispiel #4
0
qeo_retcode_t qeo_json_get_device_id(char **json_device_id)
{
    qeo_retcode_t                   ret           = QEO_EINVAL;
    const qeo_platform_device_info  *qeo_dev_info = NULL;
    json_t                          *device_id    = NULL;
    char                            *upper        = NULL;
    char                            *lower        = NULL;

    do {
        if (NULL == json_device_id) {
            qeo_log_e("NULL == json_device_id");
            break;
        }

        qeo_dev_info = qeo_platform_get_device_info();
        if (qeo_dev_info == NULL) {
            qeo_log_d("qeo_platform_get_device_info failed");
            ret = QEO_EFAIL;
            break;
        }

        device_id = json_object();
        if (NULL == device_id) {
            qeo_log_e("unable to create new JSON object");
            break;
        }

        if (-1 == asprintf(&upper, "%" PRId64, qeo_dev_info->qeoDeviceId.upperId)) {
            qeo_log_e("asprintf failed");
            break;
        }

        if (-1 == asprintf(&lower, "%" PRId64, qeo_dev_info->qeoDeviceId.lowerId)) {
            qeo_log_e("asprintf failed");
            break;
        }

        if (0 != json_object_set_new(device_id, "upper", json_string(upper))) {
            qeo_log_e("json_object_set_new failed");
            break;
        }

        if (0 != json_object_set_new(device_id, "lower", json_string(lower))) {
            qeo_log_e("json_object_set_new failed");
            break;
        }

        *json_device_id = json_dumps(device_id, JSON_INDENT(4));

        ret = QEO_OK;
    } while (0);

    free(upper);
    free(lower);

    return ret;
}
Beispiel #5
0
/** This callback will be called for each forwarder in the list received from the management client. */
qeo_mgmt_client_retcode_t forwarder_cb(qeo_mgmt_client_forwarder_t* forwarder, void *cookie)
{
    qeo_factory_t             *factory = (qeo_factory_t *) cookie;
    qeo_mgmt_client_locator_t *locator = NULL;
    int                       i = 0;

    /* Get the IP address and port from the qeo_mgmt_client_forwarder_t info. */
    if ((forwarder != NULL) && (forwarder->nrOfLocators > 0)) {
        qeo_log_d("received %d locators", forwarder->nrOfLocators);
        for (i = 0, locator = forwarder->locators; i < forwarder->nrOfLocators; i++, locator++) {
            qeo_log_d("locator %d", i);
            if (locator != NULL) {
                qeo_log_i("valid locator: %s:%d", locator->address, locator->port);
                if (factory->fwd.u.client.state == FWD_CLIENT_STATE_WAIT) {
                    qeo_log_i("Going to use this forwarder");
                    flags_t flags = { .forwarding_enabled = true };
                    client_state_machine_eval(factory, CLIENT_EVENT_LOC_SRV_DATA_RECEIVED, locator, forwarder->deviceID, flags);
                }
                else {
                    /* TODO: at the moment only one forwarder is taken into account. */
                    qeo_log_i("Going to ignore this forwarder as not the first in the list");
                }
                break;
            }
Beispiel #6
0
/*#######################################################################
#                   STATIC FUNCTION IMPLEMENTATION                      #
########################################################################*/
static int verify_server_cb(int ok, X509_STORE_CTX *ctx)
{
    qeo_log_d("Verifying server, pre-verify is %s", ok ? "ok" : "not ok");
    if (!ok) {
        X509 *err_cert = X509_STORE_CTX_get_current_cert(ctx);
        int err = X509_STORE_CTX_get_error(ctx);
        int depth = X509_STORE_CTX_get_error_depth(ctx);
        char subj[256], issuer[256];

        X509_NAME_oneline(X509_get_subject_name(err_cert), subj, sizeof(subj));
        X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), issuer, sizeof(issuer));
        qeo_log_e("peer certificate verification failed: %s (@depth=%d, subject=%s, issuer=%s)",
                  X509_verify_cert_error_string(err), depth, subj, issuer);
    }
    /* no extra verification needed */
    return ok;
}
void qeo_mgmt_curl_util_shutdown_connections(qeo_mgmt_client_ctx_t* ctx) {
    qeo_log_d("qeo_mgmt_curl_util_shutdown_connections");
    if (ctx) {
        if (_lock_fd_mutex(ctx)) {
            qeo_mgmt_fd_link_t* fd_link = ctx->fd_list;
            while (fd_link) {
                shutdown(fd_link->fd, SHUT_RDWR);
                fd_link = fd_link->next;
            }
            ctx->is_closed = true;
            _unlock_fd_mutex(ctx);
        }
        else {
            qeo_log_e("Can't take mgmt ctx lock");
        }
    }
}
Beispiel #8
0
static qeo_retcode_t object_add_member(const qeo_factory_t *factory, qeocore_type_t *type, const char *member_name, json_t *member)
{
    qeo_retcode_t       result        = QEO_EFAIL;
    qeocore_type_t      *qeoType      = NULL;
    qeocore_member_id_t qeo_member_id = QEOCORE_MEMBER_ID_DEFAULT;
    json_t              *member_key   = json_object_get(member, KEY_KEY); // optional  => BOOLEAN
    json_t              *member_id    = json_object_get(member, KEY_ID);  // optional  => INTxx

    assert(factory != NULL);

    if (((NULL != member_key) && !json_is_boolean(member_key)) ||
        ((NULL != member_id) && !json_is_integer(member_id)) ||
        (NULL == member_name)) {
        // syntax error
        return QEO_EINVAL;
    }

    qeo_log_d("Processing %s", member_name);
    qeoType = build_member_type(factory, member);
    if (NULL == qeoType) {
        qeo_log_e("Could not build member_type");
        return result;
    }

    bool is_key = (member_key && json_is_true(member_key));
    do {
        result = qeocore_type_struct_add(type,                            // container
                qeoType,                         // new member to add
                member_name,                     // name of member
                &qeo_member_id,                  // member id
                is_key ? QEOCORE_FLAG_KEY : 0);  // flag
        if (QEO_OK != result) {
            qeo_log_e("qeocore_type_struct_add failed for member %s", member_name);
            break;
        }

        qeocore_type_free(qeoType);

        // Modify the json member to add/update the qeo member id
        json_object_set_new(member, KEY_ID, json_integer(qeo_member_id));
    } while (0);


    return result;
}
Beispiel #9
0
static qeo_retcode_t fwd_get_list(qeo_factory_t *factory)
{
    qeo_retcode_t             rc = QEO_OK;

    if (!qeocore_parameter_get_number("FWD_DISABLE_LOCATION_SERVICE")) {
        qeo_security_hndl         qeo_sec = factory->qeo_sec;
        qeo_mgmt_client_retcode_t mgmt_rc = QMGMTCLIENT_EFAIL;
        qeo_mgmt_client_ctx_t     *mgmt_client_ctx = NULL;

        do {
            if ((rc = qeo_security_get_mgmt_client_ctx(qeo_sec, &mgmt_client_ctx)) != QEO_OK) {
                qeo_log_e("get_forwarders get security mgmt client failed (rc=%d)", rc);
                break;
            }
            /* Factory is already locked when calling this function. */
            if (true == factory->fwd.rqst_pending) {
                /* Just break, we will retry later. */
                qeo_log_i("no need to send request (previous fwd request still ongoing)");
                break;
            }

            /* Now get the list of forwarders. */
            factory->fwd.rqst_pending = true;
            mgmt_rc = qeo_mgmt_client_get_forwarders(mgmt_client_ctx, factory->qeo_id.url, forwarder_cb, result_cb,
                                                     factory, ssl_ctx_cb, qeo_sec);
            if (mgmt_rc == QMGMTCLIENT_OK) {
                qeo_log_d("get_forwarders succeeded");
            } else {
                factory->fwd.rqst_pending = false; /* result callback will not be called. */
                if ((mgmt_rc == QMGMTCLIENT_ESSL) || (mgmt_rc == QMGMTCLIENT_ENOTALLOWED)) {
                    qeo_log_e("get_forwarders failed (rc=%d), aborting", mgmt_rc);
                    rc = QEO_EFAIL;
                    break;
                }
                else {
                    qeo_log_e("get_forwarders failed (rc=%d), ignoring", mgmt_rc);
                }
            }

        } while (0);
    }
    return rc;
}
Beispiel #10
0
static int fwd_server_count_instances(const qeocore_reader_t *reader)
{
    qeo_retcode_t rc = QEO_OK;
    qeocore_filter_t filter = { 0 };
    qeocore_data_t *data;
    int cnt = 0;

    data = qeocore_reader_data_new(reader);
    if (NULL != data) {
        filter.instance_handle = DDS_HANDLE_NIL;
        while (1) {
            rc = qeocore_reader_read(reader, &filter, data);
            if (QEO_OK == rc) {
                filter.instance_handle = qeocore_data_get_instance_handle(data);
                cnt++;
#ifdef DEBUG
                {
                    const org_qeo_system_Forwarder_t *fwd = qeocore_data_get_data(data);

                    qeo_log_d("forwarder %d : id=%" PRIx64 " -> %s", cnt, fwd->deviceId,
                              (fwd->deviceId == reader->entity.factory->qeo_id.device_id ? "self" : "other"));
                }
#endif
                qeocore_data_reset(data);
                continue;
            }
            else if (QEO_ENODATA == rc) {
                rc = QEO_OK;
            }
            /* QEO_ENODATA or error */
            break;
        }
        qeocore_data_free(data);
    }
    if (QEO_OK == rc) {
        qeo_log_i("found %d local forwarders", cnt);
    }
    else {
        qeo_log_e("failed to read all local forwarders");
    }
    return cnt;
}
Beispiel #11
0
static qeocore_type_t *build_object(const qeo_factory_t *factory, json_t *typedesc)
{
    qeocore_type_t    *qeoType  = NULL;
    const char        *name     = NULL;
    json_t            *value    = NULL;
    qeo_retcode_t     ret       = QEO_EFAIL;
    bool              iret      = true;
    const char        *topic    = NULL;

    assert(typedesc != NULL);
    assert(factory != NULL);

    do {
        json_t *type_topic = json_object_get(typedesc, KEY_TOPIC);
        if ((NULL == type_topic) || !json_is_string(type_topic)) {
            qeo_log_e("Invalid type_topic (%p)", type_topic);
            return qeoType;
        }

        json_t *properties = json_object_get(typedesc, KEY_PROPERTIES);
        if ((NULL == properties) || !json_is_object(properties)) {
            qeo_log_e("Invalid properties (%p)", properties);
            return qeoType;
        }

        topic = json_string_value(type_topic);
        //Replace all "::" with ".", because there's a mismatch in topic definitions found in the TSM structs, with "." and the QDM topic definitions with "::"
        find_and_replace((char *) topic, "::", ".");

        qeoType = qeocore_type_struct_new(topic);

        if (qeoType == NULL) {
            qeo_log_e("qeocore_type_struct_new failed for topic:%s", topic);
            break;
        }
        qeo_log_d("Registered new struct with name %s", topic);

        void *iter = json_object_iter(properties);
        while (iter) {
            name = json_object_iter_key(iter);
            if (name == NULL) {
                qeo_log_e("name == NULL");
                iret = false;
                break;
            }

            value = json_object_iter_value(iter);
            if (value == NULL) {
                qeo_log_e("value == NULL");
                iret = false;
                break;
            }

            if (!json_is_object(value)) {
                qeo_log_e("no json object");
                iret = false;
                break;
            }

            if (QEO_OK != object_add_member(factory, qeoType, name, value)) {
                qeo_log_e("object add member failed");
                iret = false;
                break;
            }

            iter = json_object_iter_next(properties, iter);
        }

        if (true != iret) {
            break;
        }

        if (QEO_OK != qeocore_type_register(factory, qeoType, topic)) {
            qeo_log_e("failed to register type: %s", topic);
        }

        ret = QEO_OK;
    } while (0);

    if (ret != QEO_OK) {
        qeocore_type_free(qeoType);
        qeoType = NULL;
    }

    return qeoType;
}
static qeo_mgmt_client_retcode_t qeo_mgmt_curl_util_https_put_with_cb(qeo_mgmt_client_ctx_t *mg_ctx,
                                                     const char* url,
                                                     char *header,
                                                     qeo_mgmt_client_ssl_ctx_cb ssl_cb,
                                                     void *ssl_cookie,
                                                     curl_read_callback data_cb,
                                                     void *read_cookie,
                                                     intptr_t length)
{
    curl_ssl_ctx_helper curlsslhelper = { ssl_cb, ssl_cookie };
    char correlation_id[CURL_UTIL_CORRELATION_ID_MAX_SIZE];
    qeo_mgmt_client_retcode_t ret = QMGMTCLIENT_EFAIL;
    struct curl_slist *chunk = (header != NULL)?curl_slist_append(NULL, header):NULL;
    long http_status = 0;
    curl_opt_helper opts[] = {
        { CURLOPT_INFILESIZE, (void*) length }, /* keep this at index 0; value is update in code */
        { CURLOPT_UPLOAD, (void*)1 },
        { CURLOPT_READFUNCTION, (void*) data_cb },
        { CURLOPT_READDATA, (void*)read_cookie},
        { CURLOPT_HTTPHEADER, (void*) chunk},
        { CURLOPT_SSL_VERIFYPEER, (void*)0 },
        { CURLOPT_SSL_CTX_FUNCTION, (void*)qeo_mgmt_curl_sslctx_cb },
        { CURLOPT_SSL_CTX_DATA, (void*)&curlsslhelper },
    };

    bool reset = false;
    do {
        CURL* ctx;
        if ((mg_ctx == NULL ) || (mg_ctx->curl_ctx == NULL) ||  (url == NULL) || (ssl_cb == NULL) || (data_cb == NULL)){
            ret = QMGMTCLIENT_EINVAL;
            break;
        }
        ctx = mg_ctx->curl_ctx;
        reset = true;
        if (CURLE_OK != qeo_mgmt_curl_util_set_opts(opts, sizeof(opts) / sizeof(curl_opt_helper), mg_ctx)) {
            ret = QMGMTCLIENT_EINVAL;
            break;
        }
        ret = qeo_mgmt_curl_util_perform(ctx, url, correlation_id);

        if (curl_easy_getinfo(ctx, CURLINFO_RESPONSE_CODE, &http_status) == CURLE_OK) {
            qeo_log_d("returned status code %ld", http_status);
            if (http_status >= 400){
                ret = qeo_mgmt_curl_util_translate_rc(CURLE_HTTP_RETURNED_ERROR);
                curl_util_log_http_error_description(ctx, correlation_id);
                break;
            }
        }
    } while (0);

    if (reset == true){
        /* Make sure we reset all configuration for next calls */
        curl_easy_reset(mg_ctx->curl_ctx);
    }
    if (chunk != NULL){
        curl_slist_free_all(chunk);
    }

    if (ret != QMGMTCLIENT_OK) {
        qeo_log_w("Failure in https_put_%s",url);
    }

    return ret;
}