mgmt/imgmgr/src/imgmgr.c
static int
imgr_upload_inspect(const struct imgr_upload_req *req,
                    struct imgr_upload_action *action, const char **errstr)
{
    const struct image_header *hdr;
    const struct flash_area *fa;
    uint8_t rem_bytes;
    bool empty;
    int rc;

    memset(action, 0, sizeof *action);

    if (req->off == -1) {
        /* Request did not include an `off` field. */
        *errstr = imgmgr_err_str_hdr_malformed;
        return MGMT_ERR_EINVAL;
    }

    if (req->off == 0) {
        /* First upload chunk. */
        if (req->data_len < sizeof(struct image_header)) {
            /*
             * Image header is the first thing in the image.
             */
            *errstr = imgmgr_err_str_hdr_malformed;
            return MGMT_ERR_EINVAL;
        }

        if (req->size == -1) {
            /* Request did not include a `len` field. */
            *errstr = imgmgr_err_str_hdr_malformed;
            return MGMT_ERR_EINVAL;
        }
        action->size = req->size;

        hdr = (struct image_header *)req->img_data;
        if (hdr->ih_magic != IMAGE_MAGIC && hdr->ih_magic != IMAGE_MAGIC_V2) {
            *errstr = imgmgr_err_str_magic_mismatch;
            return MGMT_ERR_EINVAL;
        }

        imgr_state.is_v2_image = (hdr->ih_magic == IMAGE_MAGIC_V2);

        if (req->data_sha_len > IMGMGR_DATA_SHA_LEN) {
            return MGMT_ERR_EINVAL;
        }

        /*
         * If request includes proper data hash we can check whether there is
         * upload in progress (interrupted due to e.g. link disconnection) with
         * the same data hash so we can just resume it by simply including
         * current upload offset in response.
         */
        if ((req->data_sha_len > 0) && (imgr_state.area_id != -1)) {
            if ((imgr_state.data_sha_len == req->data_sha_len) &&
                            !memcmp(imgr_state.data_sha, req->data_sha,
                                                        req->data_sha_len)) {
                return 0;
            }
        }

        action->area_id = imgmgr_find_best_area_id();
        if (action->area_id < 0) {
            /* No slot where to upload! */
            *errstr = imgmgr_err_str_no_slot;
            return MGMT_ERR_ENOMEM;
        }

#if MYNEWT_VAL(IMGMGR_LAZY_ERASE)
        (void) empty;
#else
        rc = flash_area_open(action->area_id, &fa);
        if (rc) {
            *errstr = imgmgr_err_str_flash_open_failed;
            return MGMT_ERR_EUNKNOWN;
        }

        rc = flash_area_is_empty(fa, &empty);
        flash_area_close(fa);
        if (rc) {
            return MGMT_ERR_EUNKNOWN;
        }

        action->erase = !empty;
#endif
    } else {
        /* Continuation of upload. */
        action->area_id = imgr_state.area_id;
        action->size = imgr_state.size;

        if (req->off != imgr_state.off) {
            /*
             * Invalid offset. Drop the data, and respond with the offset we're
             * expecting data for.
             */
            return 0;
        }
    }

    /* Calculate size of flash write. */
    action->write_bytes = req->data_len;
    if (req->off + req->data_len < action->size) {
        /*
         * Respect flash write alignment if not in the last block
         */
        rc = flash_area_open(action->area_id, &fa);
        if (rc) {
            *errstr = imgmgr_err_str_flash_open_failed;
            return MGMT_ERR_EUNKNOWN;
        }

        rem_bytes = req->data_len % flash_area_align(fa);
        flash_area_close(fa);

        if (rem_bytes) {
            action->write_bytes -= rem_bytes;
        }
    }

    action->proceed = true;
    return 0;
}
/**
 * Verifies an upload request and indicates the actions that should be taken
 * during processing of the request.  This is a "read only" function in the
 * sense that it doesn't write anything to flash and doesn't modify any global
 * variables.
 *
 * @param req                   The upload request to inspect.
 * @param action                On success, gets populated with information
 *                                  about how to process the request.
 *
 * @return                      0 if processing should occur;
 *                              A MGMT_ERR code if an error response should be
 *                                  sent instead.
 */
Verifies an upload request and indicates the actions that should be taken
during processing of the request.  This is a "read only" function in the
sense that it doesn't write anything to flash and doesn't modify any global
variables.

@param req                   The upload request to inspect.
@param action                On success, gets populated with information
about how to process the request.

@return                      0 if processing should occur;
A MGMT_ERR code if an error response should be
sent instead.
Verifies an upload request and indicates the actions that should be taken during processing of the request . This is a " read only " function in the sense that it doesn ' t write anything to flash and doesn ' t modify any global variables . @param req The upload request to inspect . @param action On success gets populated with information about how to process the request . @return 0 if processing should occur ; A MGMT_ERR code if an error response should be sent instead .
static int
imgr_upload_inspect(const struct imgr_upload_req *req,
                    struct imgr_upload_action *action, const char **errstr)
{
    const struct image_header *hdr;
    const struct flash_area *fa;
    uint8_t rem_bytes;
    bool empty;
    int rc;
    memset(action, 0, sizeof *action);
    if (req->off == -1) {
        *errstr = imgmgr_err_str_hdr_malformed;
        return MGMT_ERR_EINVAL;
    }
    if (req->off == 0) {
        if (req->data_len < sizeof(struct image_header)) {
            *errstr = imgmgr_err_str_hdr_malformed;
            return MGMT_ERR_EINVAL;
        }
        if (req->size == -1) {
            *errstr = imgmgr_err_str_hdr_malformed;
            return MGMT_ERR_EINVAL;
        }
        action->size = req->size;
        hdr = (struct image_header *)req->img_data;
        if (hdr->ih_magic != IMAGE_MAGIC && hdr->ih_magic != IMAGE_MAGIC_V2) {
            *errstr = imgmgr_err_str_magic_mismatch;
            return MGMT_ERR_EINVAL;
        }
        imgr_state.is_v2_image = (hdr->ih_magic == IMAGE_MAGIC_V2);
        if (req->data_sha_len > IMGMGR_DATA_SHA_LEN) {
            return MGMT_ERR_EINVAL;
        }
        if ((req->data_sha_len > 0) && (imgr_state.area_id != -1)) {
            if ((imgr_state.data_sha_len == req->data_sha_len) &&
                            !memcmp(imgr_state.data_sha, req->data_sha,
                                                        req->data_sha_len)) {
                return 0;
            }
        }
        action->area_id = imgmgr_find_best_area_id();
        if (action->area_id < 0) {
            *errstr = imgmgr_err_str_no_slot;
            return MGMT_ERR_ENOMEM;
        }
#if MYNEWT_VAL(IMGMGR_LAZY_ERASE)
        (void) empty;
#else
        rc = flash_area_open(action->area_id, &fa);
        if (rc) {
            *errstr = imgmgr_err_str_flash_open_failed;
            return MGMT_ERR_EUNKNOWN;
        }
        rc = flash_area_is_empty(fa, &empty);
        flash_area_close(fa);
        if (rc) {
            return MGMT_ERR_EUNKNOWN;
        }
        action->erase = !empty;
#endif
    } else {
        action->area_id = imgr_state.area_id;
        action->size = imgr_state.size;
        if (req->off != imgr_state.off) {
            return 0;
        }
    }
    action->write_bytes = req->data_len;
    if (req->off + req->data_len < action->size) {
        rc = flash_area_open(action->area_id, &fa);
        if (rc) {
            *errstr = imgmgr_err_str_flash_open_failed;
            return MGMT_ERR_EUNKNOWN;
        }
        rem_bytes = req->data_len % flash_area_align(fa);
        flash_area_close(fa);
        if (rem_bytes) {
            action->write_bytes -= rem_bytes;
        }
    }
    action->proceed = true;
    return 0;
}
static int imgr_upload_inspect ( const struct imgr_upload_req * req , struct imgr_upload_action * action , const char * * errstr ) { const struct image_header * hdr ; const struct flash_area * fa ; uint8_t rem_bytes ; bool empty ; int rc ; memset ( action , 0 , sizeof * action ) ; if ( req -> off == -1 ) { * errstr = imgmgr_err_str_hdr_malformed ; return MGMT_ERR_EINVAL ; } if ( req -> off == 0 ) { if ( req -> data_len < sizeof ( struct image_header ) ) { * errstr = imgmgr_err_str_hdr_malformed ; return MGMT_ERR_EINVAL ; } if ( req -> size == -1 ) { * errstr = imgmgr_err_str_hdr_malformed ; return MGMT_ERR_EINVAL ; } action -> size = req -> size ; hdr = ( struct image_header * ) req -> img_data ; if ( hdr -> ih_magic != IMAGE_MAGIC && hdr -> ih_magic != IMAGE_MAGIC_V2 ) { * errstr = imgmgr_err_str_magic_mismatch ; return MGMT_ERR_EINVAL ; } imgr_state . is_v2_image = ( hdr -> ih_magic == IMAGE_MAGIC_V2 ) ; if ( req -> data_sha_len > IMGMGR_DATA_SHA_LEN ) { return MGMT_ERR_EINVAL ; } if ( ( req -> data_sha_len > 0 ) && ( imgr_state . area_id != -1 ) ) { if ( ( imgr_state . data_sha_len == req -> data_sha_len ) && ! memcmp ( imgr_state . data_sha , req -> data_sha , req -> data_sha_len ) ) { return 0 ; } } action -> area_id = imgmgr_find_best_area_id ( ) ; if ( action -> area_id < 0 ) { * errstr = imgmgr_err_str_no_slot ; return MGMT_ERR_ENOMEM ; } #if MYNEWT_VAL ( IMGMGR_LAZY_ERASE ) ( void ) empty ; #else rc = flash_area_open ( action -> area_id , & fa ) ; if ( rc ) { * errstr = imgmgr_err_str_flash_open_failed ; return MGMT_ERR_EUNKNOWN ; } rc = flash_area_is_empty ( fa , & empty ) ; flash_area_close ( fa ) ; if ( rc ) { return MGMT_ERR_EUNKNOWN ; } action -> erase = ! empty ; #endif } else { action -> area_id = imgr_state . area_id ; action -> size = imgr_state . size ; if ( req -> off != imgr_state . off ) { return 0 ; } } action -> write_bytes = req -> data_len ; if ( req -> off + req -> data_len < action -> size ) { rc = flash_area_open ( action -> area_id , & fa ) ; if ( rc ) { * errstr = imgmgr_err_str_flash_open_failed ; return MGMT_ERR_EUNKNOWN ; } rem_bytes = req -> data_len % flash_area_align ( fa ) ; flash_area_close ( fa ) ; if ( rem_bytes ) { action -> write_bytes -= rem_bytes ; } } action -> proceed = true ; return 0 ; }
Verifies an upload request and indicates the actions that should be taken
 during processing of the request.
Verifies an upload request and indicates the actions that should be taken during processing of the request .
/* Request did not include an `off` field. */ /* First upload chunk. */ /*
             * Image header is the first thing in the image.
             */ /* Request did not include a `len` field. */ /*
         * If request includes proper data hash we can check whether there is
         * upload in progress (interrupted due to e.g. link disconnection) with
         * the same data hash so we can just resume it by simply including
         * current upload offset in response.
         */ /* No slot where to upload! */ /* Continuation of upload. */ /*
             * Invalid offset. Drop the data, and respond with the offset we're
             * expecting data for.
             */ /* Calculate size of flash write. */ /*
         * Respect flash write alignment if not in the last block
         */