Index: /branches/amp_3_7/extensions/license_server/license_server/server/http_server.c
===================================================================
--- /branches/amp_3_7/extensions/license_server/license_server/server/http_server.c	(revision 2586)
+++ /branches/amp_3_7/extensions/license_server/license_server/server/http_server.c	(working copy)
@@ -21,6 +21,8 @@
 #include "http_client.h"
 #include "license_manager.h"
 
+cJSON *license_info_root = NULL;
+
 void check_volume_license(struct evhttp_request *req, void *arg)
 {
     license_info_t license_info_table;
@@ -34,10 +36,12 @@
     char    action_name[] = "Check License";
     char    log_device[] = "CM Server";
     cJSON   *cjson_license_key = NULL;
+    cJSON   *cjson_upgrade = NULL;
     cJSON   *cjson_license_name = NULL;
     size_t  check_result = 0;
     size_t  len = 0;
     size_t  license_len = 0;
+    int     upgrade_flag = 0;
 
     /* get the event POST body */
     buff = evhttp_request_get_input_buffer(req);
@@ -67,6 +71,19 @@
         goto end;
     }
 
+    /* check license upgrade mode */
+    if (cJSON_HasObjectItem(root_json, "upgrade")) {
+        cjson_upgrade = cJSON_GetObjectItem(root_json, "upgrade");
+        if (cJSON_IsBool(cjson_upgrade)) {
+            if (cJSON_IsTrue(cjson_upgrade)) {
+                upgrade_flag = 1;
+            }
+        } else {
+            response = make_response_json(FAILURE_STATUS, "The filed upgrade is not bool format.", NULL, action_name, log_device);
+            goto end;
+        }
+    }
+
     cjson_license_key = cJSON_GetObjectItem(root_json, "license_key");
     license_key       = cjson_license_key->valuestring;
     if (!cJSON_IsString(cjson_license_key) || !(strlen(license_key))) {
@@ -93,6 +110,18 @@
         goto end;
     }
 
+    /* check the license name & licnese key existence. */
+    if (!upgrade_flag) {
+        if (!check_license_name_exist(license_name)) {
+            response = make_response_json(FAILURE_STATUS, "The license name has been imported, please check it.", NULL, action_name, log_device);
+            goto end;
+        }
+    }
+    if (!check_license_key_exist(license_key)) {
+        response = make_response_json(FAILURE_STATUS, "The license key has been imported, please check it.", NULL, action_name, log_device);
+        goto end;
+    }
+
     /* check the generation date and expire date. */
     strncpy(expdate, &license_key[license_len + 1 - BLOCK_LEN], sizeof(expdate));
     strncpy(gendate, &license_key[license_len + 1 - BLOCK_LEN * 2], sizeof(gendate));
@@ -107,18 +136,13 @@
         goto end;
     }
 
-    /* check the license name & licnese key existence. */
-    if (!(check_license_name_exist(license_name) && check_license_key_exist(license_key))) {
-        response = make_response_json(FAILURE_STATUS, "The license name or license key has been imported, please check it.", NULL, action_name, log_device);
-        goto end;
-    }
-
     /* start to call function check_license to check the validation of license key. */
     check_result = check_license(license_key, license_name, &license_info_table);
 
     if(!check_result) {
         /* store the license struct to DB. */
-        int store_result = store_license_info(&license_info_table);
+        int store_result = store_license_info(&license_info_table, upgrade_flag);
+        reload_license_info_root();
 
         if(!store_result) {
             response = make_response_json(SUCCESS_STATUS, "Check the license successfully.", NULL, action_name, log_device);
@@ -215,14 +239,14 @@
     cjson_device_list = cJSON_GetObjectItem(root_json, "device_id");
 
     /* 
-        This result array will append each device activate result. 
-        each device activate result is also a cJSON object like:
-            {
-                "device_id": "device1",
-                "status": 1,
-                "msg": ""
-            }
-    */
+       This result array will append each device activate result. 
+       each device activate result is also a cJSON object like:
+       {
+       "device_id": "device1",
+       "status": 1,
+       "msg": ""
+       }
+       */
     cJSON *result = cJSON_CreateArray();
     // cJSON_ArrayForEach(device, cjson_device_list) {
     for (i = 0; i < cJSON_GetArraySize(cjson_device_list); i++) {
@@ -293,6 +317,9 @@
     if(response) {
         free(response);
     }
+    if (req_data) {
+        free(req_data);
+    }
 }
 
 void deactivate_device(struct evhttp_request *req, void *arg)
@@ -394,6 +421,9 @@
     if(response) {
         free(response);
     }   
+    if (req_data) {
+        free(req_data);
+    }
 }
 
 void get_license_info(struct evhttp_request *req, void *arg)
@@ -556,6 +586,7 @@
     }
 
     delete_result = delete_license_info(license_name_list);
+    reload_license_info_root();
 
     if (delete_result) {
         response = make_response_json(SUCCESS_STATUS, delete_result, NULL, action_name, log_device);
@@ -595,6 +626,7 @@
     int device_status = 0;
     int assign_result = 0;
     int memory = 0;
+    int retry_time = 0;
     char *req_data = NULL;
     char *response = NULL;
     char *license_name = NULL;
@@ -661,137 +693,144 @@
 
     /* get the device version and update the version and connection of device. */
     version_json = cJSON_GetObjectItem(root_json, "version");
-    host = cJSON_GetObjectItem(root_json, "device_id")->valuestring;
     real_bandwidth = cJSON_GetObjectItem(root_json, "bandwidth")->valuestring;
+    char select_sql[100];
+    PGresult *result = NULL;
 
-    
-    strncpy(device_host, host, sizeof(device_host));
-    strncpy(version, version_json->valuestring, sizeof(version));
-
-    /* check if the host is already registered */
-    if (!check_device(device_host)) {
-        response = make_response_json(FAILURE_STATUS, "The device was not registered.", NULL, action_name, host);
-        goto end;
-    }
-
-    sprintf(update_sql, "update device2 set version = '%s', connection = 'connected', rel_bandwith = '%s' where id = '%s';", version, real_bandwidth, device_host);
-
-    if (db_execute(update_sql) < 0) {
-        response = make_response_json(FAILURE_STATUS, "Update device heartbeat info error.", NULL, action_name, host);
-        goto end;
-    }
-
-    /* here need to query the AMP serial number and insert it into response data. */
-    serial_number = get_cm_serial_number();
-    if (!serial_number) {
-        response = make_response_json(FAILURE_STATUS, "Cannot get the AMP serial number.", NULL, action_name, host);
-        goto end;
-    }
-
-    /* check the deivce memory. */
-    memory = get_device_memory_from_version(device_host);
-    if (!memory) {
-        response = make_response_json(FAILURE_STATUS, "The memory of this device is wrong.", NULL, action_name, host);
-        goto end;
-    }
-
-    /* check the device status. 1->enabled, 0->new(disbaled). */
-    device_status = get_device_status(device_host);
-
-    /* record the timestmap of this device heartbeat request. */
-    record_timestamp_by_device_id(device_host, device_status);
+    sprintf(select_sql, "select id from device2;");
+    result = db_fetch(select_sql);
 
-    /* build a json object for response data and this space will be freed in function `make_response_json`. */
-    response_data = cJSON_CreateObject();
-    cJSON_AddStringToObject(response_data, "device_id", device_host);
-    // cJSON_AddNumberToObject(response_data, "status", device_status);
-    /* serial number for device to check the validation of AMP. */
-    cJSON_AddStringToObject(response_data, "serial_number", serial_number);
-
-    if (device_status) { /* device is enabled. */
-
-        /* get the license key which enabled this device from DB and this license_key need to be freed. */
-        license_name = get_licesne_info_by_device_id(device_host, "license_name");
-        license_key = get_licesne_key_by_license_name(license_name);
+    if (result) {
+        for (i = 0; i < PQntuples(result); i++) {
+            if (PQgetvalue(result, i, 0)) {
+                host = PQgetvalue(result, i, 0);
+                strncpy(device_host, host, sizeof(device_host));
+                strncpy(version, version_json->valuestring, sizeof(version));
+                /* check if the host is already registered */
+                if (!check_device(device_host)) {
+                    response = make_response_json(FAILURE_STATUS, "The device was not registered.", NULL, action_name, host);
+                    goto end;
+                }
 
-        /* check the license key expire time. */
-        expire_date = get_license_value(license_name, "expiration_date");
+                sprintf(update_sql, "update device2 set version = '%s', connection = 'connected', rel_bandwith = '%s' where id = '%s';", version, real_bandwidth, device_host);
 
-        if (check_date(expire_date) == 0) {
-            device_status = 0;
-            cJSON_AddNumberToObject(response_data, "status", device_status);
-            cJSON_AddStringToObject(response_data, "msg", "The license is expired.");
-            response = make_response_json(SUCCESS_STATUS, "The license is expired.", response_data, action_name, host);
+                if (db_execute(update_sql) < 0) {
+                    response = make_response_json(FAILURE_STATUS, "Update device heartbeat info error.", NULL, action_name, host);
+                    goto end;
+                }
 
-            /* update device set license_name, resources, status*/      
-            char resource_str[1024];
+                /* here need to query the AMP serial number and insert it into response data. */
+                serial_number = get_cm_serial_number();
+                if (!serial_number) {
+                    response = make_response_json(FAILURE_STATUS, "Cannot get the AMP serial number.", NULL, action_name, host);
+                    goto end;
+                }
 
-            for(i = 0; i < RESOURCES_NUM; i++) {
-                if (resource_db_mapping[i].resource_id && resource_db_mapping[i].active) {
-                    sprintf(resource_str, ", %s = 1", resource_db_mapping[i].occupied_col);
+                /* check the deivce memory. */
+                memory = get_device_memory_from_version(device_host);
+                if (!memory) {
+                    response = make_response_json(FAILURE_STATUS, "The memory of this device is wrong.", NULL, action_name, host);
+                    goto end;
                 }
-            }
-            char sql_update[100];
-            sprintf(sql_update, "update device2 set status = 'new', license_name = NULL%s  where id = '%s';", resource_str, device_host);
 
-            db_execute(sql_update);
-            goto end;
-        }
+                /* check the device status. 1->enabled, 0->new(disbaled). */
+                device_status = get_device_status(device_host);
 
-        cJSON_AddNumberToObject(response_data, "status", device_status);
+                /* record the timestmap of this device heartbeat request. */
+                record_timestamp_by_device_id(device_host, device_status);
 
-        free(expire_date);
+                /* build a json object for response data and this space will be freed in function `make_response_json`. */
+                response_data = cJSON_CreateObject();
+                cJSON_AddStringToObject(response_data, "device_id", device_host);
+                // cJSON_AddNumberToObject(response_data, "status", device_status);
+                /* serial number for device to check the validation of AMP. */
+                cJSON_AddStringToObject(response_data, "serial_number", serial_number);
+
+                if (device_status) { /* device is enabled. */
+
+                    /* get the license key which enabled this device from DB and this license_key need to be freed. */
+                    license_name = get_licesne_info_by_device_id(device_host, "license_name");
+                    license_key = get_licesne_key_by_license_name(license_name);
+
+                    /* check the license key expire time. */
+                    expire_date = get_license_value(license_name, "expiration_date");
+
+                    if (check_date(expire_date) == 0) {
+                        device_status = 0;
+                        cJSON_AddNumberToObject(response_data, "status", device_status);
+                        cJSON_AddStringToObject(response_data, "msg", "The license is expired.");
+                        response = make_response_json(SUCCESS_STATUS, "The license is expired.", response_data, action_name, host);
+
+                        /* update device set license_name, resources, status*/      
+                        char resource_str[1024];
+
+                        for(i = 0; i < RESOURCES_NUM; i++) {
+                            if (resource_db_mapping[i].resource_id && resource_db_mapping[i].active) {
+                                sprintf(resource_str, ", %s = %d", resource_db_mapping[i].occupied_col, (i != 3) ? 1 : 0);
+                            }
+                        }
+                        char sql_update[100];
+                        sprintf(sql_update, "update device2 set status = 'new', license_name = NULL%s  where id = '%s';", resource_str, device_host);
 
-        if (license_key) {
-            cJSON_AddStringToObject(response_data, "license_key", license_key);
-        }
-        if (license_name) {
-            cJSON_AddStringToObject(response_data, "license_name", license_name);
-        }
+                        db_execute(sql_update);
+                        goto end;
+                    }
 
-        /* query the resource this device can take by using this license key and insert resource into the response data. */
+                    cJSON_AddNumberToObject(response_data, "status", device_status);
 
-        assign_result = assign_resource(license_name, device_host, resource_table, CONNECTED, device_status, memory);
+                    free(expire_date);
 
-        free(license_name);
+                    if (license_key) {
+                        cJSON_AddStringToObject(response_data, "license_key", license_key);
+                    }
+                    if (license_name) {
+                        cJSON_AddStringToObject(response_data, "license_name", license_name);
+                    }
 
-        /* 
-            insert this resource table into the response data. 
-            build a array json and insert each resource into this array.
-        */
-        resource_list = cJSON_CreateArray();
+                    /* query the resource this device can take by using this license key and insert resource into the response data. */
 
-        if (assign_result > 0) {
+                    assign_result = assign_resource(license_name, device_host, resource_table, CONNECTED, device_status, memory);
 
-            for (i = 0; i < assign_result; i++) {
-                int index = resource_table[i].resource_id - 1;
-                char *column_name = resource_db_mapping[index].occupied_col;
-                sprintf(resource_str, "%s = %d", column_name, resource_table[i].quantity);
+                    free(license_name);
 
-                char heartbeat_sql[100];
-                sprintf(heartbeat_sql, "update device2 set %s where id = '%s';", resource_str, device_host);
-                db_execute(heartbeat_sql);
+                    /* 
+                       insert this resource table into the response data. 
+                       build a array json and insert each resource into this array.
+                       */
+                    resource_list = cJSON_CreateArray();
+
+                    if (assign_result > 0) {
+
+                        for (i = 0; i < assign_result; i++) {
+                            int index = resource_table[i].resource_id - 1;
+                            char *column_name = resource_db_mapping[index].occupied_col;
+                            sprintf(resource_str, "%s = %d", column_name, resource_table[i].quantity);
+                            char heartbeat_sql[100];
+                            sprintf(heartbeat_sql, "update device2 set %s where id = '%s';", resource_str, device_host);
+                            db_execute(heartbeat_sql);
+
+                            resource_data = cJSON_CreateObject();
+                            cJSON_AddNumberToObject(resource_data, "resource_id", resource_table[i].resource_id);
+                            cJSON_AddStringToObject(resource_data, "resource_name", resource_table[i].resource_name);
+                            cJSON_AddNumberToObject(resource_data, "quantity", resource_table[i].quantity);
 
-                resource_data = cJSON_CreateObject();
-                cJSON_AddNumberToObject(resource_data, "resource_id", resource_table[i].resource_id);
-                cJSON_AddStringToObject(resource_data, "resource_name", resource_table[i].resource_name);
-                cJSON_AddNumberToObject(resource_data, "quantity", resource_table[i].quantity);
+                            cJSON_AddItemToArray(resource_list, resource_data);
+                        }
+                        cJSON_AddItemToObject(response_data, "resource", resource_list);
+                    } else if (assign_result == -1) {
+                        cJSON_AddNumberToObject(response_data, "status", FAILURE_STATUS);
+                        cJSON_AddStringToObject(response_data, "msg", "Cannot enable this device because the license does not manage this memory type or the number of management has reached the upper limit.");
+                    }
+                } else {
+                    cJSON_AddNumberToObject(response_data, "status", device_status);
+                    cJSON_AddStringToObject(response_data, "msg", "This device is not enabled.");
+                }
 
-                cJSON_AddItemToArray(resource_list, resource_data);
+                response = make_response_json(SUCCESS_STATUS, "Heartbeat successfully.", response_data, action_name, host);
             }
-            cJSON_AddItemToObject(response_data, "resource", resource_list);
-        } else if (assign_result == -1) {
-            cJSON_AddNumberToObject(response_data, "status", FAILURE_STATUS);
-            cJSON_AddStringToObject(response_data, "msg", "Cannot enable this device because the license does not manage this memory type or the number of management has reached the upper limit.");
         }
-
-    } else {
-        cJSON_AddNumberToObject(response_data, "status", device_status);
-        cJSON_AddStringToObject(response_data, "msg", "This device is not enabled.");
+        db_free(result);
     }
-
-    response = make_response_json(SUCCESS_STATUS, "Heartbeat successfully.", response_data, action_name, host);
-
 end:
     /* if it did not query all license info, remove a specified number of bytes data from the beginning of an evbuffer. */
     if (len) {
@@ -817,14 +856,18 @@
     if (serial_number) {
         free(serial_number);
     }
+
+    if (req_data) {
+        free(req_data);
+    }
 }
 
 void check_timer(int fd, short event, void *arg)
 {
     /* 
-        loop the time record from HEARTBEAT_TIMER_PATH and compare the timestamp each device recorded with current timestamp.
-        if the time interval is over 60s, set the connection is unconnected and make every resource that occupied empty.
-    */
+       loop the time record from HEARTBEAT_TIMER_PATH and compare the timestamp each device recorded with current timestamp.
+       if the time interval is over 60s, set the connection is unconnected and make every resource that occupied empty.
+       */
     int     nCount = 0;
     int     i = 0;
     int     j = 0;
@@ -842,8 +885,8 @@
     if (!access(HEARTBEAT_TIMER_PATH, R_OK)) {
         /* remove the device which has been delete. */
         check_and_update_timer(HEARTBEAT_TIMER_PATH);
-        
-        timer_str = get_all_text_from_file(HEARTBEAT_TIMER_PATH);
+
+        timer_str = get_all_text_from_file(HEARTBEAT_TIMER_PATH, TIMER_RECORD_LOCK);
         if (timer_str) {
             timer_json = cJSON_Parse(timer_str);
 
@@ -863,11 +906,11 @@
 
                     for(j = 0; j < RESOURCES_NUM; j++) {
                         if (resource_db_mapping[j].resource_id && resource_db_mapping[j].active) {
-                            sprintf(resource_str, ", %s = 1", resource_db_mapping[j].occupied_col);
+                            sprintf(resource_str, ", %s = %d", resource_db_mapping[j].occupied_col, (resource_db_mapping[j].resource_id == 1) ? 1 : 0);
                         }
                     }
 
-                    sprintf(update_sql, "update device2 set connection = 'unconnected'%s  where id = '%s';", resource_str, device_id);
+                    sprintf(update_sql, "update device2 set connection = 'unconnected'%s where id = '%s';", resource_str, device_id);
 
                 } else {
                     /* set the connection of device is connected */
@@ -898,7 +941,7 @@
 }
 
 
-int
+    int
 main(int argc, char **argv)
 {
     int i;
@@ -917,10 +960,10 @@
 
     evbase = event_base_new();
     listener = evconnlistener_new_bind(
-        evbase, NULL, NULL,
-        LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 1024,
-        (struct sockaddr *)&sin, sizeof(sin)
-    );
+            evbase, NULL, NULL,
+            LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, 1024,
+            (struct sockaddr *)&sin, sizeof(sin)
+            );
 
     struct evhttp *http_server = evhttp_new(evbase);
     if(!http_server) {
@@ -934,6 +977,12 @@
         fprintf(stderr, "http server start OK! \n");
     }
 
+    /* load the license info */
+    license_i license_info;
+    memset(&license_info, 0, sizeof(license_info));
+    load_license_info(&license_info);
+    license_info_root = license_info.root;
+
     evhttp_set_cb(http_server, "/cm/get_license_info", get_license_info, NULL);
     evhttp_set_cb(http_server, "/cm/delete_license_info", delete_license, NULL);
     evhttp_set_cb(http_server, "/cm/check_license", check_volume_license, NULL);
@@ -941,6 +990,7 @@
     evhttp_set_cb(http_server, "/cm/deactivate_device", deactivate_device, NULL);
     evhttp_set_cb(http_server, "/cm/device_heartbeat", device_heartbeat, NULL);
 
+
     /* set a timer for event lisener loop. */
     struct timeval tv;
     struct event *ev;
Index: /branches/amp_3_7/extensions/license_server/license_server/server/license_kernel.h
===================================================================
--- /branches/amp_3_7/extensions/license_server/license_server/server/license_kernel.h	(revision 2586)
+++ /branches/amp_3_7/extensions/license_server/license_server/server/license_kernel.h	(working copy)
@@ -2,6 +2,7 @@
 
 #include "decode.h"
 
+#define RECURSE 1
 #define MODEL_LEN           32
 #define VERSION_LEN         1500
 #define NAME_LEN            32
Index: /branches/amp_3_7/extensions/license_server/license_server/server/license_kernel.c
===================================================================
--- /branches/amp_3_7/extensions/license_server/license_server/server/license_kernel.c	(revision 2586)
+++ /branches/amp_3_7/extensions/license_server/license_server/server/license_kernel.c	(working copy)
@@ -14,6 +14,7 @@
 
 extern array_model_t array_models[MAX_MODEL];
 extern array_feature_t array_features[MAX_APV_FEATURE];
+extern cJSON *license_info_root;
 
 int decode_license_resource(uint64_t_a features, uint32_t resource_list[], int len, license_info_t *license_info_table)
 {
@@ -237,49 +238,104 @@
     strcpy(license_info_table->expiration_date, expdate);
     strcpy(license_info_table->license_version, "00000001");
 
+    free(serial);
+
     return 0;
 }
 
 license_i *query_license_info(char license_list[QUERY_LICENSE_MAX][NAME_LEN + 1], int json_res, license_i *license_info, int license_num)
 {
-    FILE *fp;
-    FILE *u_fp;
-    char *all_license_info = NULL;
-    int file_size = 0;
     int j, i = 0;
     int a_i = 0; /* json `root` index. */
     int l_count = 0; /* the length of license info list. */
     int all_count = 0; 
-    char uuid[UUID_LEN + 1]; /* uuid for license info tmp file. */
     char tmp_file[TMP_FILE_LEN + 1];
-    cJSON *all_root_array = NULL;
     cJSON *root = NULL;
     cJSON *each_license = NULL;
     cJSON *e_root = NULL;
     cJSON *all_license_json = NULL;
 
-    /* generate a uuid and make a new license info tmp file name. */
-    u_fp = popen("cat /proc/sys/kernel/random/uuid", "r");
-    if (u_fp == NULL) {
-        return NULL;
+    root = cJSON_CreateArray();
+
+    if (license_list && strlen(license_list[0]) != 0) {
+        /* query the license info list by the license name list. */
+
+        for(i = 0; i < license_num; i++) {
+            if (strlen(license_list[i]) != 0) {
+                char *license_name = license_list[i];
+                int match_flag = 0;
+
+                l_count = cJSON_GetArraySize(license_info_root);
+                for(j = 0; j < l_count; j++) {
+                    cJSON *license = cJSON_GetArrayItem(license_info_root, j);
+                    if (!strcmp(cJSON_GetObjectItem(license, "license_name")->valuestring, license_name)) {
+                        match_flag = 1;
+                        cJSON *new_license = cJSON_Duplicate(license, RECURSE);
+                        cJSON_AddNumberToObject(new_license, "state", 1);
+                        cJSON_AddStringToObject(new_license, "msg", "");
+                        cJSON_InsertItemInArray(root, a_i, new_license);
+                        a_i++;
+                        break;
+                    }
+                }
+                if (!match_flag) {
+                    e_root = cJSON_CreateObject();
+                    cJSON_AddStringToObject(e_root, "license_name", license_name);
+                    cJSON_AddNumberToObject(e_root, "state", 0);
+                    cJSON_AddStringToObject(e_root, "msg", "Could not find the license by license name.");
+
+                    cJSON_InsertItemInArray(root, a_i, e_root);
+                    a_i++;
+                }
+            }
+        }
+        if (!json_res) {
+            license_info->info = cJSON_Print(root);
+        } else {
+            license_info->root = root;
+        }
+    } else {
+        /* query all license info. */
+        if (!json_res) {
+            license_info->info = cJSON_Print(license_info_root);
+        } else {
+            all_count = cJSON_GetArraySize(license_info_root);
+            for (i = 0; i < all_count; i++) {
+                each_license = cJSON_Duplicate(cJSON_GetArrayItem(license_info_root, i), RECURSE);
+                cJSON_AddNumberToObject(each_license, "state", 1);
+                cJSON_AddStringToObject(each_license, "msg", "");
+                cJSON_InsertItemInArray(root, i, each_license);
+            }
+            license_info->root = root;
+        }
     }
-    fgets(uuid, sizeof(uuid), u_fp);
 
-    pclose(u_fp);
+    return license_info;
+}
+
+license_i *load_license_info(license_i *license_info)
+{
+    FILE *fp;
+    char *all_license_info = NULL;
+    int file_size = 0;
+    char uuid[UUID_LEN + 1]; /* uuid for license info tmp file. */
+    char tmp_file[TMP_FILE_LEN + 1];
+    cJSON *all_license_json = NULL;
+
+    random_uuid(uuid);
 
     sprintf(tmp_file, "%s%s", TMP_PATH, uuid);
     if (tmp_file[TMP_FILE_LEN] != '\0') {
         tmp_file[TMP_FILE_LEN] = '\0';
     }
 
-    // license_info = (license_i *)malloc(sizeof(license_i));
-    // memset(license_info, 0, sizeof(license_i));
-
+    if (file_lock(LICENSE_FILE_LOCK)) {
+        goto end;
+    }
     if (handle_file(LICENSE_INFO_PATH, SECRET_KEY, tmp_file) == -1) {
         return NULL;
     }
 
-
     fp = fopen(tmp_file, "rb");
     if (fp) {
         fseek(fp , 0 , SEEK_END);
@@ -290,78 +346,23 @@
         fclose(fp);
     }
 
-    if (license_list && strlen(license_list[0]) != 0) {
-        /* query the license info list by the license name list. */
-        if (all_license_info) {
-            all_root_array = cJSON_Parse(all_license_info);
-
-            root = cJSON_CreateArray();
-
-            for(i = 0; i < license_num; i++) {
-                if (strlen(license_list[i]) != 0) {
-                    char *license_name = license_list[i];
-                    int match_flag = 0;
-
-                    l_count = cJSON_GetArraySize(all_root_array);
-                    for(j = 0; j < l_count; j++) {
-
-                        cJSON *license = cJSON_GetArrayItem(all_root_array, j);
-                        if (!strcmp(cJSON_GetObjectItem(license, "license_name")->valuestring, license_name)) {
-                            match_flag = 1;
-                            char *new_license_str = cJSON_Print(license);
-                            cJSON *new_license = cJSON_Parse(new_license_str);
-                            cJSON_AddNumberToObject(new_license, "state", 1);
-                            cJSON_AddStringToObject(new_license, "msg", "");
-                            cJSON_InsertItemInArray(root, a_i, new_license);
-                            a_i++;
-                            break;
-                        }
-                    }
-                    if (!match_flag) {
-                        e_root = cJSON_CreateObject();
-                        cJSON_AddStringToObject(e_root, "license_name", license_name);
-                        cJSON_AddNumberToObject(e_root, "state", 0);
-                        cJSON_AddStringToObject(e_root, "msg", "Could not find the license by license name.");
-
-                        cJSON_InsertItemInArray(root, a_i, e_root);
-                        a_i++;
-                    }
-                }
-            }
-            if (!json_res) {
-                license_info->info = cJSON_Print(root);
-            } else {
-                license_info->root = root;
-            }
-        }
-    } else {
-        /* query all license info. */
-        if (!json_res) {
-            license_info->info = all_license_info;
-        } else {
-            if (all_license_info) {
-                all_license_json = cJSON_Parse(all_license_info);
-                all_count = cJSON_GetArraySize(all_license_json);
-                for (i = 0; i < all_count; i++) {
-                    each_license = cJSON_GetArrayItem(all_license_json, i);
-                    cJSON_AddNumberToObject(each_license, "state", 1);
-                    cJSON_AddStringToObject(each_license, "msg", "");
-                }
-                license_info->root = all_license_json;
-            }
-        }
+    if (all_license_info) {
+        all_license_json = cJSON_Parse(all_license_info);
+        license_info->root = all_license_json;
+        free(all_license_info);
     }
 
     remove(tmp_file);
 
+end:
+    file_unlock(LICENSE_FILE_LOCK);
+
     return license_info;
 }
 
 char *delete_license_info(char license_list[QUERY_LICENSE_MAX][NAME_LEN + 1])
 {
-
     FILE *fp, *create_fp;
-    FILE *u_fp;
     char *delete_result = NULL;
     char *all_license_info = NULL;
     char *root_array = NULL;
@@ -376,19 +377,16 @@
     cJSON *license = NULL;
     cJSON *each_resp = NULL;
 
-    /* generate a uuid and make a new license info tmp file name. */
-    u_fp = popen("cat /proc/sys/kernel/random/uuid", "r");
-    if (u_fp == NULL) {
-        goto end;
-    }
-    fgets(uuid, sizeof(uuid), u_fp);
-    pclose(u_fp);
+    random_uuid(uuid);
 
     sprintf(tmp_file, "%s%s", TMP_PATH, uuid);
     if (tmp_file[TMP_FILE_LEN] != '\0') {
         tmp_file[TMP_FILE_LEN] = '\0';
     }
 
+    if (file_lock(LICENSE_FILE_LOCK)) {
+        goto end;
+    }
     handle_file(LICENSE_INFO_PATH, SECRET_KEY, tmp_file);
 
 
@@ -468,6 +466,16 @@
         cJSON_Delete(all_root_array);
     }
 
+    if (root_array) {
+        free(root_array);
+    }
+
+    if (root) {
+        cJSON_Delete(root);
+    }
+
+    file_unlock(LICENSE_FILE_LOCK);
+
     return delete_result;
 
 }
@@ -502,13 +510,18 @@
     /* loop the device list and assign the resource by the license resource limit. */
     resource_t resource_table[RESOURCES_NUM];
     memset(resource_table, 0, sizeof(resource_t) * RESOURCES_NUM);
-    int a_res = assign_resource(license_name, device_id, resource_table, connection, status, memory);
+    int a_res = assign_resource(license_name, device_id, resource_table, connection, 1, memory);
     /* first should make it active and update the db. */
 
     if (a_res > 0) {
         for (i = 0; i < a_res; i++) {
             int index = resource_table[i].resource_id - 1;
             char *column_name = resource_db_mapping[index].occupied_col;
+            int auto_num = get_auto_num(3, license_name);
+            int resource_limit = get_license_fea_or_res(license_name, resource_db_mapping[index].resource_name);
+            if (auto_num && resource_table[i].quantity == resource_limit) {
+                resource_table[i].quantity = resource_table[i].quantity / (auto_num + 1);
+            } 
             buff_len = sprintf(resource_str + buff_len, ", %s = %d", column_name, resource_table[i].quantity);
         }
     } else if (a_res == -1) {
@@ -517,7 +530,7 @@
     }
 
 
-    char sql_update[100];
+    char sql_update[1024];
     sprintf(sql_update, "update device2 set status = 'active', license_name = '%s'%s where id = '%s';", license_name, resource_str, device_id);
     db_execute(sql_update);
 
@@ -538,13 +551,11 @@
 
     for(i = 0; i < RESOURCES_NUM; i++) {
         if (resource_db_mapping[i].resource_id && resource_db_mapping[i].active) {
-            sprintf(resource_str, ", %s = 1", resource_db_mapping[i].occupied_col);
+            sprintf(resource_str, ", %s = %d", resource_db_mapping[i].occupied_col, (i != 3) ? 1 : 0);
         }
     }
 
-
     /* loop the device list and assign the resource by the license resource limit. */
-
     char sql_update[100];
     sprintf(sql_update, "update device2 set status = 'new', license_name = NULL%s  where id = '%s';", resource_str, device_id);
     if (db_execute(sql_update)) {
@@ -598,7 +609,7 @@
 
     }
     /* assign the resource like memory, bandwidth. */
-    for (j = 1; j < 4; j++) {
+    for (j = 1; j <= 4; j++) {
         if (!resource_db_mapping[j - 1].active) {
             continue;
         }
@@ -610,7 +621,7 @@
             int auto_num = get_auto_num(j, license_name);
             if (auto_mode) {
                 if (status == 0) { /* device status is new. */
-                    assign_device_resource = 1;
+                    assign_device_resource = (j != 3) ? 1 : 0;
                 } else {
                     if (connection) {
                         if (auto_rest_resource_num > 0) {
@@ -620,15 +631,15 @@
                                 assign_device_resource = auto_rest_resource_num;
                             }
                         } else {
-                            assign_device_resource = 1;
+                            assign_device_resource = (j != 3) ? 1 : 0;
                         } 
                     } else {
-                        assign_device_resource = 1;
+                        assign_device_resource = (j != 3) ? 1 : 0;
                     }
                 }
             } else {
                 if (status == 0) {
-                    assign_device_resource = 1;
+                    assign_device_resource = (j != 3) ? 1 : 0;
                 } else {
                     if (connection) {
                         int per_resource_limit = query_per_resource_limit(device_id, j);
@@ -640,42 +651,20 @@
                             if (rest_resource_num > 1) {
                                 assign_device_resource = rest_resource_num;
                             } else {
-                                assign_device_resource = 1;
+                                assign_device_resource = (j != 3) ? 1 : 0;
                             }
                         }
                     } else {
-                        assign_device_resource = 1;
+                        assign_device_resource = (j != 3) ? 1 : 0;
                     }
                 }
             }
-
-
             resource_table[i].resource_id = j;
-            // (resource_table + i)->resource_id = j;
             resource_table[i].quantity = assign_device_resource;
-            // (resource_table + i)->quantity = assign_device_resource;
             resource_table[i].resource_name = resource_db_mapping[j - 1].resource_name;
-            // (resource_table + i)->resource_name = resource_db_mapping[j].resource_name;
             i++;
         }
     }
 
     return i;
 }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Index: /branches/amp_3_7/extensions/license_server/license_server/server/license_manager.h
===================================================================
--- /branches/amp_3_7/extensions/license_server/license_server/server/license_manager.h	(revision 2586)
+++ /branches/amp_3_7/extensions/license_server/license_server/server/license_manager.h	(working copy)
@@ -6,6 +6,8 @@
 // #define SERIAL_PATH "/Users/wuliang/Downloads/work/branche/amp_trunk/trunk/src/license_server/server/serial.py"
 #define SERIAL_PATH "/ca/extensions/license_server/serial.py"
 // #define DB_FILE_PATH "/var/crash/cm.db"
+#define LICENSE_FILE_LOCK "/var/crash/license_info.lock"
+#define TIMER_RECORD_LOCK "/var/crash/timer_rec.lock"
 #define DB_FILE_PATH "/ca/database/cm.db"
 #define CA_CERT_FILE "/ca/webui/conf/ArrayNetworks.crt"
 #define SERVER_CERT_FILE "/ca/webui/conf/server.crt"
@@ -31,11 +33,11 @@
 #define MEMORY_TYPE_NUM 5
 #define SQL_SELECT_LEN 100
 
-int store_license_info(license_info_t *license_info_table);
+int store_license_info(license_info_t *license_info_table, int upgrade_flag);
 
 char *get_cm_serial_number();
 
-char *get_all_text_from_file(char *path);
+char *get_all_text_from_file(char *path, char *lock_path);
 
 int record_timestamp_by_device_id(char *device_id, int status);
 
@@ -94,3 +96,11 @@
 int query_memory_occupied_sum(char *license_name, char *column_name);
 
 int match_memory_from_version(char version[VERSION_LEN]);
+
+char *random_uuid(char buf[]);
+
+void reload_license_info_root();
+
+int file_lock(char *path);
+
+void file_unlock(char *path);
Index: /branches/amp_3_7/extensions/license_server/license_server/server/license_manager.c
===================================================================
--- /branches/amp_3_7/extensions/license_server/license_server/server/license_manager.c	(revision 2586)
+++ /branches/amp_3_7/extensions/license_server/license_server/server/license_manager.c	(working copy)
@@ -12,6 +12,7 @@
 #include "http_client.h"
 #include "license_manager.h"
 
+extern cJSON *license_info_root;
 
 char *make_response_json(int status, char msg[], cJSON *data, char *action, char *device)
 /* 
@@ -146,7 +147,7 @@
     }
 }
 
-int store_license_info(license_info_t *license_info_table)
+int store_license_info(license_info_t *license_info_table, int upgrade_flag)
 {
     FILE *u_fp;
     int i, nCount = 0;
@@ -177,6 +178,9 @@
     }
 
     /* here need to make sure file is exist. */
+    if (file_lock(LICENSE_FILE_LOCK)) {
+        goto end;
+    }
     handle_file(LICENSE_INFO_PATH, SECRET_KEY, tmp_file);
     
     fp = fopen(tmp_file, "r");
@@ -212,6 +216,8 @@
                     cJSON_AddNumberToObject(root, "memory", license_info_table->resource_table[i].quantity);
                 } else if (license_info_table->resource_table[i].resource_id == 2) {
                     cJSON_AddNumberToObject(root, "cpu", license_info_table->resource_table[i].quantity);
+                } else if (license_info_table->resource_table[i].resource_id == 4) {
+                    cJSON_AddNumberToObject(root, "session", license_info_table->resource_table[i].quantity);
                 } else {
                     cJSON_AddNumberToObject(root, "bandwidth", license_info_table->resource_table[i].quantity);
                 } 
@@ -251,9 +257,20 @@
                 license_info = cJSON_Print(old_root_array);
                 goto end;
             }
+            /* remove the old license key and other info by license_name */
+            if (upgrade_flag) {
+                cJSON *license_name_json = cJSON_GetObjectItem(pArrayItem, "license_name");
+                char *license_name = license_name_json->valuestring;
+                if (!strcmp(license_name, license_info_table->license_name)) {
+                    cJSON_ReplaceItemInArray(old_root_array, i, root);
+                    break;
+                }
+            }
         }
         /* insert the new license info to license info list. */
-        cJSON_AddItemToArray(old_root_array, root);
+        if (!upgrade_flag) {
+            cJSON_AddItemToArray(old_root_array, root);
+        }
         license_info = cJSON_Print(old_root_array);
     } else {
         /* license info has no license info before. */
@@ -279,11 +296,17 @@
         cJSON_Delete(new_root);
     }
 
+    if (old_root) {
+        free(old_root);
+    }
+
     fclose(create_fp);
 
     sprintf(mv_cmd, "mv %s %s", tmp_file, LICENSE_INFO_PATH);
     system(mv_cmd);
 
+    file_unlock(LICENSE_FILE_LOCK);
+
     return 0;
 }
 
@@ -666,7 +689,7 @@
 
         for (i = 0; i < l_count; i++) {
             license = cJSON_GetArrayItem(root_array, i);
-            if (!strcmp(cJSON_GetObjectItem(license, "license_name")->valuestring, license_name)) {
+            if (!strcmp(cJSON_GetObjectItem(license, "license_name")->valuestring, license_name) && cJSON_HasObjectItem(license, key)) {
                 value = cJSON_GetObjectItem(license, key)->valuedouble;
                 break;
             }
@@ -779,7 +802,7 @@
 
 char *get_cm_serial_number() {
     char serial_number[SERIAL_NUMBER_LEN + 1] = {'\0'};
-    char cmd[100] = {'\0'};
+    char cmd[256] = {'\0'};
     char *sn_res = NULL;
     FILE * fp;
 
@@ -798,7 +821,7 @@
     return sn_res;
 }
 
-char *get_all_text_from_file(char *path)
+char *get_all_text_from_file(char *path, char *lock_path)
 /* 
     query all text from file and will assign some space for the text.
     it should be deallocated after use with free.
@@ -808,6 +831,10 @@
     char *text = NULL;
     int file_size = 0;
 
+    if (file_lock(lock_path)) {
+        goto end;
+    }
+
     fp = fopen(path, "r");
     if (fp) {
         fseek(fp, 0, SEEK_END);
@@ -818,6 +845,8 @@
         fclose(fp);
     }
 
+end:
+    file_unlock(lock_path);
     return text;
 }
 
@@ -832,7 +861,10 @@
     cJSON   *device_json = NULL;
     FILE    *create_fp;
 
-    timer_str = get_all_text_from_file(path);
+    timer_str = get_all_text_from_file(path, TIMER_RECORD_LOCK);
+    if (!timer_str) {
+        return;
+    }
     timer_json = cJSON_Parse(timer_str);
     nCount = cJSON_GetArraySize(timer_json);
 
@@ -889,7 +921,7 @@
         cJSON_AddItemToArray(new_root, root);
         record_str = cJSON_Print(new_root);
     } else { /* exist */
-        root_str = get_all_text_from_file(HEARTBEAT_TIMER_PATH);
+        root_str = get_all_text_from_file(HEARTBEAT_TIMER_PATH, TIMER_RECORD_LOCK);
         if (root_str) {
 
             old_root = cJSON_Parse(root_str);
@@ -949,7 +981,6 @@
     cJSON   *root_array = NULL;
     cJSON   *license = NULL;
     license_i license_info;
-
     memset(&license_info, 0, sizeof(license_info));
 
     /* get the license value from license name by the key. */
@@ -1024,7 +1055,81 @@
     return key_exist;
 }
 
+void reload_license_info_root()
+{
+    if (license_info_root) {
+        cJSON_Delete(license_info_root);
+    }
 
+    license_i license_info;
+    memset(&license_info, 0, sizeof(license_info));
+    load_license_info(&license_info);
+    license_info_root = license_info.root;
+}
 
+int file_lock(char *path)
+{
+    int flag = 0;
+    char cmd[CMD_LEN + 1];
 
+    while(flag < 3) {
+        if (!access(path, R_OK)) {
+            sleep(1);
+            flag++;
+        } else {
+            break;
+        }
+    }
+    if (flag >= 3) {
+        return -1;
+    }
+    sprintf(cmd, "touch %s", path);
+    system(cmd);
+    return 0;
+}
+
+void file_unlock(char *path)
+{
+    char cmd[CMD_LEN + 1];
+    sprintf(cmd, "rm -rf %s", path);
 
+    if (!access(path, R_OK)) {
+        system(cmd);
+    }
+}
+
+char *random_uuid( char buf[] )
+{
+    const char *c = "89ab";
+    char *p = buf;
+    int n;
+    for( n = 0; n < 16; ++n )
+    {
+        int b = rand()%255;
+        switch( n )
+        {
+            case 6:
+                sprintf(p, "4%x", b%15 );
+                break;
+            case 8:
+                sprintf(p, "%c%x", c[rand()%strlen(c)], b%15 );
+                break;
+            default:
+                sprintf(p, "%02x", b);
+                break;
+        }
+
+        p += 2;
+        switch( n )
+        {
+            case 3:
+            case 5:
+            case 7:
+            case 9:
+                *p++ = '-';
+                break;
+        }
+    }
+    *p = 0;
+    return buf;
+}
Index: /branches/amp_3_7/scripts/install.sh
===================================================================
--- /branches/amp_3_7/scripts/install.sh	(revision 2586)
+++ /branches/amp_3_7/scripts/install.sh	(working copy)
@@ -25,6 +25,7 @@
 echo '* hard nofile 65536' >> /etc/security/limits.conf
 echo 'vm.max_map_count=655360' >> /etc/sysctl.conf
 
+mv $DIR/exts/license_server-3.7.0-1.el7.centos.x86_64.rpm $DIR/exts/license_server-3.7.0-1.el7.centos.x86_64.rpm.backup
 cd $DIR/system && rpm -Uvh *.rpm
 cd $DIR/exts && rpm -Uvh *.rpm
-/bin/cp -rf /ca/webui/exfiles/python/lib/* /usr/lib/python2.7/site-packages/
\ No newline at end of file
+/bin/cp -rf /ca/webui/exfiles/python/lib/* /usr/lib/python2.7/site-packages/
