boolean Adafruit_FONA::enableGPS(boolean onoff) {
  uint16_t state;

  // first check if its already on or off

  if (_type == FONA808_V2) {
    if (! sendParseReply(F("AT+CGNSPWR?"), F("+CGNSPWR: "), &state) )
      return false;
  } else {
    if (! sendParseReply(F("AT+CGPSPWR?"), F("+CGPSPWR: "), &state))
      return false;
  }

  if (onoff && !state) {
    if (_type == FONA808_V2) {
      if (! sendCheckReply(F("AT+CGNSPWR=1"), F("OK")))  // try GNS command
	return false;
    } else {
      if (! sendCheckReply(F("AT+CGPSPWR=1"), F("OK")))
	return false;
    }
  } else if (!onoff && state) {
    if (_type == FONA808_V2) {
      if (! sendCheckReply(F("AT+CGNSPWR=0"), F("OK"))) // try GNS command
	return false;
    } else {
      if (! sendCheckReply(F("AT+CGPSPWR=0"), F("OK")))
	return false;
    }
  }
  return true;
}
bool Adafruit_FONA::HTTP_initialize(char *url) {
  // Handle any pending
  HTTP_terminate();

  // Initialize and set parameters
  if (! sendCheckReply(F("AT+HTTPINIT"), F("OK")))
    return false;
  if (! sendCheckReply(F("AT+HTTPPARA=\"CID\",1"), F("OK")))
    return false;
  if (! sendCheckReplyQuoted(F("AT+HTTPPARA=\"UA\","), useragent, F("OK"), 10000))
    return false;

  flushInput();
  mySerial->print(F("AT+HTTPPARA=\"URL\",\""));
  mySerial->print(url);
  mySerial->println("\"");
  readline(FONA_DEFAULT_TIMEOUT_MS);
  if (strcmp(replybuffer, "OK") != 0)
    return false;

  // HTTPS redirect
  if (httpsredirect) {
    if (! sendCheckReply(F("AT+HTTPPARA=\"REDIR\",1"), F("OK")))
      return false;

    if (! sendCheckReply(F("AT+HTTPSSL=1"), F("OK")))
      return false;
  }

  return true;
}
bool Adafruit_FONA::enableNTPTimeSync(bool onoff, const char *ntpserver) {
    if (onoff) {
        if (! sendCheckReply(F("AT+CNTPCID=1"), F("OK")))
            return false;

    mySerial->print(F("AT+CNTP=\""));
    
    if (ntpserver != 0) {
        mySerial->print(ntpserver);
    } else {
        mySerial->print(F("pool.ntp.org"));
    }
    
    mySerial->println(F("\",0"));
    readline(FONA_DEFAULT_TIMEOUT_MS);
    
    if (strcmp(replybuffer, "OK") != 0)
        return false;

    if (! sendCheckReply(F("AT+CNTP"), F("OK"), 10000))
        return false;

    uint16_t status;
    readline(10000);
    
    if (! parseReply(F("+CNTP:"), &status))
        return false;
    } else {
        if (! sendCheckReply(F("AT+CNTPCID=0"), F("OK")))
            return false;
    }

    return true;
}
boolean Adafruit_FONA::begin(uint16_t baudrate) {
  pinMode(_rstpin, OUTPUT);
  digitalWrite(_rstpin, HIGH);
  delay(10);
  digitalWrite(_rstpin, LOW);
  delay(100);
  digitalWrite(_rstpin, HIGH);

  // give 3 seconds to reboot
  delay(3000);

  mySerial->begin(baudrate);
  delay(500);
  while (mySerial->available()) mySerial->read();

  sendCheckReply(F("AT"), F("OK"));
  delay(100);
  sendCheckReply(F("AT"), F("OK"));
  delay(100);
  sendCheckReply(F("AT"), F("OK"));
  delay(100);

  // turn off Echo!
  sendCheckReply(F("ATE0"), F("OK"));
  delay(100);
  
  if (! sendCheckReply(F("ATE0"), F("OK"))) {
    return false;
  }

  return true;
}
// Reading SMS's is a bit involved so we don't use helpers that may cause delays or debug
// printouts!
bool Adafruit_FONA::readSMS(uint8_t i, char *smsbuff, uint16_t maxlen, uint16_t *readlen) {
    // text mode
    if (! sendCheckReply(F("AT+CMGF=1"), F("OK"))) return false;
    
    // show all text mode parameters
    if (! sendCheckReply(F("AT+CSDH=1"), F("OK"))) return false;
    
    // parse out the SMS len
    uint16_t thesmslen = 0;
    
    //getReply(F("AT+CMGR="), i, 1000);  //  do not print debug!
    mySerial->print(F("AT+CMGR="));
    mySerial->println(i);
    readline(1000); // timeout
    
    // parse it out...
    parseReply(F("+CMGR:"), &thesmslen, ',', 11);
    
    readRaw(thesmslen);
    
    flushInput();
    
    uint16_t thelen = min(maxlen, strlen(replybuffer));
    strncpy(smsbuff, replybuffer, thelen);
    smsbuff[thelen] = 0; // end the string
    
    #ifdef ADAFRUIT_FONA_DEBUG
    Serial.println(replybuffer);
    #endif
    *readlen = thelen;
    return true;
}
boolean Adafruit_FONA::TCPconnect(char *server, uint16_t port) {
  flushInput();

  // close all old connections
  if (! sendCheckReply(F("AT+CIPSHUT"), F("SHUT OK"), 5000) ) return false;

  // single connection at a time
  if (! sendCheckReply(F("AT+CIPMUX=0"), F("OK")) ) return false;

  // manually read data
  if (! sendCheckReply(F("AT+CIPRXGET=1"), F("OK")) ) return false;

#ifdef ADAFRUIT_FONA_DEBUG
  Serial.print(F("AT+CIPSTART=\"TCP\",\""));
  Serial.print(server);
  Serial.print(F("\",\""));
  Serial.print(port);
  Serial.println(F("\""));
#endif

  mySerial->print(F("AT+CIPSTART=\"TCP\",\""));
  mySerial->print(server);
  mySerial->print(F("\",\""));
  mySerial->print(port);
  mySerial->println(F("\""));

  if (! expectReply(F("OK"))) return false;
  if (! expectReply(F("CONNECT OK"))) return false;
}
bool Adafruit_FONA::sendSMS(char *smsaddr, char *smsmsg) {
    if (! sendCheckReply("AT+CMGF=1", "OK")) return -1;
    
    char sendcmd[30] = "AT+CMGS=\"";
    strncpy(sendcmd+9, smsaddr, 30-9-2);  // 9 bytes beginning, 2 bytes for close quote + null
    sendcmd[strlen(sendcmd)] = '\"';
    
    if (! sendCheckReply(sendcmd, "> ")) return false;
    
    #ifdef ADAFRUIT_FONA_DEBUG
    Serial.print("> "); Serial.println(smsmsg);
    #endif
    mySerial->println(smsmsg);
    mySerial->println();
    mySerial->write(0x1A);
    #ifdef ADAFRUIT_FONA_DEBUG
    Serial.println("^Z");
    #endif
    
    readline(10000); // read the +CMGS reply, wait up to 10 seconds!!!
    //Serial.print("* "); Serial.println(replybuffer);
    if (strstr(replybuffer, "+CMGS") == 0) {
        return false;
    }
    
    readline(1000); // read OK
    //Serial.print("* "); Serial.println(replybuffer);
    
    if (strcmp(replybuffer, "OK") != 0) {
        return false;
    }
    
    return true;
}
boolean Adafruit_FONA_3G::enableGPRS(boolean onoff) {

  if (onoff) {
    // disconnect all sockets
    //sendCheckReply(F("AT+CIPSHUT"), F("SHUT OK"), 5000);

    if (! sendCheckReply(F("AT+CGATT=1"), F("OK"), 10000))
      return false;


    // set bearer profile access point name
    if (apn) {
      // Send command AT+CGSOCKCONT=1,"IP","<apn value>" where <apn value> is the configured APN name.
      if (! sendCheckReplyQuoted(F("AT+CGSOCKCONT=1,\"IP\","), apn, F("OK"), 10000))
        return false;

      // set username/password
      if (apnusername) {
	char authstring[100] = "AT+CGAUTH=1,1,\"";
	char *strp = authstring + strlen(authstring);
	strcpy_P(strp, (prog_char *)apnusername);
	strp+=strlen_P((prog_char *)apnusername);
	strp[0] = '\"';
	strp++;
	strp[0] = 0;

	if (apnpassword) {
	  strp[0] = ','; strp++;
	  strp[0] = '\"'; strp++;
	  strcpy_P(strp, (prog_char *)apnpassword);
	  strp+=strlen_P((prog_char *)apnpassword);
	  strp[0] = '\"';
	  strp++;
	  strp[0] = 0;
	}

	if (! sendCheckReply(authstring, "OK", 10000))
	  return false;
      }
    }

    // connect in transparent
    if (! sendCheckReply(F("AT+CIPMODE=1"), F("OK"), 10000))
      return false;
    // open network (?)
    if (! sendCheckReply(F("AT+NETOPEN=,,1"), F("Network opened"), 10000))
      return false;

    readline(); // eat 'OK'
  } else {
    // close GPRS context
    if (! sendCheckReply(F("AT+NETCLOSE"), F("Network closed"), 10000))
      return false;

    readline(); // eat 'OK'
  }

  return true;
}
boolean Adafruit_FONA::callerIdNotification(boolean enable, uint8_t interrupt) {
  if(enable){
    attachInterrupt(interrupt, onIncomingCall, FALLING);
    return sendCheckReply(F("AT+CLIP=1"), F("OK"));
  }

  detachInterrupt(interrupt);
  return sendCheckReply(F("AT+CLIP=0"), F("OK"));
}
bool Adafruit_FONA::FMradio(bool onoff, uint8_t a) {
    if (! onoff) {
        return sendCheckReply(F("AT+FMCLOSE"), F("OK"));
    }
    
    // 0 is headset, 1 is external audio
    if (a > 1) return false;
    
    return sendCheckReply(F("AT+FMOPEN="), a, F("OK"));
}
bool Adafruit_FONA::deleteSMS(uint8_t i) {
    if (! sendCheckReply("AT+CMGF=1", "OK")) return -1;
    // read an sms
    char sendbuff[12] = "AT+CMGD=000";
    sendbuff[8] = (i / 100) + '0';
    i %= 100;
    sendbuff[9] = (i / 10) + '0';
    i %= 10;
    sendbuff[10] = i + '0';

    return sendCheckReply(sendbuff, "OK", 2000);
}
int FONA808::connect(const char* apn, const char* user, const char* password, mbed::util::FunctionPointer0<void> connectionCallback){
bool in = init();
if(!in)
  {
    return -1;
  }
 if( !m_ipInit )
  {
    m_ipInit = true;
    m_ppp.init();
  }
  m_ppp.setup(user, password, DEFAULT_MSISDN_GSM);
  
  DEBUG_PRINT("Birra\n");
  
/*
  if (m_onePort)
  {
     m_smsInit = false; //SMS status reset
     m_ussdInit = false; //USSD status reset
     m_linkMonitorInit = false; //Link monitor status reset
  }*/

  if(apn != NULL)
  {
    char cmd[48];
    int tries = 30;
    sendCheckReply("ATH","OK",500);
    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 = m_at.executeSimple(cmd, &result);
      DBG("Result of command: Err code=%d", ret);
      if(ret)
      {
        Thread::wait(500);
      }
    } while(ret && --tries);*/
    if(!sendCheckReply(cmd,"OK",500)){
	 //printf("ATResult: AT return=%d (code %d)", result.result, result.code);
         DEBUG_PRINT("APN set to %s", apn);
    }
   
  }

  //Connect
  DEBUG_PRINT("Connecting PPP");

  int ret = m_ppp.connect(connectionCallback); //TODO impostare callback per connessione
  //printf("Result of connect: Err code=%d", ret);
  return ret;
}
bool Adafruit_FONA::enableNetworkTimeSync(bool onoff) {
    if (onoff) {
        if (! sendCheckReply(F("AT+CLTS=1"), F("OK")))
            return false;
    } else {
        if (! sendCheckReply(F("AT+CLTS=0"), F("OK")))
        return false;
    }
    
    flushInput(); // eat any 'Unsolicted Result Code'
    
    return true;
}
// Retrieve the sender of the specified SMS message and copy it as a string to
// the sender buffer.  Up to senderlen characters of the sender will be copied
// and a null terminator will be added if less than senderlen charactesr are
// copied to the result.  Returns true if a result was successfully retrieved,
// otherwise false.
bool Adafruit_FONA::getSMSSender(uint8_t i, char *sender, int senderlen) {
    // Ensure text mode and all text mode parameters are sent.
    if (! sendCheckReply(F("AT+CMGF=1"), F("OK"))) return false;
    if (! sendCheckReply(F("AT+CSDH=1"), F("OK"))) return false;
    // Send command to retrieve SMS message and parse a line of response.
    mySerial->print(F("AT+CMGR="));
    mySerial->println(i);
    readline(1000);
    // Parse the second field in the response.
    bool result = parseReplyQuoted(F("+CMGR:"), sender, senderlen, ',', 1);
    // Drop any remaining data from the response.
    flushInput();
    return result;
}
void FONA808::readGPSInfoSecond(){
	DEBUG_PRINT("ReadGPS Second\n");
	mSerial.cleanBuffer();
	float lat=0, latitude;
	float lon=0, longitude;
	float elevation=0;
	if(checkGPSFix()){
		mSerial.cleanBuffer();
		sendParseReplyGPS(&lat, &lon, &elevation, this->timestamp, 500);
		float degrees = floor(lat / 100);
	    	double minutes = lat - (100 * degrees);
	    	minutes /= 60;
	    	degrees += minutes;
	    	latitude = degrees;
	    	
	    	degrees = floor(lon / 100);
	    	minutes = lon - (100 * degrees);
	    	minutes /= 60;
	    	degrees += minutes;
		longitude = degrees;
		DEBUG_PRINT("\nRAW Latitude: %d, Longitude=%d\n",(int)lat, (int)lon);
		minar::Scheduler::postCallback(gpsReadCallback.bind(latitude, longitude, elevation));
	}else{
		minar::Scheduler::postCallback(gpsNoFixCallback.bind());
	}
	
	if(m_ppp.isPPPLinkOpen()){
		sendCheckReply("ATO","CONNECT",500);
		mSerial.cleanBuffer();
		mSerial.setPppPause(false);
 	}

}
bool Adafruit_FONA::HTTP_POST_start(char *url,
              const char *contenttype,
              const uint8_t *postdata, uint16_t postdatalen,
              uint16_t *status, uint16_t *datalen){
  if (! HTTP_initialize(url))
    return false;

  if (! sendCheckReplyQuoted(F("AT+HTTPPARA=\"CONTENT\","), contenttype, F("OK"), 10000))
    return false;

  // HTTP POST data
  flushInput();
  mySerial->print(F("AT+HTTPDATA="));
  mySerial->print(postdatalen);
  mySerial->println(",10000");
  readline(FONA_DEFAULT_TIMEOUT_MS);
  if (strcmp(replybuffer, "DOWNLOAD") != 0)
    return false;

  mySerial->write(postdata, postdatalen);
  readline(10000);
  if (strcmp(replybuffer, "OK") != 0)
    return false;

  // HTTP POST
  if (! sendCheckReply(F("AT+HTTPACTION=1"), F("OK")))
    return false;

  if (! HTTP_response(status, datalen))
    return false;

  return true;
}
bool Adafruit_FONA::setAutoAnswer(int ringCount){
    char szCmd[12];
    
    sprintf(szCmd, "ATS0=%d", ringCount);
    
    return sendCheckReply(F(szCmd), F("OK"));
}
bool Adafruit_FONA::tuneFMradio(uint16_t station) {
  // Fail if FM station is outside allowed range.
  if ((station < 870) || (station > 1090))
    return false;

  return sendCheckReply(F("AT+FMFREQ="), station, F("OK"));
}
boolean Adafruit_FONA::TCPconnected(void) {
  if (! sendCheckReply(F("AT+CIPSTATUS"), F("OK"), 100) ) return false;
  readline(100);
#ifdef ADAFRUIT_FONA_DEBUG
  Serial.print (F("\t<--- ")); Serial.println(replybuffer);
#endif
  return (strcmp(replybuffer, "STATE: CONNECT OK") == 0);
}
boolean Adafruit_FONA::playDTMF(char dtmf) {
  char str[4];
  str[0] = '\"';
  str[1] = dtmf;
  str[2] = '\"';
  str[3] = 0;
  return sendCheckReply(F("AT+CLDTMF=3,"), str, F("OK"));
}
bool Adafruit_FONA::setFMVolume(uint8_t i) {
    // Fail if volume is outside allowed range (0-6).
    if (i > 6) {
        return false;
    }
    // Send FM volume command and verify response.
    return sendCheckReply(F("AT+FMVOLUME="), i, F("OK"));
}
bool FONA808::init(){
  mSerial.baud(115200);
  DEBUG_PRINT("Ciao FONA808!\n");
  m_rst = 1;         //perform FONA reboot
  wait_ms(200);
  m_rst=0;
  wait_ms(200);
  m_rst = 1;
  
  wait_ms(2000);   // wait for reboot
  
  DEBUG_PRINT("Cleaning buffer\n");
  mSerial.cleanBuffer();
  DEBUG_PRINT("Buffer clean\n");
  mSerial.printf("+++");
  
  wait_ms(1000);
  for(int tries=0; tries < 3; tries++){
	  sendCheckReply("AT", "OK",500);
	  wait_ms(100);
	  sendCheckReply("AT", "OK",500);
	  wait_ms(100);
	  sendCheckReply("AT", "OK",500);
	  wait_ms(100);

	  // turn off Echo!
	  sendCheckReply("ATE0", "OK",5000);
	  wait_ms(100);

	  if (! sendCheckReply("ATE0", "OK",5000)) {
	    continue;
	  }

	  if(getNetworkStatus()!=1){
		DEBUG_PRINT("Not registered to network yet\n");
		wait_ms(500);
		continue;
	 }
	 return true;
 }
  DEBUG_PRINT("Max num tries!\n");

  return false;
  
}
boolean Adafruit_FONA_3G::enableGPS(boolean onoff) {
  uint16_t state;

  // first check if its already on or off
  if (! Adafruit_FONA::sendParseReply(F("AT+CGPS?"), F("+CGPS: "), &state) )
    return false;

  if (onoff && !state) {
    if (! sendCheckReply(F("AT+CGPS=1"), F("OK")))
      return false;
  } else if (!onoff && state) {
    if (! sendCheckReply(F("AT+CGPS=0"), F("OK")))
      return false;
    // this takes a little time
    readline(2000); // eat '+CGPS: 0'
  }
  return true;
}
boolean Adafruit_FONA::enableGPSNMEA(uint8_t i) {

  char sendbuff[15] = "AT+CGPSOUT=000";
  sendbuff[11] = (i / 100) + '0';
  i %= 100;
  sendbuff[12] = (i / 10) + '0';
  i %= 10;
  sendbuff[13] = i + '0';

  if (_type == FONA808_V2) {
    if (i)
      return sendCheckReply(F("AT+CGNSTST=1"), F("OK"));
    else
      return sendCheckReply(F("AT+CGNSTST=0"), F("OK"));
  } else {
    return sendCheckReply(sendbuff, "OK", 2000);
  }
}
boolean Adafruit_FONA::enableGPRS(boolean onoff) {

  if (onoff) {
    if (! sendCheckReply(F("AT+CGATT=1"), F("OK"), 10000))
      return false;

    // set bearer profile! connection type GPRS
    if (! sendCheckReply(F("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""),
			   F("OK"), 10000))
      return false;

    // set bearer profile access point name
    if (apn) {
      // Send command AT+SAPBR=3,1,"APN","<apn value>" where <apn value> is the configured APN value.
      if (! sendCheckReplyQuoted(F("AT+SAPBR=3,1,\"APN\","), apn, F("OK"), 10000))
        return false;

      // set username/password
      if (apnusername) {
        // Send command AT+SAPBR=3,1,"USER","<user>" where <user> is the configured APN username.
        if (! sendCheckReplyQuoted(F("AT+SAPBR=3,1,\"USER\","), apnusername, F("OK"), 10000))
          return false;
      }
      if (apnpassword) {
        // Send command AT+SAPBR=3,1,"PWD","<password>" where <password> is the configured APN password.
        if (! sendCheckReplyQuoted(F("AT+SAPBR=3,1,\"PWD\","), apnpassword, F("OK"), 10000))
          return false;
      }
    }

    // open GPRS context
    if (! sendCheckReply(F("AT+SAPBR=1,1"), F("OK"), 10000))
      return false;
  } else {
    // close GPRS context
    if (! sendCheckReply(F("AT+SAPBR=0,1"), F("OK"), 10000))
      return false;

    if (! sendCheckReply(F("AT+CGATT=0"), F("OK"), 10000))
      return false;

  }
  return true;
}
int8_t Adafruit_FONA::getNumSMS(void) {
    uint16_t numsms;

    if (! sendCheckReply(F("AT+CMGF=1"), F("OK"))) return -1;
    // ask how many sms are stored

    if (! sendParseReply(F("AT+CPMS?"), F("+CPMS: \"SM_P\","), &numsms) ) return -1;

    return numsms;
}
/********* CALL PHONES **************************************************/
bool Adafruit_FONA::callPhone(char *number) {
    char sendbuff[35] = "ATD";
    strncpy(sendbuff+3, number, min(30, strlen(number)));
    uint8_t x = strlen(sendbuff);
    sendbuff[x] = ';';
    sendbuff[x+1] = 0;
    //Serial.println(sendbuff);
    
    return sendCheckReply(sendbuff, "OK");
}
uint8_t Adafruit_FONA::unlockSIM(char *pin)
{
    char sendbuff[14] = "AT+CPIN=";
    sendbuff[8] = pin[0];
    sendbuff[9] = pin[1];
    sendbuff[10] = pin[2];
    sendbuff[11] = pin[3];
    sendbuff[12] = NULL;
    
    return sendCheckReply(sendbuff, "OK");
}
boolean Adafruit_FONA::enableGPRS(boolean onoff) {

  if (onoff) {
    if (! sendCheckReply(F("AT+CGATT=1"), F("OK"), 10000))
      return false;

    // set bearer profile! connection type GPRS
    if (! sendCheckReply(F("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""),
			   F("OK"), 10000))
      return false;
    // set bearer profile access point name
    if (! sendCheckReply(F("AT+SAPBR=3,1,\"APN\",\"FONAnet\""),
			   F("OK"), 10000))
      return false;
    
    // open GPRS context
    if (! sendCheckReply(F("AT+SAPBR=1,1"), F("OK"), 10000))
      return false;
  } else {
    // close GPRS context
    if (! sendCheckReply(F("AT+SAPBR=0,1"), F("OK"), 10000))
      return false;

    if (! sendCheckReply(F("AT+CGATT=0"), F("OK"), 10000))
      return false;

  }
  return true;
}
Example #30
0
boolean FonaSMS::sendSMS(char *smsaddr, char *smsmsg) {
  if (! sendCheckReply(F("AT+CMGF=1"), F("OK"))) return -1;

  char sendcmd[30] = "AT+CMGS=\"";
  strncpy(sendcmd+9, smsaddr, 30-9-2);  // 9 bytes beginning, 2 bytes for close quote + null
  sendcmd[strlen(sendcmd)] = '\"';

  if (! sendCheckReply(sendcmd, "> ")) return false;
#ifdef ADAFRUIT_FONA_DEBUG
  Serial.print(F("> ")); Serial.println(smsmsg);
#endif
  mySerial->println(smsmsg);
  mySerial->println();
  mySerial->write(0x1A);
#ifdef ADAFRUIT_FONA_DEBUG
  Serial.println("^Z");
#endif
  if ( (_type == FONA3G_A) || (_type == FONA3G_E) ) {
    // Eat two sets of CRLF
    readline(200);
    //Serial.print("Line 1: "); Serial.println(strlen(replybuffer));
    readline(200);
    //Serial.print("Line 2: "); Serial.println(strlen(replybuffer));
  }
  readline(10000); // read the +CMGS reply, wait up to 10 seconds!!!
  //Serial.print("Line 3: "); Serial.println(strlen(replybuffer));
  if (strstr(replybuffer, "+CMGS") == 0) {
    return false;
  }
  readline(1000); // read OK
  //Serial.print("* "); Serial.println(replybuffer);

  if (strcmp(replybuffer, "OK") != 0) {
    return false;
  }

  return true;
}