pppob.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <barry/barry.h>
00024 #include <iomanip>
00025 #include <iostream>
00026 #include <fstream>
00027 #include <vector>
00028 #include <string>
00029 #include <memory>
00030 #include <getopt.h>
00031 #include <sys/select.h>
00032 #include <sys/time.h>
00033 #include <sys/types.h>
00034 #include <unistd.h>
00035 #include <signal.h>
00036
00037
00038 using namespace std;
00039 using namespace Barry;
00040
00041 bool data_dump = false;
00042 volatile bool signal_end = false;
00043
00044 void Usage()
00045 {
00046 int major, minor;
00047 const char *Version = Barry::Version(major, minor);
00048
00049 cerr
00050 << "pppob - PPP over Barry\n"
00051 << " Copyright 2007-2009, Net Direct Inc. (http://www.netdirect.ca/)\n"
00052 << " Using: " << Version << "\n"
00053 << "\n"
00054 << " -l file Direct pppob log output to file (useful with -v)\n"
00055 << " -p pin PIN of device to talk with\n"
00056 << " If only one device plugged in, this flag is optional\n"
00057 << " -P pass Simplistic method to specify device password\n"
00058 << " -s Use Serial mode instead of IpModem\n"
00059 << " -v Dump protocol data during operation (debugging only!)\n"
00060 << endl;
00061 }
00062
00063 void signal_handler(int signum)
00064 {
00065 signal_end = true;
00066 }
00067
00068 void SerialDataCallback(void *context, const unsigned char *data, int len)
00069 {
00070 if( len && data_dump )
00071 barryverbose("ReadThread:\n" << Data(data, len));
00072
00073 while( len ) {
00074 int written = write(1, data, len);
00075 if( written > 0 ) {
00076 len -= written;
00077 data += written;
00078 }
00079 else {
00080 barryverbose("Error in write()");
00081 }
00082 }
00083 }
00084
00085 void ProcessStdin(Modem &modem)
00086 {
00087
00088
00089 Data data;
00090 int bytes_read;
00091 fd_set rfds;
00092 struct timeval tv;
00093 int ret;
00094
00095
00096 signal_end = false;
00097 signal(SIGINT, &signal_handler);
00098 signal(SIGHUP, &signal_handler);
00099 signal(SIGTERM, &signal_handler);
00100
00101 FD_ZERO(&rfds);
00102 while( signal_end == false ) {
00103
00104
00105
00106
00107 FD_SET(0, &rfds);
00108 tv.tv_sec = 30;
00109 tv.tv_usec = 0;
00110
00111 ret = select(1, &rfds, NULL, NULL, &tv);
00112 if( ret == -1 ) {
00113 perror("select()");
00114 }
00115 else if( ret && FD_ISSET(0, &rfds) ) {
00116 bytes_read = read(0, data.GetBuffer(), data.GetBufSize());
00117 if( bytes_read == 0 )
00118 break;
00119
00120 if( bytes_read > 0 ) {
00121 data.ReleaseBuffer(bytes_read);
00122 modem.Write(data);
00123 }
00124 }
00125 }
00126 }
00127
00128 int main(int argc, char *argv[])
00129 {
00130 cout.sync_with_stdio(true);
00131
00132
00133 try {
00134
00135 uint32_t pin = 0;
00136 bool force_serial = false;
00137 std::string logfile;
00138 std::string password;
00139
00140
00141 for(;;) {
00142 int cmd = getopt(argc, argv, "l:p:P:sv");
00143 if( cmd == -1 )
00144 break;
00145
00146 switch( cmd )
00147 {
00148 case 'l':
00149 logfile = optarg;
00150 break;
00151
00152 case 'p':
00153 pin = strtoul(optarg, NULL, 16);
00154 break;
00155
00156 case 'P':
00157 password = optarg;
00158 break;
00159
00160 case 's':
00161 force_serial = true;
00162 break;
00163
00164 case 'v':
00165 data_dump = true;
00166 break;
00167
00168 case 'h':
00169 default:
00170 Usage();
00171 return 0;
00172 }
00173 }
00174
00175
00176
00177
00178 std::auto_ptr<std::ofstream> log;
00179 if( logfile.size() ) {
00180 log.reset( new std::ofstream(logfile.c_str(), ios::app) );
00181 Barry::Init(data_dump, log.get());
00182 }
00183 else {
00184 Barry::Init(data_dump, &std::cerr);
00185 }
00186
00187
00188
00189
00190 Barry::Probe probe;
00191 int activeDevice = probe.FindActive(pin);
00192 if( activeDevice == -1 ) {
00193 if( pin )
00194 cerr << "PIN " << setbase(16) << pin
00195 << " not found" << endl;
00196 cerr << "No device selected" << endl;
00197 return 1;
00198 }
00199
00200 const ProbeResult &device = probe.Get(activeDevice);
00201
00202 if( !force_serial && device.HasIpModem() ) {
00203 barryverbose("Using IpModem mode...");
00204
00205
00206 Controller con(probe.Get(activeDevice));
00207
00208
00209
00210 Mode::IpModem modem(con, SerialDataCallback, 0);
00211 modem.Open(password.c_str());
00212
00213 ProcessStdin(modem);
00214 modem.Close();
00215 }
00216 else {
00217 barryverbose("Using Serial mode...");
00218
00219
00220
00221 SocketRoutingQueue router;
00222 router.SpinoffSimpleReadThread();
00223
00224
00225 Controller con(probe.Get(activeDevice), router);
00226
00227
00228
00229 Mode::Desktop desktop(con);
00230 desktop.Open(password.c_str());
00231
00232
00233 Mode::Serial modem(con, SerialDataCallback, 0);
00234 modem.Open(password.c_str());
00235
00236 ProcessStdin(modem);
00237 }
00238
00239 barryverbose("Exiting");
00240
00241 }
00242 catch( std::exception &e ) {
00243 cerr << "exception caught in main(): " << e.what() << endl;
00244 return 1;
00245 }
00246
00247 return 0;
00248 }
00249