OSDN Git Service

cleanup
[openpts/openpts.git] / src / fsm.c
index 4ce4dcb..67f7a35 100644 (file)
--- a/src/fsm.c
+++ b/src/fsm.c
@@ -26,9 +26,9 @@
  * \brief Finite State Machine
  * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
  * @date 2010-04-01
- * cleanup 2011-01-21 SM
- * refactoring 2011-07-20 SM
- * 
+ * cleanup 2012-01-05 SM (remains one lint error)
+ *   src/fsm.c:416:  Use int16/int64/etc, rather than the C type long  [runtime/int] [4]
+ *
  * Input
  *   FSM Model
  *   IML
@@ -56,9 +56,9 @@ OPENPTS_FSM_CONTEXT *newFsmContext() {
     OPENPTS_FSM_CONTEXT *ctx = NULL;
 
     /* malloc */
-    ctx = (OPENPTS_FSM_CONTEXT *) malloc(sizeof(OPENPTS_FSM_CONTEXT));
+    ctx = (OPENPTS_FSM_CONTEXT *) xmalloc(sizeof(OPENPTS_FSM_CONTEXT));
     if (ctx == NULL) {
-        ERROR("ERROR\n");
+        LOG(LOG_ERR, "no memory");
         return NULL;
     }
     /* init */
@@ -76,36 +76,52 @@ OPENPTS_FSM_CONTEXT *newFsmContext() {
  * Free OPENPTS_FSM_Transition chain
  */
 void freeFsmTransitionChain(OPENPTS_FSM_Transition *fsm_trans) {
+    /* check */
+    if (fsm_trans == NULL) {
+        LOG(LOG_ERR, "null input");
+        return;
+    }
+
+    /* free */
     if (fsm_trans->next != NULL) {
         freeFsmTransitionChain(fsm_trans->next);
     }
 
     /* free */
     if (fsm_trans->digest != NULL) {
-        free(fsm_trans->digest);
+        xfree(fsm_trans->digest);
     }
 
-    free(fsm_trans);
+    xfree(fsm_trans);
 }
 
 /**
  * Free OPENPTS_FSM_Subvertex chain
  */
 void freeFsmSubvertexChain(OPENPTS_FSM_Subvertex *fsm_sub) {
+    /* check */
+    if (fsm_sub == NULL) {
+        LOG(LOG_ERR, "null input");
+        return;
+    }
+
+    /* chain */
     if (fsm_sub->next != NULL) {
         freeFsmSubvertexChain(fsm_sub->next);
     }
 
-    free(fsm_sub);
+    /* free */
+    xfree(fsm_sub);
 }
 
 /**
  * free FSM context
  */
 int freeFsmContext(OPENPTS_FSM_CONTEXT *ctx) {
+    /* check */
     if (ctx == NULL) {
-        ERROR("ERROR\n");
-        return -1;
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
     }
 
     /* Transition */
@@ -114,7 +130,6 @@ int freeFsmContext(OPENPTS_FSM_CONTEXT *ctx) {
         ctx->fsm_trans = NULL;
     }
 
-
     /* Subvertex */
     if (ctx->fsm_sub != NULL) {
         freeFsmSubvertexChain(ctx->fsm_sub);
@@ -123,11 +138,11 @@ int freeFsmContext(OPENPTS_FSM_CONTEXT *ctx) {
 
     /* UML filename */
     if (ctx->uml_file != NULL) {
-        free(ctx->uml_file);
+        xfree(ctx->uml_file);
         ctx->uml_file = NULL;
     }
 
-    free(ctx);
+    xfree(ctx);
     return 0;
 }
 
@@ -138,7 +153,18 @@ int freeFsmContext(OPENPTS_FSM_CONTEXT *ctx) {
  * reset FSM subvertex
  */
 void resetFsmSubvertex(OPENPTS_FSM_CONTEXT *ctx) {
-    // fsm_sub=NULL;
+    /* check */
+    if (ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return;
+    }
+
+    /* free subvertex chain */
+    if (ctx->fsm_sub != NULL) {
+        freeFsmSubvertexChain(ctx->fsm_sub);
+        ctx->fsm_sub = NULL;
+    }
+
     ctx->subvertex_num = 0;
 }
 
@@ -146,7 +172,18 @@ void resetFsmSubvertex(OPENPTS_FSM_CONTEXT *ctx) {
  * reset FSM transition
  */
 void resetFsmTransition(OPENPTS_FSM_CONTEXT *ctx) {
-    // fsm_trans=NULL;
+    /* check */
+    if (ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return;
+    }
+
+    /* free transition chain */
+    if (ctx->fsm_trans != NULL) {
+        freeFsmTransitionChain(ctx->fsm_trans);
+        ctx->fsm_trans = NULL;
+    }
+
     ctx->transition_num = 0;
 }
 
@@ -166,6 +203,29 @@ void addFsmSubvertex(
 
     DEBUG_CAL("addFsmSubvertex - %d \n", ctx->subvertex_num);
 
+    /* check */
+    if (ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return;
+    }
+    if (type == NULL) {
+        LOG(LOG_ERR, "null input");
+        return;
+    }
+    if (id == NULL) {
+        LOG(LOG_ERR, "null input");
+        return;
+    }
+    if (name == NULL) {
+        LOG(LOG_ERR, "null input");
+        return;
+    }
+    if (action == NULL) {
+        LOG(LOG_ERR, "null input");
+        return;
+    }
+
+    /* add */
     ptr = ctx->fsm_sub;
     for (i = 0; i <= ctx->subvertex_num; i++) {
         if (ptr == NULL) {
@@ -176,9 +236,8 @@ void addFsmSubvertex(
 
             /* malloc OPENPTS_FSM_Subvertex */
             ptr = (OPENPTS_FSM_Subvertex *)
-                    malloc(sizeof(OPENPTS_FSM_Subvertex));
+                    xmalloc(sizeof(OPENPTS_FSM_Subvertex));
             if (ptr == NULL) {
-                ERROR("addFsmSubvertex - no memory\n");
                 return;
             }
 
@@ -202,8 +261,8 @@ void addFsmSubvertex(
                 ptr_pre->next = ptr;  // else
                 ptr->prev = ptr_pre;
             } else {
-                ERROR("\n");
-                free(ptr);  // free last one
+                LOG(LOG_ERR, "BAD, free last one");
+                xfree(ptr);  // free last one
                 return;
             }
 
@@ -221,6 +280,17 @@ void addFsmSubvertex(
 OPENPTS_FSM_Subvertex * getSubvertex(OPENPTS_FSM_CONTEXT *ctx, char * id) {
     OPENPTS_FSM_Subvertex *ptr;
 
+    /* check */
+    if (ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return NULL;
+    }
+    if (id == NULL) {
+        LOG(LOG_ERR, "null input");
+        return NULL;
+    }
+
+    /* Final? */
     if (!strcmp(id, "Final")) return NULL;  // final state
 
     ptr = ctx->fsm_sub;
@@ -229,6 +299,7 @@ OPENPTS_FSM_Subvertex * getSubvertex(OPENPTS_FSM_CONTEXT *ctx, char * id) {
         if (!strcmp(id, ptr->id)) return ptr;
         ptr = (OPENPTS_FSM_Subvertex *) ptr->next;
     }
+
     return NULL;
 }
 
@@ -239,6 +310,17 @@ char * getSubvertexName(OPENPTS_FSM_CONTEXT *ctx, char * id) {
     int i;
     OPENPTS_FSM_Subvertex *ptr;
 
+    /* check */
+    if (ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return NULL;
+    }
+    if (id == NULL) {
+        LOG(LOG_ERR, "null input");
+        return NULL;
+    }
+
+    /* Final? */
     if (!strcmp(id, "Final")) return id;
 
     ptr = ctx->fsm_sub;
@@ -257,7 +339,15 @@ char * getSubvertexId(OPENPTS_FSM_CONTEXT *ctx, char * name) {
     int i;
     OPENPTS_FSM_Subvertex *ptr;
 
-    // if (!strcmp(id, "Final")) return id;
+    /* check */
+    if (ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return NULL;
+    }
+    if (name == NULL) {
+        LOG(LOG_ERR, "null input");
+        return NULL;
+    }
 
     ptr = ctx->fsm_sub;
     for (i = 0;i <= ctx->subvertex_num; i++) {
@@ -271,24 +361,78 @@ char * getSubvertexId(OPENPTS_FSM_CONTEXT *ctx, char * name) {
 
 /// TRANSITION ///
 
+static char *skipWhiteSpace(char *str, int *len /* out */) {
+    char *cur = str, *end = str + *len;
+
+    /* check */
+    if (str == NULL) {
+        LOG(LOG_ERR, "null input");
+        return NULL;
+    }
+
+    /* skip space */
+    while (cur < end &&
+           '\0' != *cur &&
+           ' '  == *cur) {
+        cur++;
+    }
+    *len -= cur - str;
+    return cur;
+}
+
+static int isEndOfString(char *str) {
+    /* check */
+    if (str == NULL) {
+        LOG(LOG_ERR, "null input");
+        return 0;  // TODO
+    }
+
+    return '\0' == *str;
+}
+
+static char *skipParameter(char *str, int *len /* out */) {
+    char *cur = str, *end = str + *len;
+
+    /* check */
+    if (str == NULL) {
+        LOG(LOG_ERR, "null input");
+        return NULL;
+    }
+
+    /* skip space */
+    while (cur < end &&
+           '\0' != *cur &&
+           ' '  != *cur &&
+           ','  != *cur) {
+        cur++;
+    }
+    *len -= cur - str;
+    return cur;
+}
+
 /**
  *   <body>eventtype == 0x01, digest == base64</body>
  * -1: error
  *  0: don't care
- *   1: ==
- *   2: !=
+ *   1: ==, eq
+ *   2: !=, ne
  *
  * Unit Test : check_fsm.c / test_getTypeFlag
  *
  */
-int getTypeFlag(char * cond, UINT32 *eventtype) {
+int getTypeFlag(char * cond, UINT32 *eventtype /* out */) {
     char * loc;
     int len;
     int rc = 0;
-    long int val;  // TODO uint64_t but fail to build on i386 platform
+    long int val;  // TODO uint64_t? but build fail on i386 platform
 
-    len = strlen(cond);
+    /* check */
+    if (cond == NULL) {
+        LOG(LOG_ERR, "null input");
+        return -1;
+    }
 
+    len = strlen(cond);
     loc = strstr(cond, "eventtype");
 
     if (loc == NULL) {  // miss
@@ -299,56 +443,47 @@ int getTypeFlag(char * cond, UINT32 *eventtype) {
         loc += 9;
         len -= (loc - cond);
 
-        /* skip space */
-        while (len > 0) {
-            if (loc[0] == 0) return -1;  // end
-            else if (loc[0] == ' ') {    // space
-                loc++;
-                len--;
-            } else {
-                break;
-            }
+        loc = skipWhiteSpace(loc, &len);
+        if (isEndOfString(loc)) {
+            return -1;
         }
 
         /* operation */
         if (len < 2) {
-            ERROR("ERROR 001\n");
+            LOG(LOG_ERR, "ERROR 001\n");
             return -1;  // end
         }
         if ((loc[0] == '=') && (loc[1] == '=')) {  // ==
             rc = 1;
-        } else if ((loc[0] == '!') && (loc[1] == '=')) {  // ==
+        } else if ((loc[0] == 'e') && (loc[1] == 'q')) {  // ==
+            rc = 1;
+        } else if ((loc[0] == '!') && (loc[1] == '=')) {  // !=
+            rc = 2;
+        } else if ((loc[0] == 'n') && (loc[1] == 'e')) {  // !=
             rc = 2;
         } else {
-            ERROR("ERROR 002 %c %c \n", loc[0], loc[1]);
+            LOG(LOG_ERR, "ERROR 002 %c %c \n", loc[0], loc[1]);
             return -1;  // unknown operand
         }
         loc += 2;
         len -= 2;
 
-        /* skip space */
-        while (len > 0) {
-            if (loc[0] == 0) return -1;  // end
-            else if (loc[0] == ' ') {  // space
-                loc++;
-                len--;
-            } else {
-                break;
-            }
+        loc = skipWhiteSpace(loc, &len);
+        if (isEndOfString(loc)) {
+            return -1;
         }
+
         /* value */
         // 20110117 Ubuntu i386, 0x80000002 => 7FFFFFFF, => use strtoll
         if (len > 2) {
             if  ((loc[0] == '0') && (loc[1] == 'x')) {  // 0x HEX
                 val = strtoll(loc, NULL, 16);
                 *eventtype = (UINT32)val;
-                // DEBUG("strtol [%s] => %X => %X\n", loc,val,*eventtype);
                 return rc;
             }
         }
         val = strtoll(loc, NULL, 10);
         *eventtype = (UINT32)val;
-        // DEBUG("strtol [%s] => %X => %X\n", loc,val, *eventtype);
 
         return rc;
     }
@@ -360,7 +495,7 @@ int getTypeFlag(char * cond, UINT32 *eventtype) {
  * Return
  *   0: don't care
  *   1: valid (=binary model),  return the digest => freed at freeFsmTransitionChain()
- *   2: ignore now (=behavior model)
+ *   2: ignore now (=behavior model or ignored digests in binary model)
  *  -1: Error?
  *
  * Unit Test : check_fsm.c / test_getDigestFlag
@@ -369,65 +504,64 @@ int getTypeFlag(char * cond, UINT32 *eventtype) {
  */
 int getDigestFlag(char * cond, BYTE **digest, int *digest_size) {
     char * loc;   // loc at value
-    char * loc2;  // loc at "base64"
     int len;
     BYTE *buf;
     int buf_len;
 
     DEBUG_CAL("getDigestFlag -");
 
+    /* check */
+    if (cond == NULL) {
+        LOG(LOG_ERR, "null input");
+        return -1;
+    }
+
     len = strlen(cond);
 
     loc = strstr(cond, "digest");
     if (loc == NULL) {  // miss
         *digest_size = 0;
-        return 0;
+        return DIGEST_FLAG_SKIP;
     } else {  // hit
         /* skip  digest */
         loc += 6;
         len -= (loc - cond);
 
-        /* skip space */
-        while (len > 0) {
-            if (loc[0] == 0) return -1;  // end
-            else if (loc[0] == ' ') {  // space
-                loc++;
-                len--;
-            } else {
-                break;
-            }
+        loc = skipWhiteSpace(loc, &len);
+        if (isEndOfString(loc)) {
+            return -1;
         }
 
         /* operation, "==" only */
         if (len < 2) {
-            ERROR("ERROR 001\n");
+            LOG(LOG_ERR, "ERROR 001\n");
             return -1;  // end
         }
         if ((loc[0] == '=') && (loc[1] == '=')) {  // ==
             // operand is ==
         } else {
-            ERROR("ERROR 002 [%c%c]  not  == \n", loc[0], loc[1]);
+            LOG(LOG_ERR, "ERROR 002 [%c%c]  not  ==, (cond = %s)\n", loc[0], loc[1], cond);
             return -1;  // unknown operand
         }
         loc +=2;
         len -=2;
 
         /* skip space */
-        while (len > 0) {
-            if (loc[0] == 0) return -1;  // end
-            else if (loc[0] == ' ') {  // space
-                loc++;
-                len--;
-            } else {
-                break;
-            }
+        loc = skipWhiteSpace(loc, &len);
+        if (isEndOfString(loc)) {
+            return -1;
         }
 
-        /* digest == base64 (behavior model) */
-        loc2 = strstr(loc, "base64");
-        if (loc2 != NULL) {  // HIT, temp
+        if (NULL != strstr(loc, "base64!")) {  // HIT, temp
             /* Behavior Model */
-            return 2;
+            return DIGEST_FLAG_IGNORE;
+        } else if (NULL != strstr(loc, "base64")) {  // HIT, temp
+            /* Behavior Model */
+            return DIGEST_FLAG_IGNORE;
+        } else if (NULL != strstr(loc, "transparent!")) {
+            /* we have been told to ignore this digest from the binary model */
+            /* and use the behaviour version instead */
+            return DIGEST_FLAG_TRANSPARENT;
         } else {
             /* Binary Model */
             /* Base64 str -> BYTE[] */
@@ -436,15 +570,21 @@ int getDigestFlag(char * cond, BYTE **digest, int *digest_size) {
                 SHA1_BASE64_DIGEST_SIZE,
                 &buf_len);
             if (buf == NULL) {
-                ERROR("decodeBase64 fail");
+                LOG(LOG_ERR, "decodeBase64 fail");
+                *digest = NULL;
+                *digest_size = 0;
+                return -1;
+            } else if (buf_len == SHA1_DIGEST_SIZE) {
+                *digest = buf;
+                *digest_size = SHA1_DIGEST_SIZE;
+                return DIGEST_FLAG_EQUAL;  // 1
+            } else {
+                LOG(LOG_ERR, "getDigestFlag() - decodeBase64() was failed \n");
+                xfree(buf);
                 *digest = NULL;
                 *digest_size = 0;
                 return -1;
             }
-            *digest = buf;
-            // TODO buf_len >= SHA1_DIGEST_SIZE
-            *digest_size = SHA1_DIGEST_SIZE;
-            return 1;
         }
     }
 }
@@ -459,90 +599,113 @@ int getDigestFlag(char * cond, BYTE **digest, int *digest_size) {
  *   COUNTER_FLAG_LT   1:  < name
  *   COUNTER_FLAG_GTE  2:  >= name 
  *
- *   set counter name to name 
- *
  * Unit Test : check_fsm.c / test_getCounterFlag
  */
-int getCounterFlag(char * cond, char **name) {
+int getCounterFlag(char *cond, char *name, char **flag /* out */) {
     char * loc;   // loc at value
-    char * loc2;  // loc at name
+    char * loc2;  // loc at flag
     int len;
     int rc = COUNTER_FLAG_SKIP;
 
-    // DEBUG_CAL("getCounterFlag\n");
-
     /* check */
     if (cond == NULL) {
-        ERROR("getCounterFlag()");
-        return COUNTER_FLAG_SKIP;
+        LOG(LOG_ERR, "Null condition found");
+        return 0;
+    }
+    if (name == NULL) {
+        LOG(LOG_ERR, "Null condition found");
+        return 0;
     }
 
+    /* parse the flag */
     len = strlen(cond);
-    loc = strstr(cond, "count");
+    loc = strstr(cond, name);
 
     if (loc == NULL) {
         /* miss */
         return 0;
     } else {
+        int param_len = 0;
         /* hit */
 
         /* skip  count */
-        loc += 5;
+        loc += strlen(name);
         len -= (loc - cond);
 
-        /* skip space */
-        while (len > 0) {
-            if (loc[0] == 0) return -1;  // end
-            else if (loc[0] == ' ') {  // space
-                loc++;
-                len--;
-            } else {
-                break;
-            }
+        loc = skipWhiteSpace(loc, &len);
+        if (isEndOfString(loc)) {
+            goto error;
         }
 
         /* operation, "&lt;" ">=" only */
-        if ((len >= 2) && (loc[0] == 'l') && (loc[1] == 't')) {
-            /* >= */
+        if ((len >= 2) && (loc[0] == 'l') && (loc[1] == 't')) {  // <, lt
             rc = COUNTER_FLAG_LT;
             loc +=2;
             len -=2;
-        } else if ((len >= 2) && (loc[0] == '>') && (loc[1] == '=')) {
-            /* >= */
-            rc = COUNTER_FLAG_GTE;
+        } else if ((len >= 2) && (loc[0] == 'l') && (loc[1] == 'e')) {  // <=, le
+            rc = COUNTER_FLAG_LE;
+            loc +=2;
+            len -=2;
+        } else if ((len >= 2) && (loc[0] == 'g') && (loc[1] == 't')) {  // >, gt
+            rc = COUNTER_FLAG_GT;
+            loc +=2;
+            len -=2;
+        } else if ((len >= 2) && (loc[0] == 'g') && (loc[1] == 'e')) {  // >, gt
+            rc = COUNTER_FLAG_GE;
+            loc +=2;
+            len -=2;
+        } else if ((len >= 2) && (loc[0] == '<') && (loc[1] == ' ')) {  // <, lt
+            rc = COUNTER_FLAG_LT;
+            loc +=2;
+            len -=2;
+        } else if ((len >= 2) && (loc[0] == '<') && (loc[1] == '=')) {  // <=, le
+            rc = COUNTER_FLAG_LE;
+            loc +=2;
+            len -=2;
+        } else if ((len >= 2) && (loc[0] == '>') && (loc[1] == ' ')) {  // >, gt
+            rc = COUNTER_FLAG_GT;
+            loc +=2;
+            len -=2;
+        } else if ((len >= 2) && (loc[0] == '>') && (loc[1] == '=')) {  // >=
+            rc = COUNTER_FLAG_GE;
             loc +=2;
             len -=2;
         } else {
-            // ERROR("ERROR 002 [%s]  not  >= \n", &loc[0];
-            return -1;  // unknown operand
+            LOG(LOG_ERR, "unknown operand [%s]", &loc[0]);
+            goto error;
         }
 
-        /* skip space */
-        while (len > 0) {
-            if (loc[0] == 0) return -1;  // end
-            else if (loc[0] == ' ') {  // space
-                loc++;
-                len--;
-            } else {
-                break;
-            }
+        loc = skipWhiteSpace(loc, &len);
+        if (isEndOfString(loc)) {
+            goto error;
         }
 
-        // TODO check the end, this code only support if counter is the last equation
+        // TODO check the end, this code only support if counter is the last
 
-        loc2 = loc;
-        len = strlen(loc2);
+        loc2 = skipParameter(loc, &len);
+        param_len = loc2 - loc;
+        if (0 == param_len) {
+            /* we haven't moved along the string - no valid parameter found */
+            goto error;
+        }
 
-        *name = malloc(len + 1);
-        if (*name == NULL) {
-            ERROR("no memory\n");
-            return -1;
+        /* DEBUG_FSM("[%d][%s][%s]\n",len, loc, loc2); */
+
+        *flag = xmalloc(param_len + 1);
+        if (*flag == NULL) {
+            goto error;
         }
-        memset(*name, 0, len + 1);
-        memcpy(*name, loc2, len);
+        memset(*flag, 0, param_len + 1);
+        memcpy(*flag, loc, param_len);
     }
-    DEBUG_FSM("getCounterFlag cond=[%s],  prop=[%s] rc=%d (0:1:2=skip:<:>=),\n", cond,  *name, rc);
+
+    DEBUG_FSM("getCounterFlag  %s #=> %d %s\n", cond, rc, *flag);
+
     return rc;
+
+  error:
+    LOG(LOG_ERR, "getCounterFlag(\"%s\",\"%s\") fail", cond, name);
+    return -1;
 }
 
 
@@ -566,6 +729,12 @@ int getLastFlag(char * cond) {
     int len;
     int rc = LAST_FLAG_SKIP;
 
+    /* check */
+    if (cond == NULL) {
+        LOG(LOG_ERR, "null input");
+        return -1;
+    }
+
     len = strlen(cond);
     loc = strstr(cond, "last");
 
@@ -574,21 +743,13 @@ int getLastFlag(char * cond) {
         return LAST_FLAG_SKIP;
     } else {
         /* hit */
-        // DEBUG("getLastFlag() - %s\n", cond);
-
         /* skip  count */
-        loc += 5;
+        loc += 4;  // 2011-12-30 5 => 4
         len -= (loc - cond);
 
-        /* skip space */
-        while (len > 0) {
-            if (loc[0] == 0) return -1;  // end
-            else if (loc[0] == ' ') {  // space
-                loc++;
-                len--;
-            } else {
-                break;
-            }
+        loc = skipWhiteSpace(loc, &len);
+        if (isEndOfString(loc)) {
+            return -1;
         }
 
         /* operation, "&lt;" ">=" only */
@@ -603,27 +764,20 @@ int getLastFlag(char * cond) {
             loc +=2;
             len -=2;
         } else {
-            // ERROR("ERROR 002 [%s]  not  >= \n", &loc[0];
-            return -1;  // unknown operand
+            LOG(LOG_ERR, "Unknown operation [%s], cond=[%s], BAD Validation Model\n", &loc[0], cond);
+            return -1;
         }
 
-        /* skip space */
-        while (len > 0) {
-            if (loc[0] == 0) return -1;  // end
-            else if (loc[0] == ' ') {  // space
-                loc++;
-                len--;
-            } else {
-                break;
-            }
+        loc = skipWhiteSpace(loc, &len);
+        if (isEndOfString(loc)) {
+            LOG(LOG_ERR, "Unknown operation [%s]\n", &loc[0]);
+            return -1;
         }
 
         /* value */
-
         loc2 = loc;
         len = strlen(loc2);
 
-        // DEBUG("[%d][%s]\n",len, loc2);
         if (!strncmp(loc2, "true", 4)) {
             // DEBUG("true\n");
             /* == true */
@@ -635,20 +789,14 @@ int getLastFlag(char * cond) {
             } else {
                 rc = LAST_FLAG_EQ;
             }
-            // DEBUG("false %d\n",rc);
         } else {
-            ERROR("unknown value, %s\n", loc2);
+            LOG(LOG_ERR, "unknown value, %s\n", loc2);
         }
     }
 
-    // DEBUG("getLastFlag  %s #=> %d\n",cond, rc);
-
     return rc;
 }
 
-
-
-
 /**
  * add FSM transition
  *
@@ -667,6 +815,25 @@ int addFsmTransition(
 
     DEBUG_CAL("addFsmTransition - start\n");
 
+    /* check */
+    if (ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+    if (source == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+    if (target == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+    if (cond == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+
+    /* trans */
     ptr = ctx->fsm_trans;
     for (i = 0; i <= ctx->transition_num; i++) {
         if (ptr == NULL) {  // new
@@ -676,31 +843,38 @@ int addFsmTransition(
 
             /* malloc OPENPTS_FSM_Transition */
             ptr = (OPENPTS_FSM_Transition *)
-                    malloc(sizeof(OPENPTS_FSM_Transition));
+                    xmalloc(sizeof(OPENPTS_FSM_Transition));
             if (ptr == NULL) {
-                ERROR("no memory\n");
+                LOG(LOG_ERR, "no memory");
                 return PTS_INTERNAL_ERROR;
             }
             /* init */
             memset(ptr, 0, sizeof(OPENPTS_FSM_Transition));
             memcpy(ptr->source, source, FSM_BUF_SIZE);
             memcpy(ptr->target, target, FSM_BUF_SIZE);
-            // memcpy(ptr->cond, cond, FSM_BUF_SIZE);
             ptr->num = ctx->transition_num;
             if (cond == NULL) {
                 ptr->eventTypeFlag = 0;
-                ptr->digestFlag = 0;
+                ptr->digestFlag = DIGEST_FLAG_SKIP;
             } else if  (cond[0] == 0) {
                 ptr->eventTypeFlag = 0;
-                ptr->digestFlag = 0;
+                ptr->digestFlag = DIGEST_FLAG_SKIP;
                 memcpy(ptr->cond, cond, FSM_BUF_SIZE);
             } else {
                 // 0:don't care, 1:care
                 ptr->eventTypeFlag = getTypeFlag(cond, &ptr->eventType);
-                // 0:don't care, 1:care, 2:temp
+                // 0:don't care, 1:care, 2:temp, 3:transparent
                 ptr->digestFlag = getDigestFlag(cond, &ptr->digest, &ptr->digestSize);
                 // 0:don't care, 1:<, 2:>=
-                ptr->counter_flag = getCounterFlag(cond, &ptr->counter_name);
+                ptr->counter_flag = getCounterFlag(cond, "digest_count", &ptr->counter_name);
+                if (ptr->counter_flag < 0) {
+                    LOG(LOG_ERR, "getCounterFlag() fail (%s => %s [%s])", source, target, cond);
+                }
+                // 0:don't care, 1:<, 2:>=
+                ptr->fatal_counter_flag = getCounterFlag(cond, "fatal_count", &ptr->fatal_counter_name);
+                if (ptr->fatal_counter_flag < 0) {
+                    LOG(LOG_ERR, "getCounterFlag() fail (%s => %s [%s])", source, target, cond);
+                }
                 // 0:don't care 1: ==last 2: != last
                 ptr->last_flag = getLastFlag(cond);
                 memcpy(ptr->cond, cond, FSM_BUF_SIZE);
@@ -709,6 +883,11 @@ int addFsmTransition(
             ptr->source_subvertex = getSubvertex(ctx, ptr->source);
             ptr->target_subvertex = getSubvertex(ctx, ptr->target);
 
+            if (DIGEST_FLAG_TRANSPARENT == ptr->digestFlag) {
+                DEBUG_FSM("Found transparent digest\n");
+                ctx->numTransparencies++;
+            }
+
             /* ptr */
             ptr->next = NULL;
             if (ctx->transition_num == 0) {
@@ -719,8 +898,8 @@ int addFsmTransition(
                 ptr->prev = ptr_pre;
                 ptr->next = NULL;  // last trans
             } else {
-                ERROR("\n");
-                free(ptr);  // free last one
+                LOG(LOG_ERR, "BAD, free last one");
+                xfree(ptr);  // free last one
                 return PTS_INTERNAL_ERROR;
             }
             ctx->transition_num++;
@@ -732,7 +911,7 @@ int addFsmTransition(
         ptr = (OPENPTS_FSM_Transition *)ptr->next;
     }
 
-    ERROR("missing?\n");
+    LOG(LOG_ERR, "missing?\n");
     return PTS_INTERNAL_ERROR;
 }
 
@@ -747,9 +926,8 @@ char *getEventString(OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
     char *buf;
 
     /* malloc */
-    buf = malloc(size);
+    buf = xmalloc(size);
     if (buf == NULL) {
-        ERROR("no memory\n");
         return NULL;
     }
 
@@ -758,8 +936,8 @@ char *getEventString(OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
     if (event != NULL) {
         // len = snprintf(buf, size, "PCR[%d],TYPE=%d", (int)event->ulPcrIndex, event->eventType);
     } else {
-        ERROR("NULL event\n");  // TODO(munetoh)
-        free(buf);
+        LOG(LOG_ERR, "NULL event\n");  // TODO(munetoh)
+        xfree(buf);
         return NULL;
     }
 
@@ -769,24 +947,43 @@ char *getEventString(OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
 
 /**
  * get counter(int) value from property
- * if property is missing or invalid, it returns 1;
+ * property
+ *    name=num
+ *
+ * return
+ *   -1   : ERROR
+ *    1   : missing, invalid (e.g. minus)
+ *    num 
  */
 int getCountFromProperty(OPENPTS_CONTEXT *ctx, char * name) {
     int count = 0;  // TODO get from prop
     OPENPTS_PROPERTY *prop;
 
+    /* check */
+    if (ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return -1;
+    }
+    if (name == NULL) {
+        LOG(LOG_ERR, "null input");
+        return -1;
+    }
+
+    /* lookup */
     prop = getProperty(ctx, name);
     if (prop != NULL) {
         /* Hit use this properties */
         count = atoi(prop->value);
         DEBUG_FSM("getCountFromProperty - prop %s = %d\n", name, count);
         if (count < 0) {
+            DEBUG("getCountFromProperty - prop %s is %d < 0. set count to 1\n", count, name);
             count = 1;
         }
     } else {
         /* Miss -> 1 */
         // TODO
-        // DEBUG("getCountFromProperty - prop %s is missing. set count to 1\n", name);
+        DEBUG("getCountFromProperty - prop %s is missing. add property with count=1\n", name);
+        addProperty(ctx, name, "1");
         count = 1;  // TODO
     }
     return count;
@@ -815,25 +1012,37 @@ int updateFsm(
         OPENPTS_PCR_EVENT_WRAPPER *eventWrapper
     ) {
     int rc = OPENPTS_FSM_SUCCESS;
-    OPENPTS_FSM_Subvertex  *curr_state = fsm->curr_state;
-    OPENPTS_FSM_Transition *trans = fsm->fsm_trans;
-    TSS_PCR_EVENT *event;
     int type_check;
     int digest_check;
-    int counter_check;
+    int fatal_counter_check;
     int last_check;
     int dont_care;
     int hit = 0;
     char *hex;
+    OPENPTS_FSM_Subvertex  *curr_state;
+    OPENPTS_FSM_Transition *trans;
     OPENPTS_FSM_Transition *hit_trans = NULL;
+    TSS_PCR_EVENT *event;
 
     DEBUG_CAL("updateFsm - start\n");
 
+    /* check */
+    if (ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+    if (fsm == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+
+    curr_state = fsm->curr_state;
     if (curr_state == NULL) {
         DEBUG_FSM("[RM%02d-PCR%02d] updateFsm() - curr_state == NULL => set the FSM state to 'Start'\n",
             fsm->level, fsm->pcr_index);
         curr_state = getSubvertex(fsm, "Start");
     }
+    trans = fsm->fsm_trans;
 
     /* Null event ->  push FSM until Final state */
     // TODO(munetoh) dummy event does not need event. just add flag to the wrapper
@@ -843,7 +1052,7 @@ int updateFsm(
 
         /* dummy wrapper */
         eventWrapper = (OPENPTS_PCR_EVENT_WRAPPER *)
-            malloc(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
+            xmalloc_assert(sizeof(OPENPTS_PCR_EVENT_WRAPPER));
         memset(eventWrapper, 0, sizeof(OPENPTS_PCR_EVENT_WRAPPER));
         eventWrapper->event_type = OPENPTS_DUMMY_EVENT;
         eventWrapper->push_count = 0;
@@ -852,14 +1061,14 @@ int updateFsm(
         /*  push */
         rc = updateFsm(ctx, fsm, eventWrapper);
         if (rc == OPENPTS_FSM_ERROR) {
-            ERROR("updateFsm() - updateFsm push was fail\n");
+            LOG(LOG_ERR, "updateFsm() - updateFsm push was fail\n");
         }
         if (rc == OPENPTS_FSM_ERROR_LOOP) {
             // DEBUG("updateFsm -- updateFsm push - loop \n");
         }
 
         /* free dummy wrapper */
-        free(eventWrapper);
+        xfree(eventWrapper);
         eventWrapper = NULL;
         return rc;
     } else if (eventWrapper->event == NULL) {
@@ -875,7 +1084,7 @@ int updateFsm(
                 return OPENPTS_FSM_ERROR_LOOP;
             }
         } else {
-           ERROR("missing event body\n");
+           LOG(LOG_ERR, "missing event body\n");
            return OPENPTS_FSM_ERROR;
         }
     } else {
@@ -887,12 +1096,12 @@ int updateFsm(
         fsm->level, fsm->pcr_index,
         curr_state->name, curr_state->action);
 
-    if ((event != NULL) && (verbose & DEBUG_FSM_FLAG)) {
+    if ((event != NULL) && isDebugFlagSet(DEBUG_FSM_FLAG)) {
         hex = getHexString(event->rgbPcrValue, event->ulPcrValueLength);
         DEBUG_FSM("[RM%02d-PCR%02d] eventtype=0x%x, digest=0x%s\n",
             fsm->level, fsm->pcr_index,
             event->eventType, hex);
-        free(hex);
+        xfree(hex);
     }
 
     if (eventWrapper->event_type == OPENPTS_DUMMY_EVENT) {
@@ -955,7 +1164,7 @@ int updateFsm(
                     if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
                         rc = OPENPTS_FSM_FINISH;
                     } else {
-                        ERROR("updateFsm - flash FSM was failed\n");
+                        LOG(LOG_ERR, "updateFsm - flash FSM was failed\n");
                         rc = OPENPTS_FSM_ERROR;
                     }
                 } else if (rc == OPENPTS_FSM_TRANSIT) {
@@ -967,14 +1176,14 @@ int updateFsm(
                     if  (rc == OPENPTS_FSM_FINISH_WO_HIT) {
                         rc = OPENPTS_FSM_TRANSIT;
                     } else {
-                        ERROR("updateFsm - FSM did not finish\n");
+                        LOG(LOG_ERR, "updateFsm - FSM did not finish\n");
                         rc = OPENPTS_FSM_ERROR;
                     }
                 } else if (rc == OPENPTS_FSM_ERROR) {
-                    ERROR("updateFsm - FSM doActivity False\n");
+                    LOG(LOG_ERR, "updateFsm - FSM doActivity False\n");
                     return rc;
                 } else if (rc == OPENPTS_FSM_MIGRATE_EVENT) {
-                    TODO("updateFsm - OPENPTS_FSM_MIGRATE_EVENT \n");
+                    LOG(LOG_TODO, "updateFsm - OPENPTS_FSM_MIGRATE_EVENT \n");
                     return rc;
                 } else if (rc == OPENPTS_FSM_SUCCESS) {
                     rc = updateFsm(ctx, fsm, eventWrapper);
@@ -982,12 +1191,12 @@ int updateFsm(
                     // TODO  << INFO:(TODO) action.c:97 addBIOSAction() - eventWrapper is NULL
                     rc = updateFsm(ctx, fsm, eventWrapper);
                 } else {
-                    TODO("updateFsm() - rc = %d, call updateFsm() again\n", rc);
+                    LOG(LOG_TODO, "updateFsm() - rc = %d, call updateFsm() again\n", rc);
                     rc = updateFsm(ctx, fsm, eventWrapper);
                 }
             }  // curr state
         } else {  // hit
-            TODO("no trans\n");
+            LOG(LOG_TODO, "no trans\n");
         }
     } else {
         /* check trans chain */
@@ -1074,7 +1283,8 @@ int updateFsm(
                         digest_check = -1;
                         // DEBUG_FSM("- invalid\n");
                     }
-                } else if (trans->digestFlag == DIGEST_FLAG_IGNORE) {
+                } else if (trans->digestFlag == DIGEST_FLAG_IGNORE ||
+                           trans->digestFlag == DIGEST_FLAG_TRANSPARENT) {
                     /* Behavior Model */
                     // DEBUG_FSM("digest - ignore\n");
                     digest_check = 2;
@@ -1085,54 +1295,69 @@ int updateFsm(
                 }
 
                 /* check the counter */
-                counter_check = 3;
-                if (trans->counter_flag == COUNTER_FLAG_LT) {
+                fatal_counter_check = 3;
+                if (trans->fatal_counter_flag == COUNTER_FLAG_LT) {
                     /* count < name */
-                    int count;
-                    count = getCountFromProperty(ctx, trans->counter_name);
+                    int fatal_count = getCountFromProperty(ctx, trans->fatal_counter_name);
 
-                    if (ctx->count < count) {
-                        DEBUG_FSM("COUNTER[%s] %d < %d - HIT\n",
-                            trans->counter_name, ctx->count, count);
-                        counter_check = 1;  // HIT
+                    if (fatal_count < 0) {
+                        LOG(LOG_ERR, "getCountFromProperty() fail");
+                    } else if (ctx->count < fatal_count) {
+                        DEBUG_FSM("FATAL COUNTER %d < %d - HIT\n", ctx->count, fatal_count);
+                        fatal_counter_check = 1;  // HIT
                     } else {
-                        DEBUG_FSM("COUNTER[%s] %d < %d - MISS\n",
-                            trans->counter_name, ctx->count, count);
-                        counter_check = -1;  // MISS
+                        DEBUG_FSM("FATAL COUNTER %d < %d - MISS\n", ctx->count, fatal_count);
+                        fatal_counter_check = -1;  // MISS
                     }
-
-                } else if (trans->counter_flag == COUNTER_FLAG_GTE) {
+                } else if (trans->fatal_counter_flag == COUNTER_FLAG_GE) {
                     /* count >= name */
-                    int count;
-                    count = getCountFromProperty(ctx, trans->counter_name);
+                    int fatal_count = getCountFromProperty(ctx, trans->fatal_counter_name);
 
                     // TODO at this moment we ignore >= condition,
-                    if (ctx->count >= count) {
-                        DEBUG_FSM("[RM%02d-PCR%02d] COUNTER[%s] %d >=  %d - HIT\n",
-                            fsm->level, fsm->pcr_index,
-                            trans->counter_name,
-                            ctx->count, count);
-                        counter_check = 1;  // HIT
+                    if (fatal_count < 0) {
+                        LOG(LOG_ERR, "getCountFromProperty() fail");
+                    } else if (ctx->count >= fatal_count) {
+                        DEBUG_FSM("FATAL COUNTER %d >= %d - HIT\n", ctx->count, fatal_count);
+                        fatal_counter_check = 1;  // HIT
                     } else {
-                        DEBUG_FSM("COUNTER[%s] %d >=  %d - MISS\n",
-                            trans->counter_name, ctx->count, count);
-                        counter_check = -1;  // MISS
+                        DEBUG_FSM("FATAL COUNTER %d >= %d - MISS\n", ctx->count, fatal_count);
+                        fatal_counter_check = -1;  // MISS
                     }
                 } else {
                     // DEBUG_FSM("counter - don't care\n");
                 }
 
+                if (trans->counter_flag != COUNTER_FLAG_SKIP) {
+                    int thisCount = 1 + trans->event_num;
+                    int maxCount = getCountFromProperty(ctx, trans->counter_name);
+                    if (maxCount < 0) {
+                        LOG(LOG_ERR, "getCountFromProperty() fail, trans->counter_flag=%d", trans->counter_flag);
+                    } else if (trans->counter_flag == COUNTER_FLAG_GE &&
+                        thisCount >= maxCount) {
+                        DEBUG_FSM("DIGEST COUNTER %d >= %d ('%s') - digest is transparent\n",
+                            thisCount, maxCount, trans->counter_name);
+                        eventWrapper->transparent = 1;
+                    } else if (trans->counter_flag == COUNTER_FLAG_LT &&
+                               thisCount < maxCount) {
+                        DEBUG_FSM("DIGEST COUNTER %d < %d ('%s') - digest is transparent\n",
+                            thisCount, maxCount, trans->counter_name);
+                        eventWrapper->transparent = 1;
+                    }
+                }
 
                 /* Judge */
                 // if ((type_check == 1) && (digest_check == 1)) {
-                if ((type_check > 0) && (digest_check > 0) && (counter_check > 0) && (last_check > 0)) {
+                if ((type_check > 0) &&
+                    (digest_check > 0) &&
+                    (fatal_counter_check > 0) &&
+                    (last_check > 0)) {
                     /* Hit this Trans */
                     /* If Final state, switch to next snapshot */
                     if (!strcmp(trans->target, UML2_SD_FINAL_STATE_STRING)) {
                         /* Final state */
                         DEBUG_FSM("\tPCR[%d] level %d, Final state!! move to the next snapshot\n",
                             fsm->pcr_index, fsm->level);
-                        // ERROR("PCR[%d] level %d, Final\n", fsm->pcr_index, fsm->level);
+                        // LOG(LOG_ERR, "PCR[%d] level %d, Final\n", fsm->pcr_index, fsm->level);
                         fsm->status = OPENPTS_FSM_FINISH;
                         return OPENPTS_FSM_FINISH_WO_HIT;  // FINAL
                     }
@@ -1141,6 +1366,8 @@ int updateFsm(
                     eventWrapper->fsm_trans = trans;
                     trans->event = (void *) event;   // note) hold the last link of looped trans
                     trans->event_num++;  // # of shared trans > 1
+                    DEBUG_FSM("[RM%02d-PCR%02d] trans->event_num = %d\n",
+                        fsm->level, fsm->pcr_index, (int)trans->event_num);
                     hit = 1;
 
                     /* next trans */
@@ -1164,7 +1391,7 @@ int updateFsm(
                                 if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
                                     rc = OPENPTS_FSM_FINISH;
                                 } else {
-                                    ERROR("flash FSM was failed\n");
+                                    LOG(LOG_ERR, "flash FSM was failed\n");
                                     rc = OPENPTS_FSM_ERROR;
                                 }
                             } else if (rc == OPENPTS_FSM_TRANSIT) {
@@ -1176,33 +1403,35 @@ int updateFsm(
                                 if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
                                     rc = OPENPTS_FSM_TRANSIT;
                                 } else {
-                                    ERROR("updateFsm - FSM did not finish\n");
+                                    LOG(LOG_ERR, "updateFsm - FSM did not finish\n");
                                     rc = OPENPTS_FSM_ERROR;
                                 }
                             } else if (rc == OPENPTS_FSM_ERROR) {
                                 DEBUG("updateFsm - doActivity error\n");
                                 // INFO("FSM validation of doActivity() was failed.
                                 // (FSM state = %s)\n",fsm->curr_state->name);
-                                addReason(ctx, "[PCR%02d-FSM] action '%s' fail at state '%s'",
+                                addReason(ctx, fsm->pcr_index, NLS(MS_OPENPTS, OPENPTS_FSM_ACTION_FAILED,
+                                               "[PCR%02d-FSM] The action '%s' failed at state '%s'"),
                                     fsm->pcr_index, (char *)fsm->curr_state->action, fsm->curr_state->name);
                                 return rc;
                             } else if (rc == OPENPTS_FSM_MIGRATE_EVENT) {
-                                TODO("updateFsm - OPENPTS_FSM_MIGRATE_EVENT \n");
+                                LOG(LOG_TODO, "updateFsm - OPENPTS_FSM_MIGRATE_EVENT \n");
                                 return rc;
                             } else if (rc == OPENPTS_FSM_SUCCESS) {
                                 rc = updateFsm(ctx, fsm, eventWrapper);
                             } else {
-                                TODO("rc = %d\n", rc);
+                                LOG(LOG_TODO, "rc = %d\n", rc);
                                 rc = updateFsm(ctx, fsm, eventWrapper);
                             }
                         }
                         break;
                     } else {
                         /* Trans */
-                        DEBUG_FSM("[RM%02d-PCR%02d] %s -> %s - HIT (type=%d, digest=%d) <== new curr_state\n",
+                        DEBUG_FSM("[RM%02d-PCR%02d] %s -> %s - HIT (type=%d, digest=%d)\n",
                             fsm->level, fsm->pcr_index,
-                            trans->source, trans->target, type_check, digest_check);
-
+                            trans->source,
+                            trans->target,
+                            type_check, digest_check);
                         fsm->curr_state = getSubvertex(fsm, trans->target);
 
                         if (fsm->curr_state != NULL) {
@@ -1218,7 +1447,7 @@ int updateFsm(
                                 if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
                                     rc = OPENPTS_FSM_FINISH;
                                 } else {
-                                    ERROR("updateFsm - flash FSM was failed, rc = %d\n", rc);
+                                    LOG(LOG_ERR, "updateFsm - flash FSM was failed, rc = %d\n", rc);
                                     rc = OPENPTS_FSM_ERROR;
                                 }
                             } else if (rc == OPENPTS_FSM_TRANSIT) {
@@ -1230,11 +1459,11 @@ int updateFsm(
                                 if (rc == OPENPTS_FSM_FINISH_WO_HIT) {
                                     rc = OPENPTS_FSM_TRANSIT;
                                 } else {
-                                    ERROR("updateFsm - FSM did not finish\n");
+                                    LOG(LOG_ERR, "updateFsm - FSM did not finish\n");
                                     rc = OPENPTS_FSM_ERROR;
                                 }
                             } else if (rc == OPENPTS_FSM_ERROR) {
-                                ERROR("updateFsm - FSM doActivity False, rc = %d\n", rc);
+                                LOG(LOG_ERR, "updateFsm - FSM doActivity False, rc = %d\n", rc);
                                 return rc;
                             } else if (rc == OPENPTS_FSM_MIGRATE_EVENT) {
                                 // DEBUG("updateFsm - OPENPTS_FSM_MIGRATE_EVENT \n");
@@ -1247,7 +1476,7 @@ int updateFsm(
                                 rc = OPENPTS_FSM_SUCCESS;
                             }
                         } else {
-                            ERROR("curr_state is NULL\n");
+                            LOG(LOG_ERR, "curr_state is NULL, missing %s\n", trans->target);
                             rc = OPENPTS_FSM_ERROR;
                             return rc;
                         }
@@ -1283,12 +1512,10 @@ int updateFsm(
  *   called from rm.c
  */
 OPENPTS_FSM_CONTEXT *copyFsm(OPENPTS_FSM_CONTEXT *src_fsm) {
-    OPENPTS_FSM_CONTEXT * dst_fsm = NULL;
-
+    OPENPTS_FSM_CONTEXT    *dst_fsm = NULL;
     OPENPTS_FSM_Subvertex  *src_fsm_sub;
     OPENPTS_FSM_Subvertex  *dst_fsm_sub = NULL;
     OPENPTS_FSM_Subvertex  *dst_fsm_sub_prev = NULL;
-
     OPENPTS_FSM_Transition *src_fsm_trans;
     OPENPTS_FSM_Transition *dst_fsm_trans = NULL;
     OPENPTS_FSM_Transition *dst_fsm_trans_prev = NULL;
@@ -1297,15 +1524,15 @@ OPENPTS_FSM_CONTEXT *copyFsm(OPENPTS_FSM_CONTEXT *src_fsm) {
 
     DEBUG_FSM("copyFsm - start, PCR[%d]\n", src_fsm->pcrIndex);
 
+    /* check */
     if (src_fsm == NULL) {
         DEBUG("src_fsm == NULL, SKIP COPY\n");
         return NULL;
     }
 
     /* New FSM */
-    dst_fsm = (OPENPTS_FSM_CONTEXT *) malloc(sizeof(OPENPTS_FSM_CONTEXT));
+    dst_fsm = (OPENPTS_FSM_CONTEXT *) xmalloc(sizeof(OPENPTS_FSM_CONTEXT));
     if (dst_fsm  == NULL) {
-        ERROR("copyFsm - no memory\n");
         return NULL;
     }
     memcpy((void *)dst_fsm, (void *)src_fsm, sizeof(OPENPTS_FSM_CONTEXT));
@@ -1317,14 +1544,14 @@ OPENPTS_FSM_CONTEXT *copyFsm(OPENPTS_FSM_CONTEXT *src_fsm) {
     count = 0;
     src_fsm_sub = src_fsm->fsm_sub;
     if (src_fsm_sub == NULL) {
-        ERROR("ERROR No FSM SUB\n");
+        LOG(LOG_ERR, "ERROR No FSM SUB\n");
         goto error;
     }
 
     while (src_fsm_sub != NULL) {
         /* malloc new sub */
         dst_fsm_sub = (OPENPTS_FSM_Subvertex *)
-            malloc(sizeof(OPENPTS_FSM_Subvertex));
+            xmalloc_assert(sizeof(OPENPTS_FSM_Subvertex));
         /* copy */
         memcpy((void *)dst_fsm_sub,
                (void *)src_fsm_sub,
@@ -1355,14 +1582,14 @@ OPENPTS_FSM_CONTEXT *copyFsm(OPENPTS_FSM_CONTEXT *src_fsm) {
     src_fsm_trans = src_fsm->fsm_trans;
 
     if (src_fsm_trans == NULL) {
-        ERROR("ERROR No FSM TRANS\n");
+        LOG(LOG_ERR, "ERROR No FSM TRANS\n");
         goto error;
     }
 
     while (src_fsm_trans != NULL) {
         /* malloc new sub */
         dst_fsm_trans = (OPENPTS_FSM_Transition *)
-            malloc(sizeof(OPENPTS_FSM_Transition));
+            xmalloc_assert(sizeof(OPENPTS_FSM_Transition));
         /* copy */
         memcpy((void *)dst_fsm_trans,
                (void *)src_fsm_trans,
@@ -1383,7 +1610,7 @@ OPENPTS_FSM_CONTEXT *copyFsm(OPENPTS_FSM_CONTEXT *src_fsm) {
         if (src_fsm_sub != NULL) {
             dst_fsm_trans->source_subvertex = src_fsm_sub->link;
         } else {
-            ERROR("ERROR BHV trans %s source_subvertex is NULL\n",
+            LOG(LOG_ERR, "ERROR BHV trans %s source_subvertex is NULL\n",
                 src_fsm_trans->source);
         }
 
@@ -1408,7 +1635,7 @@ OPENPTS_FSM_CONTEXT *copyFsm(OPENPTS_FSM_CONTEXT *src_fsm) {
 
   error:
     if (dst_fsm != NULL) {
-        free(dst_fsm);
+        xfree(dst_fsm);
     }
     return NULL;
 }
@@ -1436,9 +1663,24 @@ int changeTargetSubvertex(
         OPENPTS_FSM_Subvertex *old_sub,    // B
         OPENPTS_FSM_Subvertex *new_sub) {  // BN
     int rc = 0;
-    OPENPTS_FSM_Transition *fsm_trans;
     int count = 0;
+    OPENPTS_FSM_Transition *fsm_trans;
+
+    /* check */
+    if (fsm_ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+    if (old_sub == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+    if (new_sub == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
 
+    /* */
     fsm_trans = fsm_ctx->fsm_trans;
 
     /* check all trans to B */
@@ -1478,9 +1720,24 @@ int changeTransTargetSubvertex(
         OPENPTS_FSM_Subvertex *old_sub,    // B
         OPENPTS_FSM_Subvertex *new_sub) {  // BN
     int rc = 0;
-    OPENPTS_FSM_Transition *fsm_trans;
     int count = 0;
+    OPENPTS_FSM_Transition *fsm_trans;
 
+    /* check */
+    if (fsm_ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+    if (old_sub == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+    if (new_sub == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+
+    /* */
     fsm_trans = fsm_ctx->fsm_trans;
 
     /* check all trans to B */
@@ -1555,9 +1812,9 @@ int insertFsmNew(
         OPENPTS_FSM_Transition *fsm_trans,  // target Trans
         OPENPTS_PCR_EVENT_WRAPPER *eventWrapper) {
     int rc =0;
-    OPENPTS_FSM_Subvertex *prev_sub;  // STRUCT LINK
-    OPENPTS_FSM_Subvertex *new_sub;
-    OPENPTS_FSM_Subvertex *dst_sub;
+    OPENPTS_FSM_Subvertex  *prev_sub;  // STRUCT LINK
+    OPENPTS_FSM_Subvertex  *new_sub;
+    OPENPTS_FSM_Subvertex  *dst_sub;
     OPENPTS_FSM_Transition *prev_trans;  // STRUCT LINK
     OPENPTS_FSM_Transition *new_trans;
     TSS_PCR_EVENT *event;
@@ -1565,28 +1822,35 @@ int insertFsmNew(
     DEBUG_FSM("insertFsm - start\n");
 
     /* check input */
+    if (fsm_ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return -1;
+    }
     if (fsm_trans == NULL) {
-        ERROR("ERROR fsm_trans == NULL\n");
+        LOG(LOG_ERR, "null input");
         return -1;
     }
-    if (fsm_trans->source_subvertex == NULL) {
-        ERROR("ERROR fsm_trans->source_subvertex == NULL, %s -> %s\n",
-            fsm_trans->source, fsm_trans->target);
+    if (eventWrapper == NULL) {
+        LOG(LOG_ERR, "null input");
         return -1;
     }
-    if (fsm_trans->target_subvertex == NULL) {
-        ERROR("ERROR fsm_trans->target_subvertex == NULL\n");
+    event = eventWrapper->event;
+    if (event == NULL) {
+        LOG(LOG_ERR, "null input");
         return -1;
     }
 
-    if (eventWrapper == NULL) {
+    if (fsm_trans->source_subvertex == NULL) {
+        LOG(LOG_ERR, "ERROR fsm_trans->source_subvertex == NULL, %s -> %s\n",
+            fsm_trans->source, fsm_trans->target);
+        return -1;
+    }
+    if (fsm_trans->target_subvertex == NULL) {
+        LOG(LOG_ERR, "ERROR fsm_trans->target_subvertex == NULL\n");
         return -1;
     }
 
     /* start */
-
-    event = eventWrapper->event;
-
     if (fsm_trans->source_subvertex == fsm_trans->target_subvertex) {
         /* OK, this is LOOP,  */
         DEBUG_FSM("Loop (%s->%s) has %d events\n",
@@ -1596,11 +1860,9 @@ int insertFsmNew(
         dst_sub = fsm_trans->target_subvertex;
 
         /* Add new subvertex, BN (->B) */
-
         new_sub = (OPENPTS_FSM_Subvertex *)
-            malloc(sizeof(OPENPTS_FSM_Subvertex));
+            xmalloc(sizeof(OPENPTS_FSM_Subvertex));
         if (new_sub == NULL) {
-            ERROR("no memory");
             return -1;
         }
         /* copy */
@@ -1644,9 +1906,8 @@ int insertFsmNew(
 
             /* malloc */
             new_trans = (OPENPTS_FSM_Transition*)
-                malloc(sizeof(OPENPTS_FSM_Transition));
+                xmalloc(sizeof(OPENPTS_FSM_Transition));
             if (new_trans == NULL) {
-                ERROR("no memory");
                 return -1;
             }
             /* copy */
@@ -1686,14 +1947,18 @@ int insertFsmNew(
             fsm_trans->copy_num++;
 
             /* Copy digest value to trans  */
-            new_trans->digestFlag = DIGEST_FLAG_EQUAL;
-            new_trans->digestSize = event->ulPcrValueLength;
-            new_trans->digest = malloc(event->ulPcrValueLength);
-            if (new_trans->digest == NULL) {
-                ERROR("no memory\n");
-                return -1;
+            if (0 == eventWrapper->transparent) {
+                new_trans->digestFlag = DIGEST_FLAG_EQUAL;
+                new_trans->digestSize = event->ulPcrValueLength;
+                new_trans->digest = xmalloc(event->ulPcrValueLength);
+                if (new_trans->digest == NULL) {
+                    return -1;
+                }
+                memcpy(new_trans->digest, event->rgbPcrValue, event->ulPcrValueLength);
+            } else {
+                DEBUG_FSM("Changing digestFlag == DIGEST_FLAG_TRANSPARENT\n");
+                new_trans->digestFlag = DIGEST_FLAG_TRANSPARENT;
             }
-            memcpy(new_trans->digest, event->rgbPcrValue, event->ulPcrValueLength);
 
             DEBUG_FSM("new  Trans BIN(%s -> %s)\n",
                       new_trans->source, new_trans->target);
@@ -1709,24 +1974,29 @@ int insertFsmNew(
                      "%s", new_sub->id);
 
             /* Copy digest value to FSM */
-            fsm_trans->digestFlag = DIGEST_FLAG_EQUAL;
-            fsm_trans->digestSize = event->ulPcrValueLength;
-            fsm_trans->digest = malloc(event->ulPcrValueLength);
-            if (fsm_trans->digest == NULL) {
-                ERROR("no memory\n");
-                return -1;
+            if (0 == eventWrapper->transparent) {
+                fsm_trans->digestFlag = DIGEST_FLAG_EQUAL;
+                fsm_trans->digestSize = event->ulPcrValueLength;
+                fsm_trans->digest = xmalloc(event->ulPcrValueLength);
+                if (fsm_trans->digest == NULL) {
+                    return -1;
+                }
+                memcpy(fsm_trans->digest, event->rgbPcrValue, event->ulPcrValueLength);
+            } else {
+                fsm_trans->digestFlag = DIGEST_FLAG_TRANSPARENT;
             }
-            memcpy(fsm_trans->digest, event->rgbPcrValue, event->ulPcrValueLength);
 
             // DEBUG_FSM("\tupdate Trans %p->%p->%p\n",
             //          fsm_trans->prev, fsm_trans, fsm_trans->next);
             DEBUG_FSM("\tUpdate Trans BIN(%s -> %s)\n",
                       fsm_trans->source, fsm_trans->target);
         } else {
-            ERROR("BAD LOOP\n");
+            LOG(LOG_ERR, "BAD LOOP");
+            return PTS_FATAL;
         }
     } else {
-        ERROR("Not a loop");
+        LOG(LOG_ERR, "Not a loop");
+        return PTS_FATAL;
     }
 
     DEBUG_FSM("insertFsm - done\n");
@@ -1744,6 +2014,17 @@ int removeFsmTrans(
     OPENPTS_FSM_Transition * trans_prev;
     OPENPTS_FSM_Transition * trans_next;
 
+    /* check */
+    if (fsm_ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+    if (trans == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+
+    /* save */
     trans_prev = trans->prev;
     trans_next = trans->next;
 
@@ -1760,8 +2041,6 @@ int removeFsmTrans(
         //
     }
 
-    // TODO(munetoh) Free
-
     return rc;
 }
 
@@ -1773,10 +2052,20 @@ int removeFsmSub(
         OPENPTS_FSM_CONTEXT *fsm_ctx,
         OPENPTS_FSM_Subvertex * sub) {
     int rc =0;
-
     OPENPTS_FSM_Subvertex * sub_prev;
     OPENPTS_FSM_Subvertex * sub_next;
 
+    /* check */
+    if (fsm_ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+    if (sub == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
+
+    /* save */
     sub_prev = sub->prev;
     sub_next = sub->next;
 
@@ -1809,13 +2098,13 @@ int cleanupFsm(OPENPTS_FSM_CONTEXT *fsm_ctx) {
     int hit;
     OPENPTS_FSM_Transition * trans;
     OPENPTS_FSM_Transition * trans_next;
-
     OPENPTS_FSM_Subvertex * sub;
     OPENPTS_FSM_Subvertex * sub_next;
 
+    /* check */
     if (fsm_ctx == NULL) {
-        ERROR("ERROR No FSM TRANS\n");
-        return -1;
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
     }
 
     DEBUG_FSM("cleanupFsm - start, PCR[%d]\n", fsm_ctx->pcrIndex);
@@ -1825,7 +2114,7 @@ int cleanupFsm(OPENPTS_FSM_CONTEXT *fsm_ctx) {
     trans = fsm_ctx->fsm_trans;
 
     if (trans == NULL) {
-        ERROR("ERROR No FSM TRANS\n");
+        LOG(LOG_ERR, "ERROR No FSM TRANS\n");
         return -1;
     }
 
@@ -1837,7 +2126,7 @@ int cleanupFsm(OPENPTS_FSM_CONTEXT *fsm_ctx) {
                       trans->source, trans->target);
             rc = removeFsmTrans(fsm_ctx, trans);  // remove Trans
             if (rc < 0) {
-                ERROR("removeFsmTrans of %s -> %s was failed\n",
+                LOG(LOG_ERR, "removeFsmTrans of %s -> %s was failed\n",
                       trans->source, trans->target);
                 return -1;
             }
@@ -1854,7 +2143,7 @@ int cleanupFsm(OPENPTS_FSM_CONTEXT *fsm_ctx) {
     /* Delete state which does not have incomming trans */
     sub = fsm_ctx->fsm_sub;
     if (sub == NULL) {
-        ERROR("ERROR No FSM SUB\n");
+        LOG(LOG_ERR, "ERROR No FSM SUB\n");
         return -1;
     }
 
@@ -1909,7 +2198,7 @@ int cleanupFsm(OPENPTS_FSM_CONTEXT *fsm_ctx) {
     trans = fsm_ctx->fsm_trans;
 
     if (trans == NULL) {
-        printf("ERROR No FSM TRANS\n");
+        LOG(LOG_ERR, "No FSM TRANS\n");
         return -1;
     }
 
@@ -1938,16 +2227,6 @@ int cleanupFsm(OPENPTS_FSM_CONTEXT *fsm_ctx) {
     return rc;
 }
 
-
-
-
-
-
-
-
-
-
-
 /**
  * write DOT State Diagram for Graphviz
  * dot -Tpng tests/bios_pcr0.dot -o tests/bios_pcr0.png; eog tests/bios_pcr0.png
@@ -1970,15 +2249,16 @@ int writeDotModel(OPENPTS_FSM_CONTEXT *ctx, char * filename) {
 
     /* check */
     if (ctx == NULL) {
-        ERROR("writeDotModel() - OPENPTS_FSM_CONTEXT is NULL\n");
-        return PTS_INTERNAL_ERROR;
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
     }
 
+    /* check filename, open */
     if (filename == NULL) {
         fp = stdout;
     } else {
         if ((fp = fopen(filename, "w")) == NULL) {
-            ERROR("fopen fail %s\n", filename);
+            LOG(LOG_ERR, "fopen fail %s\n", filename);
             return PTS_OS_ERROR;
         }
     }
@@ -2064,8 +2344,12 @@ int writeCsvTable(OPENPTS_FSM_CONTEXT *ctx, char * filename) {
     OPENPTS_FSM_Transition *ptr;
 
     /* check */
+    if (ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return -1;
+    }
     if (filename == NULL) {
-        ERROR("writeCsvTable - filename is NULL\n");
+        LOG(LOG_ERR, "writeCsvTable - filename is NULL\n");
         return -1;
     }
 
@@ -2090,12 +2374,14 @@ int writeCsvTable(OPENPTS_FSM_CONTEXT *ctx, char * filename) {
         }
 
 
-        if (ptr->digestFlag == 1) {
+        if (ptr->digestFlag == DIGEST_FLAG_EQUAL) {
             fprintf(fp, "digest==0x");
             // for (i=0;i<DIGEST_SIZE;i++) fprintf(fp,"%02x",ptr->digest[i]);
             fprintf(fp, ",");
-        } else if (ptr->digestFlag == 2) {
-            fprintf(fp, "digest==base64,");
+        } else if (ptr->digestFlag == DIGEST_FLAG_IGNORE) {
+            fprintf(fp, "digest==base64!,");
+        } else if (ptr->digestFlag == DIGEST_FLAG_TRANSPARENT) {
+            fprintf(fp, "digest==transparent!,");
         } else {
             fprintf(fp, ",");
         }
@@ -2120,40 +2406,49 @@ int printFsmModel(OPENPTS_FSM_CONTEXT *ctx) {
     int i, j;
     OPENPTS_FSM_Transition *ptr;
 
-    printf("ctx->transition_num = %d\n", ctx->transition_num);
+    /* check */
+    if (ctx == NULL) {
+        LOG(LOG_ERR, "null input");
+        return PTS_FATAL;
+    }
 
-    printf("trans\t\tcurrent state\t\t\tcondition\t\t\\ttnext state\n");
-    printf("  id  \t\t\t\t\ttype(hex)\tdigest(hex)\n");
-    printf("----------------------------------------------------------------------------------------------\n");
+    OUTPUT(NLS(MS_OPENPTS, OPENPTS_PRINT_FSM_HEADER,
+           "ctx->transition_num = %d\n"
+           "trans\t\tcurrent state\t\t\tcondition\t\t\\ttnext state\n"
+           "  id  \t\t\t\t\ttype(hex)\tdigest(hex)\n"), ctx->transition_num);
+    OUTPUT("----------------------------------------------------------------------------------------------\n");
 
 
     ptr = ctx->fsm_trans;
     for (i = 0; i < ctx->transition_num; i++) {
         if (ptr == NULL) {
-            ERROR("PTR is NULL at %d\n", i);
-            return -1;
+            LOG(LOG_ERR, "PTR is NULL at %d\n", i);
+            return PTS_FATAL;
         }
-        printf("%5d ", i);
-        printf("%30s ", getSubvertexName(ctx, ptr->source));
+        OUTPUT("%5d ", i);
+        OUTPUT("%30s ", getSubvertexName(ctx, ptr->source));
 
         if (ptr->eventTypeFlag == 1) {
-            printf(" 0x%08x  ", ptr->eventType);
+            OUTPUT(" 0x%08x  ", ptr->eventType);
         } else if (ptr->eventTypeFlag == 1) {
-            printf("!0x%08x  ", ptr->eventType);
+            OUTPUT("!0x%08x  ", ptr->eventType);
         } else {
-            printf("             ");
+            OUTPUT("             ");
         }
 
-        if (ptr->digestFlag == 1) {
-            printf("0x");
-            for (j = 0; j < ptr->digestSize; j++) printf("%02x", ptr->digest[j]);
-            printf(" ");
-        } else if (ptr->digestFlag == 2) {
-            printf("base64                                     ");
+        if (ptr->digestFlag == DIGEST_FLAG_EQUAL) {
+            OUTPUT("0x");
+            for (j = 0; j < ptr->digestSize; j++) OUTPUT("%02x", ptr->digest[j]);
+            OUTPUT(" ");
+        } else if (ptr->digestFlag == DIGEST_FLAG_IGNORE) {
+            OUTPUT(NLS(MS_OPENPTS, OPENPTS_PRINT_FSM_BASE64, "base64                                     "));
+        } else if (ptr->digestFlag == DIGEST_FLAG_TRANSPARENT) {
+            /* WORK NEEDED: say transparent here? */
+            OUTPUT("                                           ");
         } else {
-            printf("                                           ");
+            OUTPUT("                                           ");
         }
-        printf("%-30s\n", getSubvertexName(ctx, ptr->target));
+        OUTPUT("%-30s\n", getSubvertexName(ctx, ptr->target));
 
         ptr = ptr->next;
     }
@@ -2161,14 +2456,3 @@ int printFsmModel(OPENPTS_FSM_CONTEXT *ctx) {
     return rc;
 }
 
-
-
-
-
-
-
-
-
-
-
-