Reorganized sample ppp options files
[barry/pauldeden.git] / src / m_ipmodem.cc
blobedfa5204a0b31005616357e9cb60c5bda3f9cce3
1 ///
2 /// \file m_ipmodem.cc
3 /// Mode class for GPRS modem mode (using endpoints on
4 /// modern devices)
5 ///
7 #include "m_ipmodem.h"
8 #include "controller.h"
9 #include "data.h"
10 #include "debug.h"
11 #include <sstream>
13 namespace Barry { namespace Mode {
15 const char special_flag[] = { 0x78, 0x56, 0x34, 0x12 }; // 0x12345678
17 //////////////////////////////////////////////////////////////////////////////
18 // Mode::IpModem class
20 IpModem::IpModem(Controller &con,
21 DeviceDataCallback callback,
22 void *callback_context)
23 : m_con(con)
24 , m_dev(con.m_dev)
25 , m_continue_reading(false)
26 , m_callback(callback)
27 , m_callback_context(callback_context)
31 IpModem::~IpModem()
33 // thread running?
34 if( m_continue_reading ) {
35 m_continue_reading = false;
36 pthread_join(m_modem_read_thread, NULL);
41 //////////////////////////////////////////////////////////////////////////////
42 // protected API / static functions
44 void *IpModem::DataReadThread(void *userptr)
46 IpModem *ipmodem = (IpModem*) userptr;
48 int read_ep = ipmodem->m_con.GetProbeResult().m_epModem.read;
49 Data data;
51 while( ipmodem->m_continue_reading ) {
53 try {
55 ipmodem->m_dev.BulkRead(read_ep, data, 5000);
57 // is it a special code?
58 if( data.GetSize() > 4 &&
59 memcmp(data.GetData() + data.GetSize() - 4, special_flag, sizeof(special_flag)) == 0 ) {
60 // log, then drop it on the floor for now
61 ddout("IPModem special packet:\n" << data);
62 continue;
65 // call callback if available
66 if( ipmodem->m_callback ) {
67 (*ipmodem->m_callback)(ipmodem->m_callback_context,
68 data.GetData(),
69 data.GetSize());
71 // else {
72 // // append data to readCache
73 // FIXME;
74 // }
77 catch( Usb::Timeout &to ) {
78 // do nothing on timeouts
79 ddout("Timeout in DataReadThread!");
81 catch( std::exception &e ) {
82 eout("Exception in IpModem::DataReadThread: " << e.what());
84 catch( ... ) {
85 eout("Unknown exception in IpModem::DataReadThread, ignoring!");
89 return 0;
92 //////////////////////////////////////////////////////////////////////////////
93 // public API
95 void IpModem::Open(const char *) // password is ignored for IpModem
97 // check that we have endpoints for the modem
98 const Usb::EndpointPair &pair = m_con.GetProbeResult().m_epModem;
99 if( !pair.IsComplete() ) {
100 std::ostringstream oss;
101 oss << "IP Modem not supported by this device: "
102 << "read: " << std::hex << (unsigned int) pair.read
103 << " write: " << std::hex << (unsigned int) pair.write
104 << " type: " << std::hex << (unsigned int) pair.type;
105 eout(oss.str());
106 throw Barry::Error(oss.str());
109 // clear halt when starting out
110 m_dev.ClearHalt(pair.read);
111 m_dev.ClearHalt(pair.write);
113 // spawn read thread
114 m_continue_reading = true;
115 int ret = pthread_create(&m_modem_read_thread, NULL, &IpModem::DataReadThread, this);
116 if( ret ) {
117 m_continue_reading = false;
118 throw Barry::ErrnoError("IpModem:: Error creating USB read thread.", ret);
121 // const char start[] = { 0x01, 0, 0, 0, 1, 0, 0, 0, 0x78, 0x56, 0x34, 0x12 };
122 const char start[] = { 0x01, 0, 0, 0, 0x78, 0x56, 0x34, 0x12 };
123 Data block(start, sizeof(start));
124 Write(block);
127 void IpModem::Write(const Data &data, int timeout)
129 if( data.GetSize() == 0 )
130 return; // nothing to do
132 // m_dev.ClearHalt(m_con.GetProbeResult().m_epModem.write);
134 m_dev.BulkWrite(m_con.GetProbeResult().m_epModem.write,
135 m_filter.Write(data), timeout);
138 }} // namespace Barry::Mode