static IngestResult_t ingestDataBlock()

in source/ota.c [123:511]


static IngestResult_t ingestDataBlock( OtaFileContext_t * pFileContext,
                                       const uint8_t * pRawMsg,
                                       uint32_t messageSize,
                                       OtaPalStatus_t * pCloseResult );

/**
 * @brief Validate the incoming data block and store it in the file context.
 *
 * @param[in] pFileContext Information of file to be streamed.
 * @param[in] uBlockIndex Incoming block index.
 * @param[in] uBlockSize Incoming block size.
 * @param[out] pCloseResult Result of closing file in PAL.
 * @param[in] pPayload Data from the block.
 * @return IngestResult_t IngestResultAccepted_Continue if successful, other error for failure.
 */
static IngestResult_t processDataBlock( OtaFileContext_t * pFileContext,
                                        uint32_t uBlockIndex,
                                        uint32_t uBlockSize,
                                        OtaPalStatus_t * pCloseResult,
                                        uint8_t * pPayload );

/**
 * @brief Free the resources allocated for data ingestion and close the file handle.
 *
 * @param[in] pFileContext Information of file to be streamed.
 * @param[out] pCloseResult Result of closing file in PAL.
 * @return IngestResult_t IngestResultAccepted_Continue if successful, other error for failure.
 */

static IngestResult_t ingestDataBlockCleanup( OtaFileContext_t * pFileContext,
                                              OtaPalStatus_t * pCloseResult );

/**
 * @brief Get the File Context From Job Document.
 *
 * We received an OTA update job message from the job service so process
 * the message and update the file context.
 *
 * @param[in] pRawMsg Raw job document.
 * @param[in] messageLength length of document.
 * @return OtaFileContext_t* Information of file to be streamed.
 */
static OtaFileContext_t * getFileContextFromJob( const char * pRawMsg,
                                                 uint32_t messageLength );

/**
 * @brief Validate JSON document and the DocModel.
 *
 * @param[in] pJson JSON job document.
 * @param[in] messageLength  Length of the job document.
 * @return DocParseErr_t DocParseErrNone if successful, JSON document parser errors.
 */

static DocParseErr_t validateJSON( const char * pJson,
                                   uint32_t messageLength );

/**
 * @brief Store the parameter from the json to the offset specified by the document model.
 *
 * @param[in] docParam Structure to store the details of keys and where to store them.
 * @param[in] pContextBase Start of file context.
 * @param[in] pValueInJson Pointer to the value of the key in JSON buffer.
 * @param[in] valueLength Length of the value.
 * @return DocParseErr_t DocParseErrNone if successful, JSON document parser errors.
 */
static DocParseErr_t extractParameter( JsonDocParam_t docParam,
                                       void * pContextBase,
                                       const char * pValueInJson,
                                       size_t valueLength );

/**
 * @brief Extract the desired fields from the JSON document based on the specified document model.
 *
 * @param[in] pJson JSON job document.
 * @param[in] messageLength  Length of the job document.
 * @param[in] pDocModel Details of expected parameters in the job doc.
 * @return DocParseErr_t DocParseErr_t DocParseErrNone if successful, JSON document parser errors.
 */
static DocParseErr_t parseJSONbyModel( const char * pJson,
                                       uint32_t messageLength,
                                       JsonDocModel_t * pDocModel );

/**
 * @brief Decode the base64 encoded file signature key from the job document and store it in file context.
 *
 * @param[in] pValueInJson Pointer to the value of the key in JSON buffer.
 * @param[in] valueLength Length of the value.
 * @param[out] pParamAdd Pointer to the location where the value is stored.
 * @return DocParseErr_t DocParseErrNone if successful, JSON document parser errors.
 */
static DocParseErr_t decodeAndStoreKey( const char * pValueInJson,
                                        size_t valueLength,
                                        void * pParamAdd );

/**
 * @brief Extract the value from json and store it into the allocated memory.
 *
 * @param[in] pKey Name of the Key to extract.
 * @param[in] pValueInJson Pointer to the value of the key in JSON buffer.
 * @param[in] valueLength Length of the value.
 * @param[out] pParamAdd Pointer to the location where the value is stored.
 * @param[in] pParamSizeAdd Size required to store the param.
 * @return DocParseErr_t DocParseErrNone if successful, JSON document parser errors.
 */
static DocParseErr_t extractAndStoreArray( const char * pKey,
                                           const char * pValueInJson,
                                           size_t valueLength,
                                           void * pParamAdd,
                                           uint32_t * pParamSizeAdd );

/**
 * @brief Check if all the required parameters for job document are extracted from the JSON.
 *
 * @param[in] pModelParam Structure to store the details of keys and where to store them.
 * @param[in] pDocModel Details of expected parameters in the job doc.
 * @return DocParseErr_t DocParseErrNone if successful, JSON document parser errors.
 */
static DocParseErr_t verifyRequiredParamsExtracted( const JsonDocParam_t * pModelParam,
                                                    const JsonDocModel_t * pDocModel );

/**
 * @brief Validate the version of the update received.
 *
 * @param[in] pFileContext Information of file to be streamed.
 * @return OtaErr_t OtaErrNone if successful, other error codes if failure.
 */
static OtaErr_t validateUpdateVersion( const OtaFileContext_t * pFileContext );

/**
 * @brief Check if the JSON can be parsed through the app callback if initial parsing fails.
 *
 * @param[in] pJson JSON job document.
 * @param[in] messageLength Length of the job document.
 * @return OtaJobParseErr_t OtaJobParseErrNone if successful, other error codes if failure.
 */
static OtaJobParseErr_t handleCustomJob( const char * pJson,
                                         uint32_t messageLength );

/**
 * @brief Check if the incoming job document is not conflicting with current job status.
 *
 * @param[in] pFileContext Information of file to be streamed.
 * @param[out] pFinalFile File that stores all extracted params.
 * @param[out] pUpdateJob Represents if the job is accepted.
 * @return OtaJobParseErr_t OtaErrNone if successful, other error codes if failure.
 */
static OtaJobParseErr_t verifyActiveJobStatus( OtaFileContext_t * pFileContext,
                                               OtaFileContext_t ** pFinalFile,
                                               bool * pUpdateJob );

/**
 * @brief Check if all the file context params are valid and initialize resources for the job transfer.
 *
 * @param[in] pFileContext Information of file to be streamed.
 * @param[out] pFinalFile File that stores all extracted params.
 * @param[out] pUpdateJob Represents if the job is accepted.
 * @return OtaJobParseErr_t OtaJobParseErrNone if successful, other error codes if failure.
 */
static OtaJobParseErr_t validateAndStartJob( OtaFileContext_t * pFileContext,
                                             OtaFileContext_t ** pFinalFile,
                                             bool * pUpdateJob );

/**
 * @brief Parse the OTA job document, validate and return the populated OTA context if valid.
 *
 * @param[in] pJsonExpectedParams Structure to store the details of keys and where to store them.
 * @param[in] numJobParams Number of parameters to be extracted.
 * @param[in] pJson JSON job document.
 * @param[in] messageLength Length of the job document.
 * @param[in] pUpdateJob Represents if the job is accepted.
 * @return OtaFileContext_t* File context to store file information.
 */
static OtaFileContext_t * parseJobDoc( const JsonDocParam_t * pJsonExpectedParams,
                                       uint16_t numJobParams,
                                       const char * pJson,
                                       uint32_t messageLength,
                                       bool * pUpdateJob );

/**
 * @brief Validate block index and block size of the data block.
 *
 * @param[in] pFileContext Information of file to be streamed.
 * @param[in] blockIndex Block index of incoming data block.
 * @param[in] blockSize Block size of incoming data block.
 * @return true if successful, false otherwise.
 */
static bool validateDataBlock( const OtaFileContext_t * pFileContext,
                               uint32_t blockIndex,
                               uint32_t blockSize );

/**
 * @brief Decode and ingest the incoming data block.
 *
 * @param[in] pFileContext Information of file to be streamed.
 * @param[in] pRawMsg Raw job document.
 * @param[in] messageSize Length of document.
 * @param[in] pPayload Data stored in the document.
 * @param[out] pBlockSize Block size of incoming data block.
 * @param[out] pBlockIndex Block index of incoming data block.
 * @return IngestResult_t IngestResultAccepted_Continue if successful, other error for failure.
 */
static IngestResult_t decodeAndStoreDataBlock( OtaFileContext_t * pFileContext,
                                               const uint8_t * pRawMsg,
                                               uint32_t messageSize,
                                               uint8_t ** pPayload,
                                               uint32_t * pBlockSize,
                                               uint32_t * pBlockIndex );

/**
 * @brief Close an open OTA file context and free it.
 *
 * @param[in] pFileContext Information of file to be streamed.
 * @return true if successful, false otherwise.
 */
static bool otaClose( OtaFileContext_t * const pFileContext );

/**
 * @brief OTA Timer callback.
 *
 * @param[in] otaTimerId Reference to the timer to use.
 */
static void otaTimerCallback( OtaTimerId_t otaTimerId );

/**
 * @brief Internal function to set the image state including an optional reason code.
 *
 * @param[in] stateToSet State to set.
 * @param[in] reasonToSet Reason to set.
 * @return OtaErr_t OtaErrNone if successful, other codes on failure.
 */
static OtaErr_t setImageStateWithReason( OtaImageState_t stateToSet,
                                         uint32_t reasonToSet );

/**
 * @brief Internal function to update the job status to the jobs service from current image state.
 *
 * @param[in] state State to set.
 * @param[in] subReason Reason for status.
 * @return OtaErr_t OtaErrNone if successful, other codes on failure.
 */
static OtaErr_t updateJobStatusFromImageState( OtaImageState_t state,
                                               int32_t subReason );

/**
 * @brief  A helper function to cleanup resources during OTA agent shutdown.
 */
static void agentShutdownCleanup( void );

/**
 * @brief A helper function to cleanup resources when data ingestion is complete.
 */
static void dataHandlerCleanup( void );

/**
 * @brief Prepare the document model for use by sanity checking the initialization parameters and detecting all required parameters.
 *
 * @param[inout] pDocModel Details of expected parameters in the job doc.
 * @param[in] pBodyDef Structure to store the details of keys and where to store them.
 * @param[in] contextBaseAddr Start of file context.
 * @param[in] contextSize Size of file context.
 * @param[in] numJobParams Number of parameters to be extracted.
 * @return DocParseErr_t DocParseErrNone if successful, JSON document parser errors.
 */
static DocParseErr_t initDocModel( JsonDocModel_t * pDocModel,
                                   const JsonDocParam_t * pBodyDef,
                                   void * contextBaseAddr,
                                   uint32_t contextSize,
                                   uint16_t numJobParams );

/**
 * @brief Initialize buffers for storing the file attributes.
 *
 * @param[out] pOtaBuffer OTA Application buffers.
 */
static void initializeAppBuffers( OtaAppBuffer_t * pOtaBuffer );

/**
 * @brief Initialize jobId and protocol buffers.
 */
static void initializeLocalBuffers( void );

/**
 * @brief Search the state transition table for the entry based on current state and incoming event.
 *
 * @param[in] pEventMsg Incoming event information.
 * @return uint32_t Index of the transition.
 */
static uint32_t searchTransition( const OtaEventMsg_t * pEventMsg );

/**
 * @brief Initiate download if not in self-test else reboot
 *
 * @return OtaErr_t OtaErrNone if successful.
 */
static OtaErr_t processValidFileContext( void );

/**
 * @brief Validate update version when receiving job doc in self test state.
 *
 * @param[in] pFileContext Stores file information.
 */
static void handleSelfTestJobDoc( OtaFileContext_t * pFileContext );

/**
 * @brief Handle invalid file context.
 *
 * @return OtaErr_t OtaErrNone if job parsing is handled.
 */
static OtaErr_t processNullFileContext( void );

/**
 * @brief Check if the platform is in self-test
 *
 * @return true if in self-test, else false.
 */
static bool platformInSelftest( void );

/**
 * @brief Function to handle events that were unexpected in the current state.
 *
 * @param[in] pEventMsg Stores information of the event.
 */
static void handleUnexpectedEvents( const OtaEventMsg_t * pEventMsg );

/**
 * @brief Free or clear multiple buffers used in the file context.
 *
 * @param[in] pFileContext Information of file to be streamed.
 */
static void freeFileContextMem( OtaFileContext_t * const pFileContext );

/**
 * @brief Handle job parsing error.
 *
 * @param[in] pFileContext Pointer to the file context.
 *
 * @param[in] err Parsing error of type OtaJobParseErr_t.
 */
static void handleJobParsingError( const OtaFileContext_t * pFileContext,
                                   OtaJobParseErr_t err );

/**
 * @brief Receive and process the next available event from the event queue.
 *
 * Each event is processed based on the behavior defined in the OTA transition
 * table. The state of the OTA state machine will be updated and the
 * corresponding event handler will be called.
 */
static void receiveAndProcessOtaEvent( void );

/* OTA state event handler functions. */

static OtaErr_t startHandler( const OtaEventData_t * pEventData );           /*!< Start timers and initiate request for job document. */
static OtaErr_t requestJobHandler( const OtaEventData_t * pEventData );      /*!< Initiate a request for a job. */
static OtaErr_t processJobHandler( const OtaEventData_t * pEventData );      /*!< Update file context from job document. */
static OtaErr_t inSelfTestHandler( const OtaEventData_t * pEventData );      /*!< Handle self test. */
static OtaErr_t initFileHandler( const OtaEventData_t * pEventData );        /*!< Initialize and handle file transfer. */
static OtaErr_t processDataHandler( const OtaEventData_t * pEventData );     /*!< Process incoming data blocks. */
static OtaErr_t requestDataHandler( const OtaEventData_t * pEventData );     /*!< Request for data blocks. */
static OtaErr_t shutdownHandler( const OtaEventData_t * pEventData );        /*!< Shutdown OTA and cleanup. */
static OtaErr_t closeFileHandler( const OtaEventData_t * pEventData );       /*!< Close file opened for download. */
static OtaErr_t userAbortHandler( const OtaEventData_t * pEventData );       /*!< Handle user interrupt to abort task. */
static OtaErr_t suspendHandler( const OtaEventData_t * pEventData );         /*!< Handle suspend event for OTA agent. */
static OtaErr_t resumeHandler( const OtaEventData_t * pEventData );          /*!< Resume from a suspended state. */
static OtaErr_t jobNotificationHandler( const OtaEventData_t * pEventData ); /*!< Upon receiving a new job document cancel current job if present and initiate new download. */
static void executeHandler( uint32_t index,
                            const OtaEventMsg_t * const pEventMsg );         /*!< Execute the handler for selected index from the transition table. */

/**
 * @brief This is THE OTA agent context and initialization state.
 */
static OtaAgentContext_t otaAgent =
{
    OtaAgentStateStopped, /* state */
    { 0 },                /* pThingName */
    { 0 },                /* fileContext */
    0,                    /* fileIndex */
    0,                    /* serverFileID */
    { 0 },                /* pActiveJobName */
    NULL,                 /* pClientTokenFromJob */
    0,                    /* timestampFromJob */
    OtaImageStateUnknown, /* imageState */
    1,                    /* numOfBlocksToReceive */
    { 0 },                /* statistics */
    0,                    /* requestMomentum */
    NULL,                 /* pOtaInterface */
    NULL,                 /* OtaAppCallback */
    1                     /* unsubscribe flag */
};