• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mendersoftware / mender-mcu / 1559779716

25 Nov 2024 06:45PM UTC coverage: 9.39% (-0.03%) from 9.418%
1559779716

push

gitlab-ci

danielskinstad
fix: fail deployment when it's aborted

Changelog: Title
Ticket: MEN-7693

Signed-off-by: Daniel Skinstad Drabitzius <daniel.drabitzius@northern.tech>

0 of 16 new or added lines in 3 files covered. (0.0%)

472 existing lines in 5 files now uncovered.

251 of 2673 relevant lines covered (9.39%)

0.67 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/core/src/mender-api.c
1
/**
2
 * @file      mender-api.c
3
 * @brief     Implementation of the Mender API
4
 *
5
 * Copyright joelguittet and mender-mcu-client contributors
6
 * Copyright Northern.tech AS
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20

21
#define _GNU_SOURCE // asprintf
22
#include <stdio.h>  // asprintf
23

24
#include "mender-api.h"
25
#include "mender-artifact.h"
26
#include "mender-storage.h"
27
#include "mender-http.h"
28
#include "mender-log.h"
29
#include "mender-tls.h"
30

31
/**
32
 * @brief Paths of the mender-server APIs
33
 */
34
#define MENDER_API_PATH_POST_AUTHENTICATION_REQUESTS "/api/devices/v1/authentication/auth_requests"
35
#define MENDER_API_PATH_GET_NEXT_DEPLOYMENT          "/api/devices/v1/deployments/device/deployments/next"
36
#define MENDER_API_PATH_POST_NEXT_DEPLOYMENT_V2      "/api/devices/v2/deployments/device/deployments/next"
37
#define MENDER_API_PATH_PUT_DEPLOYMENT_STATUS        "/api/devices/v1/deployments/device/deployments/%s/status"
38
#define MENDER_API_PATH_GET_DEVICE_CONFIGURATION     "/api/devices/v1/deviceconfig/configuration"
39
#define MENDER_API_PATH_PUT_DEVICE_CONFIGURATION     "/api/devices/v1/deviceconfig/configuration"
40
#define MENDER_API_PATH_GET_DEVICE_CONNECT           "/api/devices/v1/deviceconnect/connect"
41
#define MENDER_API_PATH_PUT_DEVICE_ATTRIBUTES        "/api/devices/v1/inventory/device/attributes"
42

43
/**
44
 * @brief Mender API configuration
45
 */
46
static mender_api_config_t mender_api_config;
47

48
/**
49
 * @brief Authentication token
50
 */
51
static char *mender_api_jwt = NULL;
52

53
/**
54
 * @brief HTTP callback used to handle text content
55
 * @param event HTTP client event
56
 * @param data Data received
57
 * @param data_length Data length
58
 * @param params Callback parameters
59
 * @return MENDER_OK if the function succeeds, error code otherwise
60
 */
61
static mender_err_t mender_api_http_text_callback(mender_http_client_event_t event, void *data, size_t data_length, void *params);
62

63
mender_err_t
64
mender_api_init(mender_api_config_t *config) {
×
65

66
    assert(NULL != config);
×
67
    assert(NULL != config->device_type);
×
68
    assert(NULL != config->host);
×
69
    mender_err_t ret;
70

71
    /* Save configuration */
72
    memcpy(&mender_api_config, config, sizeof(mender_api_config_t));
×
73

74
    /* Initializations */
75
    mender_http_config_t mender_http_config = { .host = mender_api_config.host };
×
76
    if (MENDER_OK != (ret = mender_http_init(&mender_http_config))) {
×
77
        mender_log_error("Unable to initialize HTTP");
×
78
        return ret;
×
79
    }
80

81
    return ret;
×
82
}
83

84
bool
85
mender_api_is_authenticated(void) {
×
86
    return NULL != mender_api_jwt;
×
87
}
88

89
mender_err_t
90
mender_api_perform_authentication(mender_err_t (*get_identity)(mender_identity_t **identity)) {
×
91

92
    assert(NULL != get_identity);
×
93
    mender_err_t       ret;
94
    char              *public_key_pem       = NULL;
×
95
    cJSON             *json_identity        = NULL;
×
96
    mender_identity_t *identity             = NULL;
×
97
    char              *unformatted_identity = NULL;
×
98
    cJSON             *json_payload         = NULL;
×
99
    char              *payload              = NULL;
×
100
    char              *response             = NULL;
×
101
    char              *signature            = NULL;
×
102
    size_t             signature_length     = 0;
×
103
    int                status               = 0;
×
104

105
    /* Get public key in PEM format */
106
    if (MENDER_OK != (ret = mender_tls_get_public_key_pem(&public_key_pem))) {
×
107
        mender_log_error("Unable to get public key");
×
108
        goto END;
×
109
    }
110

111
    /* Get identity */
112
    if (MENDER_OK != (ret = get_identity(&identity))) {
×
113
        mender_log_error("Unable to get identity");
×
114
        goto END;
×
115
    }
116

117
    /* Format identity */
118
    if (MENDER_OK != (ret = mender_utils_identity_to_json(identity, &json_identity))) {
×
119
        mender_log_error("Unable to format identity");
×
120
        goto END;
×
121
    }
122
    if (NULL == (unformatted_identity = cJSON_PrintUnformatted(json_identity))) {
×
123
        mender_log_error("Unable to allocate memory");
×
124
        ret = MENDER_FAIL;
×
125
        goto END;
×
126
    }
127

128
    /* Format payload */
129
    if (NULL == (json_payload = cJSON_CreateObject())) {
×
130
        mender_log_error("Unable to allocate memory");
×
131
        ret = MENDER_FAIL;
×
132
        goto END;
×
133
    }
134
    cJSON_AddStringToObject(json_payload, "id_data", unformatted_identity);
×
135
    cJSON_AddStringToObject(json_payload, "pubkey", public_key_pem);
×
136
    if (NULL != mender_api_config.tenant_token) {
×
137
        cJSON_AddStringToObject(json_payload, "tenant_token", mender_api_config.tenant_token);
×
138
    }
139
    if (NULL == (payload = cJSON_PrintUnformatted(json_payload))) {
×
140
        mender_log_error("Unable to allocate memory");
×
141
        ret = MENDER_FAIL;
×
142
        goto END;
×
143
    }
144

145
    /* Sign payload */
146
    if (MENDER_OK != (ret = mender_tls_sign_payload(payload, &signature, &signature_length))) {
×
147
        mender_log_error("Unable to sign payload");
×
148
        goto END;
×
149
    }
150

151
    /* Perform HTTP request */
152
    if (MENDER_OK
×
153
        != (ret = mender_http_perform(NULL,
×
154
                                      MENDER_API_PATH_POST_AUTHENTICATION_REQUESTS,
155
                                      MENDER_HTTP_POST,
156
                                      payload,
157
                                      signature,
158
                                      &mender_api_http_text_callback,
159
                                      (void *)&response,
160
                                      &status))) {
161
        mender_log_error("Unable to perform HTTP request");
×
162
        goto END;
×
163
    }
164

165
    /* Treatment depending of the status */
166
    if (200 == status) {
×
167
        if (NULL == response) {
×
168
            mender_log_error("Response is empty");
×
169
            ret = MENDER_FAIL;
×
170
            goto END;
×
171
        }
172
        if (NULL != mender_api_jwt) {
×
173
            free(mender_api_jwt);
×
174
        }
175
        if (NULL == (mender_api_jwt = strdup(response))) {
×
176
            mender_log_error("Unable to allocate memory");
×
177
            ret = MENDER_FAIL;
×
178
            goto END;
×
179
        }
180
        ret = MENDER_OK;
×
181
    } else {
182
        mender_api_print_response_error(response, status);
×
183
        ret = MENDER_FAIL;
×
184
    }
185

186
END:
×
187

188
    /* Release memory */
189
    free(unformatted_identity);
×
190
    free(response);
×
191
    free(signature);
×
192
    free(payload);
×
193
    cJSON_Delete(json_payload);
×
194
    cJSON_Delete(json_identity);
×
195
    free(public_key_pem);
×
196

197
    return ret;
×
198
}
199

200
static mender_err_t
201
api_check_for_deployment_v2(int *status, void *response) {
×
202
    assert(NULL != status);
×
203
    assert(NULL != response);
×
204

205
    mender_err_t ret           = MENDER_FAIL;
×
206
    cJSON       *json_payload  = NULL;
×
207
    char        *payload       = NULL;
×
208
    const char  *artifact_name = NULL;
×
209
#ifdef CONFIG_MENDER_PROVIDES_DEPENDS
210
#ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT
211
    mender_key_value_list_t *provides = NULL;
×
212
#endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */
213
#endif /* CONFIG_MENDER_PROVIDES_DEPENDS */
214

215
    /* Create payload */
216
    if (NULL == (json_payload = cJSON_CreateObject())) {
×
217
        mender_log_error("Unable to allocate memory");
×
218
        goto END;
×
219
    }
220

221
    /* Add "device_provides" entity to payload */
222
    cJSON *json_provides = NULL;
×
223
    if (NULL == (json_provides = cJSON_AddObjectToObject(json_payload, "device_provides"))) {
×
224
        mender_log_error("Unable to allocate memory");
×
225
        goto END;
×
226
    }
227

228
    if (NULL == cJSON_AddStringToObject(json_provides, "device_type", mender_api_config.device_type)) {
×
229
        mender_log_error("Unable to allocate memory");
×
230
        goto END;
×
231
    }
232

233
#ifdef CONFIG_MENDER_PROVIDES_DEPENDS
234
#ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT
235
    /* Add provides from storage */
236
    if (MENDER_FAIL == mender_storage_get_provides(&provides)) {
×
237
        mender_log_error("Unable to get provides");
×
238
        goto END;
×
239
    }
240
    for (mender_key_value_list_t *item = provides; NULL != item; item = item->next) {
×
241
        if (NULL == cJSON_AddStringToObject(json_provides, item->key, item->value)) {
×
242
            mender_log_error("Unable to allocate memory");
×
243
            goto END;
×
244
        }
245
    }
246
#endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */
247
#endif /* CONFIG_MENDER_PROVIDES_DEPENDS */
248

249
    if ((MENDER_OK != mender_storage_get_artifact_name(&artifact_name)) && (NULL != artifact_name)) {
×
250
        mender_log_error("Unable to get artifact name");
×
251
        return MENDER_FAIL;
×
252
    }
253

254
    if (NULL == cJSON_AddStringToObject(json_provides, "artifact_name", artifact_name)) {
×
255
        mender_log_error("Unable to allocate memory");
×
256
        goto END;
×
257
    }
258

259
    if (NULL == (payload = cJSON_PrintUnformatted(json_payload))) {
×
260
        mender_log_error("Unable to allocate memory");
×
261
        goto END;
×
262
    }
263

264
    /* Perform HTTP request */
265
    if (MENDER_OK
×
266
        != (ret = mender_http_perform(mender_api_jwt,
×
267
                                      MENDER_API_PATH_POST_NEXT_DEPLOYMENT_V2,
268
                                      MENDER_HTTP_POST,
269
                                      payload,
270
                                      NULL,
271
                                      &mender_api_http_text_callback,
272
                                      (void *)response,
273
                                      status))) {
274
        mender_log_error("Unable to perform HTTP request");
×
275
        goto END;
×
276
    }
277

278
    ret = MENDER_OK;
×
279

280
END:
×
281

282
#ifdef CONFIG_MENDER_PROVIDES_DEPENDS
283
#ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT
284
    mender_utils_key_value_list_free(provides);
×
285
#endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */
286
#endif /* CONFIG_MENDER_PROVIDES_DEPENDS */
287
    cJSON_Delete(json_payload);
×
288
    free(payload);
×
289
    return ret;
×
290
}
291

292
static mender_err_t
293
api_check_for_deployment_v1(int *status, void *response) {
×
294

295
    assert(NULL != status);
×
296
    assert(NULL != response);
×
297

298
    mender_err_t ret           = MENDER_FAIL;
×
299
    char        *path          = NULL;
×
300
    const char  *artifact_name = NULL;
×
301

302
    if ((MENDER_OK != mender_storage_get_artifact_name(&artifact_name)) && (NULL != artifact_name)) {
×
303
        mender_log_error("Unable to get artifact name");
×
304
        return MENDER_FAIL;
×
305
    }
306

307
    /* Compute path */
308
    if (-1 == asprintf(&path, MENDER_API_PATH_GET_NEXT_DEPLOYMENT "?artifact_name=%s&device_type=%s", artifact_name, mender_api_config.device_type)) {
×
309
        mender_log_error("Unable to allocate memory");
×
310
        goto END;
×
311
    }
312

313
    /* Perform HTTP request */
314
    if (MENDER_OK != (ret = mender_http_perform(mender_api_jwt, path, MENDER_HTTP_GET, NULL, NULL, &mender_api_http_text_callback, (void *)response, status))) {
×
315
        mender_log_error("Unable to perform HTTP request");
×
316
        goto END;
×
317
    }
318

319
    ret = MENDER_OK;
×
320

321
END:
×
322

323
    /* Release memory */
324
    free(path);
×
325

326
    return ret;
×
327
}
328

329
mender_err_t
330
mender_api_check_for_deployment(mender_api_deployment_data_t *deployment) {
×
331

332
    assert(NULL != deployment);
×
333
    mender_err_t ret      = MENDER_FAIL;
×
334
    char        *response = NULL;
×
335
    int          status   = 0;
×
336

337
    if (MENDER_FAIL == (ret = api_check_for_deployment_v2(&status, (void *)&response))) {
×
338
        goto END;
×
339
    }
340

341
    /* Yes, 404 still means MENDER_OK above */
342
    if (404 == status) {
×
343
        mender_log_debug("POST request to v2 version of the deployments API failed, falling back to v1 version and GET");
344
        FREE_AND_NULL(response);
×
345
        if (MENDER_FAIL == (ret = api_check_for_deployment_v1(&status, (void *)&response))) {
×
346
            goto END;
×
347
        }
348
    }
349

350
    /* Treatment depending of the status */
351
    if (200 == status) {
×
352
        cJSON *json_response = cJSON_Parse(response);
×
353
        if (NULL != json_response) {
×
354
            cJSON *json_id = cJSON_GetObjectItem(json_response, "id");
×
355
            if (NULL != json_id) {
×
356
                if (NULL == (deployment->id = strdup(cJSON_GetStringValue(json_id)))) {
×
357
                    ret = MENDER_FAIL;
×
358
                    goto END;
×
359
                }
360
            }
361
            cJSON *json_artifact = cJSON_GetObjectItem(json_response, "artifact");
×
362
            if (NULL != json_artifact) {
×
363
                cJSON *json_artifact_name = cJSON_GetObjectItem(json_artifact, "artifact_name");
×
364
                if (NULL != json_artifact_name) {
×
365
                    if (NULL == (deployment->artifact_name = strdup(cJSON_GetStringValue(json_artifact_name)))) {
×
366
                        ret = MENDER_FAIL;
×
367
                        goto END;
×
368
                    }
369
                }
370
                cJSON *json_source = cJSON_GetObjectItem(json_artifact, "source");
×
371
                if (NULL != json_source) {
×
372
                    cJSON *json_uri = cJSON_GetObjectItem(json_source, "uri");
×
373
                    if (NULL != json_uri) {
×
374
                        if (NULL == (deployment->uri = strdup(cJSON_GetStringValue(json_uri)))) {
×
375
                            ret = MENDER_FAIL;
×
376
                            goto END;
×
377
                        }
378
                        ret = MENDER_OK;
×
379
                    } else {
380
                        mender_log_error("Invalid response");
×
381
                        ret = MENDER_FAIL;
×
382
                    }
383
                } else {
384
                    mender_log_error("Invalid response");
×
385
                    ret = MENDER_FAIL;
×
386
                }
387
                cJSON *json_device_types_compatible = cJSON_GetObjectItem(json_artifact, "device_types_compatible");
×
388
                if (NULL != json_device_types_compatible && cJSON_IsArray(json_device_types_compatible)) {
×
389
                    deployment->device_types_compatible_size = cJSON_GetArraySize(json_device_types_compatible);
×
390
                    deployment->device_types_compatible      = (char **)malloc(deployment->device_types_compatible_size * sizeof(char *));
×
391
                    if (NULL == deployment->device_types_compatible) {
×
392
                        mender_log_error("Unable to allocate memory");
×
393
                        ret = MENDER_FAIL;
×
394
                        goto END;
×
395
                    }
396
                    for (size_t i = 0; i < deployment->device_types_compatible_size; i++) {
×
397
                        cJSON *json_device_type = cJSON_GetArrayItem(json_device_types_compatible, i);
×
398
                        if (NULL != json_device_type && cJSON_IsString(json_device_type)) {
×
399
                            if (NULL == (deployment->device_types_compatible[i] = strdup(cJSON_GetStringValue(json_device_type)))) {
×
400
                                ret = MENDER_FAIL;
×
401
                                goto END;
×
402
                            }
403
                        } else {
404
                            mender_log_error("Could not get device type form device_types_compatible array");
×
405
                            ret = MENDER_FAIL;
×
406
                        }
407
                    }
408
                } else {
409
                    mender_log_error("Could not load device_types_compatible");
×
410
                    ret = MENDER_FAIL;
×
411
                }
412
            } else {
413
                mender_log_error("Invalid response");
×
414
                ret = MENDER_FAIL;
×
415
            }
416
            cJSON_Delete(json_response);
×
417
        } else {
418
            mender_log_error("Invalid response");
×
419
            ret = MENDER_FAIL;
×
420
        }
421
    } else if (204 == status) {
×
422
        /* No response expected */
423
        ret = MENDER_NOT_FOUND;
×
424
    } else {
425
        mender_api_print_response_error(response, status);
×
426
        ret = MENDER_FAIL;
×
427
    }
428

429
END:
×
430

431
    /* Release memory */
432
    free(response);
×
433

434
    return ret;
×
435
}
436

437
mender_err_t
438
mender_api_publish_deployment_status(const char *id, mender_deployment_status_t deployment_status) {
×
439

440
    assert(NULL != id);
×
441
    mender_err_t ret;
442
    char        *value        = NULL;
×
443
    cJSON       *json_payload = NULL;
×
444
    char        *payload      = NULL;
×
445
    char        *path         = NULL;
×
446
    char        *response     = NULL;
×
447
    int          status       = 0;
×
448

449
    /* Deployment status to string */
450
    if (NULL == (value = mender_utils_deployment_status_to_string(deployment_status))) {
×
451
        mender_log_error("Invalid status");
×
452
        ret = MENDER_FAIL;
×
453
        goto END;
×
454
    }
455

456
    /* Format payload */
457
    if (NULL == (json_payload = cJSON_CreateObject())) {
×
458
        mender_log_error("Unable to allocate memory");
×
459
        ret = MENDER_FAIL;
×
460
        goto END;
×
461
    }
462
    cJSON_AddStringToObject(json_payload, "status", value);
×
463
    if (NULL == (payload = cJSON_PrintUnformatted(json_payload))) {
×
464
        mender_log_error("Unable to allocate memory");
×
465
        ret = MENDER_FAIL;
×
466
        goto END;
×
467
    }
468

469
    /* Compute path */
470
    size_t str_length = strlen(MENDER_API_PATH_PUT_DEPLOYMENT_STATUS) - strlen("%s") + strlen(id) + 1;
×
471
    if (NULL == (path = (char *)malloc(str_length))) {
×
472
        mender_log_error("Unable to allocate memory");
×
473
        ret = MENDER_FAIL;
×
474
        goto END;
×
475
    }
476
    snprintf(path, str_length, MENDER_API_PATH_PUT_DEPLOYMENT_STATUS, id);
×
477

478
    /* Perform HTTP request */
479
    if (MENDER_OK
×
480
        != (ret = mender_http_perform(mender_api_jwt, path, MENDER_HTTP_PUT, payload, NULL, &mender_api_http_text_callback, (void *)&response, &status))) {
×
481
        mender_log_error("Unable to perform HTTP request");
×
482
        goto END;
×
483
    }
484

485
    /* Treatment depending of the status */
486
    if (204 == status) {
×
487
        /* No response expected */
488
        ret = MENDER_OK;
×
NEW
489
    } else if (409 == status) {
×
490
        /* Deployment aborted */
NEW
491
        mender_api_print_response_error(response, status);
×
NEW
492
        ret = MENDER_ABORTED;
×
493
    } else {
UNCOV
494
        mender_api_print_response_error(response, status);
×
495
        ret = MENDER_FAIL;
×
496
    }
497

498
END:
×
499

500
    /* Release memory */
UNCOV
501
    free(response);
×
502
    free(path);
×
UNCOV
503
    free(payload);
×
UNCOV
504
    cJSON_Delete(json_payload);
×
505

506
    return ret;
×
507
}
508

509
#ifdef CONFIG_MENDER_CLIENT_INVENTORY
510

511
mender_err_t
512
mender_api_publish_inventory_data(mender_keystore_t *inventory) {
513

514
    mender_err_t ret;
515
    char        *payload       = NULL;
516
    char        *response      = NULL;
517
    int          status        = 0;
518
    const char  *artifact_name = NULL;
519

520
    if ((MENDER_OK != mender_storage_get_artifact_name(&artifact_name)) && (NULL != artifact_name)) {
521
        mender_log_error("Unable to get artifact name");
522
        return MENDER_FAIL;
523
    }
524

525
    /* Format payload */
526
    cJSON *object = cJSON_CreateArray();
527
    if (NULL == object) {
528
        mender_log_error("Unable to allocate memory");
529
        ret = MENDER_FAIL;
530
        goto END;
531
    }
532
    cJSON *item = cJSON_CreateObject();
533
    if (NULL == item) {
534
        mender_log_error("Unable to allocate memory");
535
        ret = MENDER_FAIL;
536
        goto END;
537
    }
538
    cJSON_AddStringToObject(item, "name", "artifact_name");
539
    cJSON_AddStringToObject(item, "value", artifact_name);
540
    cJSON_AddItemToArray(object, item);
541
    item = cJSON_CreateObject();
542
    if (NULL == item) {
543
        mender_log_error("Unable to allocate memory");
544
        ret = MENDER_FAIL;
545
        goto END;
546
    }
547
    cJSON_AddStringToObject(item, "name", "device_type");
548
    cJSON_AddStringToObject(item, "value", mender_api_config.device_type);
549
    cJSON_AddItemToArray(object, item);
550
    if (NULL != inventory) {
551
        size_t index = 0;
552
        while ((NULL != inventory[index].name) && (NULL != inventory[index].value)) {
553
            if (NULL == (item = cJSON_CreateObject())) {
554
                mender_log_error("Unable to allocate memory");
555
                ret = MENDER_FAIL;
556
                goto END;
557
            }
558
            cJSON_AddStringToObject(item, "name", inventory[index].name);
559
            cJSON_AddStringToObject(item, "value", inventory[index].value);
560
            cJSON_AddItemToArray(object, item);
561
            index++;
562
        }
563
    }
564
    if (NULL == (payload = cJSON_PrintUnformatted(object))) {
565
        mender_log_error("Unable to allocate memory");
566
        ret = MENDER_FAIL;
567
        goto END;
568
    }
569

570
    /* Perform HTTP request */
571
    if (MENDER_OK
572
        != (ret = mender_http_perform(mender_api_jwt,
573
                                      MENDER_API_PATH_PUT_DEVICE_ATTRIBUTES,
574
                                      MENDER_HTTP_PUT,
575
                                      payload,
576
                                      NULL,
577
                                      &mender_api_http_text_callback,
578
                                      (void *)&response,
579
                                      &status))) {
580
        mender_log_error("Unable to perform HTTP request");
581
        goto END;
582
    }
583

584
    /* Treatment depending of the status */
585
    if (200 == status) {
586
        /* No response expected */
587
        ret = MENDER_OK;
588
    } else {
589
        mender_api_print_response_error(response, status);
590
        ret = MENDER_FAIL;
591
    }
592

593
END:
594

595
    /* Release memory */
596
    free(response);
597
    free(payload);
598
    cJSON_Delete(object);
599

600
    return ret;
601
}
602

603
#endif /* CONFIG_MENDER_CLIENT_INVENTORY */
604

605
mender_err_t
UNCOV
606
mender_api_exit(void) {
×
607

608
    /* Release all modules */
UNCOV
609
    mender_http_exit();
×
610

611
    /* Release memory */
UNCOV
612
    FREE_AND_NULL(mender_api_jwt);
×
613

UNCOV
614
    return MENDER_OK;
×
615
}
616

617
static mender_err_t
618
mender_api_http_text_callback(mender_http_client_event_t event, void *data, size_t data_length, void *params) {
×
619

UNCOV
620
    assert(NULL != params);
×
UNCOV
621
    char       **response = (char **)params;
×
622
    mender_err_t ret      = MENDER_OK;
×
623
    char        *tmp;
624

625
    /* Treatment depending of the event */
626
    switch (event) {
×
UNCOV
627
        case MENDER_HTTP_EVENT_CONNECTED:
×
628
            /* Nothing to do */
UNCOV
629
            break;
×
630
        case MENDER_HTTP_EVENT_DATA_RECEIVED:
×
631
            /* Check input data */
UNCOV
632
            if ((NULL == data) || (0 == data_length)) {
×
633
                mender_log_error("Invalid data received");
×
634
                ret = MENDER_FAIL;
×
UNCOV
635
                break;
×
636
            }
637
            /* Concatenate data to the response */
638
            size_t response_length = (NULL != *response) ? strlen(*response) : 0;
×
639
            if (NULL == (tmp = realloc(*response, response_length + data_length + 1))) {
×
UNCOV
640
                mender_log_error("Unable to allocate memory");
×
UNCOV
641
                ret = MENDER_FAIL;
×
642
                break;
×
643
            }
644
            *response = tmp;
×
645
            memcpy((*response) + response_length, data, data_length);
×
646
            *((*response) + response_length + data_length) = '\0';
×
UNCOV
647
            break;
×
648
        case MENDER_HTTP_EVENT_DISCONNECTED:
×
649
            /* Nothing to do */
650
            break;
×
651
        case MENDER_HTTP_EVENT_ERROR:
×
652
            /* Downloading the response fails */
UNCOV
653
            mender_log_error("An error occurred");
×
654
            ret = MENDER_FAIL;
×
655
            break;
×
UNCOV
656
        default:
×
657
            /* Should no occur */
658
            ret = MENDER_FAIL;
×
659
            break;
×
660
    }
661

662
    return ret;
×
663
}
664

665
void
666
mender_api_print_response_error(char *response, int status) {
×
667

668
    char *desc;
669

670
    /* Treatment depending of the status */
UNCOV
671
    if (NULL != (desc = mender_utils_http_status_to_string(status))) {
×
UNCOV
672
        if (NULL != response) {
×
UNCOV
673
            cJSON *json_response = cJSON_Parse(response);
×
UNCOV
674
            if (NULL != json_response) {
×
675
                cJSON *json_error = cJSON_GetObjectItemCaseSensitive(json_response, "error");
×
676
                if (NULL != json_error) {
×
677
                    mender_log_error("[%d] %s: %s", status, desc, cJSON_GetStringValue(json_error));
×
678
                } else {
679
                    mender_log_error("[%d] %s: unknown error", status, desc);
×
680
                }
681
                cJSON_Delete(json_response);
×
682
            } else {
683
                mender_log_error("[%d] %s: unknown error", status, desc);
×
684
            }
685
        } else {
UNCOV
686
            mender_log_error("[%d] %s: unknown error", status, desc);
×
687
        }
688
    } else {
UNCOV
689
        mender_log_error("Unknown error occurred, status=%d", status);
×
690
    }
UNCOV
691
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc