Index: /branches/rel_apv_10_7_3/usr/click/bin/heartbeat/Makefile
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/bin/heartbeat/Makefile	(revision 40136)
+++ /branches/rel_apv_10_7_3/usr/click/bin/heartbeat/Makefile	(working copy)
@@ -5,15 +5,16 @@
 CFLAGS+= -I${.CURDIR}/../../lib/libfeactl \
 	-I${.CURDIR}/../../lib/libsysmon \
 	-I${.OBJDIR}/../../lib/libkernelapi \
+	-I${.OBJDIR}/../../lib/libfastlog \
 	-I${.CURDIR}/../../lib/libip \
 	-I${.CURDIR}/../../bin/backend \
 	-I/usr/include
 
 LDADD=  -L/usr/local/lib \
+	-L${.OBJDIR}/../../lib/libfastlog -lfastlog \
 	-L${.OBJDIR}/../../lib/libfeactl -lfeactl \
 	-L${.OBJDIR}/../../lib/libsysmon -lsysmon \
 	-L${.OBJDIR}/../../lib/libkernelapi -lkernelapi \
-	-L${.OBJDIR}/../../lib/libfastlog -lfastlog \
 	-L${.OBJDIR}/../../lib/libip -lip \
 	-L${.OBJDIR}/../../lib/libversion -lversion \
 	-L${.OBJDIR}/../../lib/libenglog -lenglog \
@@ -35,4 +36,4 @@
 
 .if defined(UOS_X86)
 CFLAGS+= -DUOS_X86
-.endif
\ No newline at end of file
+.endif
Index: /branches/rel_apv_10_7_3/usr/click/bin/heartbeat/heartbeat.c
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/bin/heartbeat/heartbeat.c	(revision 40136)
+++ /branches/rel_apv_10_7_3/usr/click/bin/heartbeat/heartbeat.c	(working copy)
@@ -18,10 +18,12 @@
 #include <json/json.h>
 #endif
 #include "feactl.h"
+#include "fastlog.h"
 #include "heartbeat_writer.h"
 #include <click/sys/clickarray.h>
 #include <uinet_api.h>
 #include <sys/sysctl.h>
+#include <u_sysctl.h>
 
 #define sysctlbyname    u_sysctlbyname
 #define BUFFER_LEN 5000
@@ -32,6 +34,7 @@
 #define PCAFILE_PATH "/ca/webui/conf/server.crt"
 #define CM_INFO "/ca/conf/cm_info.confg"
 #define LICENSE_FILE_PATH "/ca/etc/license.txt"
+#define HEARTBEAT_TIMER_PATH "/var/crash/timer.txt"
 #define ENABLED 2
 #define REGISTERED 1
 #define UNREGISTERED 0
@@ -583,6 +586,8 @@
     response_t response;
     feactl_t *feactl_p = NULL;
     int feactl_fd = -1;
+    static time_t cached_start_time = 0;
+    static int cached_last_day = -2;
 
     feactl_fd = feactl_shm_get();
     if( feactl_fd == -1 ) {
@@ -653,6 +658,14 @@
         //         }
         //     ]
         // }
+
+	/* Remove timer file when CM server is UP */
+	if ( cached_start_time != 0 || access(HEARTBEAT_TIMER_PATH, F_OK) == 0) {
+	    unlink(HEARTBEAT_TIMER_PATH);
+	    cached_start_time = 0;
+	    cached_last_day = -2;
+	    logging("[heartbeat]Status 200 received. Stopping and resetting license timer.\n", 1);
+	}
         result = json_tokener_parse(response.buffer);
         if (!result) {
             logging("[heartbeat]Invalid response.", 3);
@@ -881,9 +894,70 @@
 		write_heartbeat_info(CM_INFO, &heartbeat_info);
 	    }
 	} else {
+#define SECONDS_IN_DAY 86400
+#define EXPIRY_DAYS 7
+
+	    int is_licensepermit_expire = 0;
 	    logging("[heartbeat]http status != 200. licensepermit enabled!", 1);
-	    write_heartbeat_info(CM_INFO, &heartbeat_info);
+	    /* Capture the start time, when the CM server is down */
+	    if (cached_start_time == 0) {
+		int fd = open(HEARTBEAT_TIMER_PATH, O_RDONLY);
+		if (fd >= 0) {
+		    /* Restart Timer: Create file if it doesn't exist */
+		    char buf[64];
+		    ssize_t bytes = read(fd, buf, sizeof(buf) - 1);
+		    close(fd);
+		    if (bytes > 0) {
+			buf[bytes] = '\0';
+			sscanf(buf, "%ld %d", &cached_start_time, &cached_last_day);
+		    }
+		} else {
+		    /* File doesn't exist, create it (Start Timer) */
+		    cached_start_time = t;
+		    cached_last_day = -1;
+
+		    int fd_w = open(HEARTBEAT_TIMER_PATH, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+		    if (fd_w >= 0) {
+			char out[64];
+			int len = snprintf(out, sizeof(out), "%ld %d", (long)t, -1);
+			write(fd_w, out, len);
+			close(fd_w);
+		    }
+		    printf("Licensepermit enabled. Timer started for %d days.\n", EXPIRY_DAYS);
+		}
+	    }
+	    double seconds_diff = difftime(t, cached_start_time);
+	    int days_passed = (int)(seconds_diff / SECONDS_IN_DAY);
+	    int days_remaining = EXPIRY_DAYS - days_passed;
+	    /* Log and update once per day */
+	    if (days_passed > cached_last_day) {
+		if (days_remaining > 0) {
+		    char buf[256];
+		    sprintf(buf, "WARNING: Activationserver is down. License will be disabled in %d day(s).", days_remaining);
+		    logging(buf, 1);
+		    fastlog_logex(FC_CM_LIC_WILL_EXPIRE, 1, days_remaining);
+		    write_heartbeat_info(CM_INFO, &heartbeat_info);
+		    printf("LOG: License will expire in %d days.\n", days_remaining);
+		} else {
+		    logging("CRITICAL: Activationserver down for 7 days, License Key has expired!.", 1);
+		    fastlog_logex(FC_CM_LIC_HAS_EXPIRED, 0);
+		    is_licensepermit_expire = 1; // Set to 1 if CM down from more than 7 days
+		    disable_license(1);
+		    heartbeat_info.device_manage_status = UNREGISTERED;
+		}
+		cached_last_day = days_passed;
+		int fd_u = open(HEARTBEAT_TIMER_PATH, O_WRONLY | O_TRUNC);
+		if (fd_u >= 0) {
+		    char out[64];
+		    int len = snprintf(out, sizeof(out), "%ld %d", (long)cached_start_time, cached_last_day);
+		    write(fd_u, out, len);
+		    close(fd_u);
+		}
+	    }
+	    sysctlbyname("net.inet.clicktcp.licensepermit_expire", NULL, 0,
+		    &is_licensepermit_expire, sizeof(is_licensepermit_expire));
 	}
+
     }
 end:
     if (feactl_p) {
Index: /branches/rel_apv_10_7_3/usr/click/bin/vtch/vtch-guest.c
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/bin/vtch/vtch-guest.c	(revision 40136)
+++ /branches/rel_apv_10_7_3/usr/click/bin/vtch/vtch-guest.c	(working copy)
@@ -341,12 +341,17 @@
 		syslog(LOG_USER | LOG_INFO, "CMD_DEL_LICENSE : feactl_p->flag = %d\n", feactl_p->flag);
 		if(access("/var/crash/cm_address", F_OK) == 0){
 		    int is_licensepermit_enable;
+		    int is_licensepermit_expire;
 		    size_t len = sizeof(is_licensepermit_enable);
 		    if (sysctlbyname("net.inet.clicktcp.licensepermit_enable", &is_licensepermit_enable,
 			&len, NULL, 0)) {
 			syslog(LOG_EMERG, "error retrieving license information");
 		    }
-		    if (is_licensepermit_enable) {
+		    if (sysctlbyname("net.inet.clicktcp.licensepermit_expire", &is_licensepermit_expire,
+					    &len, NULL, 0)) {
+			    syslog(LOG_EMERG, "error retrieving license expiry");
+		    }
+		    if ((is_licensepermit_enable) && !(is_licensepermit_expire)) {
 			syslog(LOG_EMERG, "licensepermit is enabled.\n");
 			if (access("/ca/etc/bw_cm", F_OK) == 0) {
 			    syslog(LOG_EMERG, "CMD_DEL_LICENSE : read bandwidth from file\n");
Index: /branches/rel_apv_10_7_3/usr/click/lib/libfeactl/feactl.c
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/lib/libfeactl/feactl.c	(revision 40136)
+++ /branches/rel_apv_10_7_3/usr/click/lib/libfeactl/feactl.c	(working copy)
@@ -3171,12 +3171,17 @@
 	feactl_p->max_vapv_bandwidth *= vapv_bandwidth_multiplier;
 	if (access("/var/crash/cm_address", F_OK) == 0) {
 		int is_licensepermit_enable;
+		int is_licensepermit_expire;
 		size_t len = sizeof(is_licensepermit_enable);
 		if (sysctlbyname("net.inet.clicktcp.licensepermit_enable", &is_licensepermit_enable,
 					&len, NULL, 0)) {
 			syslog(LOG_EMERG, "error retrieving license information");
 		}
-		if (is_licensepermit_enable) {
+		if (sysctlbyname("net.inet.clicktcp.licensepermit_expire", &is_licensepermit_expire,
+					&len, NULL, 0)) {
+			syslog(LOG_EMERG, "error retrieving license expiry");
+		}
+		if ((is_licensepermit_enable) && !(is_licensepermit_expire)) {
 			syslog(LOG_EMERG, "licensepermit is enabled.\n");
 			int fd = open("/ca/etc/bw_cm", O_RDONLY);
 			if (fd != -1) {
Index: /branches/rel_apv_10_7_3/usr/click/lib/libwebui/webui.c
===================================================================
--- /branches/rel_apv_10_7_3/usr/click/lib/libwebui/webui.c	(revision 40136)
+++ /branches/rel_apv_10_7_3/usr/click/lib/libwebui/webui.c	(working copy)
@@ -3514,12 +3514,18 @@
         model_id = get_manufacture_model_id();
         if (model_id == AFM_MODEL_vAPV) {
                 int is_licensepermit_enable;
-                size_t len = sizeof(is_licensepermit_enable);
-                if (sysctlbyname("net.inet.clicktcp.licensepermit_enable", &is_licensepermit_enable,
-                                        &len, NULL, 0)) {
-                        fastlog_syslog(LOG_EMERG, "error retrieving license information");
-                }
-                if (is_licensepermit_enable) {
+		int is_licensepermit_expire;
+
+		size_t len = sizeof(is_licensepermit_enable);
+		if (sysctlbyname("net.inet.clicktcp.licensepermit_enable", &is_licensepermit_enable,
+					&len, NULL, 0)) {
+			fastlog_syslog(LOG_EMERG, "error retrieving license information");
+		}
+		if (sysctlbyname("net.inet.clicktcp.licensepermit_expire", &is_licensepermit_expire,
+					&len, NULL, 0)) {
+			syslog(LOG_EMERG, "error retrieving license expiry");
+		}
+		if ((is_licensepermit_enable) && !(is_licensepermit_expire)) {
                         fastlog_syslog(LOG_EMERG, "licensepermit is enabled.\n");
                         restart_flag = 1;
 
Index: /branches/rel_apv_10_7_3/usr/src/sys/click/app/fastlog/fastlog_var.h
===================================================================
--- /branches/rel_apv_10_7_3/usr/src/sys/click/app/fastlog/fastlog_var.h	(revision 40136)
+++ /branches/rel_apv_10_7_3/usr/src/sys/click/app/fastlog/fastlog_var.h	(working copy)
@@ -442,6 +442,8 @@
 	FC_WR_LIC_WILL_EXPIRE,
 	FC_WR_LIC_HAS_EXPIRED,
 	FC_MODEL_ID_ERR,
+	FC_CM_LIC_WILL_EXPIRE,
+	FC_CM_LIC_HAS_EXPIRED,
 
 /******** End Feature Control Log Messages ******/
 
Index: /branches/rel_apv_10_7_3/usr/src/sys/click/app/fastlog/logex_def.h
===================================================================
--- /branches/rel_apv_10_7_3/usr/src/sys/click/app/fastlog/logex_def.h	(revision 40136)
+++ /branches/rel_apv_10_7_3/usr/src/sys/click/app/fastlog/logex_def.h	(working copy)
@@ -619,6 +619,8 @@
 	{ FC_WR_LIC_WILL_EXPIRE, 100005017, LOG_WARNING, LOG_MOD_FC, 1, "Website Classification License Key will expire in %d days!", "网站分类许可密钥将在%d天后过期!","Website Classification License Key will expire!", "Website Classification License will expire soon!"},
 	{ FC_WR_LIC_HAS_EXPIRED, 100005018, LOG_WARNING, LOG_MOD_FC, 0, "Website Classification License Key has expired!","网站分类许可密钥已过期!", "Website Classification License Key has expired!", "Please "CONTACT_ARRAY_SUPPORT" for new license"},
 	{ FC_MODEL_ID_ERR, 100005019, LOG_INFO, LOG_MOD_FC, 0, "Feature Control: A new value is assigned.","Feature Control: 分配了一个新值", NULL, NULL},
+	{ FC_CM_LIC_WILL_EXPIRE, 100005020, LOG_WARNING, LOG_MOD_FC, 1, "Activation server down. License Key will expire in %d days!", "激活服务器已停机. 许可证密钥将在%d天后过期!","License Key will expire!", "License will expire soon!"},
+	{ FC_CM_LIC_HAS_EXPIRED, 100005021, LOG_WARNING, LOG_MOD_FC, 0, "Activation server down for 7 days, License Key has expired!","激活服务器宕机7天, 许可证密钥已过期!", "License Key has expired!", "Please "CONTACT_ARRAY_SUPPORT" for new license"},
 /******** End Feature Control Log Messages ********/
 
 /******** Begin VA (Clustering) Log Messages ********/
Index: /branches/rel_apv_10_7_3/usr/src/sys/click/netinet/click_input.c
===================================================================
--- /branches/rel_apv_10_7_3/usr/src/sys/click/netinet/click_input.c	(revision 40136)
+++ /branches/rel_apv_10_7_3/usr/src/sys/click/netinet/click_input.c	(working copy)
@@ -872,6 +872,9 @@
 int licensepermit_enable = 1;
 SYSCTL_INT(_net_inet_clicktcp, OID_AUTO, licensepermit_enable, CTLFLAG_RW,
                 &licensepermit_enable, 0, "license retention enable");
+int licensepermit_expire = 0;
+SYSCTL_INT(_net_inet_clicktcp, OID_AUTO, licensepermit_expire, CTLFLAG_RW,
+		&licensepermit_expire, 0, "license retention expire");
 
 static int sysctl_atcp_thread_init_done(SYSCTL_HANDLER_ARGS);
 int atcp_thread_init_done[ATCP_MAXTHREADS] = { 0 };
