Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 2:61ac95f0af72, committed 2015-04-14
- Comitter:
- clemounet
- Date:
- Tue Apr 14 13:27:07 2015 +0000
- Parent:
- 1:fbf17fb09581
- Commit message:
- .up (working)
Changed in this revision
--- a/ATCommandsInterface.cpp Fri Feb 20 17:15:55 2015 +0000
+++ b/ATCommandsInterface.cpp Tue Apr 14 13:27:07 2015 +0000
@@ -17,7 +17,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include "dbg.h"
+#define __DEBUG__ 0
+#ifndef __MODULE__
+#define __MODULE__ "ATCommandsInterface.cpp"
+#endif
+#include "MyDebug.h"
+
#include <cstdio>
//#include <cstring> //For memset, strstr...
@@ -38,10 +43,10 @@
{
if( m_open )
{
- USB_WARN("AT interface is already open");
+ WARN("AT interface is already open");
return OK;
}
- USB_DBG("Opening AT interface");
+ DBG("Opening AT interface");
//Start processing
m_processingThread.signal_set(AT_SIG_PROCESSING_START);
@@ -60,34 +65,34 @@
}
m_eventsMtx.unlock();
- USB_DBG("AT interface opened");
+ DBG("AT interface opened");
return OK;
}
//Initialize AT link
-int ATCommandsInterface::init()
+int ATCommandsInterface::init(const char *atInitSeq)
{
- USB_DBG("Sending ATZ E1 V1");
+ DBG("Sending %s",atInitSeq);
//Should we flush m_pStream at this point ???
int err;
int tries = 5;
do
{
- err = executeSimple("ATZ E1 V1", NULL, 3000); //Enable echo and verbosity
+ err = executeSimple(atInitSeq, NULL, 3000); //Enable echo and verbosity
if(err && tries)
{
- USB_WARN("No response, trying again");
+ WARN("No response, trying again");
Thread::wait(1000); //Give dongle time to recover
}
} while(err && tries--);
if( err )
{
- USB_ERR("Sending ATZ E1 V1 returned with err code %d", err);
+ ERR("Sending %s returned with err code %d", atInitSeq, err);
return err;
}
- USB_DBG("AT interface initialized");
+ DBG("AT interface initialized");
return OK;
}
@@ -97,11 +102,11 @@
{
if( !m_open )
{
- USB_WARN("AT interface is already closed");
+ WARN("AT interface is already closed");
return OK;
}
- USB_DBG("Closing AT interface");
+ DBG("Closing AT interface");
//Stop processing
m_processingThread.signal_set(AT_SIG_PROCESSING_STOP);
@@ -127,7 +132,7 @@
}
m_eventsMtx.unlock();
- USB_DBG("AT interface closed");
+ DBG("AT interface closed");
return OK;
}
@@ -143,10 +148,10 @@
int ATCommandsInterface::execute(const char* command, IATCommandsProcessor* pProcessor, ATResult* pResult, uint32_t timeout/*=1000*/)
{
- USB_DBG("Executing command %s", command);
+ DBG("Executing command %s", command);
if(!m_open)
{
- USB_WARN("Interface is not open!");
+ WARN("Interface is not open!");
return NET_INVALID;
}
@@ -159,7 +164,7 @@
if(evt.status == osEventMail)
{
m_AT2Env.free((int*)evt.value.p);
- USB_WARN("Previous result discarded");
+ WARN("Previous result discarded");
}
//Send params to the process routine
@@ -175,14 +180,14 @@
Thread::wait(100); //FIXME find stg else
- USB_DBG("Sending command ready signal to AT thread & aborting current blocking read operation");
+ DBG("Sending command ready signal to AT thread & aborting current blocking read operation");
//Produce command ready signal
int* msg = m_env2AT.alloc(osWaitForever);
*msg = AT_CMD_READY;
m_env2AT.put(msg);
- USB_DBG("Trying to enter abortRead()");
+ DBG("Trying to enter abortRead()");
//Unlock process routine (abort read)
m_pStream->abortRead(); //This is thread-safe
@@ -196,15 +201,15 @@
*msg = AT_TIMEOUT;
m_env2AT.put(msg);
- USB_DBG("Trying to enter abortRead()");
+ DBG("Trying to enter abortRead()");
//Unlock process routine (abort read)
m_pStream->abortRead(); //This is thread-safe
- USB_WARN("Command returned no message");
+ WARN("Command returned no message");
m_transactionMtx.unlock();
return NET_TIMEOUT;
}
- USB_DBG("Command returned with message %d", *msg);
+ DBG("Command returned with message %d", *msg);
m_AT2Env.free((int*)evt.value.p);
@@ -216,10 +221,10 @@
int ret = ATResultToReturnCode(m_transactionResult);
if(ret != OK)
{
- USB_WARN("Command returned AT result %d with code %d", m_transactionResult.result, m_transactionResult.code);
+ WARN("Command returned AT result %d with code %d", m_transactionResult.result, m_transactionResult.code);
}
- USB_DBG("Command returned successfully");
+ DBG("Command returned successfully");
//Unlock transaction mutex
m_transactionMtx.unlock();
@@ -265,7 +270,7 @@
static bool lineDetected = false;
//Block on serial read or incoming command
- USB_DBG("Trying to read a new line from stream");
+ 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)
@@ -276,33 +281,33 @@
{
m_inputPos+=readLen;
m_inputBuf[m_inputPos] = '\0'; //Add null terminating character to ease the use of str* functions
- USB_DBG("In buffer: [%s]", m_inputBuf);
+ DBG("In buffer: [%s]", m_inputBuf);
}
if( ret == NET_INTERRUPTED ) //It is worth checking readLen as data might have been read even though the read was interrupted
{
- USB_DBG("Read was interrupted");
+ DBG("Read was interrupted");
return NET_INTERRUPTED; //0 chars were read
}
else if(readLen == 0)
{
- USB_DBG("Nothing read");
+ DBG("Nothing read");
return OK; //0 chars were read
}
- USB_DBG("Trying to process incoming line");
+ DBG("Trying to process incoming line");
bool lineProcessed = false;
do
{
lineProcessed = false; //Reset flag
- USB_DBG("New iteration");
+ DBG("New iteration");
//Look for a new line
if(!lineDetected)
{
- USB_DBG("No line detected yet");
+ DBG("No line detected yet");
//Try to look for a starting CRLF
char* crPtr = strchr(m_inputBuf, CR);
/*
@@ -318,7 +323,7 @@
*/
if(crPtr != NULL)
{
- USB_DBG("CR char found");
+ DBG("CR char found");
#if 0
//Discard all preceding characters (can do nothing if m_inputBuf == crPtr)
@@ -338,24 +343,24 @@
//At this point we can check whether this is the end of a preceding line or the beginning of a new one
if(m_inputBuf[2] != CR)
{
- USB_DBG("Beginning of new line found");
+ DBG("Beginning of new line found");
//Beginning of a line
lineDetected = true; //Move to next state-machine step
}
else
{
//End of an unprocessed line
- USB_WARN("End of unprocessed line");
+ WARN("End of unprocessed line");
}
//In both cases discard CRLF
- USB_DBG("Discarding CRLF");
+ DBG("Discarding CRLF");
memmove(m_inputBuf, m_inputBuf + 2, (m_inputPos + 1) - 2); //Move null-terminating char as well
m_inputPos = m_inputPos - 2; //Adjust m_inputPos
}
else
{
//This is completely unexpected, discard the CR char to try to recover good state
- USB_WARN("Unexpected %c char (%02d code) found after CR char", m_inputBuf[1]);
+ WARN("Unexpected %c char (%02d code) found after CR char", m_inputBuf[1]);
memmove(m_inputBuf, m_inputBuf + 1, (m_inputPos + 1) - 1); //Move null-terminating char as well
m_inputPos = m_inputPos - 1; //Adjust m_inputPos
}
@@ -366,7 +371,7 @@
{
int crPos = crPtr - m_inputBuf;
int lfOff = 0; //Offset for LF if present
- USB_DBG("New line found (possible echo of command)");
+ DBG("New line found (possible echo of command)");
//This is the end of line
//Replace m_inputBuf[crPos] with null-terminating char
m_inputBuf[crPos] = '\0';
@@ -394,14 +399,14 @@
memmove(m_inputBuf, m_inputBuf + crPos + lfOff + 1, (m_inputPos + 1) - (crPos + lfOff + 1)); //Move null-terminating char as well
m_inputPos = m_inputPos - (crPos + lfOff + 1); //Adjust m_inputPos
}
- USB_DBG("One line was successfully processed");
+ DBG("One line was successfully processed");
lineProcessed = true; //Line was processed with success
lineDetected = false; //Search now for a new line
}
}
else if(m_inputBuf[0] == LF) //If there is a remaining LF char from the previous line, discard it
{
- USB_DBG("Discarding single LF char");
+ DBG("Discarding single LF char");
memmove(m_inputBuf, m_inputBuf + 1, (m_inputPos + 1) - 1); //Move null-terminating char as well
m_inputPos = m_inputPos - 1; //Adjust m_inputPos
}
@@ -410,7 +415,7 @@
//Look for the end of line
if(lineDetected)
{
- USB_DBG("Looking for end of line");
+ DBG("Looking for end of line");
//Try to look for a terminating CRLF
char* crPtr = strchr(m_inputBuf, CR);
/*
@@ -428,7 +433,7 @@
if(crPtr != NULL)
{
- USB_DBG("CR char found");
+ DBG("CR char found");
int crPos = crPtr - m_inputBuf;
//To determine the sequence we need at least 2 chars
if(m_inputPos - crPos >= 2)
@@ -436,7 +441,7 @@
//Look for a LF char next to the CR char
if(m_inputBuf[crPos + 1] == LF)
{
- USB_DBG("End of new line found");
+ DBG("End of new line found");
//This is the end of line
//Replace m_inputBuf[crPos] with null-terminating char
m_inputBuf[crPos] = '\0';
@@ -458,13 +463,13 @@
m_inputPos = m_inputPos - (crPos + 2); //Adjust m_inputPos
}
- USB_DBG("One line was successfully processed");
+ DBG("One line was successfully processed");
lineProcessed = true; //Line was processed with success
}
else
{
//This is completely unexpected, discard all chars till the CR char to try to recover good state
- USB_WARN("Unexpected %c char (%02d code) found in incoming line", m_inputBuf[crPos + 1]);
+ WARN("Unexpected %c char (%02d code) found in incoming line", m_inputBuf[crPos + 1]);
memmove(m_inputBuf, m_inputBuf + crPos + 1, (m_inputPos + 1) - (crPos + 1)); //Move null-terminating char as well
m_inputPos = m_inputPos - (crPos + 1); //Adjust m_inputPos
}
@@ -473,7 +478,7 @@
}
else if(greaterThanPtr != NULL)
{
- USB_DBG("> char found");
+ DBG("> char found");
int gdPos = greaterThanPtr - m_inputBuf;
//To determine the sequence we need at least 2 chars
if(m_inputPos - gdPos >= 2)
@@ -499,13 +504,13 @@
return ret;
}
- USB_DBG("One line was successfully processed");
+ DBG("One line was successfully processed");
lineProcessed = true; //Line was processed with success
}
else
{
//This is completely unexpected, discard all chars till the GD char to try to recover good state
- USB_WARN("Unexpected %c char (%02d code) found in incoming line", m_inputBuf[gdPos + 1]);
+ WARN("Unexpected %c char (%02d code) found in incoming line", m_inputBuf[gdPos + 1]);
memmove(m_inputBuf, m_inputBuf + gdPos + 1, (m_inputPos + 1) - (gdPos + 1)); //Move null-terminating char as well
m_inputPos = m_inputPos - (gdPos + 1); //Adjust m_inputPos
}
@@ -521,12 +526,12 @@
//Discard everything
m_inputPos = 0;
m_inputBuf[0] = '\0'; //Always have a null-terminating char at start of buffer
- USB_WARN("Incoming buffer is too short to process incoming line");
+ WARN("Incoming buffer is too short to process incoming line");
//Look for a new line
lineDetected = false;
}
- USB_DBG("Processed every full incoming lines");
+ DBG("Processed every full incoming lines");
return OK;
}
@@ -534,7 +539,7 @@
int ATCommandsInterface::trySendCommand()
{
osEvent evt = m_env2AT.get(0);
- USB_DBG("status = %d, msg = %d", evt.status, evt.value.p);
+ DBG("status = %d, msg = %d", evt.status, evt.value.p);
if(evt.status == osEventMail)
{
int* msg = (int*) evt.value.p;
@@ -542,9 +547,9 @@
{
if(m_transactionState != IDLE)
{
- USB_WARN("Previous command not processed!");
+ WARN("Previous command not processed!");
}
- USB_DBG("Sending pending command");
+ DBG("Sending pending command");
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
@@ -561,14 +566,14 @@
int ATCommandsInterface::processReadLine()
{
- USB_DBG("Processing read line [%s]", m_inputBuf);
+ DBG("Processing read line [%s]", m_inputBuf);
//The line is stored in m_inputBuf
if(m_transactionState == COMMAND_SENT)
{
//If the command has been sent, checks echo to see if it has been received properly
if( strcmp(m_transactionCommand, m_inputBuf) == 0 )
{
- USB_DBG("Command echo received");
+ DBG("Command echo received");
//If so, it means that the following lines will only be solicited results
m_transactionState = READING_RESULT;
return OK;
@@ -613,7 +618,7 @@
//The following lines can either be a command response or a result code (OK / ERROR / CONNECT / +CME ERROR: %s / +CMS ERROR: %s)
if(strcmp("OK", m_inputBuf) == 0)
{
- USB_DBG("OK result received");
+ DBG("OK result received");
m_transactionResult.code = 0;
m_transactionResult.result = ATResult::AT_OK;
m_transactionState = IDLE;
@@ -624,7 +629,7 @@
}
else if(strcmp("ERROR", m_inputBuf) == 0)
{
- USB_DBG("ERROR result received");
+ DBG("ERROR result received");
m_transactionResult.code = 0;
m_transactionResult.result = ATResult::AT_ERROR;
m_transactionState = IDLE;
@@ -635,7 +640,7 @@
}
else if(strncmp("CONNECT", m_inputBuf, 7 /*=strlen("CONNECT")*/) == 0) //Result can be "CONNECT" or "CONNECT %d", indicating baudrate
{
- USB_DBG("CONNECT result received");
+ DBG("CONNECT result received");
m_transactionResult.code = 0;
m_transactionResult.result = ATResult::AT_CONNECT;
m_transactionState = IDLE;
@@ -646,7 +651,7 @@
}
else if(strcmp("COMMAND NOT SUPPORT", m_inputBuf) == 0) //Huawei-specific, not normalized
{
- USB_DBG("COMMAND NOT SUPPORT result received");
+ DBG("COMMAND NOT SUPPORT result received");
m_transactionResult.code = 0;
m_transactionResult.result = ATResult::AT_ERROR;
m_transactionState = IDLE;
@@ -658,7 +663,7 @@
else if(strstr(m_inputBuf, "+CME ERROR:") == m_inputBuf) //Mobile Equipment Error
{
std::sscanf(m_inputBuf + 12 /* =strlen("+CME ERROR: ") */, "%d", &m_transactionResult.code);
- USB_DBG("+CME ERROR: %d result received", m_transactionResult.code);
+ DBG("+CME ERROR: %d result received", m_transactionResult.code);
m_transactionResult.result = ATResult::AT_CME_ERROR;
m_transactionState = IDLE;
int* msg = m_AT2Env.alloc(osWaitForever);
@@ -669,7 +674,7 @@
else if(strstr(m_inputBuf, "+CMS ERROR:") == m_inputBuf) //SIM Error
{
std::sscanf(m_inputBuf + 13 /* =strlen("+CME ERROR: ") */, "%d", &m_transactionResult.code);
- USB_DBG("+CMS ERROR: %d result received", m_transactionResult.code);
+ DBG("+CMS ERROR: %d result received", m_transactionResult.code);
m_transactionResult.result = ATResult::AT_CMS_ERROR;
m_transactionState = IDLE;
int* msg = m_AT2Env.alloc(osWaitForever);
@@ -679,7 +684,7 @@
}
else
{
- USB_DBG("Unprocessed result received: '%s'", m_inputBuf);
+ DBG("Unprocessed result received: '%s'", m_inputBuf);
//Must call transaction processor to complete line processing
int ret = m_pTransactionProcessor->onNewATResponseLine(this, m_inputBuf); //Here sendData can be called
return ret;
@@ -691,12 +696,12 @@
int ATCommandsInterface::processEntryPrompt()
{
- USB_DBG("Calling prompt handler");
+ DBG("Calling prompt handler");
int ret = m_pTransactionProcessor->onNewEntryPrompt(this); //Here sendData can be called
if( ret != NET_MOREINFO ) //A new prompt is expected
{
- USB_DBG("Sending break character");
+ DBG("Sending break character");
//Send CTRL+Z (break sequence) to exit prompt
char seq[2] = {BRK, 0x00};
sendData(seq);
@@ -710,11 +715,11 @@
{
//m_inputBuf is cleared at this point (and MUST therefore be empty)
int dataLen = strlen(data);
- USB_DBG("Sending raw string of length %d", dataLen);
+ DBG("Sending raw string of length %d", dataLen);
int ret = m_pStream->write((uint8_t*)data, dataLen, osWaitForever);
if(ret)
{
- USB_WARN("Could not write to stream (returned %d)", ret);
+ WARN("Could not write to stream (returned %d)", ret);
return ret;
}
@@ -726,7 +731,7 @@
int ret = m_pStream->read((uint8_t*)m_inputBuf, &readLen, MIN(dataLen - dataPos, AT_INPUT_BUF_SIZE - 1), osWaitForever); //Make sure we do not read more than needed otherwise it could break the parser
if(ret)
{
- USB_WARN("Could not read from stream (returned %d)", ret);
+ WARN("Could not read from stream (returned %d)", ret);
m_inputPos = 0; //Reset input buffer state
m_inputBuf[0] = '\0'; //Always have a null-terminating char at start of buffer
return ret;
@@ -735,7 +740,7 @@
if( memcmp(m_inputBuf, data + dataPos, readLen) != 0 )
{
//Echo does not match output
- USB_WARN("Echo does not match output");
+ WARN("Echo does not match output");
m_inputPos = 0; //Reset input buffer state
m_inputBuf[0] = '\0'; //Always have a null-terminating char at start of buffer
return NET_DIFF;
@@ -746,7 +751,7 @@
} while(dataPos < dataLen);
- USB_DBG("String sent successfully");
+ DBG("String sent successfully");
m_inputPos = 0; //Reset input buffer state
m_inputBuf[0] = '\0'; //Always have a null-terminating char at start of buffer
@@ -783,14 +788,14 @@
void ATCommandsInterface::process() //Processing thread
{
- USB_DBG("AT Thread started");
+ DBG("AT Thread started");
while(true)
{
- USB_DBG("AT Processing on hold");
+ DBG("AT Processing on hold");
m_processingThread.signal_wait(AT_SIG_PROCESSING_START); //Block until the process is started
m_processingMtx.lock();
- USB_DBG("AT Processing started");
+ DBG("AT Processing started");
//First of all discard buffer
int ret;
size_t readLen;
@@ -801,13 +806,13 @@
m_inputPos = 0; //Clear input buffer
do
{
- USB_DBG("Trying to read a new line");
+ DBG("Trying to read a new line");
tryReadLine();
- USB_DBG("Trying to send a pending command");
+ DBG("Trying to send a pending command");
trySendCommand();
} while( m_processingThread.signal_wait(AT_SIG_PROCESSING_STOP, 0).status != osEventSignal ); //Loop until the process is interrupted
m_processingMtx.unlock();
- USB_DBG("AT Processing stopped");
+ DBG("AT Processing stopped");
}
}
--- a/ATCommandsInterface.h Fri Feb 20 17:15:55 2015 +0000 +++ b/ATCommandsInterface.h Tue Apr 14 13:27:07 2015 +0000 @@ -20,7 +20,7 @@ #ifndef ATCOMMANDSINTERFACE_H_ #define ATCOMMANDSINTERFACE_H_ -#include "core/fwk.h" +#include "fwk.h" #include "rtos.h" #define MAX_AT_EVENTS_HANDLERS 4 @@ -75,7 +75,7 @@ int open(); //Initialize AT link - int init(); + int init(const char *atInitSeq = "ATZ E1 V1"); //Close connection int close();
--- a/HuaweiUSBModemInitializer.cpp Fri Feb 20 17:15:55 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-
-#include "dbg.h"
-#include "HuaweiUSBModemInitializer.h"
-
-// switch string => "55 53 42 43 00 00 00 00 00 00 00 00 00 00 00 11 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00"
-static uint8_t huawei_E372_switch_packet[] = {
- 0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x11, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00
-};
-
-HuaweiE372USBModemInitializer::HuaweiE372USBModemInitializer(USBHost *h): WANDongleInitializer(h) {
-
-}
-
-bool HuaweiE372USBModemInitializer::switchMode(USBDeviceConnected* pDev) {
- for (int i = 0; i < pDev->getNbIntf(); i++) {
- if (pDev->getInterface(i)->intf_class == MSD_CLASS) {
- USBEndpoint* pEp = pDev->getEndpoint(i, BULK_ENDPOINT, OUT);
- if ( pEp != NULL ) {
- USB_DBG("MSD descriptor found on device %p, intf %d, will now try to switch into serial mode", (void *)pDev, i);
- m_pHost->bulkWrite(pDev, pEp, huawei_E372_switch_packet, 31);
- return true;
- }
- }
- }
- return false;
-}
- USBEndpoint* HuaweiE372USBModemInitializer::getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx) {
- return pDev->getEndpoint(serialPortNumber, BULK_ENDPOINT, tx ? OUT : IN, 0);
-}
-
-void HuaweiE372USBModemInitializer::setVidPid(uint16_t vid, uint16_t pid) {
- if( (vid == getSerialVid()) && (pid == getSerialPid()) ) {
- m_hasSwitched = true;
- m_currentSerialIntf = 0;
- m_endpointsToFetch = 4*2;
- } else {
- m_hasSwitched = false;
- m_endpointsToFetch = 1;
- }
-}
-
-bool HuaweiE372USBModemInitializer::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) {
- if( m_hasSwitched ) {
- USB_DBG("Interface #%d; Class:%02x; SubClass:%02x; Protocol:%02x", intf_nb, intf_class, intf_subclass, intf_protocol);
- if( intf_class == VENDSPEC_CLASS ) {
- // The first 4 Interfaces are parsable.
- if( m_currentSerialIntf <4 ) {
- m_currentSerialIntf++;
- return true;
- }
- m_currentSerialIntf++;
- }
- } else {
- // The first 2 Interface are parsable.
- if( ((intf_nb == 0) || (intf_nb == 1)) && (intf_class == MSD_CLASS) ) {
- return true;
- }
- }
- return false;
-}
-
-bool HuaweiE372USBModemInitializer::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) {//Must return true if the endpoint will be used
- if( m_hasSwitched ) {
- USB_DBG("USBEndpoint on Inteface #%d; Type:%d; Direction:%d", intf_nb, type, dir);
- if( (type == BULK_ENDPOINT) && m_endpointsToFetch ) {
- m_endpointsToFetch--;
- return true;
- }
- } else {
- if( (type == BULK_ENDPOINT) && (dir == OUT) && m_endpointsToFetch ) {
- m_endpointsToFetch--;
- return true;
- }
- }
- return false;
-}
--- a/HuaweiUSBModemInitializer.h Fri Feb 20 17:15:55 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-
-
-#ifndef HUAWEI_USB_BMODEM_INITIALIZER_H
-#define HUAWEI_USB_BMODEM_INITIALIZER_H
-
-#include "mbed.h"
-#include "USBHost/USBHost3GModule/WANDongleInitializer.h"
-
-// For the moment we have only one key
-class HuaweiE372USBModemInitializer: public WANDongleInitializer{
-public:
- HuaweiE372USBModemInitializer(USBHost *h);
- virtual uint16_t getMSDVid() { return 0x12D1; }
- virtual uint16_t getMSDPid() { return 0x1505; }
- virtual uint16_t getSerialVid() { return 0x12D1; }
- virtual uint16_t getSerialPid() { return 0x14ac; }
- virtual bool switchMode(USBDeviceConnected* pDev) ;
- virtual USBEndpoint* getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx);
- virtual int getSerialPortCount() { return 4; }
- virtual void setVidPid(uint16_t vid, uint16_t pid) ;
- virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed
- virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) ; //Must return true if the endpoint will be used
- virtual int getType() { return WAN_DONGLE_TYPE_HUAWEI_E372; }
- virtual uint8_t getSerialIntf(int index) { return index; }
-private:
- bool m_hasSwitched;
- int m_currentSerialIntf;
- int m_endpointsToFetch;
-};
-
-#endif
\ No newline at end of file
--- a/IPInterface.cpp Fri Feb 20 17:15:55 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/* IPInterface.cpp */
-/* Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include "core/fwk.h"
-
-#include "IPInterface.h"
-
-#include <cstring> //For strcpy
-
-
-IPInterface::IPInterface() : m_connected(false)
-{
-
-}
-
-/*virtual*/ IPInterface::~IPInterface()
-{
-
-}
-
-void IPInterface::registerAsDefaultInterface() //First come, first served
-{
- s_pDefaultInterface = this;
-}
-
-void IPInterface::unregisterAsDefaultInterface() //Must be called before inst is destroyed to avoid invalid ptr fault
-{
- s_pDefaultInterface = NULL;
-}
-
-/*static*/ IPInterface* IPInterface::getDefaultInterface() //For use by TCP, UDP sockets library
-{
- return s_pDefaultInterface;
-}
-
-/*static*/ IPInterface* IPInterface::s_pDefaultInterface = NULL;
-
-
-char* IPInterface::getIPAddress() //Get IP Address as a string ('a.b.c.d')
-{
- if(isConnected())
- {
- return m_ipAddr;
- }
- else
- {
- return NULL;
- }
-}
-
-bool IPInterface::isConnected() //Is the interface connected?
-{
- return m_connected;
-}
-
-void IPInterface::setIPAddress(char* ipAddr)
-{
- std::strcpy(m_ipAddr, ipAddr); //Let's trust the derived class not to buffer overflow us
-}
-
-void IPInterface::setConnected(bool connected)
-{
- m_connected = connected;
-}
-
--- a/IPInterface.h Fri Feb 20 17:15:55 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/* IPInterface.h */
-/* Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef IPINTERFACE_H_
-#define IPINTERFACE_H_
-
-#include "core/fwk.h"
-
-/** Generic IP-based network interface
- *
- */
-class IPInterface
-{
-public:
- IPInterface();
- virtual ~IPInterface();
-
- //int init(); //Initialize interface; no connection should be performed at this stage
- virtual int connect() = 0; //Do connect the interface
- virtual int disconnect() = 0;
- //It is encouraged that the derived class implement a "setup(...)" function to configure the interface before the connection
-
- char* getIPAddress(); //Get IP Address as a string ('a.b.c.d')
- bool isConnected(); //Is the interface connected?
-
- static IPInterface* getDefaultInterface(); //For use by TCP, UDP sockets library
-
- //WARN: Implementation will have to be more careful in case of multiple interfaces (or implement a routing protocol based on local IP addresses differentiation)
- void registerAsDefaultInterface(); //First come, first served
- void unregisterAsDefaultInterface(); //Must be called before inst is destroyed to avoid invalid ptr fault
-
-protected:
- //Must be called by subclasses
- void setIPAddress(char* ipAddr);
- void setConnected(bool connected);
-
-private:
- char m_ipAddr[16];
- bool m_connected;
-
- static IPInterface* s_pDefaultInterface;
-};
-
-#endif /* IPINTERFACE_H_ */
--- a/LwIPInterface.cpp Fri Feb 20 17:15:55 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/* LwIPInterface.cpp */
-/* Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#include "core/fwk.h"
-
-#include "LwIPInterface.h"
-
-extern "C" {
-#include "lwip/init.h"
-#include "lwip/tcpip.h"
-}
-
-LwIPInterface::LwIPInterface() : IPInterface(), m_rdySphre(1)
-{
- m_rdySphre.wait();
-}
-
-LwIPInterface::~LwIPInterface()
-{
-
-}
-
-int LwIPInterface::init() //Init LwIP-specific stuff, create the right bindings, etc
-{
- //lwip_init(); //All LwIP initialisation functions called on a per-module basis (according to lwipopts.h)
- tcpip_init(LwIPInterface::tcpipRdyCb, this); //Start TCP/IP processing thread
- m_rdySphre.wait(); //Wait for callback to produce resource
- return OK;
-}
-
-/*static*/ void LwIPInterface::tcpipRdyCb(void* ctx) //Result of TCP/IP thread launch
-{
- LwIPInterface* pIf = (LwIPInterface*) ctx;
- pIf->m_rdySphre.release();
-}
--- a/LwIPInterface.h Fri Feb 20 17:15:55 2015 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/* LwIPInterface.h */
-/* Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef LWIPINTERFACE_H_
-#define LWIPINTERFACE_H_
-
-#include "core/fwk.h"
-#include "IPInterface.h"
-
-#include "rtos.h"
-
-/** LwIP-based network interface
- *
- */
-class LwIPInterface : public IPInterface
-{
-public:
- LwIPInterface();
- virtual ~LwIPInterface();
-
- int init(); //Init LwIP-specific stuff, create the right bindings, etc
-
-private:
- static void tcpipRdyCb(void* ctx); //Result of TCP/IP thread launch
- Semaphore m_rdySphre;
-};
-
-#endif /* LWIPINTERFACE_H_ */
--- a/PPPIPInterface.cpp Fri Feb 20 17:15:55 2015 +0000
+++ b/PPPIPInterface.cpp Tue Apr 14 13:27:07 2015 +0000
@@ -16,25 +16,27 @@
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-
-#define __DEBUG__ 0
+
+#define __DEBUG__ 3
#ifndef __MODULE__
#define __MODULE__ "PPPIPInterface.cpp"
#endif
+#include "MyDebug.h"
-#include "dbg.h"
-#define DBG(x, ...) USB_DBG(x, __VA_ARGS__)
-
+#include "core/errors.h"
#include "core/fwk.h"
+#include "core/IOStream.h"
#include "rtos.h"
#include <cstdio>
using std::sscanf;
#include "PPPIPInterface.h"
+#include "USBSerialStream.h"
+
+#define PPP_SERIAL_PORT 0
#define MSISDN "*99#"
-
#define CONNECT_CMD "ATD " MSISDN "\x0D"
#define EXPECTED_RESP CONNECT_CMD "\x0D" "\x0A" "CONNECT" "\x0D" "\x0A"
#define EXPECTED_RESP_DATARATE CONNECT_CMD "\x0D" "\x0A" "CONNECT %d" "\x0D" "\x0A"
@@ -43,418 +45,345 @@
#define ESCAPE_SEQ "+++"
#define HANGUP_CMD "ATH" "\x0D"
#define NO_CARRIER_RESP "\x0D" "\x0A" "NO CARRIER" "\x0D" "\x0A"
+
extern "C" {
#include "lwip/ip_addr.h"
#include "lwip/inet.h"
#include "lwip/err.h"
-#include "lwip/dns.h"
-
+//#include "lwip/dns.h"
+#include "lwip/tcpip.h"
#include "netif/ppp/ppp.h"
}
-PPPIPInterface::PPPIPInterface(IOStream* pStream) : LwIPInterface(), m_linkStatusSphre(1), m_pppErrCode(0), m_pStream(pStream), m_streamAvail(true), m_pppd(-1)
-{
- m_linkStatusSphre.wait();
-}
+PPPIPInterface::PPPIPInterface(USBSerialStream* pStream):
+ pppStream(pStream),
+ pppSession(0),
+ ipInitiated(false),
+ pppInitiated(false),
+ connected(false) {}
+PPPIPInterface::~PPPIPInterface() { }
-/*virtual*/ PPPIPInterface::~PPPIPInterface()
-{
-
+void PPPIPInterface::stackInits(const char* user, const char* pw) {
+ // LwIP Stuffs
+ if(!ipInitiated) {
+ DBG("LwIP: Init Stack");
+ tcpip_init(PPPIPInterface::tcpipInitDoneCb, this);
+ DBG("LwIP: Wait for setup");
+ while (!ipInitiated)
+ Thread::wait(1);
+ DBG("LwIP: setup done");
+ }
+ // PPP Stuffs
+ if(!pppInitiated) {
+ pppInit();
+ pppSetAuth(PPPAUTHTYPE_ANY, user, pw);
+ pppInitiated = true;
+ }
}
-/*virtual*/ int PPPIPInterface::init() //Init PPP-specific stuff, create the right bindings, etc
-{
- DBG("Initializing LwIP");
- LwIPInterface::init(); //Init LwIP, NOT including PPP
- DBG("Initializing PPP");
- pppInit();
- DBG("Done");
- return OK;
+int PPPIPInterface::dial(void) {
+ int ret;
+ char buf[32];
+ size_t len;
+
+ DBG("Sending %s", CONNECT_CMD);
+ ret = pppStream->write((uint8_t*)CONNECT_CMD, strlen(CONNECT_CMD), osWaitForever);
+ if( ret != OK )
+ return NET_UNKNOWN;
+ DBG("Expect %s", EXPECTED_RESP);
+
+ /*
+ size_t readLen;
+ ret = pppStream->read((uint8_t*)buf, &readLen, EXPECTED_RESP_MIN_LEN, 10000);
+ if( ret != OK )
+ return NET_UNKNOWN;
+
+ DBG("Readed %d chars", readLen);
+ DBG_MEMDUMP("PPPAT",buf,readLen);
+ */
+
+ len = 0;
+ size_t readLen;
+ ret = pppStream->read((uint8_t*)buf + len, &readLen, EXPECTED_RESP_MIN_LEN, 10000);
+ if( ret != OK )
+ return NET_UNKNOWN;
+
+ len += readLen;
+ while( (len < EXPECTED_RESP_MIN_LEN) || (buf[len-1] != LF) ) {
+ ret = pppStream->read((uint8_t*)buf + len, &readLen, 1, 10000);
+ if( ret != OK )
+ return NET_UNKNOWN;
+ len += readLen;
+ }
+
+ buf[len]=0;
+
+ DBG("Got %s[len %d]", buf, len);
+
+ int datarate = 0;
+ if( (sscanf( buf, EXPECTED_RESP_DATARATE, &datarate ) != 1) && (strcmp(EXPECTED_RESP, buf) != 0) ) {
+ //Discard buffer
+ do { //Clear buf
+ ret = pppStream->read((uint8_t*)buf, &len, 32, 0);
+ DBG("Got %s[len %d]", buf, len);
+ } while( (ret == OK) && (len > 0) );
+ return NET_CONN;
+ }
+
+ DBG("Transport link open");
+ if(datarate != 0)
+ DBG("Datarate: %d bps", datarate);
+ return OK;
}
-int PPPIPInterface::setup(const char* user, const char* pw)
-{
- DBG("Configuring PPP authentication method");
- pppSetAuth(PPPAUTHTYPE_ANY, user, pw);
- DBG("Done");
- return OK;
+int PPPIPInterface::escape(void) {
+ DBG("Sending %s", ESCAPE_SEQ);
+ Thread::wait(1000);
+ int ret = pppStream->write((uint8_t*)ESCAPE_SEQ, strlen(ESCAPE_SEQ), osWaitForever);
+ Thread::wait(1000);
+ if( ret != OK )
+ return NET_UNKNOWN;
+ return OK;
+}
+
+int PPPIPInterface::connect(const char* user, const char* pw) {
+
+ DBG("Trying to connect with PPP");
+
+ // Init the lWIP Stacks
+ stackInits(user,pw);
+
+ // Clear the line
+ cleanupLink();
+
+ // Do the dialing
+ dial();
+
+ // Launch the ppp session
+ pppSession = pppOverSerialOpen(this, PPPIPInterface::linkStatusCb, this);
+ DBG("PPP over serial opening returned = %d, pppSession");
+ if (pppSession >= 0) {
+ // the thread was successfully started.
+ int retries = 600; // Approx (600*100ms) = 60s
+ while (!connected && (retries-- > 0)) {
+ Thread::wait(100);
+ }
+
+ if (retries!=0) {
+ // We are connected on lwIP over PPP!
+ DBG("Got Connected");
+ return OK;
+ } else {
+ DBG("Got a Timeout");
+ return NET_UNKNOWN;
+ }
+ }else {
+ DBG("Could not get ppp session");
+ return NET_UNKNOWN;
+ }
+}
+
+int PPPIPInterface::disconnect() {
+ DBG("Do something on ppp stack and close the session");
+ pppClose(pppSession);
+ escape();
+ cleanupLink();
+ return OK;
}
-/*virtual*/ int PPPIPInterface::connect()
-{
- int ret;
- char buf[32];
- size_t len;
- DBG("Trying to connect with PPP");
-
- cleanupLink();
-
- DBG("Sending %s", CONNECT_CMD);
-
- ret = m_pStream->write((uint8_t*)CONNECT_CMD, strlen(CONNECT_CMD), osWaitForever);
- if( ret != OK )
- {
- return NET_UNKNOWN;
- }
-
- DBG("Expect %s", EXPECTED_RESP);
-
- len = 0;
- size_t readLen;
- ret = m_pStream->read((uint8_t*)buf + len, &readLen, EXPECTED_RESP_MIN_LEN, 10000);
- if( ret != OK )
- {
- return NET_UNKNOWN;
- }
- len += readLen;
- while( (len < EXPECTED_RESP_MIN_LEN) || (buf[len-1] != LF) )
- {
- ret = m_pStream->read((uint8_t*)buf + len, &readLen, 1, 10000);
- if( ret != OK )
- {
- return NET_UNKNOWN;
- }
- len += readLen;
- }
-
- buf[len]=0;
-
- DBG("Got %s[len %d]", buf, len);
-
- int datarate = 0;
- if( (sscanf( buf, EXPECTED_RESP_DATARATE, &datarate ) != 1) && (strcmp(EXPECTED_RESP, buf) != 0) )
- {
- //Discard buffer
- do //Clear buf
- {
- ret = m_pStream->read((uint8_t*)buf, &len, 32, 0);
- } while( (ret == OK) && (len > 0) );
- return NET_CONN;
- }
-
- DBG("Transport link open");
- if(datarate != 0)
- {
- DBG("Datarate: %d bps", datarate);
- }
- m_linkStatusSphre.wait(0);
- if((m_pppd != -1) && (m_pppErrCode == 0)) //Already connected
- {
- return NET_INVALID;
- }
-
- ret = pppOverSerialOpen(this, PPPIPInterface::linkStatusCb, this);
- if(ret < 0)
- {
- switch(ret)
- {
- case PPPERR_OPEN:
- default:
- return NET_FULL; //All available resources are already used
- }
- }
- m_pppd = ret; //PPP descriptor
- m_linkStatusSphre.wait(); //Block indefinitely; there should be a timeout there
- if(m_pppErrCode != PPPERR_NONE)
- {
- m_pppd = -1;
- }
- switch(m_pppErrCode)
- {
- case PPPERR_NONE: //Connected OK
- return OK;
- case PPPERR_CONNECT: //Connection lost
- return NET_INTERRUPTED;
- case PPPERR_AUTHFAIL: //Authentication failed
- return NET_AUTH;
- case PPPERR_PROTOCOL: //Protocol error
- return NET_PROTOCOL;
- default:
- return NET_UNKNOWN;
- }
+void PPPIPInterface::setConnected(bool val) {
+ connected = val;
+}
+
+bool PPPIPInterface::isConnected(void) {
+ return connected;
}
-/*virtual*/ int PPPIPInterface::disconnect()
-{
- int ret = m_linkStatusSphre.wait(0);
- if(ret > 0) //Already disconnected?
- {
- m_pppd = -1; //Discard PPP descriptor
- switch(m_pppErrCode)
- {
- case PPPERR_CONNECT: //Connection terminated
- case PPPERR_AUTHFAIL: //Authentication failed
- case PPPERR_PROTOCOL: //Protocol error
- case PPPERR_USER:
- return OK;
- default:
+int PPPIPInterface::cleanupLink() {
+ int ret;
+ char buf[32];
+ size_t len;
+
+ do { //Clear buf
+ ret = pppStream->read((uint8_t*)buf, &len, 32, 100);
+ if(ret == OK) {
+ buf[len] = '\0';
+ DBG("Got %s", buf);
+ }
+ } while( (ret == OK) && (len > 0) );
+
+ DBG("Sending %s", HANGUP_CMD);
+
+ // Here we could need to pass the ATStream to hangup
+ IOStream *hangupPort = pppStream;
+ ret = hangupPort->write((uint8_t*)HANGUP_CMD, strlen(HANGUP_CMD), osWaitForever);
+ if( ret != OK )
return NET_UNKNOWN;
- }
- }
- else
- {
- if(m_pppd == -1)
- {
- return NET_INVALID;
+
+ size_t readLen;
+
+ //Hangup
+ DBG("Expect %s", HANGUP_CMD);
+
+ len = 0;
+ while( len < strlen(HANGUP_CMD) ) {
+ ret = hangupPort->read((uint8_t*)buf + len, &readLen, strlen(HANGUP_CMD) - len, 100);
+ if( ret != OK )
+ break;
+ len += readLen;
+ /////
+ buf[len]=0;
+ DBG("Got %s", buf);
+ }
+
+ buf[len]=0;
+
+ DBG("Got %s[len %d]", buf, len);
+
+ //OK response
+ DBG("Expect %s", OK_RESP);
+
+ len = 0;
+ while( len < strlen(OK_RESP) ) {
+ ret = hangupPort->read((uint8_t*)buf + len, &readLen, strlen(OK_RESP) - len, 100);
+ if( ret != OK ) {
+ break;
+ }
+ len += readLen;
+ /////
+ buf[len]=0;
+ DBG("Got %s", buf);
+ }
+
+ buf[len]=0;
+
+ DBG("Got %s[len %d]", buf, len);
+
+ //NO CARRIER event
+ DBG("Expect %s", NO_CARRIER_RESP);
+
+ len = 0;
+ while( len < strlen(NO_CARRIER_RESP) ) {
+ ret = pppStream->read((uint8_t*)buf + len, &readLen, strlen(NO_CARRIER_RESP) - len, 100);
+ if( ret != OK ) {
+ break;
+ }
+ len += readLen;
+ /////
+ buf[len]=0;
+ DBG("Got %s", buf);
}
- pppClose(m_pppd);
- do
- {
- m_linkStatusSphre.wait(); //Block indefinitely; there should be a timeout there
- DBG("Received PPP err code %d", m_pppErrCode);
- } while(m_pppErrCode != PPPERR_USER);
- m_pppd = -1; //Discard PPP descriptor
- }
-
- DBG("Sending %s", ESCAPE_SEQ);
-
- ret = m_pStream->write((uint8_t*)ESCAPE_SEQ, strlen(ESCAPE_SEQ), osWaitForever);
- if( ret != OK )
- {
- return NET_UNKNOWN;
- }
-
- cleanupLink();
-
- return OK;
+
+ buf[len]=0;
+
+ DBG("Got %s[len %d]", buf, len);
+
+ do { //Clear buf
+ ret = pppStream->read((uint8_t*)buf, &len, 32, 100);
+ if(ret == OK) {
+ buf[len] = '\0';
+ DBG("Got %s", buf);
+ }
+ } while( (ret == OK) && (len > 0) );
+
+ return OK;
+}
+
+// IP Stuffs
+char *PPPIPInterface::getIPAddress(void) {
+ return ipAddress;
+}
+
+void PPPIPInterface::setIPAddress(char *ip) {
+ strcpy(ipAddress,ip);
+}
+
+// PPP Stuffs
+extern "C" {
+ u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len) {
+ //DBG("LEN %d",len);
+ //DBG_MEMDUMP("IN",(const char*)data,len);
+ PPPIPInterface* pIf = (PPPIPInterface*)fd;
+ USBSerialStream *s = pIf->pppStream;
+ int ret = s->write(data, len, osWaitForever); //Blocks until all data is sent or an error happens
+ //DBG("sio_write OUT");
+ if(ret != OK) {
+ return 0;
+ }
+ return len;
+ }
+
+ u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len) {
+ //DBG("sio_read");
+ PPPIPInterface* pIf = (PPPIPInterface*)fd;
+ size_t readLen;
+ int ret = pIf->pppStream->read(data, &readLen, len, osWaitForever); //Blocks until some data is received or an error happens
+ if(ret != OK) {
+ return 0;
+ }
+ return readLen;
+ }
+
+ void sio_read_abort(sio_fd_t fd) {
+ //DBG("sio_read_abort");
+ PPPIPInterface* pIf = (PPPIPInterface*)fd;
+ pIf->pppStream->abortRead();
+ }
}
-int PPPIPInterface::cleanupLink()
-{
- int ret;
- char buf[32];
- size_t len;
-
- do //Clear buf
- {
- ret = m_pStream->read((uint8_t*)buf, &len, 32, 100);
- if(ret == OK)
- {
- buf[len] = '\0';
- DBG("Got %s", buf);
- }
- } while( (ret == OK) && (len > 0) );
-
- DBG("Sending %s", HANGUP_CMD);
-
- ret = m_pStream->write((uint8_t*)HANGUP_CMD, strlen(HANGUP_CMD), osWaitForever);
- if( ret != OK )
- {
- return NET_UNKNOWN;
- }
-
- size_t readLen;
-
- //Hangup
- DBG("Expect %s", HANGUP_CMD);
-
- len = 0;
- while( len < strlen(HANGUP_CMD) )
- {
- ret = m_pStream->read((uint8_t*)buf + len, &readLen, strlen(HANGUP_CMD) - len, 100);
- if( ret != OK )
- {
- break;
- }
- len += readLen;
- /////
- buf[len]=0;
- DBG("Got %s", buf);
- }
-
- buf[len]=0;
-
- DBG("Got %s[len %d]", buf, len);
-
- //OK response
- DBG("Expect %s", OK_RESP);
-
- len = 0;
- while( len < strlen(OK_RESP) )
- {
- ret = m_pStream->read((uint8_t*)buf + len, &readLen, strlen(OK_RESP) - len, 100);
- if( ret != OK )
- {
- break;
- }
- len += readLen;
- /////
- buf[len]=0;
- DBG("Got %s", buf);
- }
-
- buf[len]=0;
-
- DBG("Got %s[len %d]", buf, len);
-
- //NO CARRIER event
- DBG("Expect %s", NO_CARRIER_RESP);
-
- len = 0;
- while( len < strlen(NO_CARRIER_RESP) )
- {
- ret = m_pStream->read((uint8_t*)buf + len, &readLen, strlen(NO_CARRIER_RESP) - len, 100);
- if( ret != OK )
- {
- break;
- }
- len += readLen;
- /////
- buf[len]=0;
- DBG("Got %s", buf);
- }
-
- buf[len]=0;
-
- DBG("Got %s[len %d]", buf, len);
-
- do //Clear buf
- {
- ret = m_pStream->read((uint8_t*)buf, &len, 32, 100);
- if(ret == OK)
- {
- buf[len] = '\0';
- DBG("Got %s", buf);
- }
- } while( (ret == OK) && (len > 0) );
-
-
- return OK;
+// LwIP Callbacks
+void PPPIPInterface::tcpipInitDoneCb(void *ctx) {
+ PPPIPInterface *pIf = (PPPIPInterface*)ctx;
+ pIf->ipInitiated = true;
}
-/*static*/ void PPPIPInterface::linkStatusCb(void *ctx, int errCode, void *arg) //PPP link status
-{
- PPPIPInterface* pIf = (PPPIPInterface*)ctx;
- struct ppp_addrs* addrs = (struct ppp_addrs*) arg;
+void PPPIPInterface::linkStatusCb(void *ctx, int errCode, void *arg) {
+ PPPIPInterface* pIf = (PPPIPInterface*)ctx;
+ struct ppp_addrs* addrs = (struct ppp_addrs*) arg;
- switch(errCode)
- {
- case PPPERR_NONE:
- WARN("Connected via PPP.");
- DBG("Local IP address: %s", inet_ntoa(addrs->our_ipaddr));
- DBG("Netmask: %s", inet_ntoa(addrs->netmask));
- DBG("Remote IP address: %s", inet_ntoa(addrs->his_ipaddr));
- DBG("Primary DNS: %s", inet_ntoa(addrs->dns1));
- DBG("Secondary DNS: %s", inet_ntoa(addrs->dns2));
- //Setup DNS
- if (addrs->dns1.addr != 0)
- {
- dns_setserver(0, (struct ip_addr*)&(addrs->dns1));
- }
- if (addrs->dns2.addr != 0)
- {
- dns_setserver(1, (struct ip_addr*)&(addrs->dns1));
- }
-
- pIf->setConnected(true);
- pIf->setIPAddress(inet_ntoa(addrs->our_ipaddr));
- break;
- case PPPERR_CONNECT: //Connection lost
- WARN("Connection lost/terminated");
- pIf->setConnected(false);
- break;
- case PPPERR_AUTHFAIL: //Authentication failed
- WARN("Authentication failed");
- pIf->setConnected(false);
- break;
- case PPPERR_PROTOCOL: //Protocol error
- WARN("Protocol error");
- pIf->setConnected(false);
- break;
- case PPPERR_USER:
- WARN("Disconnected by user");
- pIf->setConnected(false);
- break;
- default:
- WARN("Unknown error (%d)", errCode);
- pIf->setConnected(false);
- break;
- }
-
- pIf->m_linkStatusSphre.wait(0); //If previous event has not been handled, "delete" it now
- pIf->m_pppErrCode = errCode;
- pIf->m_linkStatusSphre.release();
-}
-
-//LwIP PPP implementation
-extern "C"
-{
+ switch(errCode) {
+ case PPPERR_NONE:
+ WARN("Connected via PPP.");
+ DBG("Local IP address: %s", inet_ntoa(addrs->our_ipaddr));
+ DBG("Netmask: %s", inet_ntoa(addrs->netmask));
+ DBG("Remote IP address: %s", inet_ntoa(addrs->his_ipaddr));
+ DBG("Primary DNS: %s", inet_ntoa(addrs->dns1));
+ DBG("Secondary DNS: %s", inet_ntoa(addrs->dns2));
+ //Setup DNS
+ if (addrs->dns1.addr != 0) {
+ //dns_setserver(0, (struct ip_addr*)&(addrs->dns1));
+ }
+ if (addrs->dns2.addr != 0) {
+ //dns_setserver(1, (struct ip_addr*)&(addrs->dns1));
+ }
-/**
- * Writes to the serial device.
- *
- * @param fd serial device handle
- * @param data pointer to data to send
- * @param len length (in bytes) of data to send
- * @return number of bytes actually sent
- *
- * @note This function will block until all data can be sent.
- */
-u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len)
-{
- DBG("sio_write");
- PPPIPInterface* pIf = (PPPIPInterface*)fd;
- int ret;
- if(!pIf->m_streamAvail) //If stream is not available (it is a shared resource) don't go further
- {
- return 0;
- }
- ret = pIf->m_pStream->write(data, len, osWaitForever); //Blocks until all data is sent or an error happens
- if(ret != OK)
- {
- return 0;
- }
- return len;
-}
+ pIf->setConnected(true);
+ pIf->setIPAddress(inet_ntoa(addrs->our_ipaddr));
+ break;
+ case PPPERR_CONNECT: //Connection lost
+ WARN("Connection lost/terminated");
+ pIf->setConnected(false);
+ break;
+ case PPPERR_AUTHFAIL: //Authentication failed
+ WARN("Authentication failed");
+ pIf->setConnected(false);
+ break;
+ case PPPERR_PROTOCOL: //Protocol error
+ WARN("Protocol error");
+ pIf->setConnected(false);
+ break;
+ case PPPERR_USER:
+ WARN("Disconnected by user");
+ pIf->setConnected(false);
+ break;
+ default:
+ WARN("Unknown error (%d)", errCode);
+ pIf->setConnected(false);
+ break;
+ }
-/**
- * Reads from the serial device.
- *
- * @param fd serial device handle
- * @param data pointer to data buffer for receiving
- * @param len maximum length (in bytes) of data to receive
- * @return number of bytes actually received - may be 0 if aborted by sio_read_abort
- *
- * @note This function will block until data can be received. The blocking
- * can be cancelled by calling sio_read_abort().
- */
-u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len)
-{
- DBG("sio_read");
- PPPIPInterface* pIf = (PPPIPInterface*)fd;
- int ret;
- size_t readLen;
- if(!pIf->m_streamAvail) //If stream is not available (it is a shared resource) don't go further
- {
- WARN("EXIT NOT AVAIL");
- return 0;
- }
- ret = pIf->m_pStream->read(data, &readLen, len, osWaitForever); //Blocks until some data is received or an error happens
- if(ret != OK)
- {
- return 0;
- }
- DBG("ret");
- return readLen;
+ //pIf->m_linkStatusSphre.wait(0); //If previous event has not been handled, "delete" it now
+ //pIf->m_pppErrCode = errCode;
+ //pIf->m_linkStatusSphre.release();
}
-
-/**
- * Aborts a blocking sio_read() call.
- *
- * @param fd serial device handle
- */
-void sio_read_abort(sio_fd_t fd)
-{
- DBG("sio_read_abort");
- PPPIPInterface* pIf = (PPPIPInterface*)fd;
- if(!pIf->m_streamAvail) //If stream is not available (it is a shared resource) don't go further
- {
- return;
- }
- pIf->m_pStream->abortRead();
- DBG("ret");
-}
-
-}
-
--- a/PPPIPInterface.h Fri Feb 20 17:15:55 2015 +0000
+++ b/PPPIPInterface.h Tue Apr 14 13:27:07 2015 +0000
@@ -1,65 +1,48 @@
-/* PPPIPInterface.h */
-/* Copyright (C) 2012 mbed.org, MIT License
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
- * and associated documentation files (the "Software"), to deal in the Software without restriction,
- * including without limitation the rights to use, copy, modify, merge, publish, distribute,
- * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all copies or
- * substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
#ifndef PPPIPINTERFACE_H_
#define PPPIPINTERFACE_H_
#include "core/fwk.h"
-
-#include "LwIPInterface.h"
-
#include "lwip/sio.h"
+#include "USBSerialStream.h"
-namespace rtos {
-class Semaphore;
-}
-using namespace rtos;
-
-/** Interface using PPP to connect to an IP-based network
- *
- */
-class PPPIPInterface : public LwIPInterface
-{
+class PPPIPInterface {
+private:
+ char ipAddress[16];
+
+ USBSerialStream* pppStream; //Serial stream
+
+ int cleanupLink();
+ int pppSession;
+ bool ipInitiated;
+ bool pppInitiated;
+ bool connected;
public:
- PPPIPInterface(IOStream* pStream);
+ PPPIPInterface(USBSerialStream* pStream);
virtual ~PPPIPInterface();
-
- int init(); //Init PPP-specific stuff, create the right bindings, etc
- int setup(const char* user, const char* pw); //Setup authentication
- virtual int connect();
- virtual int disconnect();
-
-private:
- int cleanupLink();
-
- static void linkStatusCb(void *ctx, int errCode, void *arg); //PPP link status
- Semaphore m_linkStatusSphre;
- int m_pppErrCode;
-
- IOStream* m_pStream; //Serial stream
- bool m_streamAvail;
-
- int m_pppd;
-
+
+ void stackInits(const char* user, const char* pw);
+ int dial(void);
+ int escape(void);
+
+ int connect(const char* user, const char* pw);
+ int disconnect();
+
+ void setConnected(bool val);
+ bool isConnected(void);
+
+ // IP stuffs
+ char *getIPAddress(void);
+ void setIPAddress(char *ip);
+
+ // PPP implementaion
friend u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len);
friend u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len);
friend void sio_read_abort(sio_fd_t fd);
+
+ // CallBacks
+ static void tcpipInitDoneCb(void *arg);
+ static void linkStatusCb(void *ctx, int errCode, void *arg);
};
#endif /* PPPIPINTERFACE_H_ */
--- a/PyrnUSBModem.cpp Fri Feb 20 17:15:55 2015 +0000
+++ b/PyrnUSBModem.cpp Tue Apr 14 13:27:07 2015 +0000
@@ -1,7 +1,11 @@
-#include "dbg.h"
#include "PyrnUSBModem.h"
-#include "HuaweiUSBModemInitializer.h"
+
+#define __DEBUG__ 5
+#ifndef __MODULE__
+#define __MODULE__ "PyrnUSBModem.cpp"
+#endif
+#include "MyDebug.h"
// Command Processors
@@ -12,18 +16,18 @@
PIN_STATUS getStatus() { return status; }
private:
virtual int onNewATResponseLine(ATCommandsInterface* pInst, const char* line) {
- USB_DBG("GOT %s",line);
+ DBG("GOT %s",line);
if(!strncmp(line, "+CPIN: READY",12)) {
status = STATUS_READY;
- USB_DBG("STATUS_READY");
+ DBG("STATUS_READY");
} else if(!strncmp(line, "+CPIN: SIM PIN",14)) {
status = STATUS_SIMPIN;
- USB_DBG("STATUS_SIMPIN");
+ DBG("STATUS_SIMPIN");
}else if(!strncmp(line, "+CPIN: SIM PUK",14)) {
status = STATUS_SIMPUK;
- USB_DBG("STATUS_SIMPUK");
+ DBG("STATUS_SIMPUK");
} else
- USB_DBG("STATUS_NONE");
+ DBG("STATUS_NONE");
return OK;
}
virtual int onNewEntryPrompt(ATCommandsInterface* pInst) { return OK; }
@@ -117,135 +121,210 @@
volatile bool valid;
};
-PyrnUSBModem::PyrnUSBModem(USBHost *host):
+// ==================== MODEM =====================
+
+PyrnUSBModem::PyrnUSBModem():
+ initialiser(USBHost::getHostInst()),
dongle(),
atStream(dongle.getSerial(3)),
- pppStream(dongle.getSerial(3)),
+ pppStream(dongle.getSerial(0)),
at(&atStream),
- ppp(&pppStream),
+ ppp(&pppStream),
atOpen(false),
- pppOpen(false) {
- // If we support more dongle add the initializer here.
- // furthermore add dongle specific initialisation int init().
- HuaweiE372USBModemInitializer *huaweie372Initializer = new HuaweiE372USBModemInitializer(host);
- dongle.addInitializer(huaweie372Initializer);
+ simReady(false),
+ pppOpen(false),
+ ipInit(false) {
+ DBG("Add E372 dongle initializer");
+ dongle.addInitializer(&initialiser);
}
bool PyrnUSBModem::init() {
-
+ int ret = 0;
+
if(!dongle.connected()){
- while(!dongle.connected()) {
- USB_INFO("Dongle try connect");
- dongle.tryConnect();
- Thread::wait(10);
+ bool detectConnectedModem = false;
+ for (int x=0; x<5;x++){
+ DBG("Trying to connect the dongle");
+ dongle.tryConnect();
+ if (dongle.connected()) {
+ DBG("Great the dongle is connected - I've tried %d times to connect", x);
+ detectConnectedModem = true;
+ break; // Break out of the for loop once the dongle is connected - otherwise try for a while more
+ }
+ Thread::wait(7000);
}
- if(!dongle.connected())
+ if (!detectConnectedModem) {
+ // OK we got this far - so give up trying and let someone know you can't see the modem
+ ERR("There is no dongle pluged into the board, or the module does not respond. Is the module/modem switched on?");
return false;
- } else
- USB_INFO("Dongle is already connected ... continue");
-
- if(atOpen) {
- USB_INFO("Stream is already opened");
- return true;
+ }
+ } else {
+ INFO("Dongle is already connected ... continue");
}
- USB_INFO("Starting AT thread if needed");
- int ret = at.open();
- if(ret) {
- USB_ERR("Opening AT failed");
- return false;
- }
-
- USB_INFO("Sending initialisation commands");
- ret = at.init();
- if(ret) {
- USB_ERR("Initialisation AT failed");
- return false;
- }
-
- if(dongle.getDongleType() == WAN_DONGLE_TYPE_HUAWEI_E372) {
- USB_INFO("Using a Vodafone E372 Dongle");
- // Specific dongle initisation
- ret = at.executeSimple("AT", NULL,5000);
- if(ret != OK){
- USB_ERR("AT Simple command ERROR");
+ if(atOpen) {
+ INFO("Stream is already opened go to SIM Check");
+ } else {
+
+ INFO("Starting AT thread if needed");
+ ret = at.open();
+ if(ret) {
+ ERR("Opening AT failed");
return false;
- } else {
- USB_INFO("AT Simple command gone well!!");
+ }
+
+ INFO("Sending initialisation commands");
+ // Echo 1
+ // Format CRLF
+ // Unsollicited Codes disabled
+ ret = at.init("ATZ E1 V1 ^CURC=0");
+ if(ret) {
+ ERR("Initialisation AT failed");
+ return false;
}
- } else {
- USB_WARN("Using an Unknown Dongle");
+
+ if(dongle.getDongleType() == WAN_DONGLE_TYPE_HUAWEI_E372) {
+ INFO("Using a Vodafone E372 Dongle");
+ ERR("Send CMEE cmd ...");
+ ret = at.executeSimple("AT+CMEE=1",NULL,5000);
+ if(ret != OK) {
+ ERR("CMEE cmd failed");
+ return false;
+ }
+ } else {
+ WARN("Using an Unknown Dongle.. do specific init");
+ }
+
+ atOpen = true;
}
ATCommandsInterface::ATResult result;
- // SIM PIN Stuff here
- bool pin = false;
- int retries = 3;
- do {
- CPINProcessor cpinProcessor;
- USB_INFO("Check CPIN STATE");
- ret = at.execute("AT+CPIN?", &cpinProcessor, &result,5000);
- USB_INFO("Result of command: Err code=%d\n", ret);
- USB_INFO("ATResult: AT return=%d (code %d)\n", result.result, result.code);
- if(ret == OK) {
- if(cpinProcessor.getStatus() == CPINProcessor::STATUS_READY) {
- USB_INFO("ME PIN READY\n");
- pin = true;
- break;
- } else if (cpinProcessor.getStatus() == CPINProcessor::STATUS_SIMPIN) {
- USB_INFO("ME SIM PIN NEEDED\n");
- ret = at.executeSimple("AT+CPIN=\"0000\"", NULL,5000);
- if(ret != OK){
- USB_ERR("CPIN ERROR ... do not retry");
+ if(!simReady){
+ // SIM PIN Stuff here
+ int retries = 3;
+ do {
+ CPINProcessor cpinProcessor;
+ INFO("Check CPIN STATE");
+ ret = at.execute("AT+CPIN?", &cpinProcessor, &result,5000);
+ //INFO("Result of command: Err code=%d", ret);
+ //INFO("ATResult: AT return=%d (code %d)", result.result, result.code);
+ if(result.code == 14) {
+ WARN("SIM IS Busy retry");
+ retries++;
+ Thread::wait(500);
+ } else if(ret == OK) {
+ if(cpinProcessor.getStatus() == CPINProcessor::STATUS_READY) {
+ INFO("ME PIN READY");
+ simReady = true;
+ break;
+ } else if (cpinProcessor.getStatus() == CPINProcessor::STATUS_SIMPIN) {
+ INFO("ME SIM PIN NEEDED");
+ ret = at.executeSimple("AT+CPIN=\"0000\"",NULL,5000);
+ if(ret != OK){
+ ERR("CPIN ERROR ... do not retry");
+ break;
+ } else {
+ INFO("CPIN OK");
+ }
+ } else if (cpinProcessor.getStatus() == CPINProcessor::STATUS_SIMPUK) {
+ INFO("CPIN IS PUKED");
break;
} else {
- USB_INFO("CPIN OK");
+ ERR("UNKNOWN STATUS");
+ break;
}
- } else if (cpinProcessor.getStatus() == CPINProcessor::STATUS_SIMPUK) {
- USB_INFO("CPIN IS PUKED");
- break;
} else {
- USB_ERR("UNKNOWN STATUS");
+ INFO("SIM PIN ERROR: SIM Probably not inserted");
break;
}
- } else {
- USB_INFO("SIM PIN ERROR: SIM Probably not inserted\n");
- break;
+ retries--;
+ } while(retries);
+
+ if(!simReady) {
+ ERR("Couldn't pin unlock ...");
+ return false;
}
- retries--;
- } while(retries);
+ } else {
+ INFO("SIM PIN have been unlocked somewhere!");
+ }
- if(!pin) {
- USB_ERR("Couldn't pin unlock ...");
- return false;
- }
-
//Wait for network registration
CREGProcessor cregProcessor;
do {
- USB_INFO("Waiting for network registration");
+ INFO("Waiting for network registration");
ret = at.execute("AT+CREG?", &cregProcessor, &result);
- USB_INFO("Result of command: Err code=%d\n", ret);
- USB_INFO("ATResult: AT return=%d (code %d)\n", result.result, result.code);
+ //INFO("Result of command: Err code=%d", ret);
+ //INFO("ATResult: AT return=%d (code %d)", result.result, result.code);
if(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING) {
- Thread::wait(3000);
+ Thread::wait(500);
}
} while(cregProcessor.getStatus() == CREGProcessor::STATUS_REGISTERING);
if(cregProcessor.getStatus() == CREGProcessor::STATUS_FAILED) {
- USB_ERR("Registration denied");
+ ERR("Registration denied");
return false;
}
-
- atOpen = true;
return true;
}
-bool PyrnUSBModem::isConnected(void) {
+bool PyrnUSBModem::attached(void) {
return dongle.connected();
}
+bool PyrnUSBModem::pppConnected(void) {
+ return ppp.isConnected();
+}
+
+/*
WANDongleSerialPort *PyrnUSBModem::getAtInterface(int i) {
return dongle.getWANSerial(i);
+}*/
+
+int PyrnUSBModem::connect(const char* apn, const char* user, const char* password) {
+ int ret;
+
+ if(!init()) {
+ ERR("Modem could not register");
+ return -1;
+ }
+
+ ATCommandsInterface::ATResult result;
+
+ if(apn != NULL) {
+ char cmd[48];
+ int tries = 30;
+ DBG("Setting APN to %s", apn);
+ sprintf(cmd, "AT+CGDCONT=1,\"IP\",\"%s\"", apn);
+ do {//Try 30 times because for some reasons it can fail *a lot* with the K3772-Z dongle
+ ret = at.executeSimple(cmd, &result);
+ //DBG("Result of command: Err code=%d", ret);
+ if(ret)
+ Thread::wait(500);
+ } while(ret && --tries);
+ // DBG("ATResult: AT return=%d (code %d)", result.result, result.code);
+ }
+
+ DBG("Connecting PPP");
+ ret = ppp.connect(user, password);
+ DBG("Result of connect: Err code=%d", ret);
+
+ return ret;
+}
+
+int PyrnUSBModem::disconnect() {
+ DBG("Disconnecting from PPP");
+ int ret = ppp.disconnect();
+ if(ret) {
+ ERR("Disconnect returned %d, still trying to disconnect", ret);
+ }
+
+ Thread::wait(500);
+
+ return OK;
+}
+
+char* PyrnUSBModem::getIPAddress() {
+ // return NULL;//ppp.getIPAddress();
+ return ppp.getIPAddress();
}
\ No newline at end of file
--- a/PyrnUSBModem.h Fri Feb 20 17:15:55 2015 +0000
+++ b/PyrnUSBModem.h Tue Apr 14 13:27:07 2015 +0000
@@ -3,26 +3,42 @@
#define PYRN_USB_MODEM_H
#include "mbed.h"
+
#include "USBHost/USBHost3GModule/WANDongle.h"
#include "USBSerialStream.h"
#include "ATCommandsInterface.h"
#include "PPPIPInterface.h"
+#include "HuaweiE372DongleInitializer.h"
+
class PyrnUSBModem {
private:
+ HuaweiE372DongleInitializer initialiser;
WANDongle dongle;
+
USBSerialStream atStream;
USBSerialStream pppStream;
+
ATCommandsInterface at;
PPPIPInterface ppp;
+
bool atOpen;
+ bool simReady;
bool pppOpen;
+ bool ipInit;
public:
- PyrnUSBModem(USBHost *h);
+ PyrnUSBModem();
bool init();
- bool isConnected(void);
- void testAT(void);
+
WANDongleSerialPort *getAtInterface(int i);
+
+ bool attached(void);
+ bool pppConnected(void);
+
+ int connect(const char* apn, const char* user, const char* password);
+ int disconnect(void);
+
+ char* getIPAddress(void);
};
#endif
\ No newline at end of file
--- a/USBSerialStream.cpp Fri Feb 20 17:15:55 2015 +0000
+++ b/USBSerialStream.cpp Tue Apr 14 13:27:07 2015 +0000
@@ -17,10 +17,15 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
-#include <stdio.h>
+#include <cstdio>
#include "USBSerialStream.h"
+#define __DEBUG__ 0
+#ifndef __MODULE__
+#define __MODULE__ "USBSerialStream.cpp"
+#endif
+#include "MyDebug.h"
USBSerialStream::USBSerialStream(IUSBHostSerial& serial) : m_serial(serial), m_serialTxFifoEmpty(true),
m_availableSphre(1), m_spaceSphre(1), m_inBuf()
@@ -39,11 +44,11 @@
//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*/)
{
- USB_DBG("Trying to read at most %d chars", maxLength);
+ DBG("Trying to read at most %d chars", maxLength);
int ret = waitAvailable(timeout);
if(ret)
{
- USB_WARN("Error %d while waiting for incoming data", ret);
+ WARN("Error %d while waiting for incoming data", ret);
return ret;
}
int a = available(); //Prevent macro issues
@@ -57,7 +62,7 @@
buf++;
}
setupReadableISR(true);
- USB_DBG("Read %d chars successfully", *pLength);
+ DBG("Read %d chars successfully", *pLength);
return OK;
}
@@ -78,19 +83,19 @@
return OK;
}
- USB_DBG("Waiting for data availability %d ms (-1 is infinite)", timeout);
+ DBG("Waiting for data availability %d ms (-1 is infinite)", timeout);
ret = m_availableSphre.wait(timeout); //Wait for data to arrive or for abort
if(ret <= 0)
{
- USB_DBG("Timeout");
+ DBG("Timeout");
return NET_TIMEOUT;
}
if(!m_inBuf.available()) //Even if abort has been called, return that data is available
{
- USB_DBG("Aborted");
+ DBG("Aborted");
return NET_INTERRUPTED;
}
- USB_DBG("Finished waiting");
+ DBG("Finished waiting");
while( m_availableSphre.wait(0) > 0 ); //Clear the queue as data is available
return OK;
}
@@ -103,7 +108,7 @@
}
else
{
- USB_DBG("Serial is readable"); ;
+ DBG("Serial is readable"); ;
}
return OK;
}
@@ -126,18 +131,18 @@
//0 for non-blocking (returns immediately), -1 for infinite blocking
/*virtual*/ int USBSerialStream::write(uint8_t* buf, size_t length, uint32_t timeout/*=-1*/)
{
- USB_DBG("Trying to write %d chars", length);
+ DBG("Trying to write %d chars", length);
do
{
int ret = waitSpace(timeout);
if(ret)
{
- USB_WARN("Error %d while waiting for space", ret);
+ WARN("Error %d while waiting for space", ret);
return ret;
}
int s = space(); //Prevent macro issues
int writeLen = MIN( s, length );
- USB_DBG("Writing %d chars", writeLen);
+ DBG("Writing %d chars", writeLen);
setupWriteableISR(false);
while(writeLen)
{
@@ -154,7 +159,7 @@
setupWriteableISR(true);
} while(length);
- USB_DBG("Write successful");
+ DBG("Write successful");
return OK;
}
@@ -175,16 +180,16 @@
return OK;
}
- USB_DBG("Waiting for data space %d ms (-1 is infinite)", timeout);
+ DBG("Waiting for data space %d ms (-1 is infinite)", timeout);
ret = m_spaceSphre.wait(timeout); //Wait for space to be made or for abort
if(ret <= 0)
{
- USB_DBG("Timeout");
+ DBG("Timeout");
return NET_TIMEOUT;
}
if(!space()) //Even if abort has been called, return that space is available
{
- USB_DBG("Aborted");
+ DBG("Aborted");
return NET_INTERRUPTED;
}
while( m_spaceSphre.wait(0) > 0); //Clear the queue as space is available
--- a/USBSerialStream.h Fri Feb 20 17:15:55 2015 +0000 +++ b/USBSerialStream.h Tue Apr 14 13:27:07 2015 +0000 @@ -21,8 +21,6 @@ #define USBSERIALSTREAM_H_ #include "rtos.h" - -#include "dbg.h" #include "core/IOStream.h" #include "core/MtxCircBuffer.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core/IOStream.h Tue Apr 14 13:27:07 2015 +0000
@@ -0,0 +1,61 @@
+/* IOStream.h */
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef IOSTREAM_H_
+#define IOSTREAM_H_
+
+#include "fwk.h"
+
+#include "rtos.h"
+
+class IStream
+{
+public:
+ //IStream();
+ //virtual ~IStream();
+
+ //0 for non-blocking (returns immediately), osWaitForever for infinite blocking
+ virtual int read(uint8_t* buf, size_t* pLength, size_t maxLength, uint32_t timeout=osWaitForever) = 0;
+ virtual size_t available() = 0;
+ virtual int waitAvailable(uint32_t timeout=osWaitForever) = 0; //Wait for data to be available
+ virtual int abortRead() = 0; //Abort current reading (or waiting) operation
+};
+
+class OStream
+{
+public:
+ //OStream();
+ //virtual ~OStream();
+
+ //0 for non-blocking (returns immediately), osWaitForever for infinite blocking
+ virtual int write(uint8_t* buf, size_t length, uint32_t timeout=osWaitForever) = 0;
+ virtual size_t space() = 0;
+ virtual int waitSpace(uint32_t timeout=osWaitForever) = 0; //Wait for space to be available
+ virtual int abortWrite() = 0; //Abort current writing (or waiting) operation
+};
+
+class IOStream : public IStream, public OStream
+{
+public:
+ //IOStream();
+ //virtual ~IOStream();
+};
+
+
+#endif /* IOSTREAM_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/core/MtxCircBuffer.h Tue Apr 14 13:27:07 2015 +0000
@@ -0,0 +1,103 @@
+/* MtxCircBuf.h */
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef MTXCIRCBUFFER_H
+#define MTXCIRCBUFFER_H
+
+#include "fwk.h"
+
+#include "rtos.h"
+
+//Mutex protected circualr buffer
+template<typename T, int size>
+class MtxCircBuffer
+{
+public:
+ MtxCircBuffer() //:
+ //mtx()
+ {
+ write = 0;
+ read = 0;
+ }
+
+ bool isFull()
+ {
+ mtx.lock();
+ bool r = (((write + 1) % size) == read);
+ mtx.unlock();
+ return r;
+ }
+
+ bool isEmpty()
+ {
+ mtx.lock();
+ bool r = (read == write);
+ mtx.unlock();
+ return r;
+ }
+
+ void queue(T k)
+ {
+ mtx.lock();
+ while (((write + 1) % size) == read) //if (isFull())
+ {
+ /*while((((write + 1) % size) == read))
+ {*/
+ mtx.unlock();
+ Thread::wait(10);
+ mtx.lock();
+ /*}*/
+ //read++;
+ //read %= size;
+ }
+ buf[write++] = k;
+ write %= size;
+ mtx.unlock();
+ }
+
+ uint16_t available()
+ {
+ mtx.lock();
+ uint16_t a = (write >= read) ? (write - read) : (size - read + write);
+ mtx.unlock();
+ return a;
+ }
+
+ bool dequeue(T * c)
+ {
+ mtx.lock();
+ bool empty = (read == write);
+ if (!empty)
+ {
+ *c = buf[read++];
+ read %= size;
+ }
+ mtx.unlock();
+ return (!empty);
+ }
+
+private:
+ volatile uint16_t write;
+ volatile uint16_t read;
+ volatile T buf[size];
+ Mutex mtx;
+};
+
+#endif
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/config.h Tue Apr 14 13:27:07 2015 +0000 @@ -0,0 +1,27 @@ +/* config.h */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef CONFIG_H_ +#define CONFIG_H_ + + +//Configuration +#define AT_THREAD_PRIORITY 0 + + +#endif /* CONFIG_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/errors.h Tue Apr 14 13:27:07 2015 +0000 @@ -0,0 +1,47 @@ +/* errors.h */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef ERRORS_H_ +#define ERRORS_H_ + +/** \page Network-related errors */ + +#define OK 0 //No error + +#define NET_FULL 1 //>All available resources are already used +#define NET_EMPTY 2 //>No resource +#define NET_NOTFOUND 3 //>Element cannot be found +#define NET_INVALID 4 //>Invalid +#define NET_CONTEXT 5 //>Called in a wrong context (eg during an interrupt) +#define NET_TIMEOUT 6 //>Timeout +#define NET_UNKNOWN 7 //>Unknown error +#define NET_OVERFLOW 8 //>Overflow +#define NET_PROCESSING 9 //>Command is processing +#define NET_INTERRUPTED 10 //>Current operation has been interrupted +#define NET_MOREINFO 11 //>More info on this error can be retrieved elsewhere (eg in a parameter passed as ptr) +#define NET_ABORT 12 //>Current operation must be aborted +#define NET_DIFF 13 //>Items that should match are different +#define NET_AUTH 14 //>Authentication failed +#define NET_PROTOCOL 15 //>Protocol error +#define NET_OOM 16 //>Out of memory +#define NET_CONN 17 //>Connection error +#define NET_CLOSED 18 //>Connection was closed by remote end +#define NET_TOOSMALL 19 //>Buffer is too small + +#endif /* ERRORS_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/fwk.h Tue Apr 14 13:27:07 2015 +0000 @@ -0,0 +1,58 @@ +/* fwk.h */ +/* Copyright (C) 2012 mbed.org, MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software + * and associated documentation files (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef FWK_H_ +#define FWK_H_ + +#include "config.h" + +#include "string.h" +//using namespace std; + +#include "stdint.h" +typedef unsigned int size_t; + +#ifndef __cplusplus +//boolean type compatibility +typedef byte bool; +#define true 1 +#define false 0 +#endif + +#ifndef NULL +#define NULL ((void*)0) +#endif + +#define CR '\x0D' +#define LF '\x0A' +#define GD '\x3E' +#define BRK '\x1A' + +//Custom utility classes +#include "IOStream.h" +//#include "String.h" + +//Error codes +#include "errors.h" + +//Utility macros +#define MIN(x,y) (((x)<(y))?(x):(y)) +#define MAX(x,y) (((x)>(y))?(x):(y)) + +#endif /* FWK_H_ */