anchor.diff:          (return-from run nil)))))
   
   (defun serial-run (serial comm result fail-result repeat)
  -  (loop while (>= repeat 0)
  -        do
  -           (serial-log-clear)
  -           (let ((r (serial-run-program serial comm result fail-result)))
  -             (if r
  -                 (progn
  -                   (serial-log-clear)
  -                   (return r)))
  -             (setq repeat (- repeat 1)))
  -        ))
  -
  -(defun serial-run-wait (serial comm result fail-result)
  +  (format t "run command: ~a ~%" comm)
  +  (when (wait-shell serial "" 10)
  +    (loop while (>= repeat 0)
  +          do
  +             (serial-log-clear)
  +             (let ((r (serial-run-program serial comm result fail-result)))
  +               (if r
  +                   (progn
  +                     (sleep 1)
  +                     (serial-log-clear)
  +                     (return r)))
  +               (setq repeat (- repeat 1)))
  +          )))
  +
  +(defun serial-run-wait (serial comm result fail-result &key error collect)
  +  ;;success return result
  +  ;;failed will rerun the command
  +  ;;error handle used work error happen,ensure need redo comm
  +  (format t "run command: ~a ~%" comm)
     (when (wait-shell serial "" 10)
       (serial-log-clear)
       (serial-force-output serial comm)
  
positive.code: (defvar *serial-log* nil)
  (defvar *loop-count* nil)
  (defvar *wdt-reset* nil)
  
  (setq *loop-count* 0)
  (setq *serial* (ccl::make-serial-stream "/dev/ttyUSB3"
  
negative.code:     (setq *wdt-reset* t)
      (format t "wdt reset found~%")))
  
  (defun shutdown-machine (serial)
    (format t "Now do reboot machine~%")
    (serial-run-wait serial "svc power shutdown" "" "shell@gladiator:/ #")
    )
  
  (defun search-key-by-name (key)
    (loop for entry in *key-list*
          do
             (when (search key (car entry) :test #'char-equal)
               (return entry))))
  
  (defun input-key-event (serial name)
    (let* ((key (search-key-by-name name))
           (comm nil))
      (when key
        (setq comm (format nil "input keyevent ~D" (cdr key)))
        (format t "input key ~a ~%" name)
        (serial-run-wait serial comm "shell@gladiator:/ #" nil)
        )))
  
  (defun top-activity (serial)
    (let* ((stack nil)
          (result (serial-run-wait serial
                                   "dumpsys activity activities |busybox grep \"* TaskRecord\""
                                   "shell@gladiator:/ " nil
                                   :collect #'(lambda (log)
                                                (mapcar #'(lambda (entry)
                                                            (when (search "* TaskRecord" entry :test #'char-equal)
                                                              (push entry stack))) log)
                                                ))))
      (when result
        (pop stack))))
  
  (defun start-activity (serial name result repeat)
    (loop while (> repeat 0)
          do
             (let* ((comm (format nil "am start -n ~a" name))
                   (ret (serial-run-wait serial comm "shell@gladiator:/ "
                                "Error: Activity" :error #'(lambda (err)
                                                      (when (search "Error: Activity" err :test #'char-equal)
                                                        (format t "Error: Activity~%")
                                                        nil
                                                        )))))
               (if (search "Error: Activity" ret :test #'char-equal )
                   (progn
                     (format t "~a not found,please check~%")
                     (return nil))
                   (progn
                     (sleep 5)
                     (when (search result (top-activity serial) :test #'char-equal)
                       (return result))
                     (format t "run app ~a [~a] failed~%" name result)
                     (setq repeat (- repeat 1)))
                   ))
          ))
  
  (defun serial-run-app (serial name result)
    ;;nil run app failed
    ;;name, run app name
    (let ((current (top-activity serial)))
      (if (search name current :test #'char-equal)
          (progn
            (format t "~a is running on~%" name)
            name)
          (progn
            (when (start-activity serial name result 5)
              name
              )))
      ))
  
  (defun find-app (name)
    (loop for app in *activity-list*
          do
             (when (search name (car app) :test #'char-equal)
               (return (cadr app)))))
  
  (defun run-app (serial name)
    (let ((app (find-app name)))
      (when app
          (serial-run-app serial (car app) (cdr app)))
      )
    )
  
  (defun get-random-from-list (list)
    (let* ((state (make-random-state t))
           (n (random (length list) state)))
      (nth n list)
      ))
  
  (defun random-number (n)
    (let ((state (make-random-state t)))
      (+ 1 (random n state))))
  
  (defun run-test-case (serial)
    (let* ((case (get-random-from-list *test-case*))
           (app (car case))
           (key-list (cadr case))
           (period (caddr case))
           (repeat (random-number (cadddr case))))
      (format t "run test case ~a period ~D repeat ~D~%" app period repeat)
      (when (run-app serial app)
        (loop repeat repeat
              do
                 (sleep (random-number period))
                 (input-key-event serial (get-random-from-list key-list))
                 (sleep (random-number period))
              ))))
  
  (defun start-serial-test (serial)
    (format t "Start Test~%")
    (loop repeat 3
          do
             (run-test-case serial))
    (sleep 10)
    (input-key-event serial "Home")
    (shutdown-machine serial)
    )
  
  (defun wdt-save-log (serial)
    (let* ((save-file (format nil "/data/logs-~a"
                              (get-universal-time)))
           (prepare (format nil "mkdir -p ~a" save-file))
           (comm (format nil "busybox cp /data/log ~a -rf" save-file)))
      (serial-run serial prepare "shell@gladiator:/ #" "1|shell@gladiator:/ " 10)
      (serial-run serial comm "shell@gladiator:/ #" "1|shell@gladiator:/ " 10)
      )
    )
  
  (defun bootfinish-callback (serial str result fail-result)
    (serial-run serial "su" "shell@gladiator:/ #" "shell@gladiator:/ $" 60)
    (serial-run serial "getprop | grep dev.bootcomplete" result fail-result 60)
  
    (when  *wdt-reset*
      (wdt-save-log serial)
      )
    (start-serial-test serial)
    )
  
  (defun mboot-callback (serial str result fail-result)
    (serial-force-output serial "reset"))
  
  (defun serial-loop (serial)
    (let ((str (serial-log-get -1)))
  