You are reading a single comment by @net-tobi and its replies. Click here to read the full conversation.
  • Hello all, I started writing a driver for the SIM900A today based on the ESP8266 driver.

    1. init is working
    2. connect is working
    3. getIP is working
    4. reset is just calling init currently because I didn't find a way to reset the SIM900 by using an AT-command (for ESP8266 there is AT+RST)

    I got stuck at sending a HTTP-Request through NetworkJS. What happens is, that the send-method is called over and over and after a few retries it stops. I can not see any response from the server currently. I assume that there are subtle differences in the use of the AT+CIPSEND command for ESP8266 and SIM900A. Any ideas?

    Here you find the code:

    Serial1.setup(115200, { rx: B7, tx : B6 });
    
    
    var at;
    var socks = [];
    var sockData = ["","","","",""];
    var MAXSOCKETS = 5;
    
    var netCallbacks = {
      create : function(host, port) {
        /* Create a socket and return its index, host is a string, port is an integer.
        If host isn't defined, create a server socket */  
        if (host===undefined) {
          sckt = MAXSOCKETS;
          socks[sckt] = "Wait";
          sockData[sckt] = "";
          at.cmd("AT+CIPSERVER=1,"+port+"\r\n", 10000, function(d) {
            if (d=="OK") {
              socks[sckt] = true;
            } else {
              socks[sckt] = undefined;
              throw new Error("CIPSERVER failed");
            }
          });
          return MAXSOCKETS;
        } else {
          var sckt = 0;
          while (socks[sckt]!==undefined) sckt++; // find free socket
          if (sckt>=MAXSOCKETS) throw new Error("No free sockets");
          socks[sckt] = "Wait";
          sockData[sckt] = "";
          at.cmd('AT+CIPSTART='+sckt+',"TCP",'+JSON.stringify(host)+','+port+'\r\n',10000, function(d) {
            if (d=="OK") {
              at.registerLine(sckt + ', CONNECT OK', function() {
                at.unregisterLine(sckt + ', CONNECT OK');
                socks[sckt] = true;
              });
              at.registerLine(sckt + ', CLOSED', function() {
                at.unregisterLine(sckt + ', CLOSED');
                socks[sckt] = undefined;
              });
            } else {
              socks[sckt] = undefined;
              throw new Error("CIPSTART failed");
            }
          });
        }
        return sckt;
      },
      /* Close the socket. returns nothing */
      close : function(sckt) {    
        at.cmd('AT+CIPCLOSE='+sckt+"\r\n",1000, function(/*d*/) {
          socks[sckt] = undefined;
          //console.log("?"+JSON.stringify(d));
        });
      },
      /* Accept the connection on the server socket. Returns socket number or -1 if no connection */
      accept : function(sckt) {
        // console.log("Accept",sckt);
        for (var i=0;i<MAXSOCKETS;i++)
          if (sockData[i] && socks[i]===undefined) {
            //console.log("Socket accept "+i,JSON.stringify(sockData[i]),socks[i]);
            socks[i] = true;
            return i;
          }
        return -1;
      },
      /* Receive data. Returns a string (even if empty).
      If non-string returned, socket is then closed */
      recv : function(sckt, maxLen) {    
        if (at.isBusy() || socks[sckt]=="Wait") return "";
        if (sockData[sckt]) {
          var r;
          if (sockData[sckt].length > maxLen) {
            r = sockData[sckt].substr(0,maxLen);
            sockData[sckt] = sockData[sckt].substr(maxLen);
          } else {
            r = sockData[sckt];
            sockData[sckt] = "";
          }
          return r;
        }
        if (!socks[sckt]) return -1; // close it
        return "";
      },
      /* Send data. Returns the number of bytes sent - 0 is ok.
      Less than 0  */
      send : function(sckt, data) {
        console.log(data);
        if (at.isBusy() || socks[sckt]=="Wait") return 0;
        if (!socks[sckt]) return -1; // error - close it
        console.log("Send: " + data);
        var f = function(d) {
          // TODO: register for '>'
          //console.log("?"+JSON.stringify(d));
          if (d=="> ") {
            return f;
          }
        };
        at.cmd('AT+CIPSEND='+sckt+','+data.length+'\r\n' + data , 10000, f);
        return data.length;
      }
    };
    
    
    //Handle +IPD input data from SIM900A
    function ipdHandler(line) {
      var colon = line.indexOf(":");
      if (colon<0) return line; // not enough data here at the moment
      var parms = line.substring(5,colon).split(",");
      parms[1] = 0|parms[1];
      var len = line.length-(colon+1);
      if (len>=parms[1]) {
       // we have everything
       sockData[parms[0]] += line.substr(colon+1,parms[1]);
       return line.substr(colon+parms[1]+1); // return anything else
      } else { 
       // still some to get
       sockData[parms[0]] += line.substr(colon+1,len);
       return "+IPD,"+parms[0]+","+(parms[1]-len)+":"; // return IPD so we get called next time    
      }
    }
    
    var gprsFuncs = {
      ipdHandler:ipdHandler,
      "debug" : function() {
        return {
          socks:socks,
          sockData:sockData
        };
      },
      // initialise the SIM900A
      "init" : function(callback) { 
        var s = 0;
        var cb = function(r) {
          console.log(r);
          switch(s) {
            case 0:
              if(r === 'ATE0' || r === 'OK') return cb;
              else if(r) {
                callback('Error in ' + s + ': ' + r);
              } else {
                s = 1;
                at.cmd('AT+CPIN?\r\n', 100, cb);
              }
              break;
            case 1:
              if(r === '+CPIN: READY' || r === 'OK') return cb;
              else if(r) {
                callback('Error in ' + s + ': ' + r);
              } else {
                s = 2;
                at.cmd('AT+CGATT?\r\n', 100, cb);
              }
              break;
            case 2:
              if(r === '+CGATT: 1' || r === 'OK') return cb;
              else if(r) {
                callback('Error in ' + s + ': ' + r);
              } else {
                s = 3;
                at.cmd('AT+CIPSHUT\r\n', 100, cb);
              }
              break;
            case 3:
              if(r === 'SHUT OK') return cb;
              else if(r) {
                callback('Error in ' + s + ': ' + r);
              } else {
                s = 4;
                at.cmd('AT+CIPSTATUS\r\n', 100, cb);
              }
              break;
            case 4:
              if(r === 'STATE: IP INITIAL' || r === 'OK') return cb;
              else if(r) {
                callback('Error in ' + s + ': ' + r);
              } else {
                s = 5;
                at.cmd('AT+CIPMUX=1\r\n', 100, cb);
              }
              break;
            case 5:
              if(r === 'OK') return cb;
              else if(r) {
                callback('Error in ' + s + ': ' + r);
              } else {
                callback(null);
              }
              break;
          }
          return cb;
        };
        at.cmd("ATE0\r\n",1000,cb);
      },
      "reset" : function(callback) {
        gprsFuncs.init(callback);
      },
      "getVersion" : function(callback) {
        at.cmd("AT+GMR\r\n", 1000, function(d) {
          callback(null,d);
        });
      },
      "connect" : function(apn, username, password, callback) {
        var s = 0;
        var cb = function(r) {
          switch(s) {
            case 0:
              if(r === 'OK') return cb;
              else if(r) {
                callback('Error in ' + s + ': ' + r);
              } else {
                s = 1;
                at.cmd('AT+CIICR\r\n', 2000, cb);
              }
              break;
            case 1:
              if(r === 'OK') return cb;
              else if(r) {
                callback('Error in ' + s + ': ' + r);
              } else {
                callback(null);
              }
              break;
          }
        };
        at.cmd('AT+CSTT="' + apn + '", "' + username + '", "' + password + '"\r\n', 1000, cb);
      },
      "getIP" : function(callback) {
        var ip;
        var cb = function(r) {
          if(r && r != 'ERROR') {
            ip = r;
            return cb;
          } else if(r === 'ERROR') {
            callback('CIFSR Error');
          } else if(!r) {
            callback(null, ip);
          }
        };
        at.cmd('AT+CIFSR\r\n', 2000, cb);
      }
    };
    var connect = function(usart, connectedCallback) {
      gprsFuncs.at = at = require("AT").connect(usart);
      require("NetworkJS").create(netCallbacks);
      at.register("+IPD", ipdHandler);
      gprsFuncs.reset(connectedCallback);
      return gprsFuncs;
    };
    
    connect(Serial1, function() {
      gprsFuncs.connect('pinternet.interkom.de', '', '', function(err) {
        console.log(err);
        gprsFuncs.getIP(function(err, ip) {
          console.log('IP:' + ip);
          require("http").get("http://www.pur3.co.uk/hello.txt", function(res) {
            console.log("Response: ",res);
            res.on('data', function(d) {
              console.log("--->"+d);
            });
          });
        });
      });
    });
    
About

Avatar for net-tobi @net-tobi started