Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't read data from socket because MKRNB creates multiple UDP sockets. #109

Open
sebastienlabine opened this issue Apr 3, 2023 · 3 comments
Labels
type: imperfection Perceived defect in any part of project

Comments

@sebastienlabine
Copy link

It took us some time to figure out, but sockets doesn't always gracefully close, making it impossible to read data from a socket.

Our software creates a UDP Socket on setup and listen to the data it receives. However, when the device is not shutdown for a proper amount of time (5s), the socket is never closed, making it impossible to read the data that the socket receive because it creates a new socket and the library only listens to the second socket.

This might be a SARA-R4 specific issue, but we realized that we needed to clear every socket on boot to make sure a SINGLE UDP socket is connected and being listened to.

@per1234 per1234 added the type: imperfection Perceived defect in any part of project label Apr 3, 2023
@r5hjk
Copy link

r5hjk commented Oct 21, 2023

I can confirm this issue.
Without (hard) resetting the Modem it is not possible to send and receive UDP packets. Please fix this Issue.

Here is a workaround example:

#include <MKRNB.h>
#include "secrets.h"

// Network
const char PINNUMBER[] = SECRET_PINNUMBER;  // see secrets.h
const char apn[]       = "iot.1nce.net";
NBModem modem;
bool debugModem = true;
NB nbAccess(debugModem);
boolean connected = false; // connection state
NBScanner scanner;
const int UDP_PACKET_SIZE = 512;

int getRssi() {
  int rssi = atoi( scanner.getSignalStrength().c_str() );
  if ((rssi >= 0) && (rssi <= 31)) {
    rssi = -113 + (rssi * 2);
  } else {
    rssi = 1;
  }
  return rssi;
}


void connectNetwork(){
  Serial.println("Check Network connection");

  if(connected) {
    Serial.println("Shutdown Network");
    nbAccess.secureShutdown();  
    delay(1000);
    Serial.println("Modem hard reset");
    MODEM.hardReset();  
    delay(2000);
    connected = false;
  }

  while (! connected ) {
    Serial.println("Not connected, connecting...");
    if ((nbAccess.begin(PINNUMBER, apn) == NB_READY) ) {
      connected = true;
      Serial.println("Connected to NB-IoT / LTE-M network");
    } else {
      Serial.println("Retry");
      delay(1000);
    }
  }
  
  // Don't try to send until we have a good RSSI
  int rssi;
  while ((rssi = getRssi()) == 1) {
    Serial.println("RSSI to bad (CSQ=99). Wait.");
    delay(1000);
  }
  Serial.print("RSSI OK: ");
  Serial.println(rssi);
  
  Serial.println("Established stable connection to network ");
}

String sendReceive(String payload) {

  // Sending
  NBUDP localUdp;
  localUdp.begin(15000);       // local port
  IPAddress ip(x,x,x,x);       // target host
  localUdp.beginPacket(ip, y); // target port 
  localUdp.write(payload.c_str(), payload.length());
  int ret = localUdp.endPacket();
  if(ret == 0) {
    Serial.println("Error sending UDP packet");
  }else {
    Serial.println("UDP packet sent");
  }

  // Receiving
  char packetBuffer[UDP_PACKET_SIZE];  
  memset(packetBuffer, 0, UDP_PACKET_SIZE);
  int retries = 10;
  int i = 0;
  Serial.print("Receive:");
  while (i < retries) {
    int packetSize = localUdp.parsePacket();
    if (packetSize > 0) {
      Serial.print("Receive ");
      Serial.print(packetSize);
      Serial.println(" Bytes");
      localUdp.read(packetBuffer, packetSize);
      break;
    }

    i++;
    delay(1000);
    Serial.print(".");
  }
  Serial.println("");
  String response = String(packetBuffer);
  return response;
}

void setup() {
    Serial.begin(9600);
    delay(500);   
}

void loop() {
  delay(3000);

  connectNetwork();

  String response = sendReceive("lala");  
  Serial.print("Received UDP Packet: ");
  Serial.print(response);
  Serial.println("");
}

@sebastienlabine
Copy link
Author

@r5hjk Thanks for your workaround, I'll try it because for us it's unbearable. How long do is usally take when you are waiting for the RSSI to be OK?

@r5hjk
Copy link

r5hjk commented Oct 21, 2023

@sebastienlabine You are welcome. On my location the RSSI check take ~4sec to a rssi of ~73dbm (the RAT is configures to priority LTE-M and use NB-IoT as alternative, don't use GPRS).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: imperfection Perceived defect in any part of project
Projects
None yet
Development

No branches or pull requests

3 participants