SIM900 GPRS HTTP AT Commands – Page 2 of 2
Uploading a file to the server using HTTP POST
We will upload a file to the server using HTTP POST multipart/form-data method. You can search in google for more information on multipart/form-data method of sending data in HTTP POST. In this method the POST variables are sent between demarcation strings called boundary.
The server will be told before what boundary will demarcate our data in the HTTP header. In our case below our Boundary string is —-WebKitFormBoundaryvZ0ZHShNAcBABWFy.
Here we are using the Henry’s HTTP POST Dumping server available at the url http://posttestserver.com/ .
The URL where you need to POST the variables is http://posttestserver.com/post.php.
Whatever data you post at this url is available at the url http://posttestserver.com/data .
Lets get started and when we are already allocated a IP address, now we can proceed by enabling the HTTP mode
AT+HTTPINIT
OK
OPTIONAL, ONLY IF URL is HTTPS or SSL enabled: Also Remove the http:// part in the HTTPPARA=”URL”,xxxx command
AT+HTTPSSL=1
OK
Start by setting up the HTTP bearer profile identifier
AT+HTTPPARA=”CID”,1
OK
Set the url to the address of the webpage you want to post to
AT+HTTPPARA=“URL”,”http://posttestserver.com/post.php”
OK
Set the Content as multipart/form-data type of HTTP POST and also set the boundary value
AT+HTTPPARA=”CONTENT”,”multipart/form-data; boundary=—-WebKitFormBoundaryvZ0ZHShNAcBABWFy”
OK
Tell the module that you will be sending 192 bytes of data and it can timeout after 10 seconds of inactivity. After this command you get the DOWNLOAD URC then you can type in 192 bytes of data within 10 seconds. The typed data is filled in a local buffer of the module and is not yet posted to the server. In the post body is the multi part form data which contains the necessary headers and data to post a file with name data.txt with 10 bytes of data Hello Ravi
AT+HTTPDATA=192,10000
OK
DOWNLOAD
——WebKitFormBoundaryvZ0ZHShNAcBABWFy
Content-Disposition: form-data; name=”fileToUpload”; filename=”data.txt”
Content-Type: text/plain
Hello Ravi
——WebKitFormBoundaryvZ0ZHShNAcBABWFy
OK
Execute the HTTP POST command so that the buffer contents are POST to the server
AT+HTTPACTION=1
OK
This URC means that the data was successfully posted to the server and a received a data of 141 bytes which is the server response to your HTTP POST
+HTTPACTION:1,200,141
The below command tells the module that we want to read the received data
AT+HTTPREAD
The below is the data received from the server
+HTTPREAD:141
Successfully dumped 0 post variables.
View it at http://posttestserver.com/data/2015/10/07/07.41.291690063480
Post body was 0 chars long.
OK
After this you can see the uploaded file at the above URL. Note: The data length to be uploaded is very strict here and needs to be carefully calculated. So i wrote the below script which can be RUN on Windows and Linux using GCC. Also make sure you set the correct COM port in Windows and right tty/USBx device in Linux You can modify according to your use. Watch the video above to get more idea. This code also needs the RS232.c Library which you can find here >> Serial Port programming in Linux using C – Working code
{code lang:c title:”demo_tx.c” lines:false hidden:false}
/**************************************************
file: demo_tx.c
purpose: simple demo that transmits characters to
the serial port and print them on the screen,
exit the program by pressing Ctrl-C
compile with the command: gcc demo_tx.c rs232.c -Wall -Wextra -o2 -o test_tx
**************************************************/
#include <stdlib.h>
#include <stdio.h>
#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif
#include “rs232.h”
/*******************************************************************************
* Funtion name : MapForward *
* *
* Description : This function performs forward mapping and returns pointer *
* to the start of the found data or else returns NULL pointer *
* *
* Arguments : 1) Poshorter to the data in which mapping is to be made *
* 2) Length of the data in which mapping is to be made *
* 3) Poshorter to the data points to be mapped *
* 4) Length of the data points to be mapped *
* *
* Returns : Pointer in which result is returned *
*******************************************************************************/
unsigned char * MapForward
(
unsigned char *pMapData,
unsigned short MapDataLength,
unsigned char *pMapPoints,
unsigned short MapPointsLength
)
{
unsigned short DataIndex;
unsigned short MapPointIndex;
for(DataIndex = 0; DataIndex < MapDataLength – MapPointsLength + 1; DataIndex++)
{
for(MapPointIndex = 0; MapPointIndex < MapPointsLength; MapPointIndex++)
{
if( pMapData[DataIndex + MapPointIndex] != pMapPoints[MapPointIndex])
{
goto PICK_NEXT_FMAPDATA;
}
}
return(& pMapData[DataIndex]);
PICK_NEXT_FMAPDATA:;
}
return(NULL);
}
int ReadComport(int cport_nr,unsigned char *buf,int size,useconds_t count) //size=6000
{
int n;
n=0;
usleep(count);
while(1)
{
n = RS232_PollComport(cport_nr, buf, size);
if(n > 0)
{
buf[n] = 0; /* always put a “null” at the end of a string! */
//for(i=0; i < n; i++)
//{
//if(buf[i] < 32) /* replace unreadable control-codes by dots */
//{
// buf[i] = ‘.’;
//}
//}
printf(“%sn”, (char *)buf);
break;
}
}
return n;
}
void Resetbufer(unsigned char *buf,int size)
{
int i;
for(i=0;i<size;i++)
{
buf[i] = ‘0’;
}
}
/*
char comports[38][16]={“/dev/ttyS0″,”/dev/ttyS1=2″,”/dev/ttyS2″,”/dev/ttyS3″,”/dev/ttyS4″,”/dev/ttyS5”,
“/dev/ttyS6″,”/dev/ttyS7″,”/dev/ttyS8″,”/dev/ttyS9″,”/dev/ttyS10″,”/dev/ttyS11”,
“/dev/ttyS12″,”/dev/ttyS13″,”/dev/ttyS14″,”/dev/ttyS15″,”/dev/ttyUSB0=16”,
“/dev/ttyUSB1=17″,”/dev/ttyUSB2=18″,”/dev/ttyUSB3=19″,”/dev/ttyUSB4=20″,”/dev/ttyUSB5=21”,
“/dev/ttyAMA0″,”/dev/ttyAMA1″,”/dev/ttyACM0″,”/dev/ttyACM1”,
“/dev/rfcomm0″,”/dev/rfcomm1″,”/dev/ircomm0″,”/dev/ircomm1”,
“/dev/cuau0″,”/dev/cuau1″,”/dev/cuau2″,”/dev/cuau3”,
“/dev/cuaU0″,”/dev/cuaU1″,”/dev/cuaU2″,”/dev/cuaU3”};
*/
int main()
{
int cport_nr=0, /* /dev/ttyUSB5 Look above to get the port code. () */
bdrate=9600; /* 9600 baud */
const unsigned char OKToken[]={“OK”};
unsigned char URL[]={“http://posttestserver.com/post.php”};
unsigned char FILENAME[]={“data.txt”}; // File to be sent
char mode[]={‘8′,’N’,’1′,0},
str[512];
unsigned char buf[6000];
int buf_SIZE=sizeof(buf);
int fsize;
char string[10000];
FILE *f = fopen((const char*)FILENAME, “rb”);
if (f != NULL)
{
fseek(f, 0, SEEK_END);
fsize = ftell(f);
fseek(f, 0, SEEK_SET);
//char *string = malloc(fsize + 1);
fread(string, fsize, 1, f);
fclose(f);
string[fsize] = 0;
printf(“%s”,string);
}
else
{
printf(“Doesnt exist”);
}
if(RS232_OpenComport(cport_nr, bdrate, mode))
{
printf(“Can not open comportn”);
return(0);
}
restart:
RS232_cputs(cport_nr, “AAAAAAAAAAAAATrn”);
//usleep(5000000); /* sleep for 100 milliSeconds */
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,500000);
if(MapForward(buf,buf_SIZE,(unsigned char*)OKToken,2) == NULL)
goto exit;
RS232_cputs(cport_nr, “AT+SAPBR=3,1,”ConType”,”GPRS”rn”);
//usleep(5000000); /* sleep for 100 milliSeconds */
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,500000);
if(MapForward(buf,buf_SIZE,(unsigned char*)OKToken,2) == NULL)
goto exit;
RS232_cputs(cport_nr, “AT+SAPBR=3,1,”APN”,”www”rn”);
//usleep(5000000); /* sleep for 100 milliSeconds */
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,500000);
if(MapForward(buf,buf_SIZE,(unsigned char*)OKToken,2) == NULL)
goto exit;
RS232_cputs(cport_nr, “AT+SAPBR=3,1,”USER”,””rn”);
//usleep(5000000); /* sleep for 100 milliSeconds */
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,500000);
if(MapForward(buf,buf_SIZE,(unsigned char*)OKToken,2) == NULL)
goto exit;
RS232_cputs(cport_nr, “AT+SAPBR=3,1,”PWD”,””rn”);
//usleep(5000000); /* sleep for 100 milliSeconds */
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,500000);
if(MapForward(buf,buf_SIZE,(unsigned char*)OKToken,2) == NULL)
goto exit;
RS232_cputs(cport_nr, “AT+SAPBR=1,1rn”);
usleep(5000000); /* sleep for 100 milliSeconds */
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,1000000);
if(MapForward(buf,buf_SIZE,(unsigned char*)”ERROR”,5) == NULL)
{
RS232_cputs(cport_nr, “AT+SAPBR=1,0rn”);
//usleep(5000000); /* sleep for 100 milliSeconds */
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,500000);
if(MapForward(buf,buf_SIZE,(unsigned char*)OKToken,2) == NULL)
goto exit;
goto restart;
}
RS232_cputs(cport_nr, “AT+SAPBR=2,1rn”);
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,500000);
if(MapForward(buf,buf_SIZE,(unsigned char*)OKToken,2) == NULL)
goto exit;
RS232_cputs(cport_nr, “AT+HTTPINITrn”);
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,500000);
if(MapForward(buf,buf_SIZE,(unsigned char*)”ERROR”,5) != NULL)
{
RS232_cputs(cport_nr, “AT+HTTPTERMrn”);
//usleep(5000000); /* sleep for 100 milliSeconds */
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,500000);
if(MapForward(buf,buf_SIZE,(unsigned char*)OKToken,2) == NULL)
goto exit;
goto restart;
}
RS232_cputs(cport_nr, “AT+HTTPPARA=”CID”,1rn”);
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,500000);
if(MapForward(buf,buf_SIZE,(unsigned char*)OKToken,2) == NULL)
goto exit;
RS232_cputs(cport_nr, “AT+HTTPPARA=”URL”,””);
RS232_cputs(cport_nr, (const char*)URL);
RS232_cputs(cport_nr, “”rn”);
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,500000);
if(MapForward(buf,buf_SIZE,(unsigned char*)OKToken,2) == NULL)
goto exit;
RS232_cputs(cport_nr, “AT+HTTPPARA=”CONTENT”,”multipart/form-data; boundary=—-WebKitFormBoundaryvZ0ZHShNAcBABWFy”rn”);
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,500000);
if(MapForward(buf,buf_SIZE,(unsigned char*)OKToken,2) == NULL)
goto exit;
RS232_cputs(cport_nr, “AT+HTTPDATA=”);
sprintf(str,”%d,10000rn”,fsize+182);
RS232_cputs(cport_nr, str);
Resetbufer(buf,sizeof(buf));
ReadComport(cport_nr,buf,6000,500000);
if(MapForward(buf,buf_SIZE,(unsigned char*)”DOWNLOAD”,8) == NULL)
goto exit;
//printf(“%s”,string);
RS232_cputs(cport_nr, “——WebKitFormBoundaryvZ0ZHShNAcBABWFyn”);
RS232_cputs(cport_nr, “Content-Disposition: form-data; name=”fileToUpload”; filename=””);
RS232_cputs(cport_nr, (const char*)FILENAME);
RS232_cputs(cport_nr, “”n”);
RS232_cputs(cport_nr, “Content-Type: text/plainnn”);
RS232_cputs(cport_nr, string);
RS232_cputs(cport_nr, “n——WebKitFormBoundaryvZ0ZHShNAcBABWFyn”);
//RS232_SendByte(cport_nr,0x1A);
//RS232_SendByte(cport_nr,0x1A);
//RS232_SendByte(cport_nr,0x1A);
Resetbufer(buf,sizeof(buf));
usleep(5000000);
ReadComport(cport_nr,buf,6000,12000000);
if(MapForward(buf,buf_SIZE,(unsigned char*)OKToken,2) == NULL)
goto exit;
RS232_cputs(cport_nr, “AT+HTTPACTION=1rn”);
Resetbufer(buf,sizeof(buf));
usleep(5000000);
usleep(5000000);
usleep(5000000);
usleep(5000000);
usleep(5000000);
usleep(5000000);
usleep(5000000);
usleep(5000000);
ReadComport(cport_nr,buf,6000,8000000);
if(MapForward(buf,buf_SIZE,(unsigned char*)”ACTION:”,7) == NULL)
goto exit;
RS232_cputs(cport_nr, “AT+HTTPREADrn”);
Resetbufer(buf,sizeof(buf));
usleep(5000000);
ReadComport(cport_nr,buf,6000,6000000);
if(MapForward(buf,buf_SIZE,(unsigned char*)”READ:”,5) == NULL)
goto exit;
goto SUCCESS;
//free(string);
SUCCESS: printf(“SUCCESS”);
return(0);
exit: printf(“FAILED”);
return(0);
}
{/code}
This is applicable to SIM900/SIM900A/SIM900D and SIM800 GSM module also.
Watch this video if you want to see the live demo,
Hope it helps someone.
Also see:
- SIM900 DTMF commands
- SIM900 & SIM908 GSM module – Autobaud rate [Solution]
- SIM900 SMS and Call Commands
- SIM900 / SIM800 USSD Code AT Commands – Working example