From f680e4c4148f8c0e5290d1b2b92038263069395f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E6=98=95?= Date: Thu, 27 Apr 2023 15:11:34 +0800 Subject: [PATCH] =?UTF-8?q?OCT=201.=20DHCP=20=E6=B5=8B=E8=AF=95=E5=B7=A5?= =?UTF-8?q?=E5=85=B7=E6=94=AF=E6=8C=81=E8=AF=A6=E7=BB=86=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E6=9F=A5=E7=9C=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dhcp_tools/detail_wnd.c | 336 ++++++++++++++++++++++++++++++ dhcp_tools/main.h | 39 ++-- dhcp_tools/main_wnd.c | 149 +++++++++---- dhcp_tools/res/detail.glade | 210 +++++++++++++++++++ dhcp_tools/res/style.css | 4 + srcs/service/dhcpd/db_interface.c | 1 - 6 files changed, 690 insertions(+), 49 deletions(-) create mode 100644 dhcp_tools/detail_wnd.c create mode 100644 dhcp_tools/res/detail.glade diff --git a/dhcp_tools/detail_wnd.c b/dhcp_tools/detail_wnd.c new file mode 100644 index 0000000..42c9bd4 --- /dev/null +++ b/dhcp_tools/detail_wnd.c @@ -0,0 +1,336 @@ +// +// Created by HuangXin on 2023/4/26. +// +#include +#include "main.h" +#include "zlog_module.h" +#include "dhcp_network.h" +#include "sds/sds.h" + +static GtkWidget *g_detailWnd = NULL; + +#if 0 +static void dhcp_details_store_create(GtkBuilder *builder) { + int i, j; + PDHCP_INFO pInfo, pTemp; + GtkTreeIter iter, iter_child; + GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(builder, "tvDiscDhcp")); + GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(builder, "lsDhcpInfo")); + + gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); + gtk_tree_store_clear(store); + + // 创建根节点 + gtk_tree_store_append(store, &iter, NULL); + // clang-format off + gtk_tree_store_set(store, + &iter, + COL_DHCP_ITEM, "name", + COL_DHCP_VALUE, "", + COL_ITEM_ATTR_VISIABLE, TRUE, + COL_VALUE_ATTR_VISIABLE, FALSE, + -1); + // clang-format on + gtk_tree_store_append(store, &iter_child, &iter); + + // clang-format off + // 创建子节点 + gtk_tree_store_set(store, + &iter_child, + COL_DHCP_VALUE, "", + COL_ITEM_ATTR_VISIABLE, FALSE, + COL_VALUE_ATTR_VISIABLE, TRUE, + -1); + // clang-format on + gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); +} + + +void details_wnd_create(void *b) { + GtkBuilder *builder = gtk_builder_new(); + gtk_builder_add_from_file(builder, "./res/detail.glade", NULL); + + GtkWidget *deatilWnd = GTK_WIDGET(gtk_builder_get_object(builder, "wndDetails")); + GtkWidget *panDisc = GTK_WIDGET(gtk_builder_get_object(builder, "hbDisc")); + GtkWidget *tab = GTK_WIDGET(gtk_builder_get_object(builder, "nbDetails")); + GtkWidget *labDisc = GTK_WIDGET(gtk_builder_get_object(builder, "labDiscover")); + GtkWidget *labAck = GTK_WIDGET(gtk_builder_get_object(builder, "labAck")); + GtkWidget *scAck = GTK_WIDGET(gtk_builder_get_object(builder, "scAck")); + + gtk_container_add(GTK_CONTAINER(deatilWnd), tab); // 笔记本放进窗口 + gtk_notebook_append_page(GTK_NOTEBOOK(tab), panDisc, labDisc); + gtk_notebook_append_page(GTK_NOTEBOOK(tab), scAck, labAck); + + g_signal_connect(G_OBJECT(deatilWnd), "delete_event", G_CALLBACK(delete_event), builder); + g_signal_connect(G_OBJECT(deatilWnd), "show", G_CALLBACK(show), builder); + + gtk_builder_connect_signals(builder, NULL); + //gtk_widget_show(deatilWnd); +} +#endif + +static GtkTextBuffer *g_pTxtBuf[4]; +static GtkWidget *g_ptvDHcp[4]; +static GtkWidget *g_ptvHex[4]; + +static gboolean delete_event(GtkWidget *widget, GdkEventAny *event) { + /* 如果你的 "delete_event" 信号处理函数返回 FALSE,GTK 会发出 "destroy" 信号。 + * 返回 TRUE,你不希望关闭窗口。 + * 当你想弹出“你确定要退出吗?”对话框时它很有用。*/ + //gtk_widget_hide_all(window_test); + gtk_widget_hide(widget); + return TRUE; //注意必须为TRUE,否则子窗口点击关闭按钮后,就摧毁了,而不是隐藏了。 +} + +static void add_dhcp_tree_colums(GtkWidget *treeView) { + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes("协议", renderer, "text", 0, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), column); + + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes("值", renderer, "text", 1, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), column); +} + +#define ADD_SUB_STRING(name, s) \ + do { \ + gtk_tree_store_append(store, &iterSub, &iter); \ + gtk_tree_store_set(store, &iterSub, 0, (name), 1, (s), -1); \ + } while (0) + +#define ADD_SUB_INT(name, fmt, v) \ + do { \ + gtk_tree_store_append(store, &iterSub, &iter); \ + s = sdsempty(); \ + sprintf(s, (fmt), (v)); \ + gtk_tree_store_set(store, &iterSub, 0, (name), 1, s, -1); \ + sdsfree(s); \ + } while (0) + +static void create_dhcp_tree_mode(PDHCP_PACKAGE p, GtkWidget *treeView) { + // 填充右上侧 TreeView 协议数据 + sds s; + GtkTreeIter iter, iterSub; + GtkTreeStore *store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_STRING); + const char *itemTitle[] = {"Ethernet II", "802.1Q Virtual LAN", "IP Version 4", "UDP", "DHCP"}; + + gtk_tree_store_append(store, &iter, NULL); + gtk_tree_store_set(store, &iter, 0, itemTitle[0], 1, "", -1); + + // 添加 Ethernet II 头相关内容 + + s = sdsempty(); + MAC_TO_STR(p->vlan_hdr.eth.h_dest, s); + ADD_SUB_STRING("Destination", s); + sdsfree(s); + + s = sdsempty(); + MAC_TO_STR(p->vlan_hdr.eth.h_source, s); + ADD_SUB_STRING("Source", s); + sdsfree(s); + + // 添加 VLan 头相关内容 + gtk_tree_store_append(store, &iter, NULL); + gtk_tree_store_set(store, &iter, 0, itemTitle[1], 1, "", -1); + ADD_SUB_INT("ID", "%u", VLAN_VNI_ID(p->vlan_hdr.vlan.id)); + ADD_SUB_INT("Type", "0x%04X", ntohs(p->vlan_hdr.vlan.type)); + + // 添加 IP 头 + gtk_tree_store_append(store, &iter, NULL); + gtk_tree_store_set(store, &iter, 0, itemTitle[2], 1, "", -1); + + // 添加 UDP 头 + gtk_tree_store_append(store, &iter, NULL); + gtk_tree_store_set(store, &iter, 0, itemTitle[3], 1, "", -1); + + // 添加 DHCP 内容 + gtk_tree_store_append(store, &iter, NULL); + gtk_tree_store_set(store, &iter, 0, itemTitle[4], 1, "", -1); + + gtk_tree_view_set_model(GTK_TREE_VIEW(treeView), GTK_TREE_MODEL(store)); + g_object_unref(GTK_TREE_MODEL(store)); +} + +void details_wnd_show(PDHCP_INFO pInfo) { + PBUF_INFO hexBuf[4]; + + if (pInfo) { + hexBuf[0] = &pInfo->pDiscBuf; + hexBuf[1] = &pInfo->pOfferBuf; + hexBuf[2] = &pInfo->pReqBuf; + hexBuf[3] = &pInfo->pAckBuf; + // 填充HEX 窗口数据 + for (int i = 0; i < 4; i++) { + char buf[128] = {0}; + U32 offset = 0; + GtkTextIter iter, iter1; + + if (hexBuf[i]->buf_size == 0) { + continue; + } + + gtk_text_buffer_get_start_iter(g_pTxtBuf[i], &iter); + gtk_text_buffer_get_end_iter(g_pTxtBuf[i], &iter1); + + if (strlen(gtk_text_buffer_get_text(g_pTxtBuf[i], &iter, &iter1, TRUE)) > 0) { + continue; + } + + gtk_text_buffer_get_iter_at_offset(g_pTxtBuf[i], &iter, 0); + sprintf(buf, " Offset(h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ASCII Tables\n"); + gtk_text_buffer_insert_with_tags_by_name(g_pTxtBuf[i], &iter, buf, -1, "hex_head", NULL); + + int row = hexBuf[i]->buf_size / 16 + ((hexBuf[i]->buf_size % 16) > 0 ? 1 : 0); + + for (int k = 0; k < row; k++) { + char bufOffset[24] = {0}; + memset(buf, 0, 128); + sprintf(bufOffset, " %08X ", offset); + gtk_text_buffer_insert_with_tags_by_name(g_pTxtBuf[i], &iter, bufOffset, -1, "hex_offset", NULL); + + for (int m = 0; m < 16; m++) { + char bufStr[4] = {0}; + sprintf(bufStr, "%02X ", hexBuf[i]->p[k * 16 + m]); + strcat(buf, bufStr); + if (m == 7 || m == 15) { + strcat(buf, " "); + } + } + + for (int m = 0; m < 16; m++) { + if (isprint(hexBuf[i]->p[k * 16 + m])) { + char bufStr[2] = {0}; + bufStr[0] = (char)hexBuf[i]->p[k * 16 + m]; + strcat(buf, bufStr); + } else { + strcat(buf, "."); + } + } + strcat(buf, "\n"); + gtk_text_buffer_insert_with_tags_by_name(g_pTxtBuf[i], &iter, buf, -1, "bold", NULL); + offset += 16; + } + + // 填充 TreeView + add_dhcp_tree_colums(g_ptvDHcp[i]); + create_dhcp_tree_mode((PDHCP_PACKAGE)hexBuf[i]->p, g_ptvDHcp[i]); + } + } + + gtk_widget_show_all(g_detailWnd); +} + +static gboolean button_release_event(GtkWidget *self, GdkEventButton event, gpointer user_data) { + GtkTextIter iter, start_sel, end_sel; + GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(self)); + gtk_text_buffer_get_iter_at_mark(buffer, &iter, gtk_text_buffer_get_insert(buffer)); + int row = gtk_text_iter_get_line(&iter); + int col = gtk_text_iter_get_line_offset(&iter); + + if (col <= 57 && col >= 11) { + if ((col <= 35 && ((col - 11) % 3) == 0) || (col > 35 && (col - 12) % 3 == 0)) { + GtkTextMark *mark = gtk_text_buffer_get_insert(buffer); + gtk_text_buffer_get_iter_at_mark(buffer, &start_sel, mark); + gtk_text_buffer_get_iter_at_line_offset(buffer, &end_sel, row, 59); + char *text = (char *)gtk_text_buffer_get_text(buffer, &iter, &end_sel, FALSE); + //printf("Select %s(%d, %d)\n", text, row, col); + } + } + + return FALSE; +} + +void details_wnd_create(GtkBuilder *builder) { + // 创建主窗口 + GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + //设置窗口大小 + gtk_widget_set_size_request(window, 900, 600); + + // 创建笔记本控件 + GtkWidget *notebook = gtk_notebook_new(); + // 笔记本放进窗口 + gtk_container_add(GTK_CONTAINER(window), notebook); + + // 页标签的位置,可以有四种位置:上、下、左或右。 + gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP); + + for (int i = 0; i < 4; i++) { + GtkTreeIter iter; + const char *pTabName[] = {"Discover", "Offer", "Request", "Ack"}; + // 第一个页面 + GtkWidget *label = gtk_label_new(pTabName[i]); + + // 水平分割面板 + GtkWidget *boxTab = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 3); + + // 左侧 Hex 窗口 + GtkWidget *scHex = gtk_scrolled_window_new(NULL, NULL); + GtkWidget *scText = gtk_text_view_new(); + gtk_container_add(GTK_CONTAINER(scHex), scText); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scHex), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + + // 分隔条 + GtkWidget *vSepar = gtk_separator_new(GTK_ORIENTATION_VERTICAL); + // 右侧 详细信息窗口 + GtkWidget *scMsg = gtk_scrolled_window_new(NULL, NULL); + // 上下分割面包 + GtkWidget *vpaned = gtk_paned_new(GTK_ORIENTATION_VERTICAL); + gtk_container_add(GTK_CONTAINER(scMsg), vpaned); + // 上半部分控件 + GtkWidget *tvDhcp = gtk_tree_view_new(); + gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(tvDhcp), GTK_TREE_VIEW_GRID_LINES_BOTH); + + gtk_paned_pack1(GTK_PANED(vpaned), tvDhcp, TRUE, FALSE); + gtk_widget_set_size_request(tvDhcp, -1, 300); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scMsg), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + + // 下半部分控件 + GtkWidget *tvHex = gtk_tree_view_new(); + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes("类型", renderer, "text", 0, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(tvHex), column); + g_object_set(column, "min-width", 120, NULL); + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes("值", renderer, "text", 1, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(tvHex), column); + + GtkListStore *store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); + + const char *itemTitle[] = {"Binary", "unsigne char", "unsigne short", "unsigne int", "unsigne char long long", + "char", "short", "int", "long long"}; + for (int k = 0; k < ARRAY_SIZE(itemTitle); k++) { + gtk_list_store_append(store, &iter); + gtk_list_store_set(store, &iter, 0, itemTitle[k], 1, "", -1); + } + gtk_tree_view_set_model(GTK_TREE_VIEW(tvHex), GTK_TREE_MODEL(store)); + + gtk_tree_view_set_grid_lines(GTK_TREE_VIEW(tvHex), GTK_TREE_VIEW_GRID_LINES_BOTH); + gtk_paned_pack2(GTK_PANED(vpaned), tvHex, FALSE, FALSE); + + // 控件布局 + gtk_box_pack_start(GTK_BOX(boxTab), scHex, TRUE, TRUE, 1); + gtk_box_pack_start(GTK_BOX(boxTab), vSepar, FALSE, FALSE, 1); + gtk_box_pack_start(GTK_BOX(boxTab), scMsg, TRUE, TRUE, 1); + gtk_widget_set_size_request(scHex, 580, -1); + gtk_widget_set_size_request(tvDhcp, 300, -1); + + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), boxTab, label); + g_pTxtBuf[i] = gtk_text_view_get_buffer(GTK_TEXT_VIEW(scText)); + gtk_text_view_set_editable(GTK_TEXT_VIEW(scText), FALSE); + gtk_text_view_set_monospace(GTK_TEXT_VIEW(scText), TRUE); + + gtk_text_buffer_create_tag(g_pTxtBuf[i], "blue_foreground", "foreground", "blue", NULL); + gtk_text_buffer_create_tag(g_pTxtBuf[i], "hex_head", "foreground", "red", "pixels_below_lines", 5, NULL); + gtk_text_buffer_create_tag(g_pTxtBuf[i], "hex_offset", "foreground", "red", NULL); + gtk_text_buffer_create_tag(g_pTxtBuf[i], "bold", "weight", PANGO_WEIGHT_BOLD, NULL); + g_signal_connect(G_OBJECT(scText), "button_release_event", G_CALLBACK(button_release_event), builder); + + g_ptvDHcp[i] = tvDhcp; + g_ptvHex[i] = tvHex; + } + + g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), builder); + //g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), builder); + + g_detailWnd = window; +} \ No newline at end of file diff --git a/dhcp_tools/main.h b/dhcp_tools/main.h index e186629..3a98829 100644 --- a/dhcp_tools/main.h +++ b/dhcp_tools/main.h @@ -5,6 +5,7 @@ #ifndef VCPE_MAIN_H #define VCPE_MAIN_H +#include #include "uthash/uthash.h" #include "rfc2131.h" @@ -25,6 +26,15 @@ typedef enum { NUM_COLS } COL_NAME; +typedef enum { + COL_DHCP_ITEM = 0, + COL_DHCP_VALUE, + + COL_ITEM_ATTR_VISIABLE, + COL_VALUE_ATTR_VISIABLE, + NUM_DHCP_COLS +} COL_DHCP_INFO_NAME; + typedef enum { STEP_BEGIN = 0, STEP_DISCOVER, @@ -46,19 +56,20 @@ typedef struct { } BUF_INFO, *PBUF_INFO; typedef struct { - U32 index; - U32 vni; - U8 mac[6]; - S8 hostname[64]; - DHCP_STEP step; - DHCP_STATUS status; - BUF_INFO pDiscBuf; - BUF_INFO pOfferBuf; - BUF_INFO pReqBuf; - BUF_INFO pAckBuf; - DHCP_RSP offerRsp; - DHCP_RSP ackRsp; - UT_hash_handle hh; + U32 index; + U32 vni; + U8 mac[6]; + S8 hostname[64]; + DHCP_STEP step; + DHCP_STATUS status; + BUF_INFO pDiscBuf; + BUF_INFO pOfferBuf; + BUF_INFO pReqBuf; + BUF_INFO pAckBuf; + DHCP_RSP offerRsp; + DHCP_RSP ackRsp; + S8 treeId[32]; + UT_hash_handle hh; } DHCP_INFO, *PDHCP_INFO; U32 rand_number(); @@ -67,4 +78,6 @@ int dhcp_tools_init_network(const char *pNicName); U8 *dhcp_create_discover_req(PDHCP_INFO pInfo, int *pOutSize); U8 *dhcp_create_request_req(PDHCP_INFO pInfo, int *pOutSize); int cacheDhcpOfferBuffer(PDHCP_INFO pInfo, U8 *pBuf, int size); +void details_wnd_create(GtkBuilder *builder); +void details_wnd_show(PDHCP_INFO pInfo); #endif //VCPE_MAIN_H diff --git a/dhcp_tools/main_wnd.c b/dhcp_tools/main_wnd.c index 22af386..01c1876 100644 --- a/dhcp_tools/main_wnd.c +++ b/dhcp_tools/main_wnd.c @@ -1,7 +1,6 @@ // // Created by xajhuang on 2023/4/12. // -#include #include #include "main.h" #include "misc.h" @@ -12,11 +11,10 @@ #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; +static GtkBuilder *g_mainBuilder = NULL; +static PDHCP_INFO g_pDhcpInfo = NULL; +static GThread *g_pEvLoopThread = NULL; +static int g_runTask = FALSE; U32 rand_number() { GRand *pRand = g_rand_new_with_seed(time(NULL)); @@ -52,26 +50,104 @@ static void load_css(void) { 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; - } + 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) { + if (pInfo->step >= step) { return TRUE; } return FALSE; } +void view_popup_menu_onDoSomething(GtkWidget *menuitem, gpointer userdata) { + PDHCP_INFO pInfo = (PDHCP_INFO)userdata; + //GtkWidget *deatilWnd = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "wndDetails")); + // + g_print("Do something of %s\n", pInfo->treeId); + //gtk_notebook_set_current_page(GTK_NOTEBOOK(tab), 0); + //gtk_widget_show(deatilWnd); + details_wnd_show(pInfo); +} + +void view_popup_menu(GtkWidget *treeview, GdkEventButton *event, gpointer userdata) { + GtkWidget *menu, *menuitem; + + menu = gtk_menu_new(); + + menuitem = gtk_menu_item_new_with_label("详细信息"); + + g_signal_connect(menuitem, "activate", (GCallback)view_popup_menu_onDoSomething, userdata); + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + + gtk_widget_show_all(menu); + gtk_menu_popup_at_pointer(GTK_MENU(menu), (GdkEvent *)event); +} + +gboolean view_onButtonPressed(GtkWidget *treeview, GdkEventButton *event, gpointer userdata) { + gboolean showMenu = FALSE; + + PDHCP_INFO p = NULL; + GtkTreeIter iter; + GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); + /* single click with the right mouse button? */ + if (event->type == GDK_BUTTON_PRESS && event->button == 3) { + /* optional: select row if no row is selected or only + * one other row is selected (will only do something + * if you set a tree selection mode as described later + * in the tutorial) */ + GtkTreeSelection *selection; + selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); + /* Note: gtk_tree_selection_count_selected_rows() does not + * exist in gtk+-2.0, only in gtk+ >= v2.2 ! */ + if (gtk_tree_selection_count_selected_rows(selection) <= 1) { + GtkTreePath *path; + + /* Get tree path for row that was clicked */ + if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(treeview), (gint)event->x, (gint)event->y, &path, NULL, + NULL, NULL)) { + + gtk_tree_selection_unselect_all(selection); + gtk_tree_selection_select_path(selection, path); + if (gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path)) { + gchar *index; + gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, COL_INDEX, &index, -1); + if (index[0] != 'V') { + U32 id = strtoul(index, NULL, 10); + HASH_FIND_INT(g_pDhcpInfo, &id, p); + if (p) { + showMenu = TRUE; + } + } + g_free(index); + } + gtk_tree_path_free(path); + } + } + + if (showMenu) { + view_popup_menu(treeview, event, p); + } + return TRUE; /* we handled this */ + } + + return FALSE; /* we did not handle this */ +} + +gboolean view_onPopupMenu(GtkWidget *treeview, gpointer userdata) { + view_popup_menu(treeview, NULL, userdata); + return TRUE; /* we handled this */ +} + static void tree_view_data_store_create() { int i, j; PDHCP_INFO pInfo, pTemp; - GtkTreeIter iter, iter_child, iter_sub; + GtkTreeIter iter, iter_child; GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); GtkWidget *vniStart = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVni")); @@ -84,7 +160,7 @@ static void tree_view_data_store_create() { for (i = 0; i < nRequest; i++) { int isCreateRoot = FALSE; - + j = 0; HASH_ITER(hh, g_pDhcpInfo, pInfo, pTemp) { if (pInfo->vni == (nVni + i)) { char idx[64] = {0}; @@ -130,11 +206,17 @@ static void tree_view_data_store_create() { COL_ATTR_VISIABLE, TRUE, -1); // clang-format on + memset(pInfo->treeId, 0, 32); + sprintf(pInfo->treeId, "%d:%d", i, j++); } } } gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store)); + + g_signal_connect(view, "button-press-event", (GCallback)view_onButtonPressed, NULL); + g_signal_connect(view, "popup-menu", (GCallback)view_onPopupMenu, NULL); + #if 0 for (i = 0; i < 1000; i++) { char buf[24] = {0}; @@ -185,22 +267,20 @@ static void tree_view_data_store_create() { // clang-format on } #endif - //g_object_unref(store); } static gboolean tree_view_data_store_upgade(gpointer pInfo) { -#if 0 - char buf[32] = {0}; GtkTreeIter iter; GtkTreeStore *store = GTK_TREE_STORE(gtk_builder_get_object(g_mainBuilder, "tsDhcpInfo")); + GtkTreeModel *model; - if (!pInfo) { + if (!pInfo || !store || !g_runTask) { return FALSE; } - sprintf(buf, "%d", ((PDHCP_INFO)pInfo)->index); + model = GTK_TREE_MODEL(store); - if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, buf)) { + if (model && gtk_tree_model_get_iter_from_string(model, &iter, ((PDHCP_INFO)pInfo)->treeId)) { // clang-format off gtk_tree_store_set(store, &iter, @@ -215,11 +295,11 @@ static gboolean tree_view_data_store_upgade(gpointer pInfo) { -1); // clang-format on } -#endif + return TRUE; } -G_MODULE_EXPORT void __mainWnd_on_destroy(GObject *object, gpointer user_data) { +static void mainWnd_on_destroy(GObject *object, gpointer user_data) { task_manager_exit(); g_thread_unref(g_pEvLoopThread); gtk_main_quit(); @@ -242,7 +322,6 @@ _Noreturn static void *dhcpThreadCb(void *pData) { PDHCP_INFO pInfo, pTemp; while (TRUE) { - if (!g_runTask) { g_usleep(1000); continue; @@ -311,7 +390,6 @@ _Noreturn static void *dhcpThreadCb(void *pData) { } LOG_MSG(debug, "DHCP status mathine exit......\n"); - g_thread_exit(NULL); } static void cleanupDHCPInfo() { @@ -337,7 +415,7 @@ static void cleanupDHCPInfo() { } } -G_MODULE_EXPORT void __mainWnd_on_tb_start(GObject *object, gpointer user_data) { +static void mainWnd_on_tb_start(GObject *object, gpointer user_data) { int i, j, index = 0; GtkTreeIter iter; PDHCP_INFO pInfo; @@ -405,7 +483,7 @@ G_MODULE_EXPORT void __mainWnd_on_tb_start(GObject *object, gpointer user_data) g_runTask = TRUE; } -G_MODULE_EXPORT void __mainWnd_on_tb_stop(GObject *object, gpointer user_data) { +static 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")); @@ -416,7 +494,6 @@ G_MODULE_EXPORT void __mainWnd_on_tb_stop(GObject *object, gpointer user_data) { } static void *uv_loop_thread(void *pData) { - static uv_timer_t uvTm; task_manager_run(); return NULL; } @@ -424,8 +501,7 @@ static void *uv_loop_thread(void *pData) { int main(int args, char **argv) { int i, ret; GtkTreeIter iter; - GList *pNicList = NULL; - SYS_NIC_INFO info = {0}; + 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); @@ -445,13 +521,13 @@ int main(int args, char **argv) { 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); + 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); + 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); + 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++) { @@ -470,7 +546,7 @@ int main(int args, char **argv) { free(info.pNicCtx); } - GtkWidget *macTxt = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "txtMacStart")); + //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); @@ -483,8 +559,10 @@ int main(int args, char **argv) { GtkWidget *numVniCli = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "sbVniClient")); GtkAdjustment *adjVniCli = gtk_adjustment_new(1, 1, 1000, 1, 0, 0); gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(numVniCli), adjVniCli); - GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); + //GtkWidget *view = GTK_WIDGET(gtk_builder_get_object(g_mainBuilder, "treeResult")); + + details_wnd_create(g_mainBuilder); #if 0 gtk_list_store_new(NUM_COLS, G_TYPE_INT, @@ -500,8 +578,9 @@ int main(int args, char **argv) { gtk_builder_connect_signals(g_mainBuilder, NULL); gtk_widget_show(mainWnd); - g_pEvLoopThread = g_thread_new("uv_loop", uv_loop_thread, NULL); - g_pDHCPSTMThread = g_thread_new("dhcp", dhcpThreadCb, NULL); + g_pEvLoopThread = g_thread_new("uv_loop", uv_loop_thread, NULL); + g_thread_new("dhcp", dhcpThreadCb, NULL); + gtk_main(); return 0; diff --git a/dhcp_tools/res/detail.glade b/dhcp_tools/res/detail.glade new file mode 100644 index 0000000..57ff73f --- /dev/null +++ b/dhcp_tools/res/detail.glade @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + 800 + 480 + + + True + True + + + True + + + True + True + never + automatic + + + 200 + True + True + False + + + + + 0 + + + + + True + True + never + automatic + + + 200 + True + True + 5 + lsDhcpInfo + False + both + True + + + 120 + DHCP Protocol + + + + 2 + 0 + + + + + + + Dhcp Value + + + + 3 + 1 + + + + + + + + + 1 + + + + + True + xadasldfjaldfj + + + + 2 + + + + + + + True + Discover + + + False + + + + + True + True + automatic + automatic + + + True + True + + + True + True + + + False + True + + + + + True + label + + + True + True + + + + + + + 1 + + + + + True + page 2 + + + 1 + False + + + + + True + vertical + + + 2 + + + + + True + page 3 + + + 2 + False + + + + + True + True + vertical + + + + + + + + + 3 + + + + + True + page 4 + + + 3 + False + + + + + + diff --git a/dhcp_tools/res/style.css b/dhcp_tools/res/style.css index 66eb59a..4ed82d8 100644 --- a/dhcp_tools/res/style.css +++ b/dhcp_tools/res/style.css @@ -11,6 +11,10 @@ spinbutton { font: 14px "Comic Sans"; } +textview.view { + font: 16px "Courier New"; +} + entry { font: 16px "Comic Sans"; } \ No newline at end of file diff --git a/srcs/service/dhcpd/db_interface.c b/srcs/service/dhcpd/db_interface.c index 8e1494e..1404d96 100644 --- a/srcs/service/dhcpd/db_interface.c +++ b/srcs/service/dhcpd/db_interface.c @@ -181,7 +181,6 @@ int lease_get_pre_assign(U32 uid, const char *mac, const char *hostname, U32 *pr if (rc == ERR_SUCCESS && nRow > 0 && nColumn > 0) { if (preAssign) { *preAssign = ntohl(inet_addr(dbResult[2])); - printf("pre alloc [%s(%u)] --> %s\n", mac, uid, dbResult[2]); // 更新时间戳 memset(buf, 0, 1024); snprintf(buf, 1024, UPDATE_CREATE_TIME_BY_ID_FMT, dbResult[3]);