Connect to TCP server with cellular shield

Hi, Now I'm trying to get the cellular shield to connect to a TCP server in order to transmit the data to it.
But I can't get the TCP server connect. May I know is the code below have problem or the problem is from the TCP server?

#include <PString.h>
#include <SoftwareSerial.h> 

SoftwareSerial cell(2,3);

const int ERROR_GPS_UNAVAIL  = 0;
const int ERROR_GPS_STALE    = 1;
const int ERROR_SIM_UNAVAIL  = 2;
const int ERROR_GPRS_FAIL    = 3;
const int ERROR_NETWORK_FAIL = 4;
const int ERROR_HOST         = 5;
const int ERROR_GPRS_UNKNOWN = 6;
const int ERROR_GSM_FAIL     = 7;
const boolean DEBUG          = true;

#define BUFFSIZE 90
 
char at_buffer[BUFFSIZE];
char buffidx;
int firstTimeInLoop = 1;
int continueLoop = 0;

int GPRS_registered;
int GPRS_AT_ready;

static void error(const int errorCode) {
  int flashTimes = 0;
  int i = 0;
  boolean severity = true;

  switch(errorCode) {
    case ERROR_GPS_UNAVAIL:
      Serial.println("ERROR: GPS Unavailable");
      // This error is not severe enough to break the main loop
      severity = false;
      break;
    case ERROR_SIM_UNAVAIL:
      Serial.println("ERROR: SIM Unavailable");
      break;
    case ERROR_GPRS_FAIL:
      Serial.println("ERROR: Connection to network failed");
      break;
    case ERROR_NETWORK_FAIL:
      Serial.println("ERROR: Could not connect to network");
      break;
    case ERROR_HOST:
      Serial.println("ERROR: Could not connect to host");
      break;
    case ERROR_GPRS_UNKNOWN:
      Serial.println("ERROR: Unknown");
      break;
    case ERROR_GSM_FAIL:
      Serial.println("ERROR: GSM Timeout");
      break;  
  }
}
  
void setup()
{
  //Initialize serial ports for communication.
Serial.begin(9600);
cell.begin(9600);
Serial.println("Starting SM5100B Communication...");
}

void loop() {
  if (firstTimeInLoop) {
    firstTimeInLoop = false;
    Serial.println("Establishing Connection"); 
    establishNetwork();

  }

  bool newdata = false;
  unsigned long start = millis();

  // Send data to cell network
  sendData("12345");

  delay(1000);
}

/*
 * store the serial string in a buffer until we receive a newline
 */
void readATString(boolean watchTimeout = false) {
  char c;
  char buffidx = 0;
  int time = millis();

  while (1) {
    int newTime = millis();

    if (watchTimeout) {
      // Time out if we never receive a response    
      if (newTime - time > 30000) error(ERROR_GSM_FAIL);
    }

    if (cell.available() > 0) {
      c = cell.read();
      if (c == -1) {
        at_buffer[buffidx] = '\0';
        return;
      }

      if (c == '\n') {
        continue;
      }

      if ((buffidx == BUFFSIZE - 1) || c == '\r') {
        at_buffer[buffidx] = '\0';
        return;
      }

      at_buffer[buffidx++] = c;
    } 
  }
}

/**
 * Send an AT command to the cell interface
 */
static void sendATCommand(const char* ATCom) {
  cell.println(ATCom);
  Serial.print("COMMAND: ");
  Serial.println(ATCom);

  while (continueLoop) {
    readATString();
    ProcessATString();
    Serial.print("RESPONSE: ");
    Serial.println(at_buffer);
  }

  continueLoop = true;
  delay(500);
}

/*
 * Handle response codes
 */
static void ProcessATString() {

  if (DEBUG) {
    Serial.println(at_buffer);
  }

  if (strstr(at_buffer, "+SIND: 1" ) != 0) {
    firstTimeInLoop = true;
    GPRS_registered = false;
    GPRS_AT_ready = false;

    // GPS unit pulls enough current to keep the GSM shield from starting
    // So we wait until it's initialized and then power it via a digital pin
 //   digitalWrite(GPS_RELAY, HIGH);
  }

  if (strstr(at_buffer, "+SIND: 10,\"SM\",0,\"FD\",0,\"LD\",0,\"MC\",0,\"RC\",0,\"ME\",0") != 0 
    || strstr(at_buffer, "+SIND: 0") != 0) {
    error(ERROR_SIM_UNAVAIL);
  }

  if (strstr(at_buffer, "+SIND: 10,\"SM\",1,\"FD\",1,\"LD\",1,\"MC\",1,\"RC\",1,\"ME\",1") != 0) {
    Serial.println("SIM card Detected");
//    successLED();
  }

  if (strstr(at_buffer, "+SIND: 7") != 0) {
    error(ERROR_NETWORK_FAIL);  
  }

  if (strstr(at_buffer, "+SIND: 8") != 0) {
    GPRS_registered = false;
    error(ERROR_GPRS_FAIL);
  }

  if (strstr(at_buffer, "+SIND: 11") != 0) {
    GPRS_registered = true;
    Serial.println("GPRS Registered");
 //   successLED();
  }

  if (strstr(at_buffer, "+SIND: 4") != 0) {
     GPRS_AT_ready = true;
     Serial.println("GPRS AT Ready");
//     successLED();
  }

  if (strstr(at_buffer, "+SOCKSTATUS:  1,0") != 0) {
     error(ERROR_HOST);
  }

  if (strstr(at_buffer, "+CME ERROR: 29") != 0) {
    continueLoop = false;
    return;
  }

  if (strstr(at_buffer, "+CME ERROR") != 0) {
    error(ERROR_GPRS_UNKNOWN);
  }

  if (strstr(at_buffer, "OK") != 0 || strstr(at_buffer, "NO CARRIER") != 0) {
    continueLoop = false;
 //   successLED();
  }

  if (strstr(at_buffer, "+SOCKSTATUS:  1,1") != 0) {
    continueLoop = false;
  }
}

static void establishNetwork() {
  while (GPRS_registered == false || GPRS_AT_ready == false) {
    readATString(true);
    ProcessATString();
  }
}

static void sendData(const char* data) {
//  digitalWrite(LED_STATUS, HIGH);

  Serial.println("Setting up PDP Context");
  sendATCommand("AT+CGDCONT=1,\"IP\",\"wap.cingular\"");

  Serial.println("Configure APN");
  sendATCommand("AT+CGPCO=0,\"\",\"\", 1");

  Serial.println("Activate PDP Context");
  sendATCommand("AT+CGACT=1,1");

  // Change 0.0.0.0 to reflect the server you want to connect to
  Serial.println("Configuring TCP connection to server");
  sendATCommand("AT+SDATACONF=1,\"TCP\",\"127.0.0.1\",1234");

  Serial.println("Starting TCP Connection");
  sendATCommand("AT+SDATASTART=1,1");

  delay(1000);

  //Serial.println("Getting status");
  //sendATCommand("AT+SDATASTATUS=1");

  Serial.println("Sending data");
  sendATCommand(data);

  //Serial.println("Getting status");
  //sendATCommand("AT+SDATASTATUS=1");

  Serial.println("Close connection");
  sendATCommand("AT+SDATASTART=1,0");

  Serial.println("Disable PDP Context");
  sendATCommand("AT+CGACT=0,1");

}

Below is the result I obtain from serial monitor.
Starting SM5100B Communication...
Establishing Connection

+SIND: 1

+SIND: 10,"SM",1,"FD",1,"LD",1,"MC",1,"RC",1,"ME",1
SIM card Detected

+SIND: 3

+SIND: 11
GPRS Registered

+SIND: 4
GPRS AT Ready
Setting up PDP Context
COMMAND: AT+CGDCONT=1,"IP","wap.cingular"
Configure APN
COMMAND: AT+CGPCO=0,"","", 1

RESPONSE:
OK
RESPONSE: OK
Activate PDP Context
COMMAND: AT+CGACT=1,1

RESPONSE:
OK
RESPONSE: OK
Configuring TCP connection to server
COMMAND: AT+SDATACONF=1,"TCP","127.0.0.1",1234

RESPONSE:
OK
RESPONSE: OK
Starting TCP Connection
COMMAND: AT+SDATASTART=1,1

RESPONSE:
+CME ERROR: 28
ERROR: Unknown
RESPONSE: +CME ERROR: 28

RESPONSE:
OK
RESPONSE: OK
Sending data
COMMAND: 12345

RESPONSE:
+CME ERROR: 4
ERROR: Unknown
RESPONSE: +CME ERROR: 4

Thanks for the help.

It may not be the only problem, but the command

Configuring TCP connection to server
COMMAND: AT+SDATACONF=1,"TCP","127.0.0.1",1234

points to localhost, i.e. to the same module that is initiating the connection. The error is detected only when the modem actually tries to initiate the connection, in the command that follows. You should try with the address of an external (public) host.

spatula:
You should try with the address of an external (public) host.

So the address of the external host is my laptop own IP address or the IPv4 Default Gateway adddress?

hong89:

spatula:
You should try with the address of an external (public) host.

So the address of the external host is my laptop own IP address or the IPv4 Default Gateway adddress?

I'm afraid none of them. When you use GPRS the packets travel on the cellular network, not WiFi, not your home network. When you connect to your APN (the address of the provider of the GPRS service) you are on the public Internet. You should start with some well-known public address (e.g., google.com), just to see if the rest of your code works as expected.

Then if you need to "re-enter" your home network you'll have to configure your router to allow port forwarding towards your laptop (if that is your target server). It may also be convenient to use a dynamic dns service to address your home network using a name instead of its IP address.

spatula:
You should start with some well-known public address (e.g., google.com), just to see if the rest of your code works as expected.

I tried to change the IP to the IP of www.google.com.sg, but I still get the same result as before.

RESPONSE: OK
Configuring TCP connection to server
COMMAND: AT+SDATACONF=1,"TCP","172.194.38.151"

RESPONSE:
+CME ERROR: 4
ERROR: Unknown
RESPONSE: +CME ERROR: 4

RESPONSE:
+CME ERROR: 28
ERROR: Unknown
RESPONSE: +CME ERROR: 28

This mean my code is not working?

Gee, that is about the same response my web browser gives me when I try that ip.

Oops! Google Chrome could not connect to 172.194.38.151

Try this ip: 74.125.227.127

Oops! Google Chrome could not connect to 172.194.38.151

Try this ip: 74.125.227.127
[/quote]

It give me the same result as before.
=(

hong89:

Try this ip: 74.125.227.127

It give me the same result as before.
=(

Hi, be careful of the order and meaning of the errors (google for them). CME error 28 means that the provider is not authorizing the connection, but CME error 4 is a sort of syntax error, and in your case is most likely due to the absence of the port number in the command. So

AT+SDATACONF=1,"TCP","74.125.227.127"

should be

AT+SDATACONF=1,"TCP","74.125.227.127",80

I just found this example but I couldn't get the GSM connected.
I using the example "GsmCosmClient"

I only can see the serial monitor keep showing "not connected". I have no idea what if going on.
Please help.

(p/s: Now I try to use GSM connect to cosm.com and send the data to cosm.com)

Many thanks.

Same here!

It seems that the Arduino GSM through Bluevia has a lot of restrictions and it is not possible to do almost anything of the examples.

could anyone connect the Arduino GSM anywhere?

thanks

Marc

Hi guys,

I need to do something similar to what the OP wants: To send a string of data to a remote server (HTTP PUSH in my case) and I have a random question w.r.t this whole "design".

Does the GSM / GPRS provider need to allow HTTP through their network for it work work properly? I know that if they don't, it won't work, but are there certain GSM / cellular providers who don't allow HTTP PUSH through their networks?

If that is the case though, how else would one be able to send info from an Arduino to a remote server, if USB / Wifi / Bluetooth isn't an option at all? i.e. from an Arduino which is hundreds or even thousands of miles away from the server that needs to get the data?