diff options
Diffstat (limited to 'src/framework/snapshot/fw_snapshot.c')
-rw-r--r-- | src/framework/snapshot/fw_snapshot.c | 483 |
1 files changed, 483 insertions, 0 deletions
diff --git a/src/framework/snapshot/fw_snapshot.c b/src/framework/snapshot/fw_snapshot.c new file mode 100644 index 0000000..790ecbf --- /dev/null +++ b/src/framework/snapshot/fw_snapshot.c @@ -0,0 +1,483 @@ +/* +* +* Copyright (c) 2018 Huawei Technologies Co.,Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at: +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "nstack_securec.h" +#include "nsfw_snapshot.h" +#include "nstack_log.h" +#include "fw_ss_tlv.h" + +#ifdef __cplusplus +/* *INDENT-OFF* */ +extern "C"{ +/* *INDENT-ON* */ +#endif /* __cplusplus */ + +/* *INDENT-OFF* */ +nsfw_ss_objDescManager_t g_nsfw_ss_objDescManager = +{ +.g_nsfw_ss_objDesNum = 0}; + +/* *INDENT-ON* */ + +void +nsfw_ss_register_ObjDesc (nsfw_ss_objDesc_t * objDesc) +{ + if (objDesc == NULL) + return; + nsfw_ss_objDescManager_t *manager = nsfw_ss_getObjDescManagerInst (); + if (manager->g_nsfw_ss_objDesNum >= NSFW_SS_MAX_OBJDESC_NUM) + return; + manager->g_nsfw_ss_objDescs[manager->g_nsfw_ss_objDesNum++] = objDesc; +} + +static nsfw_ss_objDesc_t * +nsfw_ss_getObjDescFromType (u16 objType) +{ + nsfw_ss_objDescManager_t *manager = nsfw_ss_getObjDescManagerInst (); + int i; + for (i = 0; i < manager->g_nsfw_ss_objDesNum && i < NSFW_SS_MAX_OBJDESC_NUM; + i++) + { + if (manager->g_nsfw_ss_objDescs[i]->objType == objType) + return manager->g_nsfw_ss_objDescs[i]; + } + return NULL; +} + +static nsfw_ss_objMemDesc_t * +nsfw_ss_getMemDescFromType (u16 objType, nsfw_ss_objDesc_t * objDesc) +{ + int i; + for (i = 0; i < objDesc->memNum; i++) + { + if (objDesc->memDesc[i].type == objType) + { + return &objDesc->memDesc[i]; + } + } + return NULL; +} + +/** + * @Function nsfw_ss_store + * @Description store object to memory + * @param (in) objType - type of object with member description + * @param (in) obj - adderss of object memory + * @param (in) storeMem - address of memory to store object data + * @param (in) storeMemLen - maximal length of storage memory + * @return positive integer means length of memory cost on success. return -1 if error + */ +int +nsfw_ss_storeObjMem (u16 objMemType, void *obj, void *storeMem, + u32 storeMemLen) +{ + if (NULL == obj || NULL == storeMem) + return -1; + + // example of object + /* struct A{ */ + /* int a1; */ + /* struct A2 a2; --> struct A2 {int a2} */ + /* struct A3 a3[2]; --> struct A3 [{int a3}, {int a3}] */ + /* } */ + + /* -------------------------------------------- */ + /* | type(object) | length | */ + /* | -------------------------------------- | */// -- + /* | | type(item) | length | | */// member a1 + /* | | item value (object->member) | | */// -- + /* | -------------------------------------- | */// object a2 + /* | | type(object) | length | | */// -- + /* | | ------------------------------- | | */// member a2 + /* | | | type(item) | length | | | */// -- + /* | | | item value (object->member) | | | */// -- + /* | | ------------------------------- | | */// + /* | -------------------------------------- | */// + /* | | type(object array) | length | | */// array member a3 + /* | | ------------------------------- | | */// -- + /* | | | type(object) | length | | | */// object a3_1 + /* | | | ----------------------------| | | */// -- + /* | | | type(item) | length | | | */// member a3_1_1 + /* | | | item value (object->member) | | | */ + /* | | | ----------------------------| | | */ + /* | | ------------------------------- | | */ + /* | | | type(object) | length | | | */ + /* | | | ----------------------------| | | */ + /* | | | type(item) | length | | | */ + /* | | | item value (object->member) | | | */ + /* | | | ----------------------------| | | */ + /* | | ------------------------------- | | */ + /* | |------------------------------------| | */ + /* -------------------------------------------- */ + nsfw_ss_objDesc_t *objDesc = + nsfw_ss_getObjDescFromType (NSFW_SS_TYPE_GETOBJ (objMemType)); + if (NULL == objDesc) + return -1; + + /* Get object header tlv */ + if (storeMemLen < tlv_header_length ()) + return -1; + nsfw_ss_tlv_t *tlv = (nsfw_ss_tlv_t *) storeMem; + tlv->type = objMemType; + tlv->length = 0; + tlv_header (storeMem); + storeMemLen -= tlv_header_length (); + + /* Search every object member */ + + /* For base item(including array of base item), it should start with a tlv header */ + /* For object array, it should start with one tlv header including array information */ + /* For object, it should call nsfw_ss_store recursively */ + int i; + for (i = 0; i < objDesc->memNum; i++) + { + nsfw_ss_objMemDesc_t *memDesc = &objDesc->memDesc[i]; + if (NSFW_SS_TYPE_IS_MEMBER_OBJ (memDesc->type)) + { + + if (NSFW_SS_TYPE_IS_MEMBER_ARRAY (memDesc->type)) + { + /* array object should includes one array tlv header, shows the array informations */ + if (storeMemLen < tlv_header_length ()) + return -1; + nsfw_ss_tlv_t *arrayTlv = (nsfw_ss_tlv_t *) storeMem; + arrayTlv->type = memDesc->type; + arrayTlv->length = 0; + tlv_header (storeMem); + storeMemLen -= tlv_header_length (); + nsfw_ss_objDesc_t *memObjDesc = + nsfw_ss_getObjDescFromType (NSFW_SS_TYPE_GETOBJ + (memDesc->type)); + if (NULL == memObjDesc) + return -1; + u32 arraySize = memDesc->length / memObjDesc->objSize; + u32 j; + for (j = 0; j < arraySize; j++) + { + int ret = + nsfw_ss_storeObjMem (NSFW_SS_TYPE_SET_MEMBER_OBJ + (NSFW_SS_TYPE_GETOBJ (memDesc->type), + 0), + (char *) obj + + (u64) (memDesc->offset) + + (u64) j * memObjDesc->objSize, + storeMem, storeMemLen); + if ((-1 == ret) || (storeMemLen < (u32) ret)) + return -1; + tlv_mem_forward (storeMem, ret); + storeMemLen -= (u32) ret; + arrayTlv->length += (u32) ret; + } + tlv->length += (arrayTlv->length + (u32) tlv_header_length ()); + } + else + { + int ret = nsfw_ss_storeObjMem (memDesc->type, + ((char *) obj + memDesc->offset), + storeMem, storeMemLen); + if (ret < 0 || (storeMemLen < (u32) ret)) + return -1; + storeMemLen -= (u32) ret; + tlv_mem_forward (storeMem, ret); + tlv->length += (u32) ret; + } + } + else + { + // Base Item + if (storeMemLen < tlv_header_length ()) + { + return -1; + } + nsfw_ss_tlv_t *curtlv = (nsfw_ss_tlv_t *) storeMem; // curTlv means next tlv elem + curtlv->type = memDesc->type; + curtlv->length = memDesc->length; + tlv_header (storeMem); + storeMemLen -= tlv_header_length (); + if (storeMemLen < curtlv->length) + return -1; + if (EOK != + MEMCPY_S (storeMem, (size_t) storeMemLen, + ((char *) obj + memDesc->offset), + (size_t) memDesc->length)) + { + return -1; + } + tlv_mem_forward (storeMem, memDesc->length); + storeMemLen -= memDesc->length; + tlv->length += (curtlv->length + (u32) tlv_header_length ()); + } + } + return (int) (tlv->length + tlv_header_length ()); +} + +/** + * @Function nsfw_ss_store + * @Description store object to memory + * @param (in) objType - type of object + * @param (in) obj - adderss of object memory + * @param (in) storeMem - address of memory to store object data + * @param (in) storeMemLen - maximal length of storage memory + * @return positive integer means length of memory cost on success. return -1 if error + */ +int +nsfw_ss_store (u16 objType, void *obj, void *storeMem, u32 storeMemLen) +{ + return nsfw_ss_storeObjMem (NSFW_SS_TYPE_SET_MEMBER_OBJ (objType, 0), + obj, storeMem, storeMemLen); +} + +/** + * @Function nsfw_ss_restoreObjArray + * @Description restore array of objects + * @param (in) objType - type of object + * @param (in) objMem - object memory to restore + * @param (in) mem - memory of storage + * @param (in) storeMemLength - maximal length of storage memroy + * @return 0 on succss , -1 on error + */ +NSTACK_STATIC int +nsfw_ss_restoreObjArray (int objType, void *objMem, void *mem, + u32 storeMemLength) +{ + if (storeMemLength < tlv_header_length ()) + return -1; + nsfw_ss_tlv_t *arrayTlv = (nsfw_ss_tlv_t *) mem; + storeMemLength -= tlv_header_length (); + tlv_header (mem); + if (0 == arrayTlv->length || storeMemLength < arrayTlv->length) + return -1; + storeMemLength = arrayTlv->length; // Only cares tlv->value + nsfw_ss_objDesc_t *objDesc = nsfw_ss_getObjDescFromType ((u16) objType); + if (NULL == objDesc) + return -1; + + /* Now we are going to iterate every object */ + u32 objCnt = 0; + while (storeMemLength) + { + if (storeMemLength < tlv_header_length ()) + return -1; // Format error + nsfw_ss_tlv_t *objTlv = (nsfw_ss_tlv_t *) mem; + if ((int) NSFW_SS_TYPE_GETOBJ (objTlv->type) != objType) + { + return -1; + } + int ret = + nsfw_ss_restore ((char *) objMem + (u64) objDesc->objSize * objCnt, + mem, storeMemLength); + if (-1 == ret) + return -1; + objCnt++; + tlv_mem_forward (mem, (objTlv->length + tlv_header_length ())); + storeMemLength -= (objTlv->length + tlv_header_length ()); + } + return 0; +} + +/** + * @Function nsfw_ss_restore + * @Description restore object from memory + * @param (in) objMem - memory of object + * @param (in) mem - memory of storage + * @param (in) storeMemLen - maximal length of storage memory + * @return positive integer stands on object type, -1 on error + */ +int +nsfw_ss_restore (void *objMem, void *mem, u32 storeMemLen) +{ + if (NULL == objMem || NULL == mem || 0 == storeMemLen) + return -1; + + // example of object + /* struct A{ */ + /* int a1; */ + /* struct A2 a2; --> struct A2 {int a2} */ + /* struct A3 a3[2]; --> struct A3 [{int a3}, {int a3}] */ + /* } */ + + /* -------------------------------------------- */// -- + /* | type(object) | length | */// type length + /* | -------------------------------------- | */// -- + /* | | type(item) | length | | */// member a1 + /* | | item value (object->member) | | */// -- + /* | -------------------------------------- | */// object a2 + /* | | type(object) | length | | */// -- + /* | | ------------------------------- | | */// member a2 + /* | | | type(item) | length | | | */// -- + /* | | | item value (object->member) | | | */// -- + /* | | ------------------------------- | | */// + /* | -------------------------------------- | */// + /* | | type(object array) | length | | */// array member a3 + /* | | ------------------------------- | | */// -- + /* | | | type(object) | length | | | */// object a3_1 + /* | | | ----------------------------| | | */// -- + /* | | | type(item) | length | | | */// member a3_1_1 + /* | | | item value (object->member) | | | */ + /* | | | ----------------------------| | | */ + /* | | ------------------------------- | | */ + /* | | | type(object) | length | | | */ + /* | | | ----------------------------| | | */ + /* | | | type(item) | length | | | */ + /* | | | item value (object->member) | | | */ + /* | | | ----------------------------| | | */ + /* | | ------------------------------- | | */ + /* | |------------------------------------| | */ + /* -------------------------------------------- */ + if (storeMemLen < tlv_header_length ()) + return -1; + nsfw_ss_tlv_t *tlv = (nsfw_ss_tlv_t *) mem; + storeMemLen -= tlv_header_length (); + tlv_header (mem); + nsfw_ss_objDesc_t *objDesc = + nsfw_ss_getObjDescFromType (NSFW_SS_TYPE_GETOBJ (tlv->type)); + if (NULL == objDesc) + { + return -1; + } + if (!NSFW_SS_TYPE_IS_MEMBER_OBJ (tlv->type)) + return -1; + if (0 == tlv->length || storeMemLen < tlv->length) + return -1; + + /* Now we go to inner of object */ + storeMemLen = tlv->length; /* Only care about tlv values */ + while (storeMemLen) + { + if (storeMemLen < tlv_header_length ()) + return -1; // Format error + nsfw_ss_tlv_t *curtlv = (nsfw_ss_tlv_t *) mem; + nsfw_ss_objMemDesc_t *memDesc = + nsfw_ss_getMemDescFromType (curtlv->type, objDesc); + if (NULL == memDesc) + { // This type not support + storeMemLen -= tlv_header_length (); + tlv_header (mem); + if (storeMemLen < curtlv->length) + return -1; + tlv_mem_forward (mem, curtlv->length); + storeMemLen -= curtlv->length; + continue; + } + if (NSFW_SS_TYPE_IS_MEMBER_OBJ (curtlv->type)) + { + if (NSFW_SS_TYPE_IS_MEMBER_ARRAY (curtlv->type)) + { + int ret = + nsfw_ss_restoreObjArray ((int) + NSFW_SS_TYPE_GETOBJ (curtlv->type), + (void *) ((char *) objMem + + memDesc->offset), mem, + storeMemLen); + if (-1 == ret) + return -1; + } + else + { + int ret = + nsfw_ss_restore ((void *) ((char *) objMem + + memDesc->offset), mem, + storeMemLen); + if (-1 == ret) + return -1; + } + tlv_mem_forward (mem, (curtlv->length + tlv_header_length ())); + storeMemLen -= (curtlv->length + tlv_header_length ()); + } + else + { + tlv_header (mem); + storeMemLen -= tlv_header_length (); + NSFW_LOGDBG + ("curtlv->type(%u), curtlv->length(%u), memDesc->offset(%u), memDesc->length(%u), mem(%u)", + curtlv->type, curtlv->length, memDesc->offset, memDesc->length, + *(u32 *) mem); + if (storeMemLen < curtlv->length) + return -1; + if (EOK != + MEMCPY_S ((void *) ((char *) objMem + memDesc->offset), + (size_t) memDesc->length, mem, + (size_t) curtlv->length)) + { + return -1; + } + tlv_mem_forward (mem, curtlv->length); + storeMemLen -= curtlv->length; + } + } + return (int) tlv->type; +} + +/** + * @Function nsfw_ss_getObjStoreMemLen + * @Description Get the maximal memory it needs + * @param (in) objType - type of object + * @return length of memory needs, -1 if error + */ +int +nsfw_ss_getObjStoreMemLen (int objType) +{ + u32 maxlength = tlv_header_length (); + u32 i; + nsfw_ss_objDesc_t *objDesc = nsfw_ss_getObjDescFromType ((u16) objType); + if (!objDesc) + return -1; + for (i = 0; i < objDesc->memNum; i++) + { + nsfw_ss_objMemDesc_t *memDesc = &objDesc->memDesc[i]; + int temp_len; + if (NSFW_SS_TYPE_IS_MEMBER_OBJ (memDesc->type)) + { + nsfw_ss_objDesc_t *curObjDesc = + nsfw_ss_getObjDescFromType (NSFW_SS_TYPE_GETOBJ (memDesc->type)); + if (NULL == curObjDesc) + return -1; + if (NSFW_SS_TYPE_IS_MEMBER_ARRAY (memDesc->type)) + { + maxlength += tlv_header_length (); // array length + u32 arrSize = memDesc->length / curObjDesc->objSize; + u32 j; + for (j = 0; j < arrSize; j++) + { + temp_len = + nsfw_ss_getObjStoreMemLen ((int) curObjDesc->objType); + if (temp_len < 0) + return -1; + maxlength += (u32) temp_len; + } + } + else + { + temp_len = + nsfw_ss_getObjStoreMemLen ((int) curObjDesc->objType); + if (temp_len < 0) + return -1; + maxlength += (u32) temp_len; + } + } + else + { + maxlength += ((u32) tlv_header_length () + memDesc->length); + } + } + return (int) maxlength; +} + +#ifdef __cplusplus +/* *INDENT-OFF* */ +} +/* *INDENT-ON* */ +#endif /* __cplusplus */ |