// // Created by xajhuang on 2023/4/12. // #include #include #include "common.h" #include "main.h" #include "misc.h" #include "task_manager.h" #include "user_errno.h" #include "zlog_module.h" #include "dhcp_network.h" #define ZLOG_CFG_PATH "./config/zlog.conf" static GtkBuilder *g_mainBuilder = NULL; static PDHCP_INFO g_pDhcpInfo = NULL; static GThread *g_pEvLoopThread = NULL; static GThread *g_pDHCPSTMThread = NULL; static int g_runTask = FALSE; U32 rand_number() { GRand *pRand = g_rand_new_with_seed(time(NULL)); return g_rand_int(pRand); } PDHCP_INFO get_dhcp_info_by_id(U32 xid) { PDHCP_INFO pInfo; U32 index = xid & 0x00FFFFFF; HASH_FIND_INT(g_pDhcpInfo, &index, pInfo); return pInfo; } static void load_css(void) { GtkCssProvider *provider; GdkDisplay *display; GdkScreen *screen; GFile *css_fp = g_file_new_for_path("./res/style.css"); GError *error = 0; provider = gtk_css_provider_new(); display = gdk_display_get_default(); screen = gdk_display_get_default_screen(display); gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); gtk_css_provider_load_from_file(provider, css_fp, &error); } static double calc_total_progress(PDHCP_INFO pInfo) { double pre_cnt = 0.0; if (pInfo) { pre_cnt += pInfo->step * 20; pre_cnt += pInfo->status * 5; } return pre_cnt; } static gboolean calc_step_progress(PDHCP_INFO pInfo, DHCP_STEP step) { if (pInfo && pInfo->step >= step) { return TRUE; } return FALSE; } static void tree_view_data_store_create() { int i, j; PDHCP_INFO pInfo, pTemp; GtkTreeIter iter, iter_child, iter_sub; GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); GtkListStore *store = GTK_LIST_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); gtk_list_store_clear(store); HASH_ITER(hh, g_pDhcpInfo, pInfo, pTemp) { char mac[24] = {0}; sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", pInfo->mac[0], pInfo->mac[1], pInfo->mac[2], pInfo->mac[3], pInfo->mac[4], pInfo->mac[5]); gtk_list_store_append(store, &iter); // clang-format off gtk_list_store_set(store, &iter, COL_INDEX, pInfo->index, COL_MAC, mac, COL_HOSTNAME, pInfo->hostname, COL_DISCOVER, calc_step_progress(pInfo, STEP_DISCOVER), COL_OFFER, calc_step_progress(pInfo, STEP_OFFER), COL_REQUEST, calc_step_progress(pInfo, STEP_REQUEST), COL_ACK, calc_step_progress(pInfo, STEP_ACK), COL_RESULT, "", COL_STATUS, calc_total_progress(pInfo), COL_ATTR_EDITABLE, FALSE, -1); // clang-format on } gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); #if 0 for (i = 0; i < 1000; i++) { char buf[24] = {0}; char bufHost[32] = {0}; char bufVni[16] = {0}; sprintf(bufVni, "%d", i); sprintf(bufHost, "hostname%d", i); sprintf(buf, "06:01:02:%02X:%02X:%02X", (i & 0xFF0000) >> 16, (i & 0xFF00) >> 8, (i & 0xFF)); gtk_tree_store_append(store, &iter, NULL); // clang-format off gtk_tree_store_set(store, &iter, COL_INDEX, bufVni, COL_MAC, buf, COL_HOSTNAME, bufHost, COL_STATUS, 20.0, -1); gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_set(store, &iter_child, COL_INDEX, "", COL_STEP, "Discover", COL_RESULT, "", COL_STATUS, 10.0, -1); gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_set(store, &iter_child, COL_INDEX, "", COL_STEP, "Offer", COL_RESULT, "", COL_STATUS, 10.0, -1); gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_set(store, &iter_child, COL_INDEX, "", COL_STEP, "Request", COL_RESULT, "", COL_STATUS, 10.0, -1); gtk_tree_store_append(store, &iter_child, &iter); gtk_tree_store_set(store, &iter_child, COL_INDEX, "", COL_STEP, "ACK", COL_RESULT, "", COL_STATUS, 10.0, -1); // clang-format on } #endif //g_object_unref(store); } static gboolean tree_view_data_store_upgade(gpointer pInfo) { char buf[32] = {0}; GtkTreePath *path; GtkTreeIter iter; GtkListStore *store = GTK_LIST_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); if (!pInfo) { return FALSE; } sprintf(buf, "%d", ((PDHCP_INFO)pInfo)->index); if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, buf)) { // clang-format off gtk_list_store_set(store, &iter, COL_DISCOVER, calc_step_progress(pInfo, STEP_DISCOVER), COL_OFFER, calc_step_progress(pInfo, STEP_OFFER), COL_REQUEST, calc_step_progress(pInfo, STEP_REQUEST), COL_ACK, calc_step_progress(pInfo, STEP_ACK), COL_RESULT, "", COL_STATUS, calc_total_progress(pInfo), COL_ATTR_EDITABLE, FALSE, -1); // clang-format on } return TRUE; } G_MODULE_EXPORT void __mainWnd_on_destroy(GObject *object, gpointer user_data) { task_manager_exit(); g_thread_unref(g_pEvLoopThread); gtk_main_quit(); } int cacheDhcpOfferBuffer(PDHCP_INFO pInfo, U8 *pBuf, int size) { pInfo->pOfferBuf.p = (U8 *)malloc(size); if (pInfo->pOfferBuf.p) { memcpy(pInfo->pOfferBuf.p, pBuf, size); pInfo->pOfferBuf.buf_size = size; return ERR_SUCCESS; } return -ERR_MALLOC_MEMORY; } static void *dhcpThreadCb(void *pData) { U8 *pkg; int size = 0; PDHCP_INFO pInfo, pTemp; while (TRUE) { if (!g_runTask) { g_usleep(1000); continue; } HASH_ITER(hh, g_pDhcpInfo, pInfo, pTemp) { switch (pInfo->step) { case STEP_BEGIN: pInfo->pDiscBuf.p = dhcp_create_discover_req(pInfo, &size); if (pInfo->pDiscBuf.p) { pInfo->pDiscBuf.buf_size = size; pInfo->step = STEP_DISCOVER; pInfo->status = STA_WAIT_START; g_idle_add(tree_view_data_store_upgade, pInfo); } break; case STEP_DISCOVER: if (pInfo->status == STA_WAIT_START) { pkg = get_pkg_free_buf(); if (pkg) { memcpy(pkg, pInfo->pDiscBuf.p, pInfo->pDiscBuf.buf_size); if (pkg_mmap_tx((U8 *)pkg, pInfo->pDiscBuf.buf_size) == pInfo->pDiscBuf.buf_size) { pInfo->status = STA_SEND_REQ; g_idle_add(tree_view_data_store_upgade, pInfo); } } } break; case STEP_OFFER: if (pInfo->status == STA_RECV_RSP) { pInfo->pReqBuf.p = dhcp_create_request_req(pInfo, &size); if (pInfo->pReqBuf.p) { pInfo->pReqBuf.buf_size = size; pInfo->step = STEP_REQUEST; pInfo->status = STA_WAIT_START; g_idle_add(tree_view_data_store_upgade, pInfo); } } break; case STEP_REQUEST: if (pInfo->status == STA_WAIT_START) { pkg = get_pkg_free_buf(); if (pkg) { memcpy(pkg, pInfo->pReqBuf.p, pInfo->pReqBuf.buf_size); if (pkg_mmap_tx((U8 *)pkg, pInfo->pReqBuf.buf_size) == pInfo->pReqBuf.buf_size) { pInfo->status = STA_SEND_REQ; g_idle_add(tree_view_data_store_upgade, pInfo); } } } break; case STEP_ACK: break; case STEP_END: break; } } g_usleep(100); } LOG_MSG(debug, "DHCP status mathine exit......\n"); g_thread_exit(NULL); return NULL; } static void cleanupDHCPInfo() { PDHCP_INFO pInfo, pTemp; HASH_ITER(hh, g_pDhcpInfo, pInfo, pTemp) { HASH_DEL(g_pDhcpInfo, pInfo); if (pInfo->pOfferBuf.p) { free(pInfo->pOfferBuf.p); } if (pInfo->pDiscBuf.p) { free(pInfo->pDiscBuf.p); } if (pInfo->pReqBuf.p) { free(pInfo->pReqBuf.p); } if (pInfo->pAckBuf.p) { free(pInfo->pAckBuf.p); } free(pInfo); } } G_MODULE_EXPORT void __mainWnd_on_tb_start(GObject *object, gpointer user_data) { int i; GtkTreeIter iter; PDHCP_INFO pInfo; GtkTreeModel *cobModel; gchar *pCobText; unsigned char mac[6]; U32 macVal; GtkWidget *stopButton = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStop")); GtkWidget *nicSelect = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "cbNicName")); GtkWidget *macBegin = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtMacStart")); GtkWidget *preHostname = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtHostname")); GtkWidget *vniStart = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVni")); GtkWidget *numRequest = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbReqNum")); const char *strMacBegin = gtk_entry_get_text(GTK_ENTRY(macBegin)); const char *strPreHostname = gtk_entry_get_text(GTK_ENTRY(preHostname)); U32 nRequest = (U32)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(numRequest)); U32 nVni = (U32)gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(vniStart)); string_mac_to_bytes(strMacBegin, mac); macVal = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; cleanupDHCPInfo(); for (i = 0; i < nRequest; i++) { char strMac[6]; U32 macAddr = macVal + i; pInfo = (PDHCP_INFO)malloc(sizeof(DHCP_INFO)); if (pInfo == NULL) { fprintf(stderr, "Malloc %lu bytes memory error of %d\n", sizeof(DHCP_INFO), i); continue; } memset(pInfo, 0, sizeof(DHCP_INFO)); pInfo->index = i; pInfo->vni = nVni + i; pInfo->mac[0] = mac[0]; pInfo->mac[1] = mac[1]; pInfo->mac[2] = (macAddr & 0xFF000000) >> 24; pInfo->mac[3] = (macAddr & 0xFF0000) >> 16; pInfo->mac[4] = (macAddr & 0xFF00) >> 8; pInfo->mac[5] = (macAddr & 0xFF); sprintf(pInfo->hostname, "%s_%u", strPreHostname, pInfo->vni); pInfo->step = STEP_BEGIN; pInfo->status = STA_WAIT_START; HASH_ADD_INT(g_pDhcpInfo, index, pInfo); } gtk_widget_set_sensitive(GTK_WIDGET(object), FALSE); gtk_widget_set_sensitive(nicSelect, FALSE); tree_view_data_store_create(); gtk_widget_set_sensitive(stopButton, TRUE); cobModel = gtk_combo_box_get_model(GTK_COMBO_BOX(nicSelect)); gtk_combo_box_get_active_iter(GTK_COMBO_BOX(nicSelect), &iter); gtk_tree_model_get(cobModel, &iter, 0, &pCobText, -1); dhcp_tools_init_network(pCobText); g_runTask = TRUE; } G_MODULE_EXPORT void __mainWnd_on_tb_stop(GObject *object, gpointer user_data) { GtkWidget *startButton = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStart")); GtkWidget *nicSelect = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "cbNicName")); // PDHCP_INFO pInfo; // GRand *pRnd = g_rand_new_with_seed(time(NULL)); // unsigned int val = g_rand_int(pRnd) % 100; // // HASH_FIND_INT(g_pDhcpInfo, &val, pInfo); // // if (pInfo) { // tree_view_data_store_upgade(pInfo); // printf("Upgrade treeview row %u\n", val); // } printf("__mainWnd_on_tb_stop\n"); g_runTask = FALSE; //g_thread_join(g_pDHCPSTMThread); gtk_widget_set_sensitive(GTK_WIDGET(object), FALSE); gtk_widget_set_sensitive(startButton, TRUE); gtk_widget_set_sensitive(nicSelect, TRUE); } static void *uv_loop_thread(void *pData) { static uv_timer_t uvTm; task_manager_run(); return NULL; } int main(int args, char **argv) { int i, ret; GtkTreeIter iter; GList *pNicList = NULL; SYS_NIC_INFO info = {0}; if ((ret = zlog_init(ZLOG_CFG_PATH)) != ERR_SUCCESS) { printf("Zlog configure file [%s] init result: %d+++++\n", ZLOG_CFG_PATH, ret); zlog_profile(); return -ERR_ZLOG_INIT; } else { LOG_MOD(debug, ZLOG_MOD_INIT, "Zlog used configure file [%s]\n", ZLOG_CFG_PATH); dzlog_init(ZLOG_CFG_PATH, get_cur_process_name()); } get_all_network_info(&info); gtk_init(&args, &argv); load_css(); g_mainBuilder = gtk_builder_new(); gtk_builder_add_from_file(g_mainBuilder, "./res/main.glade", NULL); GtkWidget *mainWnd = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "wndMain")); g_signal_connect(mainWnd, "destroy", G_CALLBACK(__mainWnd_on_destroy), g_mainBuilder); GtkWidget *tbStart = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStart")); g_signal_connect(tbStart, "clicked", G_CALLBACK(__mainWnd_on_tb_start), g_mainBuilder); GtkWidget *tbStop = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "tbStop")); g_signal_connect(tbStop, "clicked", G_CALLBACK(__mainWnd_on_tb_stop), g_mainBuilder); GtkWidget *cbNic = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "cbNicName")); for (i = 0; i < info.nicCnt; i++) { GtkListStore *store = GTK_LIST_STORE(gtk_builder_get_object(g_mainBuilder, "lsNicName")); gtk_combo_box_set_model(GTK_COMBO_BOX(cbNic), GTK_TREE_MODEL(store)); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, info.pNicCtx[i].ethName, -1); if (i == info.nicCnt - 1) { gtk_combo_box_set_active(GTK_COMBO_BOX(cbNic), i); } } if (info.pNicCtx) { free(info.pNicCtx); } GtkWidget *macTxt = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtMacStart")); GtkWidget *numInc = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbReqNum")); GtkAdjustment *adj = gtk_adjustment_new(1, 1, 100000, 1, 0, 0); gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numInc), adj); GtkWidget *numVni = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVni")); GtkAdjustment *adjVni = gtk_adjustment_new(1, 1, 10000000, 1, 0, 0); gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numVni), adjVni); GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); #if 0 gtk_list_store_new(NUM_COLS, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_FLOAT); #endif gtk_builder_connect_signals(g_mainBuilder, NULL); //g_object_unref(G_OBJECT(g_mainBuilder)); gtk_widget_show(mainWnd); g_pEvLoopThread = g_thread_new("uv_loop", uv_loop_thread, NULL); g_pDHCPSTMThread = g_thread_new("dhcp", dhcpThreadCb, NULL); gtk_main(); return 0; }