From b0a174cf303ba2611fd55ccea9e49e36e5d2391f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E6=98=95?= <huangxin@cmhi.chinamobile.com>
Date: Wed, 25 Sep 2019 15:42:59 +0800
Subject: [PATCH] =?UTF-8?q?Mod=20=20aaa-12=20=E5=A2=9E=E5=8A=A0=E5=AF=B9?=
 =?UTF-8?q?=E8=B1=A1=E7=AE=A1=E7=90=86=E5=88=A0=E9=99=A4=E6=8E=A5=E5=8F=A3?=
 =?UTF-8?q?=20RCA=EF=BC=9A=20SOL=EF=BC=9A=20=E4=BF=AE=E6=94=B9=E4=BA=BA?=
 =?UTF-8?q?=EF=BC=9Ahuangxin=20=E6=A3=80=E8=A7=86=E4=BA=BA=EF=BC=9Ahuangxi?=
 =?UTF-8?q?n?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Product/common/common.h                      |  95 +++++++++++++
 Product/modules/proc_api/proc_api.c          |   1 +
 Product/modules/proc_api/proc_api.h          |   2 -
 Product/user/object_manager/json_interface.c |  75 ++++++++--
 Product/user/object_manager/json_interface.h |  22 ++-
 Product/user/object_manager/main.c           | 142 ++++++++++++++-----
 6 files changed, 280 insertions(+), 57 deletions(-)

diff --git a/Product/common/common.h b/Product/common/common.h
index 70696f1e2..b86a0e3de 100644
--- a/Product/common/common.h
+++ b/Product/common/common.h
@@ -42,4 +42,99 @@
 #define    RET_SENDERR     13
 #define    RET_NOCMID      14
 #define    RET_SRCERR      15
+#define    RET_JSONERR     16
+#define    RET_USED        17
+
+static inline char *get_err_message(int err)
+{
+    if(err < 0) {
+        err = -err;
+    }
+
+    switch(err) {
+        case RET_OK:                    return "OK";
+
+        case RET_ERR:                   return "Error";
+
+        case RET_UNKNOWN:               return "Unkown";
+
+        case RET_SYSERR:                return "SystemError";
+
+        case RET_NOTFOUND:              return "NotFound";
+
+        case RET_TIMEOUT:               return "Timeout";
+
+        case RET_NULLP:                 return "NullPointer" ;
+
+        case RET_NOMEM:                 return "NotEnoughMemory";
+
+        case RET_CHKERR:                return "CheckError";
+
+        case RET_NOTSUPPORT:            return "NotSupport";
+
+        case RET_INPUTERR:              return "InputError";
+
+        case RET_EXIST:                 return "AlreadyExist";
+
+        case RET_FULL:                  return "Full";
+
+        case RET_SENDERR:               return "SendErr";
+
+        case RET_NOCMID:                return "CanNotFindConfig";
+
+        case RET_SRCERR:                return "ConfigSourceErr";
+
+        case RET_JSONERR:               return "JsonFormatErr";
+
+        case RET_USED:                  return "ItemUsed";
+#if 0
+
+        case RET_IPINVALID:             return "IpInvalid";
+
+        case RET_BRNAMEERR:             return "BrNameInvalid";
+
+        case RET_VIDNUM_INVALID:        return "VidNumInvalid";
+
+        case RET_VID_INVALID:           return "VidValueInvalid";
+
+        case RET_VID_EXIST:             return "VidHasExist";
+
+        case RET_VID_NOT_EXIST:         return "VidHasNotExist";
+
+        case RET_INTERFACE_NOT_EXIST:   return "InterfaceHasNotExist";
+
+        case RET_ATTR_INVALID:          return "AttrInvalid";
+
+        case RET_OPTYPE_ERR:            return "OperationTypeError";
+
+        case RET_SYS_VCONFIG_ERR:       return "SystemVconfigError";
+
+        case RET_SYS_IFCONFIG_ERR:      return "SystemIfconfigError";
+
+        case RET_SYS_FILEOP_ERR:        return "SystemFileOperationError";
+
+        case RET_OPEN_FILE_ERR:         return "CanNotOpenConfigFile";
+
+        case RET_EXEC_ERR:              return "CanNotExecuateShell";
+
+        case RET_METRIC_ERR:            return "InvalidMetric";
+
+        case RET_NETMASK_ERR:           return "InvalidNetmask";
+
+        case RET_EMPTY_STRING:          return "InputEmpty";
+
+        case RET_WRONG_TYPE:            return "WrongType";
+
+        case RET_VERSION_ERR:           return "InvalidProtocol";
+
+        case RET_DESTIP_ERR:            return "InvalidDestIP";
+
+        case RET_GATEWAY_ERR:           return "InvalidGateway";
+
+        case RET_GW_DEV_ERR:            return "Gateway&DevEmpty";
+#endif
+    }
+
+    return "Unknown err code";
+}
 #endif
\ No newline at end of file
diff --git a/Product/modules/proc_api/proc_api.c b/Product/modules/proc_api/proc_api.c
index 39c68c0c2..f53fd829a 100644
--- a/Product/modules/proc_api/proc_api.c
+++ b/Product/modules/proc_api/proc_api.c
@@ -12,6 +12,7 @@
 
 #include "proc_api.h"
 #include "../../common/uthash.h"
+#include "../../common/common.h"
 
 #define MAX_COMMAND_LEN                 (256)
 #define MAX_CMD_LEN                     (32)
diff --git a/Product/modules/proc_api/proc_api.h b/Product/modules/proc_api/proc_api.h
index 7447272c0..263cd020d 100644
--- a/Product/modules/proc_api/proc_api.h
+++ b/Product/modules/proc_api/proc_api.h
@@ -4,8 +4,6 @@
 
 #include <asm/atomic.h>
 
-#include "../../common/common.h"
-
 #define PROC_API_DIR_NAME               ("isg")
 
 typedef enum {
diff --git a/Product/user/object_manager/json_interface.c b/Product/user/object_manager/json_interface.c
index 231daf7cb..e3208cfac 100644
--- a/Product/user/object_manager/json_interface.c
+++ b/Product/user/object_manager/json_interface.c
@@ -4,8 +4,6 @@
 #include <time.h>
 #include <cjson/cJSON.h>
 
-#include "../../common/common.h"
-
 #include "log.h"
 #include "json_interface.h"
 
@@ -72,7 +70,8 @@ static int __interface_decode(const char *pJsonS, void **pStruct)
     pData->timeStamp  = cJSON_GetObjectItem(pRoot, "timeStamp")->valueint;
 
     if(cJSON_HasObjectItem(pRoot, "msgContent")) {
-        pData->msgContent = strdup(cJSON_GetObjectItem(pRoot, "msgContent")->valuestring);
+        pData->msgContent = strdup(cJSON_GetObjectItem(pRoot,
+                                                       "msgContent")->valuestring);
     }
 
     cJSON_Delete(pRoot);
@@ -82,7 +81,48 @@ static int __interface_decode(const char *pJsonS, void **pStruct)
 
 static const char *__obj_add_encode(void *pData)
 {
+    const char     *pJsonS;
+    PIFC_RET_MSG p         = (PIFC_RET_MSG)pData;
+    cJSON           *pRoot = cJSON_CreateObject();
 
+    if(!p) {
+        return NULL;
+    }
+
+    cJSON_AddNumberToObject(pRoot, "ret_code",    p->ret_code);
+
+    if(p->mesg) {
+        cJSON_AddStringToObject(pRoot, "mesg",    p->mesg);
+    }
+
+    if(p->n_items > 0) {
+        int i;
+        cJSON *pArray = cJSON_AddArrayToObject(pRoot, "data");
+
+        if(pArray) {
+            for(i = 0; i < p->n_items; i++) {
+                cJSON *pItem = cJSON_CreateObject();
+
+                if(!pItem) {
+                    continue;
+                }
+
+                cJSON_AddStringToObject(pItem, "name",      p->data[i].name);
+                cJSON_AddNumberToObject(pItem, "ret_code",  p->data[i].ret_code);
+
+                if(p->data[i].mesg) {
+                    cJSON_AddStringToObject(pItem, "mesg", p->data[i].mesg);
+                }
+
+                cJSON_AddItemToArray(pArray, pItem);
+            }
+        }
+    }
+
+    pJsonS  = cJSON_Print(pRoot);
+    cJSON_Delete(pRoot);
+
+    return pJsonS;
 }
 
 static int __obj_add_decode(const char *pJsonS, void **pStruct)
@@ -147,25 +187,32 @@ static int __obj_add_decode(const char *pJsonS, void **pStruct)
 
         pObj->prio = cJSON_GetObjectItem(pSub, "prio")->valueint;
         pObjK->type = cJSON_GetObjectItem(pSub, "type")->valueint;
-        strncpy(pObj->name, cJSON_GetObjectItem(pSub, "name")->valuestring, MAX_NAME_LEN - 1);
-        strncpy(pObj->desc, cJSON_GetObjectItem(pSub, "desc")->valuestring, MAX_DESC - 1);
+        strncpy(pObj->name, cJSON_GetObjectItem(pSub, "name")->valuestring,
+                MAX_NAME_LEN - 1);
+        strncpy(pObj->desc, cJSON_GetObjectItem(pSub, "desc")->valuestring,
+                MAX_DESC - 1);
 
         for(j = 0; j < pObjK->ctx_num; j++) {
             cJSON *pItem = cJSON_GetArrayItem(pSubContent, j);
 
             switch(pObjK->type / 10) {
                 case OBJ_TYPE_SERVER:
-                    pObjK->objs.svr_obj[j].pro_type = cJSON_GetObjectItem(pItem, "proType")->valueint;
-                    pObjK->objs.svr_obj[j].str_val = strdup(cJSON_GetObjectItem(pItem, "porPort")->valuestring);
+                    pObjK->objs.svr_obj[j].pro_type = cJSON_GetObjectItem(pItem,
+                                                                          "proType")->valueint;
+                    pObjK->objs.svr_obj[j].str_val = strdup(cJSON_GetObjectItem(pItem,
+                                                                                "porPort")->valuestring);
                     break;
 
                 case OBJ_TYPE_ADDR:
-                    pObjK->objs.addr_obj[j].str_val = strdup(cJSON_GetObjectItem(pItem, "ipAddr")->valuestring);
+                    pObjK->objs.addr_obj[j].str_val = strdup(cJSON_GetObjectItem(pItem,
+                                                                                 "ipAddr")->valuestring);
                     break;
 
                 case OBJ_TYPE_DATETIME:
-                    pObjK->objs.dt_obj[j].rep_mode = cJSON_GetObjectItem(pItem, "repType")->valueint;
-                    pObjK->objs.dt_obj[j].str_val = strdup(cJSON_GetObjectItem(pItem, "timeValue")->valuestring);
+                    pObjK->objs.dt_obj[j].rep_mode = cJSON_GetObjectItem(pItem,
+                                                                         "repType")->valueint;
+                    pObjK->objs.dt_obj[j].str_val = strdup(cJSON_GetObjectItem(pItem,
+                                                                               "timeValue")->valuestring);
                     break;
             }
         }
@@ -179,10 +226,11 @@ static int __obj_add_decode(const char *pJsonS, void **pStruct)
 
 static JSON_ENGINE g_jSonEngine[] = {
     {JE_INTERFACE,      __interface_encode,     __interface_decode,      NULL},
-    {OBJ_CMD_ADD,       NULL,                   __obj_add_decode,      NULL}
+    {OBJ_CMD_ADD,       __obj_add_encode,       __obj_add_decode,      NULL},
 };
 
-int Json2Struct(const char *pJsonStr, void *pData, JSON_ENGINE_TYPE type, int enBase64)
+int Json2Struct(const char *pJsonStr, void *pData, JSON_ENGINE_TYPE type,
+                int enBase64)
 {
     if(pJsonStr == NULL || pData == NULL) {
         return -RET_INPUTERR;
@@ -207,7 +255,8 @@ int Json2Struct(const char *pJsonStr, void *pData, JSON_ENGINE_TYPE type, int en
     }
 }
 
-const char *Struct2Json(void *pStruct, JSON_ENGINE_TYPE type, int enBase64, int *pErr)
+const char *Struct2Json(void *pStruct, JSON_ENGINE_TYPE type, int enBase64,
+                        int *pErr)
 {
     if(pStruct == NULL || pErr == NULL) {
         if(pErr) {
diff --git a/Product/user/object_manager/json_interface.h b/Product/user/object_manager/json_interface.h
index f386afbec..c844727f3 100644
--- a/Product/user/object_manager/json_interface.h
+++ b/Product/user/object_manager/json_interface.h
@@ -13,8 +13,7 @@ typedef enum {
     OBJ_CMD_QUERYDETAIL     = 104,
 } JSON_CMD;
 
-typedef enum
-{
+typedef enum {
     JE_INTERFACE,
     JE_OBJ_ADD,
     JE_OBJ_MOD,
@@ -47,8 +46,23 @@ typedef struct {
     int             n_obj;
 } IFACE_ADD_OBJ, *PIFACE_ADD_OBJ;
 
-int Json2Struct(const char *pJsonStr, void* pData, JSON_ENGINE_TYPE type, int enBase64);
-const char* Struct2Json(void* pStruct, JSON_ENGINE_TYPE type, int enBase64, int* pErr);
+typedef struct {
+    char           *name;
+    char           *mesg;
+    int             ret_code;
+} IFC_RET_LIST, *PIFC_RET_LIST;
+
+typedef struct {
+    int             ret_code;
+    char           *mesg;
+    int             n_items;
+    IFC_RET_LIST    data[100];
+} IFC_RET_MSG, *PIFC_RET_MSG;
+
+int Json2Struct(const char *pJsonStr, void *pData, JSON_ENGINE_TYPE type,
+                int enBase64);
+const char *Struct2Json(void *pStruct, JSON_ENGINE_TYPE type, int enBase64,
+                        int *pErr);
 
 #ifdef __cplusplus
 }
diff --git a/Product/user/object_manager/main.c b/Product/user/object_manager/main.c
index 3c751d8c9..03e0ffa89 100644
--- a/Product/user/object_manager/main.c
+++ b/Product/user/object_manager/main.c
@@ -25,7 +25,7 @@ static PCMHI_OBJECT g_pObject = NULL;
 static OBJECT_K g_objItem[MAX_OBJ];
 static pthread_mutex_t g_obj_lock = PTHREAD_MUTEX_INITIALIZER;
 
-int split_params(char *pInput, char **pFirst, char **pSecond, const char *split)
+static int split_params(char *pInput, char **pFirst, char **pSecond, const char *split)
 {
     char *pStr = (char *)pInput;
     char *p;
@@ -174,7 +174,7 @@ int object_add(PCMHI_OBJECT pObj, POBJECT_K pObjK)
 
         switch(pObjK->type / 10) {
             case OBJ_TYPE_SERVER:
-                split_params((char*)pSvr->str_val, &pStart, &pEnd, "-");
+                split_params((char *)pSvr->str_val, &pStart, &pEnd, "-");
 
                 if(!pcre_match(REGEX_SVR_PORT, pStart)) {
                     LOG_EX(LOG_Error, "Input %s format error\n", pStart);
@@ -210,14 +210,14 @@ int object_add(PCMHI_OBJECT pObj, POBJECT_K pObjK)
                 break;
 
             case OBJ_TYPE_ADDR:
-                split_params((char*)pAddr->str_val, &pStart, &pEnd, "-");
+                split_params((char *)pAddr->str_val, &pStart, &pEnd, "-");
 
                 if(!pcre_match(REGEX_IP_ADDR, pStart)) {
                     LOG_EX(LOG_Error, "Input %s format error\n", pStart);
                     return -RET_INPUTERR;
                 }
 
-                split_params((char*)pStart, &pSubStart, &pSubEnd, "/");
+                split_params((char *)pStart, &pSubStart, &pSubEnd, "/");
 
                 if(pSubEnd && strlen(pSubEnd) > 0) {
                     pAddr->net_mask = strtoul(pSubEnd, NULL, 10);
@@ -263,7 +263,7 @@ int object_add(PCMHI_OBJECT pObj, POBJECT_K pObjK)
                 break;
 
             case OBJ_TYPE_DATETIME:
-                split_params((char*)pDt->str_val, &pStart, &pEnd, "-");
+                split_params((char *)pDt->str_val, &pStart, &pEnd, "-");
 
                 if(!pcre_match(REGEX_DT, pStart)) {
                     LOG_EX(LOG_Error, "Input %s format error\n", pStart);
@@ -332,6 +332,34 @@ int object_add(PCMHI_OBJECT pObj, POBJECT_K pObjK)
     pthread_mutex_unlock(&g_obj_lock);
 }
 
+int object_del(const char* pName)
+{
+    PCMHI_OBJECT p, pTmp;
+
+    pthread_mutex_lock(&g_obj_lock);
+    HASH_FIND_STR(g_pObject, pName, p);
+    pthread_mutex_unlock(&g_obj_lock);
+
+    if(p == NULL) {
+        LOG_EX(LOG_Error, "Item %s exists\n", p->name);
+        return -RET_NOTFOUND;
+    }
+
+    if(g_objItem[p->obj_index].ref_count > 0) {
+        LOG_EX(LOG_Error, "Item %s used %d\n", p->name, g_objItem[p->obj_index].ref_count);
+        return -RET_USED;
+    }
+
+    pthread_mutex_lock(&g_obj_lock);
+    HASH_DEL(g_pObject, p);
+    pthread_mutex_unlock(&g_obj_lock);
+
+    memset(&g_objItem[p->obj_index].memTag, 0, sizeof(OBJECT_K));
+    free(p);
+
+    return RET_OK;
+}
+
 static const char *read_json_file(const char *pPath)
 {
     FILE *pFile;
@@ -369,18 +397,45 @@ static const char *read_json_file(const char *pPath)
     return (const char *)pBuf;
 }
 
+static void test_del_object(void)
+{
+
+}
+
 static void test_add_object(void)
 {
-    PJSON_INTERFACE p = NULL;
-    PIFACE_ADD_OBJ pAdd = NULL;
-    int i, j, ret;
-    const char *pJson = read_json_file(ADD_JS_FILE);
+    int i, ret;
+    const char *pRetJson;
+    IFC_RET_MSG retCtx;
+    PJSON_INTERFACE p           = NULL;
+    PIFACE_ADD_OBJ  pAdd        = NULL;
+    const           char *pJson = read_json_file(ADD_JS_FILE);
 
     ret = Json2Struct(pJson, &p, JE_INTERFACE, FALSE);
 
+    memset(&retCtx, 0, sizeof(IFC_RET_MSG));
+
     if(ret != RET_OK || p == NULL) {
         LOG_EX(LOG_Error, "Decode json error: %d\n", ret);
-        free((void*)pJson);
+        free((void *)pJson);
+
+        if(p) {
+            free(p);
+        }
+
+        retCtx.ret_code = -RET_JSONERR;
+        retCtx.mesg = get_err_message(RET_JSONERR);
+        retCtx.n_items = 0;
+
+        pRetJson = Struct2Json(&retCtx, JE_OBJ_ADD, FALSE, &ret);
+
+        if(!pRetJson || ret != RET_OK) {
+            LOG_EX(LOG_Error, "Json format error: %d\n", ret);
+            return;
+        }
+
+        LOG_EX(LOG_Debug, "Respons:\n%s\n", pRetJson);
+        free((void *)pRetJson);
         return;
     }
 
@@ -396,56 +451,67 @@ static void test_add_object(void)
         LOG_EX(LOG_Error, "Decode json error: %d\n", ret);
 
         if(p->msgContent) {
-            free((void*)p->msgContent);
+            free((void *)p->msgContent);
         }
 
         free(p);
-        free((void*)pJson);
+        free((void *)pJson);
+
+        retCtx.ret_code = -RET_JSONERR;
+        retCtx.mesg = get_err_message(RET_JSONERR);
+        retCtx.n_items = 0;
+
+        pRetJson = Struct2Json(&retCtx, JE_OBJ_ADD, FALSE, &ret);
+
+        if(!pRetJson || ret != RET_OK) {
+            LOG_EX(LOG_Error, "Json format error: %d\n", ret);
+            return;
+        }
+
+        LOG_EX(LOG_Debug, "Respons:\n%s\n", pRetJson);
+        free((void *)pRetJson);
+
         return;
+    } else {
+        retCtx.n_items = pAdd->n_obj;
     }
 
     for(i = 0; i < pAdd->n_obj; i++) {
-        LOG_EX(LOG_Info, "name:         %s\n", pAdd->pCtx[i].obj.name);
-        LOG_EX(LOG_Info, "desc:         %s\n", pAdd->pCtx[i].obj.desc);
-        LOG_EX(LOG_Info, "prio:         %d\n", pAdd->pCtx[i].obj.prio);
-        LOG_EX(LOG_Info, "type:         %d\n", pAdd->pCtx[i].objk.type);
-        LOG_EX(LOG_Info, "items:        %d\n", pAdd->pCtx[i].objk.ctx_num);
+        ret = object_add(&pAdd->pCtx[i].obj, &pAdd->pCtx[i].objk);
 
-        for(j = 0; j < pAdd->pCtx[i].objk.ctx_num; j++) {
-            POBJECT_K pObjK = &pAdd->pCtx[i].objk;
-
-            switch(pObjK->type / 10) {
-                case OBJ_TYPE_SERVER:
-                    LOG_EX(LOG_Info, "    porType:      %d\n", pObjK->objs.svr_obj[j].pro_type);
-                    LOG_EX(LOG_Info, "    value:        %s\n", pObjK->objs.svr_obj[j].str_val);
-                    break;
-
-                case OBJ_TYPE_ADDR:
-                    LOG_EX(LOG_Info, "    value:        %s\n", pObjK->objs.addr_obj[j].str_val);
-                    break;
-
-                case OBJ_TYPE_DATETIME:
-                    LOG_EX(LOG_Info, "    repeat:       %d\n", pObjK->objs.dt_obj[j].rep_mode);
-                    LOG_EX(LOG_Info, "    value:        %s\n", pObjK->objs.dt_obj[j].str_val);
-                    break;
-            }
+        if(ret != RET_OK && retCtx.ret_code == RET_OK) {
+            retCtx.ret_code = -RET_JSONERR;
         }
 
-        object_add(&pAdd->pCtx[i].obj, &pAdd->pCtx[i].objk);
+        retCtx.data[i].name = pAdd->pCtx[i].obj.name;
+        retCtx.data[i].ret_code = ret;
+        retCtx.data[i].mesg = get_err_message(ret);
     }
 
     dump_object();
 
+    retCtx.mesg = get_err_message(retCtx.data[i].ret_code);
+
+    pRetJson = Struct2Json(&retCtx, JE_OBJ_ADD, FALSE, &ret);
+
+    if(!pRetJson || ret != RET_OK) {
+        LOG_EX(LOG_Error, "Json format error: %d\n", ret);
+        return;
+    }
+
+    LOG_EX(LOG_Debug, "Respons:\n%s\n", pRetJson);
+    free((void *)pRetJson);
+
     if(pAdd) {
         free(pAdd);
     }
 
     if(p->msgContent) {
-        free((void*)p->msgContent);
+        free((void *)p->msgContent);
     }
 
     free(p);
-    free((void*)pJson);
+    free((void *)pJson);
 }
 
 static void test_strsep(char *pVal)