You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Calls to udp.available() appear to return -1 x number of bytes available.
My program sends a Network Time Protocol request over UDP and receives a 48 byte response.
Here's the serial output:
Attempting to connect to the modem
Attempting to connect to the GPRS Access Point Name
Packet sent
Awaiting response
udp.parsePacket 0
udp.parsePacket 0
udp.parsePacket 48
udp.available -48 <---expected 48 here
Code (excluding secrets.h) is below. The relevant serial output comes from void loop():
#define LEAP_INDICATOR_NO_WARNING 0
#define LEAP_INDICATOR_61_SECONDS 1
#define LEAP_INDICATOR_59_SECONDS 2
#define LEAP_INDICATOR_UNKNOWN 3
#define LEAP_INDICATOR_Pos 6
#define VERSION_NUMBER_Pos 3
#define MODE_CLIENT 3
#define MODE_Pos 0
#define STRATUM_UNSPECIFIED_OR_INVALID 0
#define NTP_DOMAIN "pool.ntp.org"
const unsigned int NTP_PORT = 123u;
const unsigned int LOCAL_PORT = 2390u;
#include "arduino_secrets.h"
#include <MKRGSM.h>
/*Create the objects needed for internet requests*/
GSM gsm; //class to connect to the modem
GSMClient gsmClient;
GPRS gprs; //class to connect to the internet
GSMUDP udp;
struct NTPPacket {
unsigned int leapIndicator;
unsigned int versionNumber;
unsigned int mode;
unsigned int stratum;
int poll;
int precision;
unsigned long rootDelay;
unsigned long rootDispersion;
unsigned long referenceID;
unsigned long long referenceTimestamp;
unsigned long long originTimestamp;
unsigned long long receiveTimestamp;
unsigned long long transmitTimestamp;
//ignoring the remaining fields for now. The example implementation doesn't use them.
};
void printLongLong(long long value) {
Serial.print((long)(value >> 32), HEX);
Serial.println((unsigned long)(value), HEX);
}
void bigEndian(long long input, int sizeOfOutput, unsigned char output[]) {
for (int i = 0; i < sizeOfOutput; i++) {
int rightShift = (sizeOfOutput - 1 - i) * 8;
char nextByte = (char) (input >> rightShift);
output[i] = nextByte;
}
}
long long bigEndianToLongLong(unsigned char data[], int sizeOfData) {
long long output = 0;
for(int i = 0; i < sizeOfData; i++) {
output = output << 8;
output += data[i];
}
return output;
}
void sendNTPRequest(unsigned long long referenceTimestamp, unsigned long long originTimestamp) {
struct NTPPacket packet;
packet.leapIndicator = LEAP_INDICATOR_UNKNOWN;
packet.versionNumber = 4;
packet.mode = MODE_CLIENT;
packet.stratum = STRATUM_UNSPECIFIED_OR_INVALID;
packet.poll = 0; //presumably this is set by the server?
packet.precision = 0; // ditto
packet.rootDelay = 0;
packet.rootDispersion = 0;
packet.referenceID = 0;
packet.referenceTimestamp = referenceTimestamp;
packet.originTimestamp = originTimestamp;
packet.receiveTimestamp = 0;
packet.transmitTimestamp = 0;
while(!udp.beginPacket(NTP_DOMAIN, NTP_PORT));
udp.write(packet.leapIndicator << LEAP_INDICATOR_Pos
| packet.versionNumber << VERSION_NUMBER_Pos
| packet.mode << MODE_Pos);
udp.write(packet.stratum);
udp.write(packet.poll);
udp.write(packet.precision);
byte byteArray[8]; //byte array to be used for multi-byte fields in big endian format
bigEndian((long long)packet.rootDelay, 4, byteArray);
udp.write(byteArray, 4);
bigEndian((long long)packet.rootDispersion, 4, byteArray);
udp.write(byteArray, 4);
bigEndian((long long)packet.referenceID, 4, byteArray);
udp.write(byteArray, 4);
bigEndian(packet.referenceTimestamp, 8, byteArray);
udp.write(byteArray, 8);
bigEndian(packet.originTimestamp, 8, byteArray);
udp.write(byteArray, 8);
bigEndian(packet.receiveTimestamp, 8, byteArray);
udp.write(byteArray, 8);
bigEndian(packet.transmitTimestamp, 8, byteArray);
udp.write(byteArray, 8);
while(!udp.endPacket());
Serial.println("Packet sent");
}
void receiveNTPPacket() {
struct NTPPacket packet;
byte byteArray[8]; //byte array to be used for multi-byte fields in big endian format
Serial.print((int)udp.available());
Serial.println(" bytes available");
Serial.print("First byte: ");
Serial.println((int)udp.peek(), DEC);
packet.leapIndicator = (udp.peek() >> LEAP_INDICATOR_Pos) & 0b11;
packet.versionNumber = (udp.peek() >> VERSION_NUMBER_Pos) & 0b111;
packet.mode = (udp.read() >> MODE_Pos) & 0b111;
packet.stratum = udp.read();
packet.poll = udp.read();
packet.precision = udp.read();
udp.read(byteArray, 4);
packet.rootDelay = bigEndianToLongLong(byteArray, 4);
udp.read(byteArray, 4);
packet.rootDispersion = bigEndianToLongLong(byteArray, 4);
udp.read(byteArray, 4);
packet.referenceID = bigEndianToLongLong(byteArray, 4);
udp.read(byteArray, 8);
packet.referenceTimestamp = bigEndianToLongLong(byteArray, 8);
udp.read(byteArray, 8);
packet.originTimestamp = bigEndianToLongLong(byteArray, 8);
udp.read(byteArray, 8);
packet.receiveTimestamp = bigEndianToLongLong(byteArray, 8);
udp.read(byteArray, 8);
packet.transmitTimestamp = bigEndianToLongLong(byteArray, 8);
Serial.print("Leap indicator ");
Serial.println(packet.leapIndicator);
Serial.print("Version number ");
Serial.println(packet.versionNumber);
Serial.print("Mode ");
Serial.println(packet.mode);
Serial.print("Stratum ");
Serial.println(packet.stratum);
Serial.print("Poll ");
Serial.println(packet.poll);
Serial.print("Precision ");
Serial.println(packet.precision);
Serial.print("Root delay ");
Serial.println(packet.rootDelay);
Serial.print("Root Dispersion ");
Serial.println(packet.rootDispersion);
Serial.print("Reference ID ");
Serial.println(packet.referenceID);
Serial.print("Reference Timestamp 0x");
printLongLong(packet.referenceTimestamp);
Serial.print("Origin Timestamp 0x");
printLongLong(packet.referenceTimestamp);
Serial.print("Receive Timestamp 0x");
printLongLong(packet.receiveTimestamp);
Serial.print("Transmit Timestamp 0x");
printLongLong(packet.transmitTimestamp);
}
void setup() {
// put your setup code here, to run once:
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
Serial.begin(9600);
while(!Serial);
Serial.println("Attempting to connect to the modem");
while(gsm.begin() != GSM_READY) {
Serial.print('.');
delay(100);
}
Serial.println();
Serial.println("Attempting to connect to the GPRS Access Point Name");
while(gprs.attachGPRS(SECRET_GPRS_APN, SECRET_GPRS_LOGIN, SECRET_GPRS_PASSWORD) != GPRS_READY) {
Serial.print('.');
delay(100);
}
Serial.println();
while(!udp.begin(LOCAL_PORT));
sendNTPRequest(0,0);
Serial.println("Awaiting response");
int parsePacket;
do {
parsePacket = udp.parsePacket();
Serial.print("udp.parsePacket ");
Serial.println(parsePacket);
delay(100);
} while (parsePacket < 1);
// Serial.println("Response received");
// receiveNTPPacket();
// udp.stop();
}
void loop() {
Serial.print("udp.available ");
Serial.println(udp.available());
Serial.print("udp.peek ");
Serial.println(udp.peek());
Serial.print("udp.available ");
Serial.println(udp.available());
Serial.print("udp.read ");
Serial.println(udp.read());
delay(2000);
}
The text was updated successfully, but these errors were encountered:
Calls to
udp.available()
appear to return -1 x number of bytes available.My program sends a Network Time Protocol request over UDP and receives a 48 byte response.
Here's the serial output:
Code (excluding
secrets.h
) is below. The relevant serial output comes fromvoid loop()
:The text was updated successfully, but these errors were encountered: