diff --git a/raidguard_c_gui_server_mock/Makefile b/raidguard_c_gui_server_mock/Makefile new file mode 100644 index 0000000..9453041 --- /dev/null +++ b/raidguard_c_gui_server_mock/Makefile @@ -0,0 +1,27 @@ +# Makefile for Mock Driver + +CC = gcc +CFLAGS = -Wall -Wextra -g -O0 +SRCS = test_mock_driver.c mock_driver.c +OBJS = $(SRCS:.c=.o) +TARGET = test_mock_driver + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CC) $(CFLAGS) -o $@ $(OBJS) + +test_mock_driver.o: test_mock_driver.c mock_driver.h +mock_driver.o: mock_driver.c mock_driver.h + +clean: + rm -f $(TARGET) $(OBJS) + +run: $(TARGET) + ./$(TARGET) + +# Enable verbose output +debug: CFLAGS += -DVERBOSE=1 +debug: $(TARGET) + +.PHONY: all clean run debug diff --git a/raidguard_c_gui_server_mock/README.md b/raidguard_c_gui_server_mock/README.md new file mode 100644 index 0000000..f35b337 --- /dev/null +++ b/raidguard_c_gui_server_mock/README.md @@ -0,0 +1,198 @@ +# RAIDGuard X Mock Driver (C) + +Mock driver for RAIDGuard X GUI Server - provides simulated RAID controller for testing without hardware. + +## 目錄結構 + +``` +raidguard_c_gui_server_mock/ +├── mock_driver.h # Header file +├── mock_driver.c # Implementation +├── test_mock_driver.c # Test program +├── Makefile # Build file +└── README.md # This file +``` + +## 建構 + +```bash +make +``` + +## 執行測試 + +```bash +./test_mock_driver +``` + +## 使用方式 + +### 1. 初始化 + +```c +#include "mock_driver.h" + +// 初始化 Mock Driver +mock_init(); + +// 啟用詳細輸出 +mock_set_verbose(true); +``` + +### 2. 設定控制器 + +```c +// 設定控制器數量 (預設 1) +mock_set_controller_count(2); + +// 設定控制器序號 +mock_set_controller_serial(0, "MOCK00000001"); +mock_set_controller_serial(1, "MOCK00000002"); + +// 設定控制器型號 +mock_set_controller_model(0, "Accusys GEN2"); +``` + +### 3. 查詢控制器資訊 + +```c +UCHAR pageBuf[1024]; +UCHAR heatsink; + +// 查詢控制器資訊 +CHAR result = mock_QuaryDTR(0, pageBuf, &heatsink); + +if (result == 1) { + // 取得序號 + printf("SN: %.16s\n", pageBuf); + + // 取得型號 + printf("Model: %.20s\n", pageBuf + 16); + + // 取得韌體版本 + printf("FW: %.8s\n", pageBuf + 64); +} +``` + +### 4. 取得事件 + +```c +EVENT_INFO evt; +UCHAR result = mock_GetCtlrEvent(0, &evt); + +if (result == SYSOK && evt.bStatus) { + // 處理事件 + printf("Event Type: %d\n", evt.bEventBuf[0]); +} +``` + +### 5. 模擬事件 + +```c +// 模擬磁碟上線事件 +mock_generate_disk_event(5, 0x01); + +// 模擬 RAID 重建事件 +mock_generate_raid_event(0, 0x02); + +// 自訂事件 +UCHAR customEvent[] = { + 0x03, 0x00, 0x00, 0x00, // Event Type + 0x00, 0x00, 0x00, 0x00, // Timestamp + 0x00, 0x00, 0x00, 0x00, // Data + 0x00, 0x00, 0x00, 0x00 +}; +mock_push_event(customEvent, 16); +``` + +### 6. 清理 + +```c +mock_cleanup(); +``` + +## API 參考 + +### 初始化與清理 + +| 函數 | 說明 | +|------|------| +| `mock_init()` | 初始化 Mock Driver | +| `mock_cleanup()` | 清理資源 | +| `mock_set_verbose(bool)` | 設定詳細輸出 | + +### 控制器設定 + +| 函數 | 說明 | +|------|------| +| `mock_set_controller_count(int)` | 設定控制器數量 | +| `mock_set_controller_serial(int, const char*)` | 設定控制器序號 | +| `mock_set_controller_model(int, const char*)` | 設定控制器型號 | +| `mock_set_controller_status(int, UCHAR)` | 設定控制器狀態 | + +### Driver 函數 + +| 函數 | 說明 | +|------|------| +| `mock_QuaryDTR(UCHAR, UCHAR*, UCHAR*)` | 查詢控制器資訊 | +| `mock_DevIoControl(...)` | I/O Control (模擬) | +| `mock_GetCtlrEvent(UCHAR, EVENT_INFO*)` | 取得事件 | + +### 事件模擬 + +| 函數 | 說明 | +|------|------| +| `mock_push_event(UCHAR*, int)` | 推入自訂事件 | +| `mock_clear_events()` | 清除所有事件 | +| `mock_generate_disk_event(int, int)` | 產生磁碟事件 | +| `mock_generate_raid_event(int, int)` | 產生 RAID 事件 | + +## 模擬的 Page 資料 + +| Page | 大小 | 內容 | +|------|------|------| +| 0x00 | 1024 | Controller Info | +| 0x01 | 1024 | RAID Snapshot | +| 0x07 | 512 | LUN Map Table | +| 0x0A | 1024 | RAID Info | +| 0x0B | 1024 | RAID Info | +| 0x0E | 1024 | RAID Info | +| 0x1B | 512 | Disk List | + +## 整合到 GS + +要將 Mock Driver 整合到 GS (DtrGuiSrv),請在編譯時使用 `-DENABLE_MOCK_MODE` : + +```makefile +ifdef ENABLE_MOCK_MODE + CFLAGS += -DENABLE_MOCK_MODE + SRCS += mock_driver.c + + # 置換函數 + CFLAGS += -DQuaryDTR=mock_QuaryDTR + CFLAGS += -DDevIoControl=mock_DevIoControl + CFLAGS += -DGetCtlrEvent=mock_GetCtlrEvent +endif +``` + +或使用 FFI: + +```c +#ifdef ENABLE_MOCK_MODE + #include "mock_driver.h" + #define DevIoControl mock_DevIoControl + #define QuaryDTR mock_QuaryDTR + #define GetCtlrEvent mock_GetCtlrEvent +#endif +``` + +## 開發日誌 + +- 2024-03-29: 初始版本 + - 基本控制器模擬 + - 事件佇列 + - Page 0-1, 7, 10, 27 資料 + +## License + +Proprietary - Accusys Inc. diff --git a/raidguard_c_gui_server_mock/mock_driver.c b/raidguard_c_gui_server_mock/mock_driver.c new file mode 100644 index 0000000..e992de5 --- /dev/null +++ b/raidguard_c_gui_server_mock/mock_driver.c @@ -0,0 +1,445 @@ +/* + * mock_driver.c + * + * Mock Driver for RAIDGuard X GUI Server + * Provides simulated RAID controller for testing without hardware + */ + +#include "mock_driver.h" +#include + +// ============================================================================= +// Global Variables +// ============================================================================= + +static MOCK_CTRL_INFO g_mockCtrl[MAX_DTR_IN_HOST]; +static UCHAR g_mockEventQueue[100][MAX_EDB_SZ]; +static int g_mockEventHead = 0; +static int g_mockEventTail = 0; +static int g_mockEventCount = 0; +static bool g_bInitialized = false; + +// Configuration +static int g_controllerCount = 1; +static bool g_verbose = false; + +// ============================================================================= +// Initialization +// ============================================================================= + +void mock_set_verbose(bool verbose) { + g_verbose = verbose; +} + +bool mock_is_verbose(void) { + return g_verbose; +} + +void mock_init(void) { + if (g_bInitialized) return; + + memset(g_mockCtrl, 0, sizeof(g_mockCtrl)); + memset(g_mockEventQueue, 0, sizeof(g_mockEventQueue)); + g_mockEventHead = 0; + g_mockEventTail = 0; + g_mockEventCount = 0; + + // Initialize default controller + g_controllerCount = 1; + g_mockCtrl[0].bStatus = CTLR_STATUS_ALIVE; + memcpy(g_mockCtrl[0].bCtlrSN, "MOCK00000001\0", 16); + memcpy(g_mockCtrl[0].bModelName, "Accusys GEN2\0", 20); + + // Fill mock page data + mock_fill_page0(0); + mock_fill_page1(0); + mock_fill_page7(0); + mock_fill_page10(0); + mock_fill_page11(0); + mock_fill_page14(0); + mock_fill_page27(0); + + // Register default events + mock_register_default_events(); + + g_bInitialized = true; + + if (g_verbose) { + printf("[MOCK] Driver initialized\n"); + } +} + +void mock_cleanup(void) { + if (!g_bInitialized) return; + + memset(g_mockCtrl, 0, sizeof(g_mockCtrl)); + memset(g_mockEventQueue, 0, sizeof(g_mockEventQueue)); + g_mockEventCount = 0; + g_bInitialized = false; + + if (g_verbose) { + printf("[MOCK] Driver cleanup complete\n"); + } +} + +// ============================================================================= +// Page Data Fillers +// ============================================================================= + +void mock_fill_page0(int ctrlIndex) { + MOCK_CTRL_INFO *ctrl = &g_mockCtrl[ctrlIndex]; + unsigned char *buf = ctrl->bPage0Data; + + memset(buf, 0, 1024); + + // Serial Number (Offset 0-15, 16 bytes) + memcpy(buf + 0, ctrl->bCtlrSN, 16); + + // Model Name (Offset 16-47, 32 bytes) + memcpy(buf + 16, ctrl->bModelName, 20); + + // Firmware Version (Offset 64-71, 8 bytes) + memcpy(buf + 64, "3.8.0.0\0", 8); + + // BIOS Version (Offset 72-79, 8 bytes) + memcpy(buf + 72, "1.2.3.4\0", 8); + + // Status (Offset 96) + buf[96] = 0x01; // Online + + // Number of RAID Ports (Offset 104) + buf[104] = 4; + + // Number of Disks (Offset 105) + buf[105] = 8; + + // Controller Number (Offset 106) + buf[106] = ctrlIndex; + + if (g_verbose) { + printf("[MOCK] Page 0 filled for controller %d\n", ctrlIndex); + } +} + +void mock_fill_page1(int ctrlIndex) { + unsigned char *buf = g_mockCtrl[ctrlIndex].bPage1Data; + memset(buf, 0, 1024); + + // RAID 0: Normal + buf[0] = 0x01; // Status: Normal + buf[1] = 0x05; // RAID Level: RAID 5 + buf[2] = 0x04; // Disk Count + + // RAID 1: Normal + buf[128] = 0x01; + buf[129] = 0x06; // RAID 6 + buf[130] = 0x06; // 6 disks + + if (g_verbose) { + printf("[MOCK] Page 1 filled for controller %d\n", ctrlIndex); + } +} + +void mock_fill_page7(int ctrlIndex) { + unsigned char *buf = g_mockCtrl[ctrlIndex].bPage7Data; + memset(buf, 0, 512); + + // LUN 0 mapping + buf[0] = 0x00; // LUN 0 + buf[1] = 0x00; // RAID ID 0 + buf[2] = 0x01; // Enable + + if (g_verbose) { + printf("[MOCK] Page 7 filled for controller %d\n", ctrlIndex); + } +} + +void mock_fill_page10(int ctrlIndex) { + unsigned char *buf = g_mockCtrl[ctrlIndex].bPage10Data; + memset(buf, 0, 1024); + + // RAID Info Block 0 + buf[0] = 0x01; // Status: Normal + buf[1] = 0x05; // RAID 5 + buf[2] = 0x04; // 4 disks + buf[3] = 0x00; // Stripe Size + + // Capacity (Offset 8-15, 8 bytes) + buf[8] = 0x00; + buf[9] = 0x00; + buf[10] = 0x00; + buf[11] = 0x10; // 1 TB + buf[12] = 0x00; + buf[13] = 0x00; + buf[14] = 0x00; + buf[15] = 0x00; + + if (g_verbose) { + printf("[MOCK] Page 10 filled for controller %d\n", ctrlIndex); + } +} + +void mock_fill_page11(int ctrlIndex) { + memset(g_mockCtrl[ctrlIndex].bPage11Data, 0, 1024); + g_mockCtrl[ctrlIndex].bPage11Data[0] = 0x01; +} + +void mock_fill_page14(int ctrlIndex) { + memset(g_mockCtrl[ctrlIndex].bPage14Data, 0, 1024); +} + +void mock_fill_page27(int ctrlIndex) { + unsigned char *buf = g_mockCtrl[ctrlIndex].bPage27Data; + memset(buf, 0, 512); + + // Disk 0 + buf[0] = 0x00; // Slot 0 + buf[1] = 0x01; // Status: Online + buf[2] = 0x00; // Type: HDD + + // Disk 1 + buf[16] = 0x01; // Slot 1 + buf[17] = 0x01; // Status: Online + + // Disk 2 + buf[32] = 0x02; + buf[33] = 0x01; + + // Disk 3 + buf[48] = 0x03; + buf[49] = 0x01; + + // Disk 4 (Spare) + buf[64] = 0x04; + buf[65] = 0x01; + buf[66] = 0x02; // Spare + + // Disk 5-7 Offline + buf[80] = 0x05; + buf[81] = 0x00; // Offline + + if (g_verbose) { + printf("[MOCK] Page 27 filled for controller %d\n", ctrlIndex); + } +} + +void mock_register_default_events(void) { + // Disk Online Event (Slot 2) + UCHAR diskOnline[] = { + 0x01, 0x00, 0x00, 0x00, // Event Type: Disk Online + 0x00, 0x00, 0x00, 0x00, // Timestamp + 0x02, 0x00, 0x00, 0x00, // Slot 2 + 0x01, 0x00, 0x00, 0x00 // Status: OK + }; + mock_push_event(diskOnline, 16); +} + +// ============================================================================= +// Driver Functions +// ============================================================================= + +UCHAR mock_DevIoControl( + UCHAR bDevNo, + ULONG lControlCode, + ULONG lInSize, + char *pInBuf, + ULONG lOutSize, + char *pOutBuf, + USHORT *pusInBandErrCode) { + + if (!g_bInitialized) mock_init(); + + if (bDevNo >= MAX_DTR_IN_HOST) { + *pusInBandErrCode = 0xFF; + return 0x01; + } + + // Handle different IOCTL codes + switch (lControlCode) { + case 0x9001: // GET_CONTROLLER_INFO + if (g_verbose) { + printf("[MOCK] IOCTL: GET_CONTROLLER_INFO ctrl=%d\n", bDevNo); + } + memcpy(pOutBuf, g_mockCtrl[bDevNo].bPage0Data, + lOutSize > 1024 ? 1024 : lOutSize); + break; + + case 0x9002: // GET_RAID_INFO + if (g_verbose) { + printf("[MOCK] IOCTL: GET_RAID_INFO ctrl=%d\n", bDevNo); + } + memcpy(pOutBuf, g_mockCtrl[bDevNo].bPage1Data, + lOutSize > 1024 ? 1024 : lOutSize); + break; + + case 0x9020: // GET_INBAND_EVENT + if (g_verbose) { + printf("[MOCK] IOCTL: GET_INBAND_EVENT ctrl=%d\n", bDevNo); + } + { + EVENT_INFO evt; + UCHAR result = mock_GetCtlrEvent(bDevNo, &evt); + if (result == SYSOK) { + memcpy(pOutBuf, evt.bEventBuf, + lOutSize > 512 ? 512 : lOutSize); + } + } + break; + + default: + if (g_verbose) { + printf("[MOCK] IOCTL: 0x%04lx (not handled, returning success)\n", + lControlCode); + } + // Return success for unknown codes + break; + } + + *pusInBandErrCode = 0x0000; + return SYSOK; +} + +CHAR mock_QuaryDTR(UCHAR ucCtlrIndex, UCHAR *bPageBuf, UCHAR *pbHeatsink) { + if (!g_bInitialized) mock_init(); + + if (ucCtlrIndex >= g_controllerCount) { + return 0; // FALSE + } + + // Return controller info + memcpy(bPageBuf, g_mockCtrl[ucCtlrIndex].bPage0Data, 1024); + *pbHeatsink = 0x00; + + if (g_verbose) { + printf("[MOCK] QuaryDTR: controller %d, SN: %s\n", + ucCtlrIndex, g_mockCtrl[ucCtlrIndex].bCtlrSN); + } + + return 1; // TRUE +} + +UCHAR mock_GetCtlrEvent(UCHAR bCtlrNo, EVENT_INFO *pEvent_info) { + if (!g_bInitialized) mock_init(); + + if (g_mockEventCount <= 0) { + pEvent_info->bStatus = 0; + return 0x02; // SYSFAIL_EVENT_EMPTY + } + + // Get event from queue + memcpy(pEvent_info->bEventBuf, g_mockEventQueue[g_mockEventHead], MAX_EDB_SZ); + pEvent_info->bStatus = 1; + + // Move head + g_mockEventHead = (g_mockEventHead + 1) % 100; + g_mockEventCount--; + + if (g_verbose) { + printf("[MOCK] GetCtlrEvent: event retrieved, remaining: %d\n", + g_mockEventCount); + } + + return SYSOK; +} + +// ============================================================================= +// Configuration Functions +// ============================================================================= + +void mock_set_controller_count(int count) { + if (count < 1) count = 1; + if (count > MAX_DTR_IN_HOST) count = MAX_DTR_IN_HOST; + g_controllerCount = count; +} + +void mock_set_controller_serial(int index, const char *sn) { + if (index < 0 || index >= MAX_DTR_IN_HOST) return; + memcpy(g_mockCtrl[index].bCtlrSN, sn, 16); +} + +void mock_set_controller_model(int index, const char *model) { + if (index < 0 || index >= MAX_DTR_IN_HOST) return; + memcpy(g_mockCtrl[index].bModelName, model, 32); +} + +void mock_set_controller_status(int index, UCHAR status) { + if (index < 0 || index >= MAX_DTR_IN_HOST) return; + g_mockCtrl[index].bStatus = status; +} + +// ============================================================================= +// Event Simulation +// ============================================================================= + +void mock_push_event(UCHAR *eventData, int length) { + if (length > MAX_EDB_SZ) length = MAX_EDB_SZ; + if (g_mockEventCount >= 100) { + // Queue full, remove oldest + g_mockEventHead = (g_mockEventHead + 1) % 100; + g_mockEventCount--; + } + + memcpy(g_mockEventQueue[g_mockEventTail], eventData, length); + g_mockEventTail = (g_mockEventTail + 1) % 100; + g_mockEventCount++; + + if (g_verbose) { + printf("[MOCK] Event pushed, count: %d\n", g_mockEventCount); + } +} + +void mock_clear_events(void) { + g_mockEventHead = 0; + g_mockEventTail = 0; + g_mockEventCount = 0; + + if (g_verbose) { + printf("[MOCK] Events cleared\n"); + } +} + +void mock_generate_disk_event(int slot, int eventType) { + UCHAR event[16]; + memset(event, 0, 16); + + event[0] = eventType & 0xFF; // Event Type + event[3] = slot & 0xFF; // Slot Number + + mock_push_event(event, 16); +} + +void mock_generate_raid_event(int raidId, int eventType) { + UCHAR event[16]; + memset(event, 0, 16); + + event[0] = eventType & 0xFF; // Event Type + event[3] = raidId & 0xFF; // RAID ID + + mock_push_event(event, 16); +} + +// ============================================================================= +// Configuration File (Stub) +// ============================================================================= + +int mock_load_config(const char *filename) { + // TODO: Parse JSON config file + if (g_verbose) { + printf("[MOCK] Config file loading not implemented: %s\n", filename); + } + return 0; +} + +void mock_print_config(void) { + printf("=== Mock Configuration ===\n"); + printf("Controller Count: %d\n", g_controllerCount); + for (int i = 0; i < g_controllerCount; i++) { + printf("Controller %d:\n", i); + printf(" SN: %s\n", g_mockCtrl[i].bCtlrSN); + printf(" Model: %s\n", g_mockCtrl[i].bModelName); + printf(" Status: %s\n", + g_mockCtrl[i].bStatus == CTLR_STATUS_ALIVE ? "Online" : "Offline"); + } + printf("Pending Events: %d\n", g_mockEventCount); + printf("=========================\n"); +} diff --git a/raidguard_c_gui_server_mock/mock_driver.h b/raidguard_c_gui_server_mock/mock_driver.h new file mode 100644 index 0000000..54ac436 --- /dev/null +++ b/raidguard_c_gui_server_mock/mock_driver.h @@ -0,0 +1,107 @@ +#ifndef MOCK_DRIVER_H +#define MOCK_DRIVER_H + +#include +#include +#include +#include +#include + +// Types +typedef uint8_t UCHAR; +typedef uint16_t USHORT; +typedef uint32_t ULONG; +typedef int8_t CHAR; +typedef int SHORT; +typedef int BOOL; + +// Constants +#define MAX_DTR_IN_HOST 4 +#define MAX_EVENT_NO 512 +#define MAX_EDB_SZ 512 + +// Status +#define CTLR_STATUS_ALIVE 0x01 +#define CTLR_STATUS_DEAD 0x00 + +#define SYSOK 0x50 +#define SYSFAIL 0x40 + +// Mock Controller Info Structure +typedef struct { + UCHAR bStatus; + UCHAR bCtlrSN[16]; + UCHAR bModelName[32]; + UCHAR bPad[16]; + UCHAR bPage0Data[1024]; + UCHAR bPage1Data[1024]; + UCHAR bPage7Data[512]; + UCHAR bPage10Data[1024]; + UCHAR bPage11Data[1024]; + UCHAR bPage14Data[1024]; + UCHAR bPage20Data[512]; + UCHAR bPage26Data[512]; + UCHAR bPage27Data[512]; +} MOCK_CTRL_INFO; + +// Event Structure +typedef struct { + UCHAR bStatus; + UCHAR bEventBuf[MAX_EDB_SZ]; +} EVENT_INFO; + +// Function Declarations + +// Initialization +void mock_init(void); +void mock_cleanup(void); + +// Driver Functions +UCHAR mock_DevIoControl( + UCHAR bDevNo, + ULONG lControlCode, + ULONG lInSize, + char *pInBuf, + ULONG lOutSize, + char *pOutBuf, + USHORT *pusInBandErrCode); + +CHAR mock_QuaryDTR( + UCHAR ucCtlrIndex, + UCHAR *bPageBuf, + UCHAR *pbHeatsink); + +UCHAR mock_GetCtlrEvent( + UCHAR bCtlrNo, + EVENT_INFO *pEvent_info); + +// Configuration +void mock_set_controller_count(int count); +void mock_set_controller_serial(int index, const char *sn); +void mock_set_controller_model(int index, const char *model); +void mock_set_controller_status(int index, UCHAR status); +void mock_set_verbose(bool verbose); +bool mock_is_verbose(void); +void mock_set_verbose(bool verbose); + +// Event Simulation +void mock_push_event(UCHAR *eventData, int length); +void mock_clear_events(void); +void mock_generate_disk_event(int slot, int eventType); +void mock_generate_raid_event(int raidId, int eventType); + +// Internal functions +void mock_fill_page0(int ctrlIndex); +void mock_fill_page1(int ctrlIndex); +void mock_fill_page7(int ctrlIndex); +void mock_fill_page10(int ctrlIndex); +void mock_fill_page11(int ctrlIndex); +void mock_fill_page14(int ctrlIndex); +void mock_fill_page27(int ctrlIndex); +void mock_register_default_events(void); + +// Configuration File +int mock_load_config(const char *filename); +void mock_print_config(void); + +#endif // MOCK_DRIVER_H diff --git a/raidguard_c_gui_server_mock/test_mock_driver.c b/raidguard_c_gui_server_mock/test_mock_driver.c new file mode 100644 index 0000000..d5ac692 --- /dev/null +++ b/raidguard_c_gui_server_mock/test_mock_driver.c @@ -0,0 +1,83 @@ +/* + * test_mock_driver.c + * + * Test program for mock driver + */ + +#include +#include "mock_driver.h" + +int main(int argc, char *argv[]) { + printf("=== Mock Driver Test ===\n\n"); + + // Enable verbose output + mock_set_verbose(true); + + // Initialize mock driver + printf("\n--- Testing mock_init() ---\n"); + mock_init(); + + // Print configuration + printf("\n--- Testing mock_print_config() ---\n"); + mock_print_config(); + + // Test QuaryDTR + printf("\n--- Testing mock_QuaryDTR() ---\n"); + UCHAR pageBuf[1024]; + UCHAR heatsink; + CHAR result = mock_QuaryDTR(0, pageBuf, &heatsink); + printf("QuaryDTR result: %d\n", result); + printf("Serial Number: %.16s\n", pageBuf); + printf("Model Name: %.20s\n", pageBuf + 16); + printf("Firmware: %.8s\n", pageBuf + 64); + + // Test GetCtlrEvent + printf("\n--- Testing mock_get_ctlr_event() ---\n"); + EVENT_INFO evt; + result = mock_GetCtlrEvent(0, &evt); + printf("GetCtlrEvent result: 0x%02X\n", result); + printf("Event Status: %d\n", evt.bStatus); + if (evt.bStatus) { + printf("Event Data: "); + for (int i = 0; i < 16 && i < MAX_EDB_SZ; i++) { + printf("%02X ", evt.bEventBuf[i]); + } + printf("\n"); + } + + // Test pushing custom event + printf("\n--- Testing mock_push_event() ---\n"); + UCHAR customEvent[] = { + 0x03, 0x00, 0x00, 0x00, // Event Type: RAID Rebuild Start + 0x00, 0x00, 0x00, 0x00, // Timestamp + 0x00, 0x00, 0x00, 0x00, // RAID ID 0 + 0x00, 0x00, 0x00, 0x00 + }; + mock_push_event(customEvent, 16); + printf("Custom event pushed\n"); + + // Get the custom event + result = mock_GetCtlrEvent(0, &evt); + printf("GetCtlrEvent result: 0x%02X\n", result); + + // Test configuration functions + printf("\n--- Testing configuration functions ---\n"); + mock_set_controller_count(2); + mock_set_controller_serial(1, "MOCK00000002"); + mock_set_controller_model(1, "Accusys GEN3"); + mock_print_config(); + + // Test event generation + printf("\n--- Testing event generation ---\n"); + mock_generate_disk_event(5, 0x01); // Disk 5 online + mock_generate_raid_event(0, 0x02); // RAID 0 rebuild + printf("Generated 2 events\n"); + + // Cleanup + printf("\n--- Testing mock_cleanup() ---\n"); + mock_cleanup(); + + printf("\n=== All Tests Completed ===\n"); + + return 0; +}