#
#Disable Commands
#

#proc package {args} {
#	error "package is not supported by Catcher."
#}	
#proc load {args} {
#	error "load is not supported by Catcher."
#}	
proc exit {args} {
	error "Please use 'Exit' in the File Menu."
}
proc quit {args} {
	error "Please use 'Exit' in the File Menu."
}

#
#background errors
#
proc bgerror {args} {
	puts "Background Error"
	foreach msg $args {
	    puts $msg
	}
}

proc connect {args} {
	conn
}
proc disconnect {args} {
	disconn
}

#for query MMI Screen ID
proc qscrid {args} {
    conn
    logon MMI_L4C_SAP 4
    logon WAP_MMI_SAP 4
    
    cinst local_MSG_ID_TST_INJECT_STRING_1 tst_inject_string_struct  "{
    	ref_count = 0x1;
    	string\[0\] = 0x6d;
    	string\[10\] = 0x3f;
    	string\[1\] = 0x74;
    	string\[2\] = 0x6b;
    	string\[3\] = 0x2b;
    	string\[4\] = 0x73;
    	string\[5\] = 0x63;
    	string\[6\] = 0x72;
    	string\[7\] = 0x6e;
    	string\[8\] = 0x69;
    	string\[9\] = 0x64;
    };"
    
    cinst ilm_MSG_ID_TST_INJECT_STRING_1 ilmessage "{
    	src_mod_id = MOD_NIL;
    	dest_mod_id = MOD_MMI;
    	sap_id = INVALID_SAP;
    	msg_id = MSG_ID_TST_INJECT_STRING;
    	local_params.local_params_ptr = local_MSG_ID_TST_INJECT_STRING_1;
    	peer_buff.peer_buff_ptr = NULL;
    };"
        
    set bh [bwait msgcode==MSG_ID_MMI_INJECT_STRING_RSP {convert_mmi_scr_id 0x[getfldvalfromstream_local [getfldvalue waitMsgMSG_ID_MMI_INJECT_STRING_RSP local_params.local_params_ptr ilmessage] scrnid mmi_inject_string_rsp_struct]}]
    injectmsg ilm_MSG_ID_TST_INJECT_STRING_1
    after 500
    killbwait $bh        
}




#for l1v
proc l1v_testcase {case pattern patternsize} {    
    
    #foreach i [after info] {after cancel $i}
    deleteallwaitmsg
    cinst l1v_local ul1d_loopback_req_struct "{        
        test_id=1; case_id=$case; pattern_id=$pattern; pattern_size=$patternsize;        
    };"
    
    cinst l1v_ilm ilmessage "{
        src_mod_id = MOD_MPAL; dest_mod_id = MOD_MPAL; 
        sap_id = MPAL_L1_SAP; msg_id = MSG_ID_UL1D_LOOPBACK_REQ;
    	local_params.local_params_ptr = l1v_local; peer_buff.peer_buff_ptr = NULL;        
    };"
    
    set abort_handle [after 20000 {puts "Abort Timer Timeout!! Test Case Terminated!!";global g_e;set g_e 2}]
    puts "MSG_ID_UL1D_LOOPBACK_REQ --->|"
    after idle injectmsg l1v_ilm
    set xwaitid [xwait msgcode==MSG_ID_UL1D_LOOPBACK_RESULT_IND {puts "|-->MSG_ID_UL1D_LOOPBACK_RESULT_IND";global g_e;set g_e 1}]    
    vwait g_e
    #killallwait
    killxwait $xwaitid
    after cancel $abort_handle
    if {1 != [checkmsg waitMsgMSG_ID_UL1D_LOOPBACK_RESULT_IND_1]} then {error "Failed to wait MSG_ID_UL1D_LOOPBACK_RESULT_IND"}
    
    set localbuf [getfldvalue waitMsgMSG_ID_UL1D_LOOPBACK_RESULT_IND_1 local_params.local_params_ptr ilmessage]
    set ret_case [getfldvalfromstream_local $localbuf case_id ul1d_loopback_result_ind_struct]
    set ret_pattern [getfldvalfromstream_local $localbuf pattern_id ul1d_loopback_result_ind_struct]
    if {$ret_case != $case} then {error "Invalid Case ID Return!"}
    if {$ret_pattern != $pattern} then {error "Invalid Pattern ID Return!"}    
}

#for umts
proc ul1v_testcase {case pms szs ads} {
    
    #foreach i [after info] {after cancel $i}
    deleteallwaitmsg
    cinst l1v_local ul1d_loopback_req_struct "{ 
        ref_count=1;       
        test_id=2; case_id=$case;       
        pm = {$pms};
        sz = {$szs};
        ad = {$ads};                  
    };"
    
    cinst l1v_ilm ilmessage "{
        src_mod_id = MOD_URR; dest_mod_id = MOD_URR; 
        sap_id = UL1_UL1_SAP; msg_id = MSG_ID_UL1D_LOOPBACK_REQ;
    	local_params.local_params_ptr = l1v_local; peer_buff.peer_buff_ptr = NULL;        
    };"
    
    set abort_handle [after 20000 {puts "Abort Timer Timeout!! Test Case Terminated!!";global g_e;set g_e 2}]
    puts "MSG_ID_UL1D_LOOPBACK_REQ --->|"
    after idle injectmsg l1v_ilm
    set xwaitid [xwait msgcode==MSG_ID_UL1D_LOOPBACK_RESULT_IND {puts "|-->MSG_ID_UL1D_LOOPBACK_RESULT_IND";global g_e;set g_e 1}]
    vwait g_e
    #killallwait
    killxwait $xwaitid
    after cancel $abort_handle
    if {1 != [checkmsg waitMsgMSG_ID_UL1D_LOOPBACK_RESULT_IND_1]} then {error "Failed to wait MSG_ID_UL1D_LOOPBACK_RESULT_IND"}
    
    set localbuf [getfldvalue waitMsgMSG_ID_UL1D_LOOPBACK_RESULT_IND_1 local_params.local_params_ptr ilmessage]
    set ret_case [getfldvalfromstream_local $localbuf case_id ul1d_loopback_result_ind_struct]
    set ret_result [getfldvalfromstream_local $localbuf result ul1d_loopback_result_ind_struct]
    if {$ret_case != $case} then {error "Invalid Case ID $case Return!"}
    if {$ret_result == 0} then {
        global uL1vStopFlag
        if {$uL1vStopFlag == 1} then {error "$case: Target Return Fail!!"} else {puts "$case: Target Return Fail!"}
    }
            
}


proc read_file {filename} {

global PeerFilePath
set filename "$PeerFilePath\\$filename"
set fd [open $filename]
fconfigure $fd -translation binary
set buf [read $fd]
close $fd

global PeerFile_VarSubs
if {$PeerFile_VarSubs == 1} then {
	foreach i [info globals RunTime*] {global $i}
	set buf [subst $buf]
}
binary scan $buf c* tempbuf
set buf [string map {{ } {,}} $tempbuf]

return $buf

}

proc at_wait {com_port wait_command run_proc} {
    append atwait_listname atwait_list $com_port
    global $atwait_listname
    lappend $atwait_listname $wait_command
    
    append atproc_listname atproc_list $com_port
    global $atproc_listname
    lappend $atproc_listname $run_proc
}

proc process_atwait_list {com_port at_str} {

    append atwait_listname atwait_list $com_port
    global $atwait_listname
    
    if {0==[llength [subst $[subst $atwait_listname]]]} then {return 0}
    
    global exclue_at_command_list
    if {[lsearch -exact $exclue_at_command_list $at_str] != -1} then {
    	puts "$at_str is in exclue_at_command_list"
    	return [llength [subst $[subst $atwait_listname]]]
    }
    
    set first_ele [lindex [subst $[subst $atwait_listname]] 0]
    
    if {$first_ele == $at_str} then {
       puts "Match $at_str in $atwait_listname"
    } elseif {1==[string equal -length 7 $first_ele "RunTime"]} then {
       foreach i [info globals RunTime*] {global $i}
       puts "Assign $at_str to $first_ele"
       set $first_ele $at_str
    } else {return [llength [subst $[subst $atwait_listname]]]}    
    
    append atproc_listname atproc_list $com_port
    global $atproc_listname
    set first_ele [lindex [subst $[subst $atproc_listname]] 0]
    
    #remove the first element
    set $atwait_listname [lreplace [subst $[subst $atwait_listname]] 0 0]
    set $atproc_listname [lreplace [subst $[subst $atproc_listname]] 0 0]
    
    #run the procedure
    puts "Run: $first_ele"
    eval $first_ele
    
    return [llength [subst $[subst $atwait_listname]]]
 
}

proc read_com_port {com_port com_handle} {
	
    set read_buf [read $com_handle]
    if {[string bytelength $read_buf] != 0} then {
	append atrbufname atrbuf $com_port
	global $atrbufname    
	#append the last read
	set rbuf [subst $[subst $atrbufname]]
	    
	append rbuf $read_buf   
	set rbuf_size [string bytelength $rbuf]
	#if {$rbuf_size != 0} then { puts "read $com_port $rbuf_size:[string map {\xd _ \xa _} $rbuf]" }
	    
	set lf_count 0
	set lf_index 0
	set process_index 0
	for {set i 0} {$i<$rbuf_size} {incr i} {    	
	    if {[string index $rbuf $i] == "\xa"} then {
	    	incr lf_count
	    	if {$lf_count == 1} then {
	     	    set lf_index $i
	    	} elseif {$lf_count == 2} then {    	   
	       	    set process_index $i
	       	    set got_at_string [string range $rbuf [expr $lf_index+1] [expr $process_index-2]]
	       	    puts "Got $com_port: $got_at_string"
	       	    set ret [process_atwait_list $com_port $got_at_string]
	       	    if {$ret==0} {
	       	        puts "at_wait list empty. done!"
	       	        set $atrbufname ""
	       	        #prepare for next read!    
    			after 60 "read_com_port $com_port $com_handle"
	       	        return
	       	    }
	       	    set lf_count 0    	   	
	        }
	    } 
	    ##end if \xa   
	}
	##end for
	set $atrbufname [string range $rbuf [expr $process_index+1] end]
    }  
    ##end if read_buf
    
    #prepare for next read!    
    after 60 "read_com_port $com_port $com_handle"
}

proc repeat_fail_case {args} {  
		 	
	upvar $args params
	# proc parameters: msc_name msc_filepath reason_str msc_title
	set msc_name ""
	set msc_filepath ""
	set reason_str ""
	set msc_title ""
	set forcount 0   
	foreach i $params {	
		if {$forcount == 0} then {set msc_name $i} \
		elseif {$forcount == 1} then {set msc_filepath $i} \
		elseif {$forcount == 2} then {set reason_str $i} \
		elseif {$forcount == 3} then {set msc_title $i}		
		incr forcount
	}
	
	# Reset MoDIS
	global ResetMoDISPath;
	puts "$msc_name fail: $reason_str"	
  if {$ResetMoDISPath != ""} then {reset_MoDIS $reason_str;}
	
	# Repeat fail case	
	global RepeatTestWhenFailCount
	set count $RepeatTestWhenFailCount
	for {set idx 1} {$idx <= $count} {incr idx} {
    puts "Re-do $msc_name count: $idx\n"
		if {[catch {source $msc_filepath} redo_reason_str]} then {
		  if {$idx < $count} then {
	      # Fail, delay for next re-do
	      after 1000
	      puts "$msc_name fail: $redo_reason_str"
	      if {$ResetMoDISPath != ""} then {reset_MoDIS $redo_reason_str;}
      } else {
	      # Finally fail
			  global RedoCount;
			  set RedoCount $RepeatTestWhenFailCount;			
			  msc_list_nopass $msc_name $msc_filepath $redo_reason_str $msc_title;	# proc parameters: msc_name msc_filepath reason_str msc_title
			  return
      }
    } else {
    	# Pass   
    	global RedoCount;
    	set RedoCount $idx;
    	msc_list_pass $msc_name $msc_title;  # proc parameters: msc_name msc_title
      return
    }  	
   }   
}

proc reset_MoDIS {reason_str} {
	if {[string first {Please check the connection!} "$reason_str"]!= -1} {
		
		# Record in report
		global msc_list_report_fd
		puts $msc_list_report_fd "\"\",\"\",\"\",\"Re-Start MoDIS!! MoDIS may assert!!\",\"\""
		flush $msc_list_report_fd
		
		# Compose Restart_MoDIS.exe full path
        global Reset_MoDIS_EXE_Path
        if {$Reset_MoDIS_EXE_Path == ""} then {
    	    global Catcher_init_full_file_path
    	    set fullpathlen [string length $Catcher_init_full_file_path]
    	    set filenamelen [string length {Catcher_init.tcl}]	
    	    set Reset_MoDIS_EXE_Path [string replace $Catcher_init_full_file_path [expr $fullpathlen - $filenamelen] $fullpathlen {Restart_MoDIS.exe}]  
    	}
	
		# Reset MoDIS
		global ResetMoDISPath;
		global ResetMoDISWaitTime;		
		forkp "\"$Reset_MoDIS_EXE_Path\" -Restart_MoDIS \"$ResetMoDISPath\""
		puts "MoDIS may assert!! Wait $ResetMoDISWaitTime milliseconds to re-start MoDIS:"
		puts $ResetMoDISPath
		puts "\r\n"
		after $ResetMoDISWaitTime
		puts "Re-start MoDIS is Done.\r\n"
	}

  return 0
}


proc msc_restart_MoDIS_nUT_begin {MoDISINIPath} {
    # Compose Restart_MoDIS.exe full path
    global Reset_MoDIS_EXE_Path
    if {$Reset_MoDIS_EXE_Path == ""} then {
	    global Catcher_init_full_file_path
	    set fullpathlen [string length $Catcher_init_full_file_path]
	    set filenamelen [string length {Catcher_init.tcl}]	
	    set Reset_MoDIS_EXE_Path [string replace $Catcher_init_full_file_path [expr $fullpathlen - $filenamelen] $fullpathlen {Restart_MoDIS.exe}]  
	}
	
	# Reset global variables
	global RestartMSCCount; set RestartMSCCount 0
    global TotalMSCCount; set TotalMSCCount 0 
    
    forkp "\"$Reset_MoDIS_EXE_Path\" -Set_INI_MoDIS_UI \"$MoDISINIPath\" NO"
}

proc msc_restart_MoDIS_nUT_end {MoDISINIPath} { 
    global Reset_MoDIS_EXE_Path
    forkp "\"$Reset_MoDIS_EXE_Path\" -Set_INI_MoDIS_UI \"$MoDISINIPath\" RESTORE"
}

proc msc_restart_MoDIS_eachUT {RestartMSCNum RestartMoDISPath RestartWaitTime} {
    global RestartMSCCount;   
    incr RestartMSCCount;    
    
    if {$RestartMSCCount > $RestartMSCNum} {
        puts "\r\n***Restarting MoDIS.exe for every $RestartMSCNum UT (Wait time: $RestartWaitTime): $RestartMoDISPath***"
    
        global Reset_MoDIS_EXE_Path
        forkp "\"$Reset_MoDIS_EXE_Path\" -Restart_MoDIS \"$RestartMoDISPath\""
        after $RestartWaitTime;
        set RestartMSCCount 1;
    }
    
    global TotalMSCCount;
    incr TotalMSCCount;
    puts "\r\n***MSC Count: #$TotalMSCCount ***\r\n"
}


proc fail_cmp_buf_info {pos1 pos2 type} {
  set FailInfo "\[Check Control Buffer Warning\]\[Fail\] Failed to compare $pos1 with $pos2 !\r\n"
   
  if {$type == "CTRLBUF"} then {
		global msc_list_check_ctrl_buf_info
		global msc_list_check_ctrl_buf_result
		
		set msc_list_check_ctrl_buf_result "FAIL"	  	
		append msc_list_check_ctrl_buf_info $FailInfo
	} elseif {$type == "FLCCTRLBUF"} then {
		global msc_list_check_flc_ctrl_buf_info
		global msc_list_check_flc_ctrl_buf_result
		
		set msc_list_check_flc_ctrl_buf_result "FAIL"	  	
		append msc_list_check_flc_ctrl_buf_info $FailInfo
	}
	
	puts $FailInfo
}

proc show_check_ctrl_buf_info {target_diff_num result_diff_num pos1 pos2 result_file msc_name} {
	
	global msc_list_check_ctrl_buf_info
	global msc_list_check_ctrl_buf_result 
	
	# Control buffer is check in this MSC
  if {$msc_list_check_ctrl_buf_result == "N/A"} then {
		set msc_list_check_ctrl_buf_result "PASS"
	}
	
	if {$target_diff_num == "Same"} then {
		if {[is_ccbu_result_same $result_diff_num $result_file] == 1} then {
			set result_diff_num "Same"
		}
	}
	
  if {$target_diff_num != $result_diff_num} then {
  	# Control buffer check fail
  	set msc_list_check_ctrl_buf_result "FAIL"
  	set FailInfo "\[Check Control Buffer\]\[Not match\]The control buffer difference number '$result_diff_num', between $pos1 and $pos2 in MSC $msc_name, can not match expected '$target_diff_num'!\r\nPlease check comparison result file $result_file!\r\n"  	
  	append msc_list_check_ctrl_buf_info $FailInfo
  	puts $FailInfo
  } else {
  	if {$msc_list_check_ctrl_buf_result == "N/A"} then {
			set msc_list_check_ctrl_buf_result "PASS"
		}
    set PassInfo "\[Check Control Buffer\]\[Match\]The control buffer difference number '$result_diff_num', between $pos1 and $pos2 in MSC $msc_name, matches expected '$target_diff_num'!\r\nThe comparison result file is $result_file!\r\n"  	
  	append msc_list_check_ctrl_buf_info $PassInfo  	
  	puts $PassInfo
  }
}

proc show_check_flc_ctrl_buf_info {target_diff_num result_diff_num pos1 pos2 result_file msc_name} {

	global msc_list_check_flc_ctrl_buf_info
	global msc_list_check_flc_ctrl_buf_result
	
	# FLC Control buffer is check in this MSC
	if {$msc_list_check_flc_ctrl_buf_result == "N/A"} then {
		set msc_list_check_flc_ctrl_buf_result "PASS"
	}
	
  if {$target_diff_num != $result_diff_num} then {
  	# FLC Control buffer check fail
  	set msc_list_check_flc_ctrl_buf_result "FAIL"
  	set FailInfo "\[Check Control Buffer\]\[Not match\]The FLC control buffer difference number '$result_diff_num', between $pos1 and $pos2 in MSC $msc_name, can not match expected '$target_diff_num'!\r\nPlease check comparison result file $result_file!\r\n"  	
  	append msc_list_check_flc_ctrl_buf_info $FailInfo
  	puts $FailInfo
  } else {
    if {$msc_list_check_flc_ctrl_buf_result == "N/A"} then {
			set msc_list_check_flc_ctrl_buf_result "PASS"
		}
    set PassInfo "\[Check Control Buffer\]\[Match\]The FLC control buffer difference number '$result_diff_num', between $pos1 and $pos2 in MSC $msc_name, matches expected '$target_diff_num'!\r\nThe comparison result file is $result_file!\r\n"  	
  	append msc_list_check_flc_ctrl_buf_info $PassInfo
  	puts $PassInfo
  }
}

proc incr_check_ctrl_buf_result_count {args} {
	global msc_list_check_ctrl_buf_result
	global msc_list_check_ctrl_buf_fail_count
	global msc_list_check_ctrl_buf_pass_count
	global msc_list_check_ctrl_buf_na_count
	
	if {$msc_list_check_ctrl_buf_result == "PASS"} then {
		incr msc_list_check_ctrl_buf_pass_count
	} elseif {$msc_list_check_ctrl_buf_result == "FAIL"} then {
		incr msc_list_check_ctrl_buf_fail_count
	}	elseif {$msc_list_check_ctrl_buf_result == "N/A"} then {
		incr msc_list_check_ctrl_buf_na_count
	}	
	
	#reset
	reset_check_ctrl_buf_flag
}

proc incr_check_flc_ctrl_buf_result_count {args} {
	global msc_list_check_flc_ctrl_buf_result
	global msc_list_check_flc_ctrl_buf_fail_count
	global msc_list_check_flc_ctrl_buf_pass_count
	global msc_list_check_flc_ctrl_buf_na_count
	
	if {$msc_list_check_flc_ctrl_buf_result == "PASS"} then {
		incr msc_list_check_flc_ctrl_buf_pass_count
	} elseif {$msc_list_check_flc_ctrl_buf_result == "FAIL"} then {
		incr msc_list_check_flc_ctrl_buf_fail_count
	}	elseif {$msc_list_check_flc_ctrl_buf_result == "N/A"} then {
		incr msc_list_check_flc_ctrl_buf_na_count
	}	
	
	#reset
	reset_check_flc_ctrl_buf_flag
}

proc reset_check_ctrl_buf_flag {args} {
	global msc_list_check_ctrl_buf_info
	global msc_list_check_ctrl_buf_result
  set msc_list_check_ctrl_buf_info ""
  set msc_list_check_ctrl_buf_result "N/A"
}

proc reset_check_flc_ctrl_buf_flag {args} {
	global msc_list_check_flc_ctrl_buf_info
	global msc_list_check_flc_ctrl_buf_result	
  set msc_list_check_flc_ctrl_buf_info ""
  set msc_list_check_flc_ctrl_buf_result "N/A"
}


proc check_fail_case {msc_file} {

#The procedure will be called for a fail case when running MSC Composer test case list
#Users can customize the tcl procedure and reload catcher again.
#for example reset target and run the test case again:

#rebootm
#if {[catch {source $msc_file} fid]} then {puts $fid; return 1}
#exec xxx.bat

#return 1 to stop running the remain cases
#return 0 to continue the remain cases
return 0

}

proc error_handler {msc_name count err_string } {

#The procedure will be called when a tcl error occured
#Users can customize the tcl procedure and reload catcher again.
#for example record the error in a csv file.

#set fr [open report.csv a+]
#puts $fr "\"$msc_name\",\"$count\",\"$err_string\""
#close $fr

#return 1 to stop the next round
#return 0 to continue the next round if exist
return 1

}

proc msc_list_init {} {
#for all.tcl and folder.tcl
#Users can customize these procedures: msc_list_xxx	

	 global msc_list_check_ctrl_buf_fail_count
	 global msc_list_check_ctrl_buf_pass_count
	 global msc_list_check_ctrl_buf_na_count
	 set msc_list_check_ctrl_buf_fail_count 0
   set msc_list_check_ctrl_buf_pass_count 0
   set msc_list_check_ctrl_buf_na_count 0
   
   global msc_list_check_flc_ctrl_buf_fail_count
	 global msc_list_check_flc_ctrl_buf_pass_count
	 global msc_list_check_flc_ctrl_buf_na_count
	 set msc_list_check_flc_ctrl_buf_fail_count 0
   set msc_list_check_flc_ctrl_buf_pass_count 0
   set msc_list_check_flc_ctrl_buf_na_count 0
   
   global msc_list_fail_count
   global msc_list_pass_count
   global msc_list_report_fd
   set msc_list_pass_count 0
   set msc_list_fail_count 0
   set msc_list_report_fd [open report.csv w]
   puts $msc_list_report_fd "\"MSC\",\"PASS\",\"FAIL\",\"REASON\",\"ENDTIME\",\"CTRLBUF_CHECK\",\"CTRLBUF_CHECK_INFO\",\"FLC_CTRLBUF_CHECK\",\"FLC_CTRLBUF_CHECK_INFO\""	
}

proc msc_list_pass {args} {
#for all.tcl and folder.tcl
#Users can customize these procedures: msc_list_xxx
	
	 # Compose redo_case_string for the repeated pass case
	 global RedoCount;
	 set redo_case_string ""
	 if {$RedoCount > 0} then {set redo_case_string "\r\n<Re-do test case for $RedoCount times>"; set RedoCount 0;}

	 # proc parameters: msc_name msc_title
   set msc_name ""
   set msc_title ""
   set forcount 0   
	 foreach i $args {	
	 	if {$forcount == 0} then {set msc_name $i} \
	 	elseif {$forcount == 1} then {set msc_title $i; if {[string length $msc_title] > 0} then {set msc_title "\r\n($msc_title)"};}	 	
	 	incr forcount
	 } 
	 
	 # Output result to report (Customizable)
	 global msc_list_check_ctrl_buf_info
	 global msc_list_check_ctrl_buf_result
	 global msc_list_check_flc_ctrl_buf_info
	 global msc_list_check_flc_ctrl_buf_result
   global msc_list_fail_count
   global msc_list_pass_count
   global msc_list_report_fd	
   set msc_list_end_time "[clock format [clock seconds] -format "%H:%M:%S %Y/%m/%d %a"]"   
   puts $msc_list_report_fd "\"$msc_name$msc_title$redo_case_string\",\"v\",\"\",\"\",\"$msc_list_end_time\",\"$msc_list_check_ctrl_buf_result\",\"$msc_list_check_ctrl_buf_info\",\"$msc_list_check_flc_ctrl_buf_result\",\"$msc_list_check_flc_ctrl_buf_info\""   
   flush $msc_list_report_fd

   # Increase pass-related counts
   incr msc_list_pass_count 1	   
   incr_check_ctrl_buf_result_count
   incr_check_flc_ctrl_buf_result_count
}

proc msc_list_nopass {args} {
#for all.tcl and folder.tcl
#Users can customize these procedures: msc_list_xxx		
		  
     # Check assert_resetm here for unexpected error
	 catch {assert_resetm}
	   
	 # Compose redo_case_string for the final repeated failed case
	 global RedoCount;
	 set redo_case_string ""	 
	 if {$RedoCount > 0} then {set redo_case_string "\r\n<Re-do test case for $RedoCount times>"; set RedoCount 0;} \
	 else {
	 	# Compose parameters to repeat the failed case
		set params ""
		foreach i $args {lappend params $i}
	 	global RepeatTestWhenFailCount
	 	if {$RepeatTestWhenFailCount > 0} then {repeat_fail_case params; return;}
	 }	 
	 
	 # Get proc parameters: msc_name msc_filepath reason_str msc_title
	 set msc_name ""
	 set msc_filepath ""
	 set reason_str ""
   set msc_title ""
   set forcount 0   
	 foreach i $args {	
	 	if {$forcount == 0} then {set msc_name $i} \
	 	elseif {$forcount == 1} then {set msc_filepath $i} \
	 	elseif {$forcount == 2} then {set reason_str $i} \
	 	elseif {$forcount == 3} then {set msc_title $i; if {[string length $msc_title] > 0} then {set msc_title "\r\n($msc_title)"};}	 	
	 	incr forcount
	 } 

	 # Output result to report (Customizable)
	 global msc_list_check_ctrl_buf_info
	 global msc_list_check_ctrl_buf_result
	 global msc_list_check_flc_ctrl_buf_info
	 global msc_list_check_flc_ctrl_buf_result
   global msc_list_fail_count
   global msc_list_pass_count
   global msc_list_report_fd
   set msc_list_end_time "[clock format [clock seconds] -format "%H:%M:%S %Y/%m/%d %a"]"
   puts "$msc_name fail: $reason_str"
   puts " "
   puts $msc_list_report_fd "\"$msc_name$msc_title$redo_case_string\",\"\",\"v\",\"$reason_str\",\"$msc_list_end_time\",\"$msc_list_check_ctrl_buf_result\",\"$msc_list_check_ctrl_buf_info\",\"$msc_list_check_flc_ctrl_buf_result\",\"$msc_list_check_flc_ctrl_buf_info\""
   flush $msc_list_report_fd
   if {[check_fail_case "$msc_filepath"]==1} then {close $msc_list_report_fd; return}
   
   # Increase fail-related counts
   incr msc_list_fail_count 1	   
   incr_check_ctrl_buf_result_count
   incr_check_flc_ctrl_buf_result_count
   
   # Reset MoDIS
   global ResetMoDISPath;
   if {$ResetMoDISPath != ""} then {reset_MoDIS $reason_str;}
   
   # Save failed clg file
   global AutoSaveFailClg
   if {$AutoSaveFailClg != 0} then {
   	set clgfilepath "$msc_filepath.clg"
   	puts "Saving $clgfilepath...\r\n"
   	logtofile $clgfilepath
   	after 1000
   }
   # Save TCL console text file
   global AutoSaveFailTCLText
   if {$AutoSaveFailTCLText != 0} then {
   	set tcltextfilepath "$msc_filepath.txt"
   	puts "Saving $tcltextfilepath...\r\n"
   	savetcltxt $tcltextfilepath
   	after 1000
   }
}

proc msc_list_result {} {
#for all.tcl and folder.tcl
#Users can customize these procedures: msc_list_xxx		

	 global msc_list_check_ctrl_buf_fail_count
	 global msc_list_check_ctrl_buf_pass_count
	 global msc_list_check_ctrl_buf_na_count
	 global msc_list_check_flc_ctrl_buf_fail_count
	 global msc_list_check_flc_ctrl_buf_pass_count
	 global msc_list_check_flc_ctrl_buf_na_count
   global msc_list_fail_count
   global msc_list_pass_count
   global msc_list_report_fd	
   puts $msc_list_report_fd "\"Total\",\"$msc_list_pass_count\",\"$msc_list_fail_count\",\"\",\"\",\"P/F/N:$msc_list_check_ctrl_buf_pass_count/$msc_list_check_ctrl_buf_fail_count/$msc_list_check_ctrl_buf_na_count\",\"\",\"P/F/N:$msc_list_check_flc_ctrl_buf_pass_count/$msc_list_check_flc_ctrl_buf_fail_count/$msc_list_check_flc_ctrl_buf_na_count\",\"\""
   close $msc_list_report_fd
   puts "PASS $msc_list_pass_count, FAIL $msc_list_fail_count"
   puts "Check Control Buffer: PASS/FAIL/(N/A): $msc_list_check_ctrl_buf_pass_count/$msc_list_check_ctrl_buf_fail_count/$msc_list_check_ctrl_buf_na_count"
   puts "Check FLC Control Buffer: PASS/FAIL/(N/A): $msc_list_check_flc_ctrl_buf_pass_count/$msc_list_check_flc_ctrl_buf_fail_count/$msc_list_check_flc_ctrl_buf_na_count"
   puts "Please read [pwd]/report.csv."	
}

#---Here are some flags. Users can modify these by themselves.
#for L1v & uL1v
set L1vPatternPath "U:\\tcl\\L1vPattern"
set L1vReportPath "U:\\tcl\\L1vReport"

set uL1vPatternPath "U:\\tcl\\uL1vPattern"
set uL1vStopFlag 0

#for peer file
set PeerFilePath "U:\\tcl\\PeerFile"
#set PeerFile_VarSubs 1 to substitute runtime variables in peer file
set PeerFile_VarSubs 0

#for auto re-start MoDIS
set ResetMoDISWaitTime 60000
#for example: set ResetMoDISPath {D:\mcu\MoDIS\MoDIS\Debug\MoDIS.exe}. empty {} means to disable this function.
set ResetMoDISPath {}

#for auto re-start MoDIS every N UT (no MoDIS_UI mode)
set Reset_MoDIS_EXE_Path {}
set RestartMSCCount 0
set TotalMSCCount 0

#for auto re-start target
set RestartTargetWaitTime 30000

#for auto save clg & TCL txt files: 0:off, 1:on
set AutoSaveFailClg 0
set AutoSaveFailTCLText 0

#for auto re-try failed test cases for RepeatTestWhenFailCount times
set RepeatTestWhenFailCount 0

#---Here are some initializations. Please do not modify.
set RedoCount 0
set exclue_at_command_list [list "ABC" "XYZ"]

set msc_list_fail_count 0
set msc_list_pass_count 0
set msc_list_report_fd  0

set msc_list_check_ctrl_buf_info ""
set msc_list_check_ctrl_buf_result	"N/A"
set msc_list_check_ctrl_buf_fail_count 0
set msc_list_check_ctrl_buf_pass_count 0
set msc_list_check_ctrl_buf_na_count 0

set msc_list_check_flc_ctrl_buf_info ""
set msc_list_check_flc_ctrl_buf_result	"N/A"
set msc_list_check_flc_ctrl_buf_fail_count 0
set msc_list_check_flc_ctrl_buf_pass_count 0
set msc_list_check_flc_ctrl_buf_na_count 0

set Catcher_init_full_file_path [info script];

#---Here are some customized tcl files. Users can add their own customized tcl files here by themselves.
#try to source autotest_init.tcl
if {[catch {source "autotest_init.tcl"} fid]} then {
  #autotest_init.tcl may not exist or failed to source
} else {
  puts "source autotest_init.tcl successfully!"
}


#try to source PS2_check_fail.tcl
if {[catch {source "PS2_check_fail.tcl"} fid]} then {
  #PS2_check_fail.tcl may not exist or failed to source
} else {
  puts "source PS2_check_fail.tcl successfully!"
}

#try to source PS3_check_fail.tcl
if {[catch {source "PS3_check_fail.tcl"} fid]} then {
  #PS3_check_fail.tcl may not exist or failed to source
} else {
  puts "source PS3_check_fail.tcl successfully!"
}

#try to source CS2_check_fail.tcl
if {[catch {source "CS2_check_fail.tcl"} fid]} then {
  #CS2_check_fail.tcl may not exist or failed to source
} else {
  puts "source CS2_check_fail.tcl successfully!"
}

#try to source Custom_init.tcl
if {[catch {source "Custom_init.tcl"} fid]} then {
  #Custom_init.tcl may not exist or failed to source
} else {
  puts "source Custom_init.tcl successfully!"
}
