int16_t // no return value - provided by vt100_getError() vt100_thread(THREAD_ARGS *args ) { // char nextChar; // input character from Serial port // int16_t fd = 0; // file descriptor for Serial Port open, read, write const char *portName; VIRTUAL_DISPLAY *pVDisplay; // pointer to virtual Display char *pTextBuffer = NULL; // malloc'd text area char *pAttribsBuffer = NULL; // malloc'd attribs area char **pTextPtrsBuffer = NULL; // malloc'd text pointers (rows) area char **pAttribsPtrsBuffer = NULL; // malloc'd attribs pointers (rows) area int16_t rows = 0; int16_t cols = 0; int16_t bumpUpCols = 0; int16_t numBytes = 0; int16_t numPtrBytes = 0; int16_t rowLength = 0; int16_t i = 0; // array loop variable // unpack the two most crucial parameters - rows & cols - from args rows = args[0].thr_DisplayRows; cols = args[0].thr_DisplayCols; // have to allocate space on even pointer boundaries for rows bumpUpCols = cols % sizeof( char *); // see if number of columns is on a pointer boundary if( bumpUpCols) cols += ( sizeof(char *) - bumpUpCols); // if not (non-zero remainder), force to next boundary numBytes = rows * cols; rowLength = cols * (sizeof(char)); #if DEBUG_ON printf("\n\nvt100_THREAD %d is STARTING", args[0].thr_threadId); printf("\n - on port %s with display rows %d and cols %d, pointer size is %d bytes", args[0].thr_portName, rows, cols, sizeof( char *) ); printf("\n malloc() %d bytes each for Virtual Display text & data arrays", numBytes ); #endif // // Concept - since screen size can vary in number of row or columns, // we have dynamic arrays for the text display and the attributes display // The Virtual Display for text is a list of pointers - 1 per line, and // a similar list of pointers for the attributes - 1 pointer per line // /* * First - malloc() all Virtual Display data area and set up pointer arrays * */ pTextBuffer = (char *) malloc(numBytes); pAttribsBuffer = (char *) malloc(numBytes); numPtrBytes = numRows * (sizeof (char *)); pTextPtrsBuffer = (char **) malloc(numPtrBytes ); pAttribsPtrsBuffer = (char **) malloc(numPtrBytes ); if( (pTextBuffer == NULL) || (pAttribsBuffer == NULL) || (pTextPtrsBuffer == NULL) || (pAttribsPtrsBuffer == NULL) ) { #if DEBUG_ON & DEBUG_MALLOC printf("\n\nvt100_thread: malloc probs: numBytes %d, numPtrBytes %d ", numBytes, numPtrBytes ); printf("\n Ptrs are: %0x, %0x, %0x, %0x", (unsigned int) pTextBuffer, (unsigned int) pAttribsBuffer, (unsigned int) pTextPtrsBuffer, (unsigned int) pAttribsPtrsBuffer ); #endif return( vt100_set_errorCode(ERR_09_MEM_ALLOC) ); } #if DEBUG_ON & DEBUG_THREAD printf("\n\nvt100_thread: malloc results: numBytes %d, numPtrBytes %d ", numBytes, numPtrBytes ); #endif // init the Virtual Display with the buffer addresses & row pointer arrays // buffer & array addresses used for later free() calls vDisplay.pText = pTextPtrsBuffer; vDisplay.pAttribs = pAttribsPtrsBuffer; vDisplay.pTextBuf = pTextBuffer; vDisplay.pAttribsBuf = pAttribsBuffer; vDisplay.ptrsBufSize = numPtrBytes; vDisplay.charsBufSize = numBytes; // set up the pointer arrays from malloc'd memory for( i = 0; i < rows ; i++ ) // distribute the memory into pointer arrays { pTextPtrsBuffer[i] = pTextBuffer; pTextBuffer += rowLength; pAttribsPtrsBuffer[i] = pAttribsBuffer; pAttribsBuffer += rowLength; #if DEBUG_ON & DEBUG_MALLOC printf("\n row %d: TextPtr: %0x, Attribs Ptr: %0x,", i+1, (unsigned int) pTextPtrsBuffer[i], (unsigned int) pAttribsPtrsBuffer[i] ); #endif } #if DEBUG_ON & DEBUG_MALLOC printf("\n vDisplay struct: TextPtrBuffer: %0x, AttribsPtrBuffer: %0x,", (unsigned int) pTextPtrsBuffer, (unsigned int) pAttribsPtrsBuffer ); printf("\n=========================================================="); for( i = 0; i < rows; i++ ) { printf("\n %d: text %0x, attrib %0x ", i, (unsigned int) vDisplay.pText[i], (unsigned int) vDisplay.pAttribs[i]); } #endif // check if fpui port is present and can be opened portName = args[0].thr_portName; pVDisplay = args[0].thr_DisplayPtr; if( portName == NULL ) // no fpui present - can't read any chars { while(!vt100_allDone) { #if DEBUG_ON & DEBUG_THREAD printf("T%d, ", ++counter); if( counter % 10) printf("\n"); #endif sleep(1); // wait 1secs - allow asynch call to process file input } } else { // we are given port to open like "/dev/fpi" // we will open the port and process characters received to the VT #if DEBUG_ON // clear the display and show the results // do compare on the display that was just cleared with the local dump file // this must be removed for delivery - should not be accessed from the library routines int16_t result = 0; vt100_clearVD(); // start clean & clear before text input result = vt100_compareVD("display.clear"); printf("\nvt100_thread: compareVD: display.clear = %d \n", result); vt100_showVD(stdout, "After call to vt100_clearVD"); #endif if( (fdSerialPort = openSerialPort(portName) ) <= 0 ){ // Error on open #if DEBUG_ON printf("\n ERR_05_PORT_OPEN; received %d trying to open %s \n", fdSerialPort, portName); #endif vt100_set_errorCode(ERR_05_PORT_OPEN); threadErrorCode = ERR_05_PORT_OPEN; vt100_allDone = TRUE; } #if DEBUG_ON printf("\nTHREAD %d ready to read input from %s ... ", args[0].thr_threadId, portName); printf("\n Please start entering input:\n (terminate with a 'z' on a new line}\n"); #endif while(!vt100_allDone ) { vt100_processInput( fdSerialPort, NULL, pVDisplay ); // read Serial Port and process forever - no line buffer here } // end forever while loop // all done - close the serial port and exit closeSerialPort(fdSerialPort); // vt100_dumpVD("dump.thread.after", "thread after key inputs"); } // end - good serial port #if DEBUG_ON printf("\n\n vt100 - exiting thread # %d", args[0].thr_threadId ); #endif sleep(1); // free the malloc'd memory in reverse order free( vDisplay.pAttribs ); free( vDisplay.pText ); free( vDisplay.pAttribsBuf ); free( vDisplay.pTextBuf ); pthread_exit(&threadErrorCode); // return error code to the original start function // return (errorCode); } // end vt100_thread()
/** * \brief int16_t main() * * \param[in] pFileName - something like "dump_01.txt" * * \param[out] Description * * \return test framework main() routine * * */ int main (int argc, char *argv[]) { // arg0 is the actual command line that invoked this program! char *fileName = argv[1]; static char returnBuffer[BUFFER_LEN] = {'\0','\0','\0','\0','\0','\0','\0' }; int16_t result; int16_t fd = 0; int16_t autoIncrement = 0; // size of Front Panel Display - must be int variables for scanf() function int frontPanelRows = 0; int frontPanelCols = 0; // char *portName = "/dev/tty"; // use keyboard tty input for serial I/O char *portName = NULL; printf("\n\n Test Framework for vt100 emulator library "); printf("\n (command syntax: './vt filename')\n"); // get the working port name and fd fd = vt100_getPortFd(portName); // portName = "/dev/ttyS3"; // Initial setup of arrays in memory if( strcmp(fileName, "") == 0) fileName = "disp_dumpVD.txt"; printf("\n main: fileName is %s, portName is %s, port fd is %d \n", fileName, portName, fd); // Due to Dynamic Memory Allocation - can not call any routines until vt100_start() is called // result = vt100_dumpVD(fileName, 0, "Initial State"); // show original data array - with no number extenison // printf("\n\n Result of vt100_dumpVT = %d \n", result); // vt100_showVD(stdout, "Initial State"); // do compare on intial state // result = vt100_compareVD("display.8.40.start"); // printf("\n Default compareVD: display.8.40.start = %d \n", result); printf("\n\n Number of rows in the Front Panel Display: "); scanf("%d", &frontPanelRows ); printf("\n Number of columns in the Front Panel Display: "); scanf("%d", &frontPanelCols ); // vt100_start() printf("\n\n================= vt100_start() =============\n"); printf("\n - calling vt100_start() for port %s: with %d rows and %d columns\n", portName, frontPanelRows, frontPanelCols); // result = vt100_start(portName); // modify array result = vt100_start(NULL , frontPanelRows, frontPanelCols); // modify array if( result != 0 ) printf("\n ... returned error code = %d ", result); printf("\n Initial states of errorCode: %d and errorText %s ", vt100_get_errorCode(), vt100_get_errorText() ); vt100_dumpVD("dump.vt100_start", ++autoIncrement, "after vt100_start()"); vt100_showVD(stdout, "after vt100_start()"); vt100_clearVD(); // initialize or clear the display rows & columns from malloc garbage printf("\n\n========= vt100_clear - compare clear with display.clear =============\n"); vt100_dumpVD("dump.after_1st_clear", ++autoIncrement, "after 1st clear"); vt100_showVD(stdout, "after 1st vt100_clear(0 after the start()"); result = vt100_compareVD("display.clear"); printf("\n\n Result of vt100_compareVD = %d, for file: %s \n", result, "display.clear"); if( result != 0 ) printf("\n errorText = %s", vt100_get_errorText() ); printf("\n\n================= vt100_set_auxSwitch() ON ===========================\n"); result = vt100_set_auxSwitch( 1 ); vt100_dumpVD("auxSwitch.out", ++autoIncrement, "set_auxSwitch ON"); printf("\n\n Result vt100_set_auxSwitch = %d \n", result); vt100_showVD(stdout, "fileToVD"); sleep(1); printf("\n\n================= vt100_set_auxSwitch() OFF ==========================\n"); result = vt100_set_auxSwitch( 0 ); vt100_dumpVD("auxSwitch.out", ++autoIncrement, "set_auxSwitch OFF"); printf("\n\n Result vt100_set_auxSwitch = %d \n", result); vt100_showVD(stdout, "fileToVD"); sleep(1); printf("\n\n================= vt100_fileToVD - short file '1234.in' =============\n"); result = vt100_fileToVD("1234.in"); vt100_dumpVD("1234.out", ++autoIncrement, "fileToVD"); printf("\n\n Result vt100_fileToVD = %d \n", result); vt100_showVD(stdout, "fileToVD"); sleep(1); printf("\n ------------- return buffer: ------------"); vt100_vtInputBuffer(returnBuffer, sizeof (returnBuffer)); printf("\n returnBuffer starts on next line: \n%s\n-------------------\n", returnBuffer); sleep(2); printf("\n\n================= Command/Response sequences ========\n"); result = vt100_fileToVD("commands.in"); sleep(1); vt100_dumpVD("cmdResponses.out", ++autoIncrement, "CMD Responses"); printf("\n\n Result of cmdResponses using vt100_fileToVD = %d \n", result); vt100_showVD(stdout, "CMD_Repsonses "); sleep(1); printf("\n\n================= vt100_stringToVD # 1 - very short =============\n"); vt100_stringToVD("1234"); result = vt100_dumpVD("displayString.txt", ++autoIncrement, "short stringToVD"); printf("\n\n Result of vt100_dumpVD = %d \n", result); vt100_showVD(stdout, "short vt100_stringToVD"); printf("\n\n================= vt100_stringToVD # 2 - long multi-line ========\n"); vt100_stringToVD("This is a test \n#9999: of the emergency broadcasting system 0123456789ABC\n\n\n\tTAKE 2 \n\n\tThe END\t17abc\t25def\t33ghi\n\t\t\t7777"); result = vt100_dumpVD("displayString.txt", ++autoIncrement, "long stringToVD"); printf("\n\n Result of vt100_dumpVD = %d \n", result); vt100_showVD(stdout, "long vt100_stringToVD"); sleep(2); printf("\n\n============ Special Chars create (vt100_fileToVD) =============\n"); vt100_clearVD(); // initialize or clear the display rows & columns vt100_resetParms(); // restore all PARMs etc before doing Special Chars testing result = vt100_fileToVD("specialChars.in"); vt100_dumpVD("specialChars.out", ++autoIncrement, "Special Chars"); printf("\n\n Result of Special Chars vt100_fileToVD = %d \n", result); vt100_showVD(stdout, "Special Chars Compose "); sleep(1); printf("\n\n=========== Special Chars compare - display.special OK ============\n"); result = vt100_compareVD("display.special"); printf("\n\n Result of vt100_compareVD = %d, for file: %s \n", result, "display.special"); if( result != 0 ) printf("\n errorText = %s ", vt100_get_errorText() ); printf("\n\n======= Special Chars compare - display.special.bad - FAIL ========\n"); result = vt100_compareVD("display.special.bad"); printf("\n\n Result of vt100_compareVD = %d, for file: %s \n", result, "display.special.bad"); if( result != 0 ) printf("\n errorText = %s ", vt100_get_errorText() ); printf("\n\n============= vt100_fileToVD - junk screen =============\n"); result = vt100_fileToVD("testFileToVD.in"); vt100_dumpVD("testFileToVD.out", ++autoIncrement, "fileToVD"); printf("\n\n Result vt100_fileToVD = %d \n", result); vt100_showVD(stdout, "fileToVD"); printf("\n - compare the testFileToVD.in with the display.testIput "); result = vt100_compareVD("display.testInput"); printf("\n\n Result = %d, for file: %s \n", result, "display.testIput"); sleep(1); printf("\n ------------- return buffer: ------------"); vt100_vtInputBuffer(returnBuffer, sizeof (returnBuffer)); printf("\n returnBuffer starts on next line: \n%s\n-------------------\n", returnBuffer); sleep(1); printf("\n\n============= Command/Response sequences # 2 =======\n"); result = vt100_fileToVD("commands.in"); sleep(1); vt100_dumpVD("cmdResponses.out", ++autoIncrement, "CMD Responses"); printf("\n\n Result of cmdResponses using vt100_fileToVD = %d \n", result); vt100_showVD(stdout, "CMD_Repsonses "); sleep(1); printf("\n\n================= vt100_fromDumptoVD - display.fpm =============\n"); vt100_resetParms(); // restore to power up condition result = vt100_fromDumpToVD("display.fpm"); vt100_dumpVD("test_fromDumpToVD.out", ++autoIncrement, "fromDumpToVD"); printf("\n\n Result vt100_fromDumpToVD = %d \n", result); vt100_showVD(stdout, "fromDumpToVD"); printf("\n\n================= vt100_compareVD - display.fpm =============\n"); result = vt100_compareVD("display.fpm"); printf("\n\n Result of vt100_compareVD = %d, for file: %s \n", result, "display.fpm"); if( result != 0 ) printf("\n errorText = %s ", vt100_get_errorText() ); /************************* don't need to test this any more ..... printf("\n\n================= vt100_fromDumptoVD - bad file =======\n"); result = vt100_fromDumpToVD("display.fail"); vt100_dumpVD("test_fromDumpToVD.out", ++autoIncrement, "fromDumpToVD_FAIL"); printf("\n\n Result vt100_fromDumpToVD = %d \n", result); vt100_showVD(stdout, "fromDumpToVD_FAIL"); ****************************************************/ printf("\n\n================= vt100_fromDumptoVD - display.config =============\n"); // vt100_resetParms(); // restore to power up condition result = vt100_fromDumpToVD("display.config"); vt100_dumpVD("disp_dumpVD.tst", ++autoIncrement, "fromDumpToVD - config"); printf("\n\n Result vt100_fromDumpToVD = %d \n", result); // printf("\n errorCode: %d, errorText: %s ", vt100_get_errorCode(),vt100_get_errorText() ); vt100_showVD(stdout, "fromDumpToVD - config"); printf("\n\n================= vt100_compareVD - display.config =============\n"); result = vt100_compareVD("display.config"); printf("\n\n Result of vt100_compareVD = %d, for file: %s \n", result, "display.config"); if( result != 0 ) printf("\n errorText = %s ", vt100_get_errorText() ); printf("\n\n================= vt100_scrollVD - UP =======\n"); vt100_scrollVD(1); vt100_dumpVD("test_scrollVD_UP.out", ++autoIncrement, "scrollVD-UP!"); vt100_showVD(stdout, "scrollVD-UP!"); printf("\n\n================= vt100_scrollVD - DOWN =======\n"); vt100_scrollVD(-1); vt100_dumpVD("test_scrollVD_DOWN.out", ++autoIncrement, "scrollVD-DOWN!"); vt100_showVD(stdout, "scrollVD-DOWN!"); /* ****************** don't need this test anymore ************ printf("\n\n================= vt100_scrollVD - Bad arg =======\n"); vt100_scrollVD(5); vt100_dumpVD("test_scrollVD_badArg.out", ++autoIncrement, "scrollVD-badArg!"); vt100_showVD(stdout, "scrollVD-badArg!"); *********************************************/ /************************* usleep(3); // 300 msecs ? printf("\n\n\n\n SYSTEM CALL to show process ID:"); system( "ps -e | grep vt"); printf("\n--------------------------------\n\n"); ***********************************/ vt100_end(); sleep (1); // give time for last calls to output to screen? exit(0); } // end - main ()