/* * bapiwlt * * Simple demo program to show the usage of BAPI DLL. * This program sends GBS_GET_NODE_INFO messages to a * node on the BITBUS Network and counts the answers. */ #define __MOD_BAPIWLT #define WIN32_LEAN_AND_MEAN #include #include #include #include "resource.h" #include "bapi.h" #define s_NIL 0 #define s_WAIT 1 #define s_SUSPEND 2 #define MAX_DEVICE_NAME_LEN 100 /* global variables */ HWND hBapiWLtWnd; const char gszBapiWLtClass[] = "BapiWLtWndClass"; const char gszAppName[] = "BAPI-WLineTest"; /* thread handle */ HANDLE hThread; /* state variable (shared variable with thread) */ volatile SHORT state = s_NIL; /* global bitbus variables */ CHAR bbdev[MAX_DEVICE_NAME_LEN]; UCHAR bbnode = 255; UCHAR bbtask = 0; /* Draw the connection data and the cycle and error counters. */ VOID LTDrawOut(LPTSTR name, LPTSTR serno, BOOL master, CHAR *dev, UCHAR node, UCHAR task, ULONG cyc, ULONG err, BYTE err_gbs) { HDC hdc; char nodestr[12], taskstr[12], errstr[12], cycstr[12]; char errgbsstr[12]; hdc = GetDC(hBapiWLtWnd); wsprintf((LPTSTR)nodestr,(LPCTSTR)"%.8ld",node); wsprintf((LPTSTR)taskstr,(LPCTSTR)"%.8ld",task); wsprintf((LPTSTR)cycstr,(LPCTSTR)"%.8ld",cyc); wsprintf((LPTSTR)errstr,(LPCTSTR)"%.8ld",err); wsprintf((LPTSTR)errgbsstr,(LPCTSTR)"0x%2.2x",err_gbs); TextOut(hdc,(short)40, (short)10,(LPCTSTR) " Name ", (short) 6); TextOut(hdc,(short)150, (short)10,(LPCTSTR) ":", 1); if (name){ TextOut(hdc,(short)180, (short)10,(LPCTSTR) name, (short) strlen(name)); } else { TextOut(hdc,(short)180, (short)10,(LPCTSTR) "Unknown", (short) 7); } TextOut(hdc,(short)40, (short)30,(LPCTSTR) " Serno ", (short) 7); TextOut(hdc,(short)150, (short)30,(LPCTSTR) ":", 1); if (serno){ TextOut(hdc,(short)180, (short)30,(LPCTSTR) serno, (short) strlen(serno)); } else { TextOut(hdc,(short)180, (short)30,(LPCTSTR) "Unknown", (short) 7); } TextOut(hdc,(short)40, (short)50,(LPCTSTR) " Mode ", (short) 6); TextOut(hdc,(short)150, (short)50,(LPCTSTR) ":", 1); if (master){ TextOut(hdc,(short)180, (short)50,(LPCTSTR) "Master", (short) 6); } else { TextOut(hdc,(short)180, (short)50,(LPCTSTR) "Slave", (short) 5); } TextOut(hdc,(short)40, (short)70,(LPCTSTR) " Device ", (short) 8); TextOut(hdc,(short)150, (short)70,(LPCTSTR) ":", 1); TextOut(hdc,(short)180, (short)70,(LPCTSTR) dev, (short) strlen(dev)); TextOut(hdc,(short)40, (short)90,(LPCTSTR) " Node ", (short) 6); TextOut(hdc,(short)150, (short)90,(LPCTSTR) ":", 1); TextOut(hdc,(short)180, (short)90,(LPCTSTR) nodestr, (short) strlen(nodestr)); TextOut(hdc,(short)40, (short)110,(LPCTSTR) " Task ", (short) 6); TextOut(hdc,(short)150, (short)110,(LPCTSTR) ":", 1); TextOut(hdc,(short)180, (short)110,(LPCTSTR) taskstr, (short) strlen(taskstr)); TextOut(hdc,(short)40, (short)130,(LPCTSTR) " Cycle ", (short) 7); TextOut(hdc,(short)150, (short)130,(LPCTSTR) ":", 1); TextOut(hdc,(short)180, (short)130,(LPCTSTR) cycstr, (short) strlen(cycstr)); TextOut(hdc,(short)40, (short)150,(LPCTSTR) " Error ", (short) 7); TextOut(hdc,(short)150, (short)150,(LPCTSTR) ":", 1); TextOut(hdc,(short)180, (short)150,(LPCTSTR) errstr, (short) strlen(errstr)); TextOut(hdc,(short)40, (short)170,(LPCTSTR) " GBS-Error ", (short) 11); TextOut(hdc,(short)150, (short)170,(LPCTSTR) ":", 1); TextOut(hdc,(short)180, (short)170,(LPCTSTR) errgbsstr, (short) strlen(errgbsstr)); ReleaseDC(hBapiWLtWnd, hdc); } DWORD WINAPI BBLTThreadProc(LPVOID lpPar) { INT32 iErr; int retMsgBox; CHAR cBuf[100]; BBHANDLE bchan; BitbusOpenData device_data; LPTSTR name = NULL; LPTSTR serno = NULL; BOOL master = TRUE; BitbusMsg bmsg; ULONG cycle = 0; ULONG error = 0; BYTE last_gbs = 0; /* * Try to open device in master mode first, if that fails * try to open in slave mode, if that fails too, that device * is not found. */ device_data.len = sizeof(device_data); bchan = BitbusOpenMaster("BAPIWLT", bbdev, &device_data); if (bchan < 0){ master = FALSE; device_data.len = sizeof(device_data); bchan = BitbusOpenSlave("BAPIWLT", bbdev, (-1), 2, &device_data); if (bchan < 0){ wsprintf(cBuf, "BitbusOpenSlave error no.: %3ld\n", bchan); MessageBox(hBapiWLtWnd, cBuf, "Error", (MB_OK | MB_ICONERROR)); state = s_NIL; } else if (bbnode != 255) { retMsgBox = MessageBox(hBapiWLtWnd, "Device is a Bitbus Slave.\n Slaves can only address node 255. Continue using node 255?\n", (LPSTR)gszAppName, MB_ICONQUESTION | MB_YESNO); if (retMsgBox == IDYES){ bbnode = 255; } else { BitbusClose(bchan); state = s_NIL; } } } if (bchan >= 0){ if (device_data.len >= sizeof(device_data)){ name = device_data.name; serno = device_data.serno; } else { name = NULL; serno = NULL; } InvalidateRect(hBapiWLtWnd, NULL, TRUE); while (state != s_NIL){ if (state == s_SUSPEND) { LTDrawOut(name, serno, master, bbdev, bbnode, bbtask, cycle, error, last_gbs); state = s_NIL; continue; } cycle++; memset(&bmsg, 0, sizeof(bmsg)); bmsg.len = 20; bmsg.node = bbnode; /* * If task number > 15 we address a task on the * "destination extension", set the DE_FLAG. */ if (bbtask > 0x0f) { bmsg.flags = SE_FLAG|DE_FLAG; bmsg.src_dest = bbtask - 0x10; } else { bmsg.flags = SE_FLAG; bmsg.src_dest = bbtask; } bmsg.com_res = GBS_GET_NODE_INFO; iErr = BitbusSendMsg(bchan, &bmsg); /* * If BitbusSendMsg fails there is no reason to wait for an answer. * BAPI_ERR_NO_CONNECTION is a serious error. Close the handle and * open a new one (Press "Start" again). All other errors end up in * a retry of sending the message. */ if (iErr == BAPI_ERR_NO_CONNECTION) { wsprintf(cBuf, "BitbusSendMsg: No Connection. Stop!\n"); MessageBox(hBapiWLtWnd, cBuf, "Error", (MB_OK | MB_ICONERROR)); state = s_SUSPEND; continue; } else if (iErr != BAPI_ERR_OK) { retMsgBox = IDNO; wsprintf(cBuf, "BitbusSendMsg error no.: %3ld\nRetry?", iErr); retMsgBox = MessageBox(hBapiWLtWnd, cBuf, (LPSTR)gszAppName, MB_ICONQUESTION | MB_YESNO); if (retMsgBox != IDYES) state = s_SUSPEND; continue; } else { memset(&bmsg, 0, sizeof(bmsg)); bmsg.com_res = 0xff; do { retMsgBox = IDNO; iErr = BitbusWaitMsg(bchan, &bmsg, 5000); /* * If BitbusWaitMsg fails with BAPI_ERR_NO_CONNECTION close * the handle and open a new one (Press "Start" again). * On all other errors you will be asked to retry getting the * answer. If you answer "No" the communication is stopped * and the handle is closed. Do not send more messages to * the device until you got the answer! */ if (iErr == BAPI_ERR_NO_CONNECTION) { wsprintf(cBuf, "BitbusWaitMsg: Connection lost. Stop!\n"); MessageBox(hBapiWLtWnd, cBuf, "Error", (MB_OK | MB_ICONERROR)); state = s_SUSPEND; continue; } else if ((iErr == BAPI_ERR_TIMEOUT)||(iErr == 0)) { wsprintf(cBuf, "BitbusWaitMsg: Nothing received in timeout period.\nRetry ?"); retMsgBox = MessageBox(hBapiWLtWnd, cBuf, (LPSTR)gszAppName, MB_ICONQUESTION | MB_YESNO); } else if (iErr < 0) { wsprintf(cBuf, "BitbusWaitMsg error no.: %3ld\nRetry ?", iErr); retMsgBox = MessageBox(hBapiWLtWnd, cBuf, (LPSTR)gszAppName, MB_ICONQUESTION | MB_YESNO); } } while (retMsgBox == IDYES); if (iErr <= 0){ state = s_SUSPEND; continue; } } /* bitbus error ? */ if (bmsg.com_res != GBS_ERR_OK) { last_gbs = bmsg.com_res; error++; } /* write output every 10 messages or at error */ if (bmsg.com_res != GBS_ERR_OK || ((cycle%10) == 0)) { LTDrawOut(name, serno, master, bbdev, bbnode, bbtask, cycle , error, last_gbs); } } iErr = BitbusClose(bchan); if (iErr != BAPI_ERR_OK) { wsprintf(cBuf, "BitbusClose error no.: %3ld", iErr); MessageBox(hBapiWLtWnd, cBuf, "Error", (MB_OK | MB_ICONERROR)); } } return TRUE; } INT_PTR CALLBACK NodeDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { int inode, itask; UINT len = 0; BOOL flg; CHAR cnvt_buf[MAX_DEVICE_NAME_LEN]; switch (uMsg){ case WM_INITDIALOG : SetDlgItemText(hwndDlg, IDC_BAPIWLT_DEVICE, bbdev); wsprintf((LPSTR)cnvt_buf,(LPSTR)"%3.d", bbnode); SetDlgItemText(hwndDlg, IDC_BAPIWLT_NODE, cnvt_buf); wsprintf((LPSTR)cnvt_buf,(LPSTR)"%3.d", bbtask); SetDlgItemText(hwndDlg, IDC_BAPIWLT_TASK, cnvt_buf); return TRUE; case WM_COMMAND : switch(LOWORD(wParam)){ case IDOK: len = GetDlgItemText(hwndDlg, IDC_BAPIWLT_DEVICE, cnvt_buf, MAX_DEVICE_NAME_LEN); if (!len) { MessageBox(hwndDlg, (LPSTR)"Enter Device: BBUS0, BBUS1, ... or IP Address", (LPSTR)gszAppName, MB_ICONSTOP | MB_OK); return TRUE; } inode = GetDlgItemInt(hwndDlg, IDC_BAPIWLT_NODE, &flg, FALSE); if (!flg || inode < 1 || inode > 255) { MessageBox(hwndDlg, (LPSTR)"1 <= Node <= 255", (LPSTR)gszAppName, MB_ICONSTOP | MB_OK); return TRUE; } itask = GetDlgItemInt(hwndDlg, IDC_BAPIWLT_TASK, &flg, FALSE); if (!flg || itask < 0 || itask > 31) { MessageBox(hwndDlg, (LPSTR)"0 <= Task <= 31", (LPSTR)gszAppName, MB_ICONSTOP | MB_OK); return TRUE; } strncpy(bbdev, cnvt_buf, sizeof(bbdev)); bbdev[sizeof(bbdev)-1] = '\0'; bbnode = inode; bbtask = itask; /* fallthrough */ case IDCANCEL : EndDialog(hwndDlg, 0); return TRUE; } break; } return FALSE; } void Cls_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { DWORD dwThreadId; switch (id) { case ID_BAPIWLT_START : if (state == s_NIL){ state = s_WAIT; hThread = CreateThread(NULL, 0, BBLTThreadProc, NULL, 0, &dwThreadId); } break; case ID_BAPIWLT_STOP: if (state == s_WAIT) { state = s_SUSPEND; WaitForSingleObject(hThread, 10000); CloseHandle(hThread); hThread = NULL; } break; case ID_BAPIWLT_TARGET: DialogBox(GetWindowInstance(hwnd), MAKEINTRESOURCE(DLG_BAPIWLT), hwnd, NodeDlgProc); break; case ID_BAPIWLT_EXIT: PostMessage(hwnd, WM_CLOSE, 0, 0L); break; } } void Cls_OnDestroy(HWND hwnd) { if (state != s_NIL) { state = s_SUSPEND; WaitForSingleObject(hThread, 10000); CloseHandle(hThread); hThread = NULL; } PostQuitMessage(0); } LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg){ case WM_COMMAND: return HANDLE_WM_COMMAND(hwnd, wParam, lParam, Cls_OnCommand); case WM_DESTROY: return HANDLE_WM_DESTROY(hwnd, wParam, lParam, Cls_OnDestroy); }; return DefWindowProc(hwnd, iMsg, wParam, lParam); } BOOL InitApplication(HINSTANCE hInstance) { WNDCLASSEX wcx; /* fill WNDCLASSEX-structure for main window */ wcx.cbSize = sizeof(wcx); wcx.style = CS_HREDRAW | CS_VREDRAW; wcx.lpfnWndProc = WndProc; wcx.cbClsExtra = 0; wcx.cbWndExtra = 0; wcx.hInstance = hInstance; wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcx.hCursor = LoadCursor(NULL,IDC_ARROW); wcx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wcx.lpszMenuName = MAKEINTRESOURCE(MENU_BAPIWLT); wcx.lpszClassName = gszBapiWLtClass; wcx.hIconSm = NULL; /* register WNDCLASSEX for main window */ return RegisterClassEx(&wcx); } HWND InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; /* create, get handle and show window */ hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, gszBapiWLtClass, gszAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 322, 230, NULL, NULL, hInstance, NULL); /* If window could not be created, return "failure" */ if (!hWnd) { return (NULL); } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); strncpy(bbdev, "BBUS0", sizeof(bbdev)); return (hWnd); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; /* Other instances of app running? */ if (!hPrevInstance) { if (!InitApplication(hInstance)) { return (FALSE); } } /* Perform initializations that apply to a specific instance */ if (NULL == (hBapiWLtWnd = InitInstance( hInstance, nCmdShow ))) return ( FALSE ) ; while (GetMessage(&msg, NULL, 0, 0)){ TranslateMessage(&msg); DispatchMessage(&msg); } return ((int) msg.wParam); }