SIM 808 TCP connection (Arduino library) - c++

I AM WORKING WITH SIM808 for tcp connection, below is what my code looks like it is pretty much the basic tcp connection and i keep get fetch over and I can tell that is a problem with my content lenght but i feel if i have a better understanding that will be fine.
#include <DFRobot_sim808.h>
#include <SoftwareSerial.h>
//#define PIN_TX 10
//#define PIN_RX 11
//SoftwareSerial mySerial(PIN_TX,PIN_RX);
//DFRobot_SIM808 sim808(&mySerial);//Connect RX,TX,PWR,
DFRobot_SIM808 sim808(&Serial);
char http_cmd[] = "GET /media/uploads/mbed_official/hello.txt HTTP/1.0\r\n\r\n";
char buffer[512];
void setup(){
//mySerial.begin(9600);
Serial.begin(9600);
//******** Initialize sim808 module *************
while(!sim808.init()) {
delay(1000);
Serial.print("Sim808 init error\r\n");
}
delay(3000);
//*********** Attempt DHCP *******************
while(!sim808.join(F("cmnet"))) {
Serial.println("Sim808 join network error");
delay(2000);
}
//************ Successful DHCP ****************
Serial.print("IP Address is ");
Serial.println(sim808.getIPAddress());
//*********** Establish a TCP connection ************
if(!sim808.connect(TCP,"mbed.org", 80)) {
Serial.println("Connect error");
}else{
Serial.println("Connect mbed.org success");
}
//*********** Send a GET request *****************
Serial.println("waiting to fetch...");
sim808.send(http_cmd, sizeof(http_cmd)-1);
while (true) {
int ret = sim808.recv(buffer, sizeof(buffer)-1);
if (ret <= 0){
Serial.println("fetch over...");
break;
}
buffer[ret] = '\0';
Serial.print("Recv: ");
Serial.print(ret);
Serial.print(" bytes: ");
Serial.println(buffer);
break;
}
//************* Close TCP or UDP connections **********
sim808.close();
//*** Disconnect wireless connection, Close Moving Scene *******
sim808.disconnect();
}
void loop(){
}
but i dont seem to understand what goes on at a point of the code, what does the part below, mean in the code
while (true) {
int ret = sim808.recv(buffer, sizeof(buffer)-1);
if (ret <= 0){
Serial.println("fetch over...");
break;
}
buffer[ret] = '\0';
Serial.print("Recv: ");
Serial.print(ret);
Serial.print(" bytes: ");
Serial.println(buffer);
break;
}
with emphasis on int ret = sim808.recv(buffer, sizeof(buffer)-1); how is the value of ret gotten?

If you just open up the .h file in the library you will find that it is pretty well documented. Have a look at the declaration for the function you are asking about:
/** read data from socket
* #param socket socket
* #param buf buffer that will store the data read from socket
* #param len string length need to read from socket
* #returns bytes that actually read
*/
int recv(char* buf, int len);
It details exactly what each parameter is and what the return value is. Looks like it returns the number of bytes read.

Related

Guru Meditation Error Core 0 panic'ed (LoadProhibited). Exception was unhandled

error project
Guru Meditation Error in project
Core 0 panic'ed (LoadProhibited). Exception was unhandled.
I have project using pulsesensor with ESP32, Data from ESP32 is saved in database.
I tried many times but could not
help me
#include <ssl_client.h>
#include <WiFiClientSecure.h>
#include <WiFi.h>
#include <SPI.h>
#include <WiFiClient.h>
#include <HTTPClient.h>
#define USE_SERIAL Serial
/* Konfigurasi pada SSID dan Password Wifi */
const char* ssid = "berdikari";
const char* password = "alfian24";
/* Konfigurasi koneksi ke server */
char server[] = "192.168.43.108"; // Ganti dengan IP Address komputer aplikasi
int port = 81;
/*konfigurasi*/
int PulseSensorPurplePin = 34; // Pulse Sensor PURPLE WIRE connected to ANALOG PIN 0
int LED21 = 21; // The on-board Arduion LED
int Signal; // holds the incoming raw data. Signal value can range from 0-102
float pulse=0;
WiFiClient client;
void setup() {
USE_SERIAL.begin(115200); // Baudrate/kec. komunikasi pengiriman data ke serial terminal
delay(10);
Serial.println('\n');
WiFi.begin(ssid, password);
USE_SERIAL.print("Terhubung ke ");
USE_SERIAL.print(ssid);
// WiFi.config(local_IP, gateway, subnet, dns);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
USE_SERIAL.print('.');
}
USE_SERIAL.print('\n');
USE_SERIAL.println("Identitas ESP-32");
USE_SERIAL.print("IP Address:\t");
USE_SERIAL.println(WiFi.localIP()); // IP Address ESP-32
USE_SERIAL.print('\n');
USE_SERIAL.println("Identitas Web Server");
USE_SERIAL.println("IP Address:");
USE_SERIAL.print(server);
USE_SERIAL.print("\tport:\t");
USE_SERIAL.print(port);
}
void loop() {
Signal = analogRead(PulseSensorPurplePin); // Read the PulseSensor’s value.
// Send the Signal value to Serial Plotter.
delay(1000);
pulse = Signal;
USE_SERIAL.println(pulse);
if(WiFi.status() == WL_CONNECTED){
//URL target untuk menyimpan data sensor Pulse ke database
String url = "http://192.168.43.108:81/";
url += "sistem_monitoring/Monitoring/simpan/";
url += String(pulse);
HTTPClient http;
USE_SERIAL.print("[HTTP] begin...\n");
http.begin(url);
USE_SERIAL.print("[HTTP] GET...\n");
int httpCode = http.GET();
if(httpCode > 0) {
USE_SERIAL.printf("[HTTP] GET... code: %d\n",
httpCode);
if(httpCode == HTTP_CODE_OK) {
String payload = http.getString();
USE_SERIAL.println(payload);
}
} else {
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n",
http.errorToString(httpCode).c_str());
}
http.end();
}
}
please help me.
What should I do??
I've seen this question asked a few times but never got a good answer.

Why is my if clause are not working? How can fix variable types?

I want to change parameters with udp sentences. I'm getting udp's but my if clause is not working. How can compere 2 variables?
I have changed variable types and/or if clause type (ex if ( strcmp ( UdpMsg , "relay01_off" ) == 0) ).
Setup IF clause variable
String UdpMsg = "12345";...
Getting UDP Message
String UdpMsg ((char *)buffer);...
IF clause
if ( UdpMsg == "relay01_off" ) {
digitalWrite(relay_pin, HIGH);
Serial.print ("You!\n");
}
I expected to see "you!" when i send UDP but it's not finding equals.
Full Code for info:
#include <WiFi.h>
#include <WiFiUdp.h>
#include <cstring> //For the string functions
const char* wifi_name = "SSID"; // Your Wifi network name here
const char* wifi_pass = "password"; // Your Wifi network password here
WiFiServer server(80); // Server will be at port 80
// IP address to send UDP data to.
const char * udpAddress = "192.168.1.6";
int udpPort = 4444;
//create UDP instance
WiFiUDP udp;
// relay PINi
int relay_pin = 15;
// UDP Mesajı gelen
String UdpMsg = "12345";
void setup()
{
Serial.begin (115200);
pinMode (relay_pin, OUTPUT);
Serial.print ("Connecting to ");
Serial.print (wifi_name);
WiFi.begin (wifi_name, wifi_pass); // Connecting to the wifi network
while (WiFi.status() != WL_CONNECTED) // Waiting for the response of wifi network
{
delay (500);
Serial.print (".");
}
Serial.println("");
Serial.println("Connection Successful");
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); // Getting the IP address
Serial.println("Type the above IP address into browser search bar");
server.begin(); // Starting the server
digitalWrite(relay_pin, LOW); // switch i AC
//This initializes udp and transfer buffer
udp.begin(udpPort);
}
void loop()
{
uint8_t buffer[50] = "";
//processing incoming packet, must be called before reading the buffer
udp.parsePacket();
//receive response from server, it will be HELLO WORLD
if(udp.read(buffer, 50) > 0){
Serial.print("Recevied UDP: ");
Serial.println((char *)buffer);
String UdpMsg ((char *)buffer);
}
//////// UDP IF leri ///////////
if ( UdpMsg == "relay01_off" ) { // Equal strings
digitalWrite(relay_pin, HIGH);
Serial.print ("You!\n");
}
}
It seems that you construct a second UdpMsg variable in:
if(udp.read(buffer, 50) > 0){
Serial.print("Recevied UDP: ");
Serial.println((char *)buffer);
String UdpMsg ((char *)buffer); // <--- 2nd UdpMsg, released after 'if' clause
}
While UdpMsg at this line:
if ( UdpMsg == "relay01_off" )
refers to the first one, the global, that keeps its initial value "12345".

ESP32 to ESP32 WiFi Server/Client Problem

I've got one ESP32 acting as client and another ESP32 acting as an access-point for direct communication and outdoor use.
I have set up a server on the AP end and would like the client to communicate with it but I can't seem to make this work.
I would like to know two things:
How do I send or write data to the server from the client?
How do I read and display the data that was sent to the server from the client?
I have attached the code below:
Code for AP/Server
//SERVER
//Load Wi-Fi library
#include <WiFi.h>
// Replace with your network credentials
const char* ssid = "ESP32-Access-Point";
const char* password = "SyedAhmedAli";
//Set web server port number to 80
WiFiServer server(80);
void setup() {
Serial.begin(115200);
Serial.println("Setting AP (Access Point)…");
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address ");
Serial.println(IP);
Serial.print("MAC address ");
Serial.println(WiFi.softAPmacAddress());
server.begin();
}
void loop(){
WiFiClient client = server.available(); //Listen for incoming clients
if (client)
{ //If a new client connects,
Serial.println("New Client."); //print a message out in the serial port
while (client.connected())
{
Serial.println("Client connected.");
Serial.println(client.available());
if (client.available() > 0)
{
// read the bytes incoming from the client:
char thisChar = client.read();
// echo the bytes back to the client:
server.write(thisChar);
// echo the bytes to the server as well:
Serial.write(thisChar);
}
}
client.stop();
Serial.println("Client disconnected.");
Serial.println();
}
}
Code for Client
//Client
#include <WiFi.h>
const char* ssid = "ESP32-Access-Point";
const char* password = "SyedAhmedAli";
WiFiClient client;
IPAddress server(192, 168, 4, 1);
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println(" connected");
if(client.connect(server, 80))
{
Serial.println("connected to server");
client.write("Data");
}
else
{
Serial.println("failed to connect to server");
}
}
void loop()
{
}
Alternatively to the previous answer, you could use espnow as a protocol between various esp32. Here an example.
You must implement some sort of protocol like TCP, UDP to exchange data.
Example Project using TCP
https://www.instructables.com/id/WiFi-Communication-Between-Two-ESP8266-Based-MCU-T/
Example Project using UDP
https://circuits4you.com/2018/01/01/esp-to-esp-communication/
Look at this very handy function:
void SetWifi(const char *name, const char *password) { // Turn on wifi with server
Serial.println("Starting server");
WiFi.disconnect();
WiFi.softAP(name, password);
delay(2000);
IPAddress IP = WiFi.softAPIP();
Serial.print("Server IP : ");
Serial.println(IP);
server.begin();
server.setNoDelay(true);
Serial.println("Server started");
}
You can write data with this function :
void sendDataTCP(String message) { // function to send message back to client
if (client && client.connected()) { //check if client is there
client.println(message);
}
client.flush();
}
Receive data with this function:
void availableMessage() {
if (client.available()) {//check if client is there
while (client.available()) {
String message = client.readStringUntil('\n'); //read string until enter (end of message)
Serial.println("Received: " + message);
message.toCharArray(buffer, BUFFER); // put message in char array (buffer)
client.flush(); // discard all bytes that have been read
}
}
}
Check if someone has connected:
void connectClient() {
if (server.hasClient()) // if server has a client
{
if (client = server.available()) { // if client is connected
Serial.println("Connected");
}
}
}
I think this will get you in the direction of accomplishing your goal, good luck!

C++ how do i show ledstatus as on or off in the Client?

The code is Arduino C++ how do I show ledstatus as "on" or "off" in the HTTP Client?
The Led/status in the if statement does not like Ledstatus = off; or Ledstatus = on; why? but works if I substitute with numbers what am I doing wrong?
please help?
/*
Web Server
A simple web server that shows the value of the analog input pins.
using an Arduino Wiznet Ethernet shield.
Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13
* Analog inputs attached to pins A0 through A5 (optional)
created 18 Dec 2009
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
*/
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(10,0, 0, 210);
char linebuffer[20];
int linenumber = 0;
boolean IsLed = false;
// (Spa Variables):
int LedOn;
int Ledstatus;
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// Set Digital Pin 12 to output:
pinMode(12,OUTPUT);
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
digitalWrite (12,LOW);
}
void loop() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank){
// send a standard http response header
parseRequest();
//sendHTTPResponse(client);
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("OK ");
client.print(IsLed);
client.print(Ledstatus);
char linebuffer[20]; //Clear the line buffer
linenumber = 0;
break;
}
if (c == '\n'){
// you're starting a new line
currentLineIsBlank = true;
}else if (c != '\r') {
if(linenumber <20){ //If there is room in the buffer
linebuffer[linenumber] = c; //Add char to the buffer
linenumber++; //Increment the counter
}
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(10);
// close the connection:
client.stop();
Serial.println("client disconnected");
}
}
void parseRequest(){
if(linebuffer[5] == 'O' && linebuffer[6] == 'N'){ //if the request was for ON
//Turn on the LED
IsLed = true;
digitalWrite (12,LOW);
Serial.println("isLed ON");
Ledstatus= on;
}else{(linebuffer[5] == 'O' && linebuffer [6] == 'F' && linebuffer [7] == 'F'); //if the request was for OFF
//Turn OFF the LED
IsLed = false;
digitalWrite(12,HIGH);
Serial.println("isLed OFF");
Serial.println();
Ledstatus = off;
}
}
​
I think I finally got you, because your code is somehow confusing! As you wrote in the comment you get a OK10 or OKOO because you are printing this in your code:
...
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.println("OK "); //Prints OK of course
client.print(IsLed); //Prints an int!!
client.print(Ledstatus); //Also prints an int!!
...
You Need to Change it to something like this:
...
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close"); // the connection will be closed after completion of the response
client.println("Refresh: 5"); // refresh the page automatically every 5 sec
client.println();
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.print("OK "); //Prints OK of course
if(Ledstatus == on)
client.println("ON");
else
client.println("OFF");
...
Also what I mentioned in the comments, you don't read line buffer from the Client but you are parsing it. It will be empty! I don't know about the API but there must be a function similar to
client.read(linubuffer, 20);

libpcap and wireless signal capture

I am trying to write a c++ app (linux) that would capture a wireless packet along with the associated Signal strength (in dBm). The capturing part is easy but the problem is I can't find any documentation on how to get the signal strength for each packet.
Is it part of the header?
Here's what I have so far:
printf("Device: %s\n", dev);
printf("Number of packets: %d\n", num_packets);
printf("Filter expression: %s\n", filter_exp);
/* open capture device */
pcap_t *handler = pcap_create("wlan0", errbuf);
if (handler == NULL)
{
exit(-1);
}
if(pcap_set_rfmon(handler,1)==0 )
{
printf("monitor mode enabled\n");
}
pcap_set_snaplen(handler, 2048); // Set the snapshot length to 2048
pcap_set_promisc(handler, 0); // Turn promiscuous mode off
pcap_set_timeout(handler, 512); // Set the timeout to 512 milliseconds
int status = pcap_activate(handler);
/* now we can set our callback function */
pcap_loop(handle, num_packets, got_packet, NULL);
Here is the got_packet code:
/* define ethernet header */
ethernet = (struct sniff_ethernet*)(packet);
/* define/compute ip header offset */
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
size_ip = IP_HL(ip)*4;
if (size_ip < 20) {
printf(" * Invalid IP header length: %u bytes\n", size_ip);
return;
}
/* print source and destination IP addresses */
printf(" From: %s\n", inet_ntoa(ip->ip_src));
printf(" To: %s\n", inet_ntoa(ip->ip_dst));
/* determine protocol */
switch(ip->ip_p) {
case IPPROTO_TCP:
printf(" Protocol: TCP\n");
break;
case IPPROTO_UDP:
printf(" Protocol: UDP\n");
return;
case IPPROTO_ICMP:
printf(" Protocol: ICMP\n");
return;
case IPPROTO_IP:
printf(" Protocol: IP\n");
return;
default:
printf(" Protocol: unknown\n");
return;
}
/* define/compute tcp header offset */
tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
size_tcp = TH_OFF(tcp)*4;
if (size_tcp < 20) {
printf(" * Invalid TCP header length: %u bytes\n", size_tcp);
return;
}
printf(" Src port: %d\n", ntohs(tcp->th_sport));
printf(" Dst port: %d\n", ntohs(tcp->th_dport));
/* define/compute tcp payload (segment) offset */
payload = (char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);
/* compute tcp payload (segment) size */
size_payload = ntohs(ip->ip_len) - (size_ip + size_tcp);
/*
* Print payload data; it might be binary, so don't just
* treat it as a string.
*/
if (size_payload > 0) {
printf(" Payload (%d bytes):\n", size_payload);
//print_payload(payload, size_payload);
}
Any help would be much appreciate it.
UPDATE:
/***************/
Here's an update:
So based on my research and as Guy Scott mentioned I was looking for a wrong info. I need to look at wireless packets and was instead loading ethernet packet. So here's the updated code:
pcap_set_snaplen(handle, 2048); // Set the snapshot length to 2048
pcap_set_promisc(handle, 1); // Turn promiscuous mode off
pcap_set_timeout(handle, 512); // Set the timeout to 512 milliseconds
int status = pcap_activate(handle);
if(pcap_set_datalink(handle, DLT_IEEE802_11_RADIO) == -1) {
printf("Couldn't set datalink type %s: %s\n", device, pcap_geterr(handle));
}
So the problem now is parsing the packet which seems to be a pretty hard issue. I am interested in the source address, destination address and the associated signal etc. I don't know how to match and load the data from the packet and match it to the radiotap struct.
struct ieee80211_radiotap_header {
u_int8_t it_version; /* set to 0 */
u_int8_t it_pad;
u_int16_t it_len; /* entire length */
u_int32_t it_present; /* fields present */
} __attribute__((__packed__));
/* Presence bits */
#define RADIOTAP_TSFT 0
#define RADIOTAP_FLAGS 1
#define RADIOTAP_RATE 2
#define RADIOTAP_CHANNEL 3
#define RADIOTAP_FHSS 4
#define RADIOTAP_ANTENNA_SIGNAL 5
#define RADIOTAP_ANTENNA_NOISE 6
#define RADIOTAP_LOCK_QUALITY 7
#define RADIOTAP_TX_ATTENUATION 8
#define RADIOTAP_DB_TX_ATTENUATION 9
#define RADIOTAP_DBM_TX_POWER 10
#define RADIOTAP_ANTENNA 11
#define RADIOTAP_DB_ANTENNA_SIGNAL 12
void process_packet (u_char * args, const struct pcap_pkthdr *header, const u_char * packet)
{
struct ieee80211_radiotap_header *packet_header = (struct ieee80211_radiotap_header *) header;
// This is where I am stuck
Can someone tell me once I've captured the packet, how do I pull out the above values from it?
Thanks
Every program that calls pcap_open_live(), pcap_create()/pcap_activate(), or pcap_open_offline() should, if the calls succeed, call pcap_datalink() to find out what the link-layer header type of the capture is.
There are no exceptions to this rule.
Then see the link-layer header types page for tcpdump.org to see what the values returned by pcap_datalink() mean. Compare them against the DLT_ values listed there. The ones you're likely to get are DLT_IEEE802_11, which has no signal-strength information, and DLT_PRISM_HEADER, DLT_IEEE802_11_RADIO, and DLT_IEEE802_11_RADIO_AVS, which do have signal strength information. See the links for the latter three possibilities for information on how the signal strength information (and other radio metadata) is represented in the packet data.
(And, yes, that's three options for radio metadata, so the link given in another answer is to an incomplete source; most of the time you will probably get radiotap headers, not AVS or Prism headers. Radiotap is more general, as it's designed to be extensible, but it's more complicated to parse.)
I was stumbling upon the same problem, thought I should share my solution.
The signal strength is not in the header of PCAP callback, but within the packet. For DLT_IEEE802_11_RADIO the signal and noise could be:
void process_packet (u_char * args,
const struct pcap_pkthdr *header,
const u_char * packet){
int8_t signal_dbm = packet[22];
int8_t noise_dbm = packet[23];
....
}
But I found 22 and 23 by looking into WireShark.
The nicer solution would be of course using the radiotap (GitHub).
Here is an example:
void process_packet (u_char * args,
const struct pcap_pkthdr *header,
const u_char * packet) {
struct ieee80211_radiotap_iterator iterator;
int ret = ieee80211_radiotap_iterator_init(&iterator, packet, header->len, NULL);
while (!ret) {
ret = ieee80211_radiotap_iterator_next(&iterator);
if (ret) break;
switch (iterator.this_arg_index) {
case IEEE80211_RADIOTAP_TSFT:
printf("timestamp: %lu\n", (uint64_t)*iterator.this_arg);
break;
case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
printf("sig: %d\n", (int8_t)*iterator.this_arg);
break;
case IEEE80211_RADIOTAP_DBM_ANTNOISE:
printf("noise: %d\n", (int8_t)*iterator.this_arg);
break;
default:
break;
}
}
}