#include "config.h" using namespace maix; using namespace maix::sys; using namespace maix::peripheral; kvm_sys_state_t kvm_sys_state; kvm_oled_state_t kvm_oled_state; void build_recovery(void) { uint8_t need_recovery = 0; if (access("/recovery", F_OK) != 0) { printf("unexist /recovery\n"); mkdir("/recovery", 0777); need_recovery = 1; } else { printf("exist /recovery\n"); } } void* thread_oled_handle(void * arg) { OLED_Init(); OLED_ColorTurn(0); //0正常显示 1 反色显示 OLED_DisplayTurn(0); //0正常显示 1 屏幕翻转显示 OLED_Clear(); if(kvm_oled_state.ue_patch_state == 1){ kvm_show_UE(); while(kvm_sys_state.oled_thread_running){ time::sleep_ms(100); } OLED_Clear(); } while(kvm_sys_state.oled_thread_running) { oled_auto_sleep(); // printf("[kvmd]thread_oled_handle - while\n"); uint8_t page_changed = (kvm_oled_state.page == kvm_sys_state.page)? 0:1; uint8_t subpage_changed = (kvm_oled_state.sub_page == kvm_sys_state.sub_page)? 0:1; // printf("subpage_changed = %d", subpage_changed); // printf("kvm_oled_state.sub_page = %d", kvm_oled_state.sub_page); // printf("kvm_sys_state.sub_page = %d\n", kvm_sys_state.sub_page); kvm_oled_state.page = kvm_sys_state.page; kvm_oled_state.sub_page = kvm_sys_state.sub_page; switch(kvm_oled_state.page){ case 0 : // main page kvm_main_ui_disp(page_changed, subpage_changed); break; case 1 : // wifi config page kvm_wifi_config_ui_disp(page_changed, subpage_changed); break; default: OLED_Clear(); } time::sleep_ms(OLED_DELAY); } OLED_Clear(); kvm_sys_state.oled_thread_running = -1; } void* thread_key_handle(void * arg) { uint64_t __attribute__((unused)) press_time; uint32_t press_cycle; int fd = open ("/dev/input/event0", O_RDONLY); if (fd == -1) { kvm_sys_state.key_thread_running = 0; } struct input_event event; while(kvm_sys_state.key_thread_running) { read (fd, &event, sizeof (event)); if (event.type == EV_KEY) { if (event.value == 1){ // printf ("[kvmk]按键按下\n"); press_time = time::time_ms(); } else if (event.value == 0){ oled_auto_sleep_time_update(); // printf ("[kvmk]按键抬起\n"); press_cycle = time::time_ms() - press_time; if(press_cycle >= KEY_LONGLONG_PRESS){ kvm_reset_password(); } else if (press_cycle >= KEY_LONG_PRESS && press_cycle < KEY_LONGLONG_PRESS){ // long // printf ("[kvmk]按键长按\n"); // printf("[kvmk]wifi_state = %d\n", kvm_sys_state.wifi_state); if(kvm_sys_state.wifi_state == -2){ kvm_sys_state.page = 0; kvm_sys_state.sub_page = 0; continue; } switch(kvm_sys_state.page){ case 0: // main page kvm_sys_state.page = 1; kvm_sys_state.sub_page = 0; break; case 1: // wifi coonfig page system("/etc/init.d/S30wifi restart"); kvm_sys_state.page = 0; kvm_sys_state.sub_page = 0; kvm_sys_state.wifi_config_process = -1; break; } } else { // short // printf ("[kvmk]按键短按\n"); // printf ("[kvmk]wifi_config_process = %d\n", kvm_sys_state.wifi_config_process); // printf ("[kvmk]page = %d\n", kvm_sys_state.page); // printf ("[kvmk]sub_page = %d\n", kvm_sys_state.sub_page); switch(kvm_sys_state.page){ case 0: // main page if(kvm_sys_state.sub_page == 0) kvm_sys_state.sub_page = 1; else kvm_sys_state.sub_page = 0; break; case 1: // wifi coonfig page switch(kvm_sys_state.wifi_config_process){ case 1: // QR1<->TEXT2 if(kvm_sys_state.sub_page == 1) kvm_sys_state.sub_page = 2; else kvm_sys_state.sub_page = 1; // printf("[kvmk]sub_page = %d\n", kvm_sys_state.sub_page); break; case 2: if(kvm_sys_state.sub_page == 1) kvm_sys_state.sub_page = 2; else if(kvm_sys_state.sub_page == 2) kvm_sys_state.sub_page = 3; else if(kvm_sys_state.sub_page == 3) kvm_sys_state.sub_page = 4; else kvm_sys_state.sub_page = 1; break; } break; } } } } time::sleep_ms(KEY_DELAY); } kvm_sys_state.key_thread_running = 0; } void* thread_sys_handle(void * arg) { get_ping_allow_state(); while(kvm_sys_state.sys_thread_running) { // net if(kvm_sys_state.page == 0){ kvm_update_eth_state(); kvm_update_wifi_state(); // kvm_update_rndis_state(); // kvm_update_tailscale_state(); // sys_state kvm_update_usb_state(); kvm_update_hdmi_state(); kvm_update_stream_fps(); kvm_update_hdmi_res(); kvm_update_stream_type(); kvm_update_stream_qlty(); kvm_wifi_web_config_process(); } else if(kvm_sys_state.page == 1){ kvm_wifi_config_process(); } time::sleep_ms(STATE_DELAY); auto_remove_temp_watchdog(); } kvm_sys_state.sys_thread_running = 0; } int main(int argc, char* argv[]) { // Catch SIGINT signal(e.g. Ctrl + C), and set exit flag to true. signal(SIGINT, [](int sig){ kvm_sys_state.oled_thread_running = 0; kvm_sys_state.key_thread_running = 0; kvm_sys_state.sys_thread_running = 0; app::set_exit_flag(true); log::info("[kvms]Prepare to exit\n"); }); pthread_t sys_state_thread; pthread_t display_thread; pthread_t key_thread; // Execute only when it's a new image if(access("/kvmapp/kvm_new_img", F_OK) == 0){ new_img_init(); } // Execute only when it's a new app if(access("/kvmapp/kvm_new_app", F_OK) == 0){ new_app_init(); } // only for production testing if (access("/tmp/S49kvmtest", F_OK) == 0){ printf("Production testing patch\n"); Production_testing_patch(); } system("sync"); OLED_state = oled_exist(); if(OLED_state){ printf("oled exist\r\n"); system("touch /etc/kvm/oled_exist"); } else { printf("oled not exist\r\n"); system("rm /etc/kvm/oled_exist"); } if(kvm_sys_state.sys_thread_running == 0){ kvm_sys_state.sys_thread_running = 1; if (0 != pthread_create(&sys_state_thread, NULL, thread_sys_handle, NULL)) { kvm_sys_state.sys_thread_running = 0; printf("[kvms]create thread failed!\r\n"); } } if(OLED_state == 1 && kvm_sys_state.oled_thread_running == 0){ kvm_sys_state.oled_thread_running = 1; if (0 != pthread_create(&display_thread, NULL, thread_oled_handle, NULL)) { kvm_sys_state.oled_thread_running = 0; printf("[kvms]create thread failed!\r\n"); } } if(kvm_sys_state.key_thread_running == 0){ kvm_sys_state.key_thread_running = 1; if (0 != pthread_create(&key_thread, NULL, thread_key_handle, NULL)) { kvm_sys_state.key_thread_running = 0; printf("[kvms]create thread failed!\r\n"); } } // while(!app::need_exit()){ uint8_t kvm_wd_count = 0; int kvm_wd_state = 0; while(kvm_sys_state.sys_thread_running){ time::sleep_ms(1000); if(watchdog_sf_is_open()){ kvm_wd_state = check_watchdog(); if(kvm_wd_state == 1) kvm_wd_count = 0; else if(kvm_wd_state == 0) { kvm_wd_count++; printf("Vision service unresponsive : %d\n", kvm_wd_count); } if(kvm_wd_count > KVM_WD_COUNT_MAX){ printf("Vision service unresponsive, restart now\n"); system("reboot"); } } else { kvm_wd_count = 0; } } kvm_sys_state.sys_thread_running = 0; kvm_sys_state.oled_thread_running = 0; kvm_sys_state.key_thread_running = 0; while(kvm_sys_state.oled_thread_running != -1) time::sleep_ms(100); }