Vodafone K3770/K3772-Z modems driver & networking library
Dependencies: Socket USBHostWANDongle lwip-sys lwip
Dependents: VodafoneUSBModemHTTPClientTest VodafoneUSBModemNTPClientTest VodafoneUSBModemSMSTest VodafoneUSBModemUSSDTest ... more
Fork of VodafoneUSBModem_bleedingedge by
This is the driver for the Vodafone K3700 & K3772-Z Dongles:
More details and instructions can be found here.
Revision 83:897a0de9d668, committed 2013-03-05
- Comitter:
- ashleymills
- Date:
- Tue Mar 05 14:54:15 2013 +0000
- Parent:
- 82:ab4d6263f25c
- Child:
- 84:39e28d162195
- Commit message:
- Added MU509 support
Changed in this revision
--- a/VodafoneUSBModem.cpp Tue Jan 29 13:49:23 2013 +0000 +++ b/VodafoneUSBModem.cpp Tue Mar 05 14:54:15 2013 +0000 @@ -593,10 +593,17 @@ // this modem defaults to sending a delivery receipt to the SM storage area // need to disable this for the current library to work in a sensible manner + INFO("Disabling SMS delivery receipts"); ret = m_at.executeSimple("at+csmp=1,,0,0",NULL); if(ret!=0) { return NET_PROTOCOL; } + INFO("Disabling unsolicitied notifications"); + ret = m_at.executeSimple("AT^CURC=0", NULL); //Huawei-specific, not 3GPP-compliant + if(ret != OK) + { + return NET_PROTOCOL; + } } else {
--- a/at/ATCommandsInterface.cpp Tue Jan 29 13:49:23 2013 +0000 +++ b/at/ATCommandsInterface.cpp Tue Mar 05 14:54:15 2013 +0000 @@ -32,25 +32,34 @@ #include "ATCommandsInterface.h" ATCommandsInterface::ATCommandsInterface(IOStream* pStream) : - m_pStream(pStream), m_open(false), m_env2AT(), m_AT2Env(), m_processingMtx(), - m_processingThread(&ATCommandsInterface::staticCallback, this, (osPriority)AT_THREAD_PRIORITY, 4*192), - m_eventsMgmtMtx(), m_eventsProcessingMtx() + m_pStream(pStream), // this is the serial interface to the modem + m_open(false), // AT interface is initially in a closed state + m_env2AT(), // send messages from calling functions to AT parsing thread + m_AT2Env(), // send messages from AT parsing thread to calling functions + m_processingMtx(), // mutex for processing thread + m_processingThread( // construct processing thread + &ATCommandsInterface::staticCallback, // static callback uses this pointer to run process() + this, + (osPriority)AT_THREAD_PRIORITY, // normal priority + 4*192 // size of the processing thread + ), + m_eventsMgmtMtx(), // mutex for managing events + m_eventsProcessingMtx() // mutex for processing events { - memset(m_eventsHandlers, 0, MAX_AT_EVENTS_HANDLERS * sizeof(IATEventsHandler*)); - - m_processingMtx.lock(); + // zero the memory for the event handler pointers + memset(m_eventsHandlers, 0, MAX_AT_EVENTS_HANDLERS * sizeof(IATEventsHandler*)); + m_processingMtx.lock(); } -//Open connection to AT Interface in order to execute command & register/unregister events -int ATCommandsInterface::open() -{ - if( m_open ) - { +// open connection to AT Interface in order to execute command & register/unregister events +int ATCommandsInterface::open() { + if( m_open ) { WARN("AT interface is already open"); return OK; } DBG("Opening AT interface"); - //Start processing + + // start processing m_processingThread.signal_set(AT_SIG_PROCESSING_START); m_processingMtx.unlock(); @@ -62,7 +71,7 @@ return OK; } -//Initialize AT link & start events processing +// initialize AT link & start events processing int ATCommandsInterface::init() { DBG("Sending ATZ E1 V1"); @@ -70,7 +79,8 @@ //Lock transaction mutex m_transactionMtx.lock(); - //Should we flush m_pStream at this point ??? + // should we flush m_pStream at this point ??? + // ash - it would do no harm so we should, incase some pending crap arrives int err; int tries = 5; do @@ -121,6 +131,7 @@ m_processingThread.signal_set(AT_SIG_PROCESSING_STOP); //m_stopSphre.release(); + // ash - don't know why he sends this as it is never used XXX int* msg = m_env2AT.alloc(osWaitForever); *msg = AT_STOP; m_env2AT.put(msg); //Used to unstall the process if needed @@ -157,7 +168,7 @@ //Lock transaction mutex m_transactionMtx.lock(); - + DBG("ATCommandsInterface::execute"); disableEvents(); //Disable unsollicited result codes int ret = executeInternal(command, pProcessor, pResult, timeout); enableEvents(); //Re-enable unsollicited result codes whatever the result of the command is @@ -244,6 +255,7 @@ m_pStream->abortRead(); //This is thread-safe //Wait for a result (get result message) + DBG("Timeout: %d",timeout); evt = m_AT2Env.get(timeout); if(evt.status != osEventMail) @@ -264,7 +276,7 @@ evt = m_AT2Env.get(osWaitForever); msgResult = *((int*) evt.value.p); m_AT2Env.free((int*)evt.value.p); - } while(msgResult != AT_TIMEOUT); + } while(msgResult != AT_TIMEOUT ); WARN("Command returned no message"); return NET_TIMEOUT; @@ -296,6 +308,7 @@ //Block on serial read or incoming command DBG("Trying to read a new line from stream"); int ret = m_pStream->waitAvailable(); //This can be aborted + size_t readLen = 0; if(ret == OK) { @@ -310,7 +323,7 @@ if( ret == NET_INTERRUPTED ) //It is worth checking readLen as data might have been read even though the read was interrupted { - DBG("Read was interrupted"); + DBG("Read was interrupted with %d chars read",readLen); return NET_INTERRUPTED; //0 chars were read } else if(readLen == 0) @@ -573,7 +586,7 @@ { WARN("Previous command not processed!"); } - DBG("Sending pending command"); + DBG("Sending pending command %s (%d)",m_transactionCommand,strlen(m_transactionCommand)); m_pStream->write((uint8_t*)m_transactionCommand, strlen(m_transactionCommand), osWaitForever); char cr = CR; m_pStream->write((uint8_t*)&cr, 1, osWaitForever); //Carriage return line terminator @@ -581,6 +594,7 @@ } else //Timeout { + DBG("Timeout message received"); //Acknowledge int* msg = m_AT2Env.alloc(osWaitForever); *msg = AT_TIMEOUT; @@ -740,6 +754,7 @@ //This will be called on initialization & after the execution of a command void ATCommandsInterface::enableEvents() { + DBG("Trying to enable events"); //Advertize this to events handlers m_eventsMgmtMtx.lock(); for(int i = 0; i < MAX_AT_EVENTS_HANDLERS; i++) //Find a free slot @@ -750,10 +765,13 @@ //Enable this kind of events if(m_eventsHandlers[i]->getEventsEnableCommand() != NULL) { + DBG("Enabling events for handler %d",i); int ret = executeInternal(m_eventsHandlers[i]->getEventsEnableCommand(), this, NULL); //Execute enable command if(ret) { - WARN("Events enabling command failed"); + WARN("Events enabling command failed: %d",ret); + } else { + DBG("Enabled events"); } } }
--- a/at/ATCommandsInterface.h Tue Jan 29 13:49:23 2013 +0000 +++ b/at/ATCommandsInterface.h Tue Mar 05 14:54:15 2013 +0000 @@ -139,7 +139,7 @@ char m_inputBuf[AT_INPUT_BUF_SIZE]; // Stores characters received from the modem. int m_inputPos; // Current position of fill pointer in the input buffer. - Mutex m_transactionMtx; + Mutex m_transactionMtx; // used to lock access to the serial stream sending AT commands // These are RTOS queues, concurrent access protected. In this case both only contain an integer. Mail<int,1> m_env2AT; // used by calling function to inform processing thread of events @@ -147,8 +147,8 @@ IATEventsHandler* m_eventsHandlers[MAX_AT_EVENTS_HANDLERS]; // all registered events handlers - Mutex m_processingMtx; - Thread m_processingThread; + Mutex m_processingMtx; // not sure why you need a lock for the processing thread, as nobody else accesses it + Thread m_processingThread; // this is the at parsing thread, i.e the function process() Mutex m_eventsMgmtMtx; // locks access to event handler management (adding/removing handlers) Mutex m_eventsProcessingMtx; //Lock events use within the processing thread
--- a/serial/usb/USBSerialStream.cpp Tue Jan 29 13:49:23 2013 +0000 +++ b/serial/usb/USBSerialStream.cpp Tue Mar 05 14:54:15 2013 +0000 @@ -17,6 +17,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + #define __DEBUG__ 0 #ifndef __MODULE__ #define __MODULE__ "USBSerialStream.cpp" @@ -28,6 +30,29 @@ #include "USBSerialStream.h" +// XXX ashley's debug +void printBuffer(uint8_t* buf, int len, bool readIn) { + + if(len<0) { + return; + } + + if(readIn) { + printf("Read(%d): '",len); + } else { + printf("Writing(%d): '",len); + } + for(int i=0; i<len; i++) { + if(buf[i]==0x0a) { + putchar('N'); + } else if(buf[i]==0x0d) { + putchar('R'); + } else { + putchar(buf[i]); + } + } + printf("'\r\n"); +} USBSerialStream::USBSerialStream(IUSBHostSerial& serial) : m_serial(serial), m_serialTxFifoEmpty(true), m_availableSphre(1), m_spaceSphre(1), m_inBuf() @@ -46,6 +71,7 @@ //0 for non-blocking (returns immediately), -1 for infinite blocking /*virtual*/ int USBSerialStream::read(uint8_t* buf, size_t* pLength, size_t maxLength, uint32_t timeout/*=osWaitForever*/) { + uint8_t *bufPointerCopy = buf; DBG("Trying to read at most %d chars", maxLength); int ret = waitAvailable(timeout); if(ret) @@ -56,7 +82,8 @@ int a = available(); //Prevent macro issues int readLen = MIN( a, maxLength ); *pLength = readLen; - + + setupReadableISR(false); while(readLen--) { @@ -64,7 +91,8 @@ buf++; } setupReadableISR(true); - DBG("Read %d chars successfully", *pLength); + //printBuffer(bufPointerCopy,*pLength,true); // XXX + return OK; } @@ -130,9 +158,12 @@ m_availableSphre.release(); //Force exiting the waiting state } + + //0 for non-blocking (returns immediately), -1 for infinite blocking /*virtual*/ int USBSerialStream::write(uint8_t* buf, size_t length, uint32_t timeout/*=-1*/) { + //printBuffer(buf,length,false); // XXX DBG("Trying to write %d chars", length); do { @@ -160,7 +191,6 @@ } setupWriteableISR(true); } while(length); - DBG("Write successful"); return OK; }
--- a/sms/SMSInterface.cpp Tue Jan 29 13:49:23 2013 +0000 +++ b/sms/SMSInterface.cpp Tue Mar 05 14:54:15 2013 +0000 @@ -33,6 +33,7 @@ SMSInterface::SMSInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_msg(NULL), m_maxMsgLength(0), m_msisdn(NULL) { + DBG("registering sms"); m_pIf->registerEventsHandler(this); //Add us to the unsolicited result codes handlers } @@ -240,8 +241,9 @@ } else if(m_state == SMS_GET_HDR_RECEIVED) { - DBG("Message: %s", line); + size_t cpyLen = MIN( std::strlen(line), m_maxMsgLength - 1 ); + DBG("Message: %s (%d)", line, cpyLen); std::memcpy( m_msg, line, cpyLen ); m_msg[cpyLen] = '\0'; m_state = SMS_CMD_PROCESSED; @@ -356,7 +358,6 @@ { return; //Not supported } - DBG("Unsollicited result code: %s - %s", atCode, evt);
--- a/ussd/USSDInterface.cpp Tue Jan 29 13:49:23 2013 +0000 +++ b/ussd/USSDInterface.cpp Tue Mar 05 14:54:15 2013 +0000 @@ -17,7 +17,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#define __DEBUG__ 0 +#define __DEBUG__ 4 #ifndef __MODULE__ #define __MODULE__ "USSDInterface.cpp" #endif @@ -34,6 +34,7 @@ USSDInterface::USSDInterface(ATCommandsInterface* pIf) : m_pIf(pIf), m_responseMtx(), m_responseSphre(1), m_result(NULL), m_maxResultLength(0) { m_responseSphre.wait(0); //Take ownership of the semaphore + DBG("events handler reg ussd"); m_pIf->registerEventsHandler(this); //Add us to the unsolicited result codes handlers } @@ -45,7 +46,7 @@ int USSDInterface::send(const char* command, char* result, size_t maxLength) { - if (strlen(command) > 20) //Prevent buffer overflow + if (strlen(command) > 20) //Prevent buffer overflow XXX shouldn't this be 19 as the AT+CUSD=1,"" is 12 { return NET_TOOSMALL; } @@ -188,6 +189,7 @@ return; } size_t cpyLen = MIN( pEnd - pStart, m_maxResultLength - 1 ); + DBG("cpyLen: %d",cpyLen); memcpy((void*)m_result, pStart, cpyLen); m_result[cpyLen] = '\0'; DBG("Got USSD response: %s", m_result);