3 /// Mode class for GPRS modem mode (using endpoints on
8 #include "controller.h"
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
)
25 , m_continue_reading(false)
26 , m_callback(callback
)
27 , m_callback_context(callback_context
)
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
;
51 while( ipmodem
->m_continue_reading
) {
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
);
65 // call callback if available
66 if( ipmodem
->m_callback
) {
67 (*ipmodem
->m_callback
)(ipmodem
->m_callback_context
,
72 // // append data to readCache
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());
85 eout("Unknown exception in IpModem::DataReadThread, ignoring!");
92 //////////////////////////////////////////////////////////////////////////////
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
;
106 throw Barry::Error(oss
.str());
109 // clear halt when starting out
110 m_dev
.ClearHalt(pair
.read
);
111 m_dev
.ClearHalt(pair
.write
);
114 m_continue_reading
= true;
115 int ret
= pthread_create(&m_modem_read_thread
, NULL
, &IpModem::DataReadThread
, this);
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
));
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