summaryrefslogtreecommitdiffstats
path: root/src/framework/snapshot/fw_snapshot.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/framework/snapshot/fw_snapshot.c')
-rw-r--r--src/framework/snapshot/fw_snapshot.c483
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 */