Index: /branches/rel_apv_10_7_2/usr/click/lib/libca_snmp/snmp_cadmin.c
===================================================================
--- /branches/rel_apv_10_7_2/usr/click/lib/libca_snmp/snmp_cadmin.c	(revision 39136)
+++ /branches/rel_apv_10_7_2/usr/click/lib/libca_snmp/snmp_cadmin.c	(working copy)
@@ -128,6 +128,9 @@
 #include <sys/sysctl.h>
 #include <limits.h>
 #include <errno.h>
+#include <openssl/sha.h>
+#include <openssl/evp.h>
+#include <sys/stat.h>
 
 #include "snmpcli.h"
 #include "fastlog.h"
@@ -169,6 +172,108 @@
 
 extern array_model_t array_models[MAX_MODEL];
 
+/* Function to get serial number */
+int get_sr_num(char* serial_num, int slen)
+{
+    size_t len = 0;
+    FILE *fd = NULL;
+    if (slen < SERNUMLEN) {
+        return -1;
+    }
+    memset(serial_num, 0, SERNUMLEN);
+    len = MACLEN;
+    fd = fopen(SRNFN, "r");
+    if (!fd) {
+        if ((u_sysctlbyname("kern.click_id", serial_num, &len, NULL, 0) == -1)) {
+            return -1;
+        } else {
+            serial_num[MACLEN - 1] = '\0';
+        }
+    } else {
+        fscanf(fd, "%s", serial_num);
+        fclose(fd);
+        if ((u_sysctlbyname("kern.click_id", (serial_num + ARRAYIDLEN), &len, NULL, 0) == -1)) {
+            serial_num[ARRAYIDLEN] = '\0';
+        } else {
+            serial_num[SERNUMLEN - 1] = '\0';
+        }
+    }
+    return 0;
+}
+
+/* Generate SHA256-based engineID */
+static
+int generate_engine_id(unsigned char *engine_id, size_t *engine_len) {
+    char serial[SERIAL_MAX_LEN] = {0};
+    unsigned char hash[SHA256_DIGEST_LENGTH];
+    char input_buf[128];
+
+    if (get_sr_num(serial, sizeof(serial)) != 0) {
+        fprintf(stderr, "Failed to retrieve serial number.\n");
+        return -1;
+    }
+
+    snprintf(input_buf, sizeof(input_buf), "%u:%s", ENTERPRISE_ID, serial);
+
+    SHA256((unsigned char *)input_buf, strlen(input_buf), hash);
+
+    size_t copy_len = ENGINE_ID_BIN_LEN <= SHA256_DIGEST_LENGTH ? ENGINE_ID_BIN_LEN : SHA256_DIGEST_LENGTH;
+    memcpy(engine_id, hash, copy_len);
+    *engine_len = copy_len;
+
+    return 0;
+}
+
+/* Persist engineID across reboots */
+static
+int persist_snmp_engine_id(void) {
+    char serial[SERIAL_MAX_LEN];
+    uint8_t hash[SHA256_DIGEST_LENGTH];
+    uint8_t engineID[ENGINE_ID_BIN_LEN];
+    FILE *fp;
+    struct stat st;
+
+    // Skip if already exists
+    if (stat(SNMPD_PERSIST_FILE, &st) == 0)
+        return 0;
+
+    if (get_sr_num(serial, sizeof(serial)) != 0)
+        return -1;
+
+    SHA256((unsigned char *)serial, strlen(serial), hash);
+
+    // Build the engineID
+    engineID[0] = 0x80;
+    engineID[1] = 0x00;
+    engineID[2] = 0x00;
+    engineID[3] = 0x1D;
+    engineID[4] = 0x8C;
+    memcpy(&engineID[5], hash, ENGINE_ID_BIN_LEN - 5);
+
+    // Debug print
+    printf("SNMP EngineID: ");
+    for (int i = 0; i < ENGINE_ID_BIN_LEN; i++)
+        printf("%02X ", engineID[i]);
+    printf("\n");
+
+    // Persist to SNMP's expected persistent path
+    fp = fopen(SNMPD_PERSIST_FILE, "w");
+    if (!fp) {
+        perror("fopen");
+        return -1;
+    }
+
+    fprintf(fp, "engineBoots 1\n");
+    fprintf(fp, "engineTime 100\n");
+    fprintf(fp, "oldEngineID 0x");
+    for (int i = 0; i < ENGINE_ID_BIN_LEN; i++)
+        fprintf(fp, "%02X", engineID[i]);
+    fprintf(fp, "\n");
+
+    fclose(fp);
+    return 0;
+}
+
 /* 
  * get snmpd's pid
  * if it do not running, return 0
@@ -279,6 +384,7 @@
 		return -1;
 	}
 
+	persist_snmp_engine_id();
 
 	/* Load CA-SNMP-MIB dynamic library */
 #if defined(__linux__)
@@ -1391,6 +1497,8 @@
 		return (CA_ERR_SNMP_SHM_LOCK);
 	}
 
+	persist_snmp_engine_id();
+
 	pInfo->snmp_version = ver;
 
 	snmp_update_snmpd_conf(pInfo);
Index: /branches/rel_apv_10_7_2/usr/click/lib/libca_snmp/snmpcli.h
===================================================================
--- /branches/rel_apv_10_7_2/usr/click/lib/libca_snmp/snmpcli.h	(revision 39136)
+++ /branches/rel_apv_10_7_2/usr/click/lib/libca_snmp/snmpcli.h	(working copy)
@@ -80,6 +80,13 @@
 
 #define ENGINE_ID_MAX_LEN       32
 
+#define SERIAL_MAX_LEN		64
+#define MAX_CA_ENGINE_ID_LEN	28
+#define ENGINE_ID_BIN_LEN	32
+#define ENGINE_ID_B64_LEN	64
+#define ENGINE_ID_PREFIX_LEN	5      // 0x80 + 4-byte enterprise ID
+#define ENTERPRISE_ID		7564   // 0x1d8c
+
 #define SNMP_MAX_IPLIST         16
 #define SNMP_BUFFER_SIZE        4096
 
