Currently GPRS code is as follows -
definitions and global variables :
Code:
#define AT_GPRS_APN "vfinternet.au"
#define AT_GPRS_LOGIN "guest"
#define AT_GPRS_PASSW "guest"
#define DEST_IP "203.34.52.61"
#define DEST_PORT "80"
#define GPRS_CLIENT 0
#define BUF_SZ 100
#define ID_SZ 12 // size of the id string
#define NUM_SLAVES 5
#define GPRS_MSG_CONT "HTTP/1.1 100 Continue"
#define GPRS_MSG_OK "HTTP/1.1 200 OK"
#define MAX_LINES 300
typedef struct
{
char id[ID_SZ];
uint16_t lines;
} sd_t;
uint8_t storedNodeCount=0;
sd_t storedNode[NUM_SLAVES];
initialisation run before main loop :
Code:
void GPRS_Init()
{
uint8_t bSuccess = 0;
USB.print( "GPRS init.." );
// opens UART1 and powers the GPRS module ( performs begin() sequence )
GPRS.ON();
if(!GPRS.check())
{
PWR.reboot();
}
USB.print( "connected.." );
bSuccess |= GPRS.configureGPRS();
if( GPRS.flag != 0 )
{
USB.print( "error " );
USB.print( GPRS.flag );
USB.println( " communicating with module" );
PWR.reboot();
}
Output_Update();
delay(2000);
bSuccess |= GPRS.createSocket( DEST_IP, DEST_PORT, GPRS_CLIENT ); // web service
Output_Update();
USB.println( bSuccess?"OK":"FAIL" );
if( bSuccess == 0 )
{
PWR.reboot();
}
}
run in main loop :
Code:
void GPRS_Process_Send2Server()
{
static volatile uint16_t GPRS_Timer = 0;
int8_t bSuccess = 0;
char* buffer;
char buf[350];
static uint8_t GPRSState = 0;
static uint8_t SDState = 0;
uint8_t i, iRetVal;
static uint8_t rxCounter = 0;
static uint8_t flagRefresh = FALSE, flagFirstTime = TRUE, flagExit = FALSE;
static uint16_t DELAY_Timer = 0;
static uint16_t length = 0;
char string[5];
static uint8_t iNodeIndex = 0;
switch( SDState )
{
case( 0 ):
if( flagFirstTime )
{
USB.println( "count nodes " );
getNodesToUpload( FALSE );
flagFirstTime = FALSE;
USB.println( storedNodeCount, DEC );
if( storedNodeCount > 0 )
{
// initialise variables
flagExit = FALSE;
length = 0;
// get a line count of data for each node
memset( filename, 0x00, ID_SZ+12 );
iNodeIndex = storedNodeCount - 1;
for( i=0; i<storedNodeCount; i++ )
{
snprintf( filename, ID_SZ+12, "datalog%s.csv", storedNode[i].id );
storedNode[i].lines = SD.numln( filename );
if( ( (storedNode[i].lines - 1) == 0 ) || ( (storedNode[i].lines - 1) >= MAX_LINES ) )
{
//USB.println( "error reading" );
//i--;
}
}
GPRS_Timer = millis();
SDState = 1;
GPRSState = 0;
DELAY_Timer = millis();
}
else
{
flagExit = TRUE;
}
}
else if( flagRefresh )
{
getNodesToUpload( TRUE );
}
else
{
flagExit = TRUE;
}
break;
case( 1 ):
switch( GPRSState )
{
case( 0 ) :
if( iNodeIndex >= 0 )
{
if( Timer_PassedDelay( DELAY_Timer, 2000 ) ) // delay of 2 seconds
{
memset( filename, 0x00, ID_SZ+12 );
length = 0;
snprintf( filename, ID_SZ+12, "datalog%s.csv", storedNode[iNodeIndex].id );
if( ( (storedNode[iNodeIndex].lines - 1) == 0 ) || ( (storedNode[iNodeIndex].lines - 1) >= MAX_LINES ) )
{
//USB.println( "error reading" );
//i--;
}
else
{
buffer = SD.catln( filename, storedNode[iNodeIndex].lines, 1 );
length = strlen( buffer );
}
if( length == 0 || length > BUF_SZ-1 )
{
flagExit = TRUE;
}
else
{
snprintf( string, 5, "%u", length );
snprintf( buf, 350, "%s%s%s%s%s%s%s%s",
"POST /WebReceiver.svc HTTP/1.1\r\n",
"User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 4.0.30319.239)\r\n",
"Content-Type: text/xml; charset=utf-8\r\n",
"SOAPAction: \"http://tempuri.org/IWebReceiver/UploadInformation\"\r\n",
"Host: web.name.com\r\n",
"Content-Length: ",
string,
"\r\nExpect: 100-continue\r\n\r\n" );
if( !( GPRS.sendData( buf, GPRS.socket_ID ) ) )
{
//GPRS_Reconnect();
GPRS.OFF();
delay( 2000 );
GPRS.ON();
rxCounter = 0;
SDState = 0; // start at SDState 1 to prevent resending data - starts at the line at which gprs was failing
GPRSState = 0;
}
else
{
GPRSState++;
}
DELAY_Timer = millis();
}
}
}
break;
case( 1 ) :
bSuccess=0;
if( Timer_PassedDelay( DELAY_Timer, 2000) ) // delay of 2 seconds
{
memset(GPRS.data_URL, 0, 100);
while( !bSuccess )
{
bSuccess = GPRS.readData( GPRS.socket_ID, "90" ); // delays occurring here
}
USB.print( "GPRS: RX1->" );
USB.println( GPRS.data_URL );
if( isEqual( GPRS.data_URL, GPRS_MSG_CONT, strlen(GPRS_MSG_CONT) ) )
{
GPRSState = 2;
}
else
{
// still waiting for the Continue message
rxCounter++;
GPRSState = 1;
}
DELAY_Timer = millis();
}
break;
case( 2 ) :
if( Timer_PassedDelay( DELAY_Timer, 3000) ) // delay of 3 seconds
{
memset( filename, 0x00, ID_SZ+12 );
snprintf( filename, ID_SZ+12, "datalog%s.csv", storedNode[iNodeIndex].id );
USB.println( filename );
if( ( (storedNode[iNodeIndex].lines - 1) == 0 ) || ( (storedNode[iNodeIndex].lines - 1) >= MAX_LINES ) )
{
//USB.println( "error reading" );
//i--;
}
else
{
snprintf( filename, ID_SZ+12, "datalog%s.csv", storedNode[iNodeIndex].id );
buffer = SD.catln( filename, storedNode[iNodeIndex].lines, 1 );
// checks for error on line
if( strlen( buffer ) > BUF_SZ-1 )
{
//USB.println( "error on line" );
//i--;
}
else
{
snprintf( buf, BUF_SZ, "%s", buffer );
if( storedNodeCount==1 )
{
iRetVal = GPRS.sendData( buf, GPRS.socket_ID );
}
if( !iRetVal )
{
//GPRS_Reconnect();
GPRS.OFF();
delay( 2000 );
GPRS.ON();
rxCounter = 0;
SDState = 0;
GPRSState = 0;
break;
}
}
}
GPRSState++;
rxCounter = 0;
DELAY_Timer = millis();
}
break;
case( 3 ) :
bSuccess = 0;
if( Timer_PassedDelay( DELAY_Timer, 2000) ) // delay of 2 seconds
{
memset(GPRS.data_URL, 0, 100);
while( !bSuccess )
{
bSuccess = GPRS.readData( GPRS.socket_ID, "90" );
}
USB.print( "GPRS: RX2->" );
USB.println( GPRS.data_URL );
if( isEqual( GPRS.data_URL, GPRS_MSG_OK, strlen(GPRS_MSG_OK) ) )
{
GPRSState++;
}
else
{
// still waiting for ok message
rxCounter++;
GPRSState = 3;
}
DELAY_Timer = millis();
}
break;
case( 4 ) :
// decrement line count
storedNode[iNodeIndex].lines--;
if( (storedNode[iNodeIndex].lines-1) == 0 || (storedNode[iNodeIndex].lines-1) > MAX_LINES )
{
// no more lines to upload, delete the file
snprintf( filename, ID_SZ+12, "datalog%s.csv", storedNode[iNodeIndex].id );
SD.del( filename );
// must raise flag to refresh node count
iNodeIndex--;
}
SDState = 0;
GPRSState = 0;
XBee.print( "GPRS: Time taken " );
XBee.println( (int)(millis() - GPRS_Timer) );
rxCounter = 0;
serialFlush(PORT_USED);
DELAY_Timer = millis();
break;
}
break;
}
if( flagExit )
{
flagFirstTime = TRUE;
flagSend2Server = FALSE;
flagExit = FALSE;
}
else if( rxCounter >= MAX_RX_CNT )
{
//GPRS_Reconnect();
GPRS.OFF();
delay( 2000 );
GPRS.ON();
rxCounter = 0;
SDState = 0; // start at SDState 1 to prevent resending data - starts at the line at which gprs was failing
GPRSState = 0;
}
}
bool isEqual( char a[], char b[], uint8_t size )
{
uint8_t i;
for( i=0; i<size; i++ )
{
if( a[i] != b[i] )
{
return FALSE;
}
}
return TRUE;
}
void getNodesToUpload( bool keepLines )
{
char* buffer;
uint8_t i, j=0;
buffer = SD.ls(0,0,NAMES);
char tempID[ID_SZ];
uint8_t tempStoredNodeCount = storedNodeCount;
sd_t tempStoredNode[storedNodeCount];
if( keepLines )
{
memcpy( tempStoredNode, storedNode, sizeof(sd_t)*storedNodeCount );
memset( storedNode, 0x00, sizeof(sd_t)*NUM_SLAVES );
}
storedNodeCount = 0;
while( buffer[j] != '\0' )
{
if( buffer[j] == 'd' )
{
if( buffer[j+1] == 'a' )
{
if( buffer[j+2] == 't' )
{
if( buffer[j+3] == 'a' )
{
if( buffer[j+4] == 'l' )
{
if( buffer[j+5] == 'o' )
{
if( buffer[j+6] == 'g' )
{
for( i=0; i<ID_SZ-1; i++ )
{
tempID[i] = buffer[j+7+i];
}
tempID[ID_SZ-1] = '\0';
memcpy( storedNode[storedNodeCount].id, tempID, ID_SZ );
if( keepLines )
{
for( i=0; i<tempStoredNodeCount; i++ )
{
if( strcmp( storedNode[storedNodeCount].id, tempStoredNode[i].id ) == 0 )
{
storedNode[storedNodeCount].lines = tempStoredNode[i].lines;
}
}
}
storedNodeCount++;
}
}
}
}
}
}
}
j++;
}
}
uint8_t Timer_PassedDelay( uint16_t startTime, uint16_t msDelay )
{
uint16_t stoptime = startTime+msDelay;
uint16_t curtime = millis();
if(stoptime >= startTime)
{
if((curtime >= stoptime) || (curtime < startTime))
return TRUE;
else
return FALSE;
} else {
if((curtime > stoptime) && (curtime < startTime))
return TRUE;
else
return FALSE;
}
}
I think I've included everything of importance. Let me know if there are any queries. I'll see if your suggestion of closing and deleting sockets helps.