// ------------------------------- // // -------- Start of File -------- // // ------------------------------- // // ----------------------------------------------------------- // // C++ Source Code File Name: comserv.cpp // Compiler Used: MSVC40, egcs-2.90.29, HP CPP 10.24 // Produced By: Doug Gaer // File Creation Date: 09/20/1999 // Date Last Modified: 06/21/2000 // Copyright (c) 2000 Dougas M. Gaer // ----------------------------------------------------------- // // ------------- Program Description and Details ------------- // // ----------------------------------------------------------- // /* The VBS C++ classes are copyright (c) 2000, by Douglas M. Gaer. All those who put this code or its derivatives in a commercial product MUST mention this copyright in their documentation for users of the products in which this code or its derivative classes are used. Otherwise, you have the freedom to redistribute verbatim copies of this source code, adapt it to your specific needs, or improve the code and release your improvements to the public provided that the modified files carry prominent notices stating that you changed the files and the date of any change. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE, YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. The ComSock server is used to connect a stream socket to a serial port. */ // ----------------------------------------------------------- // #include <iostream.h> #include <stdlib.h> #include "comfile.h" #include "systime.h" // -------------------------------------------------------------- // Constants // -------------------------------------------------------------- const double comservVersionNumber = 1034.101; const char *comservProgramName = "ComSock Server"; const int __RESTART_SERVER__ = -1; const int __SHUTDOWN_SERVER__ = 0; // -------------------------------------------------------------- int CopyStreamSocketToSerialPort(vbsCommFileCache *dev, int port, char *tty_device, int baud) // Copies data from a stream socket to the memory cache // and flushes the cache buffers to a disk file. { vbStream server; vbSerialComm serial_port; unsigned byte_count = 0; // Initialize the serial port int status = serial_port.OpenSerialPort(tty_device); if(status < 0) { cout << "Cannot open " << tty_device << endl; cout << serial_port.SerialCommExceptionMessage() << endl; cout << "Exiting..." << endl; return __SHUTDOWN_SERVER__; } if(status == vbSerialComm::scommREAD_ONLY) { cout << endl; cout << tty_device << " is open for read only access." << endl; cout << "You do not have permission to write to this device!" << endl; return __SHUTDOWN_SERVER__; } serial_port.SetBaudRate(baud); if(serial_port.InitSerialPort() < 0) { cout << "Cannot initalize " << tty_device << endl; cout << serial_port.SerialCommExceptionMessage() << endl; return __SHUTDOWN_SERVER__; } if(server.StreamServer(port) != 0) { cout << server.SocketExceptionMessage() << endl; return __SHUTDOWN_SERVER__; } // Get the host name assigned to this machine char hostname[vbsMAX_NAME_LEN]; if(server.HostName(hostname) != 0) { cout << server.SocketExceptionMessage() << endl; return __SHUTDOWN_SERVER__; } cout << "Opening comsock stream server on host " << hostname << endl; cout << "Listening on port " << port << endl; cout << "Writing to " << tty_device << " at " << baud << ":N,8,1" << endl; SysTime systime; // Systime object used for logging functions cout << "Listening on port " << port << endl; vbsSocket_t remote_socket = server.Accept(); if(remote_socket < 0) { cout << server.SocketExceptionMessage() << endl; return __SHUTDOWN_SERVER__; } char client_name[vbsMAX_NAME_LEN]; int r_port = -1; while(1) { // Read the block following a client connection vbBlockHeader vb; if(server.ReadClientHeader(vb) != 0) { cout << server.SocketExceptionMessage() << endl; return __RESTART_SERVER__; } // Read the status byte to determine what to do with this block __ULWORD__ block_status = vb.Status; __SBYTE__ status = (__SBYTE__)((block_status & 0xFF00)>>8); if(status == vbKillServer) { dev->Flush(); // Flush all the cache buffers before exiting return __SHUTDOWN_SERVER__; } switch(status) { // Process each block of data case vbSendBlock : { server.GetClientInfo(client_name, r_port); cout << "Reading " << vb.Length << " bytes from " << client_name << " remote port " << r_port << endl << flush; if(!dev->CopyStreamSocketToSerialPort(&server, &serial_port, vb)) { cout << "Error copying from port " << port << " to " << tty_device << endl << flush; return __RESTART_SERVER__; } byte_count += (__ULWORD__)vb.Length; break; } case vbCloseConnection : cout << "Client closed connection at: " << systime.GetSystemDateTime() << endl << flush; dev->Flush(); // Flush all the cache buffers before closing return __RESTART_SERVER__; cout << byte_count << " bytes written to " << tty_device << endl << flush; byte_count = 0; server.CloseRemoteSocket(); cout << "Comm server listening on port " << port << endl << flush; remote_socket = server.Accept(); if(remote_socket < 0) { cout << server.SocketExceptionMessage() << endl; return __RESTART_SERVER__; } break; default: cout << "Only accepting raw data blocks" << endl; cout << "The \"" << status << "\" command was rejected" << endl; server.CloseRemoteSocket(); break; } } dev->Flush(); // Flush all the cache buffers before exiting return __SHUTDOWN_SERVER__; } // Programs main thread of execution int main(int argc, char **argv) { // Check arguments if(argc != 4) { cout << endl; cout.setf(ios::showpoint | ios::fixed); cout.precision(3); cout << comservProgramName << " version " << comservVersionNumber << endl; cout << "Usage: " << argv[0] << " port_number tty_device baud_rate" << endl; cout << endl; cout << "port_number = The port number used to listen for requests." << endl; cout << "tty_device = The serial port to write received data to." << endl; cout << "baud_rate = The serial port speed that will be used." << endl; cout << endl; return 0; } unsigned short port = (unsigned short) atoi(argv[1]); int short baud = (unsigned short) atoi(argv[3]); char *tty_device = argv[2]; vbsCommFileCache dev(__CACHE_SIZE__); // Device cache used to process a file SysTime systime; int rv = 1; cout << endl; cout << "Starting the " << comservProgramName << " server at: " << systime.GetSystemDateTime() << endl; while(rv != __SHUTDOWN_SERVER__) { rv = CopyStreamSocketToSerialPort(&dev, port, tty_device, baud); if(rv == __RESTART_SERVER__) cout << "Restarting the server at: " << systime.GetSystemDateTime() << endl; } cout << "Shutting down the server at: " << systime.GetSystemDateTime() << endl; cout << endl; return 0; } // ----------------------------------------------------------- // // ------------------------------- // // --------- End of File --------- // // ------------------------------- //