Closed mareksoldan closed 1 year ago
Hi, What kind of board are you using ? Can you share your code?
Hi, thanks for quick reply. I am just trying Mega 2560.
Here is code:
`
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
float tep; float vlh;
DHT sensorDHT(pinDHT, typeDHT); EthernetUDP udp; SNMP::Agent snmp;
const char SYSNAME_OID = "1.3.6.1.2.1.1.5.0"; const char SYSNAME_VALUE = "Nucleo F767ZI";
// Use some SNMP classes using SNMP::OctetStringBER; using SNMP::VarBind; using SNMP::VarBindList;
void echo(String text1, String text2 = ""){ if(text2 == ""){ Serial.println(text1); } else{ Serial.print(text1); Serial.print(" | "); Serial.println(text2); } } String ipAddrToString(IPAddress address){ return String(address[0]) + "." + String(address[1]) + "." + String(address[2]) + "." + String(address[3]); }
void onMessage(const SNMP::Message message, const IPAddress remote, const uint16_t port) { // Get the variable binding list from the message. exit(0); VarBindList varbindlist = message->getVarBindList(); for (unsigned int index = 0; index < varbindlist->count(); ++index) { // Each variable binding is a sequence of 2 objects: // - First one is and ObjectIdentifierBER. It holds the OID // - Second is the value of any type VarBind varbind = (varbindlist)[index]; // There is a convenient function to get the OID as a const char const char name = varbind->getName(); if (strcmp(SYSNAME_OID, name) == 0) { // System name is requested. Need to send a response. // Create an SNMP message for response SNMP::Message response = new SNMP::Message(SNMP::VERSION2C, "public", SNMP::TYPE_GETRESPONSE); // The response must have the same request-id as the request response->setRequestID(message->getRequestID()); // SYSNAME // Create an OctetStringBER to hold the variable binding value OctetStringBER value = new OctetStringBER(SYSNAME_VALUE, strlen(SYSNAME_VALUE)); // Add the variable binding to the message response->add(SYSNAME_OID, value); // Send the response to remote IP and port snmp.send(response, remote, port); // Avoid memory leak delete response; } } }
void setup() { // put your setup code here, to run once: Serial.begin (9600); echo("Starting...");
pinMode(LED_BUILTIN, OUTPUT);
sensorDHT.begin(); echo("Sensor started...");
echo("Connecting to LAN..."); if(!Ethernet.begin(mac)){ echo("DHCP request failed!"); } else{ echo("IP address:", ipAddrToString(Ethernet.localIP())); }
snmp.begin(&udp); snmp.onMessage(onMessage); echo("SNMP ready..."); }
void loop() { // put your main code here, to run repeatedly: // tep = sensorDHT.readTemperature(); // vlh = sensorDHT.readHumidity();
// echo((String)digitalRead(LED_BUILTIN)); // if(digitalRead(LED_BUILTIN)==1) // digitalWrite(LED_BUILTIN, LOW); // else // digitalWrite(LED_BUILTIN, HIGH);
// String msg1 = "Teplota: " + String(tep) + " °C"; // String msg2 = "Vlhkost: " + String(vlh) + " %"; // echo(msg1, msg2);
snmp.loop(); }
`
Why exit(0)
at the beginning of onMessage()
handler?
Sorry, its my mistake. You wrote me back so quickly and I sended some debug version. So if I try to use your example (only change ip/mac address) and if snmp packet is received, program stuck, not restarting...
`
EthernetUDP udp; SNMP::Agent snmp; const char SYSNAME_OID = "1.3.6.1.2.1.1.5.0"; const char SYSNAME_VALUE = "Nucleo F767ZI";
using SNMP::OctetStringBER; using SNMP::VarBind; using SNMP::VarBindList;
// Event handler to process SNMP messages void onMessage(const SNMP::Message message, const IPAddress remote, const uint16_t port) { // Get the variable binding list from the message. VarBindList varbindlist = message->getVarBindList(); for (unsigned int index = 0; index < varbindlist->count(); ++index) { // Each variable binding is a sequence of 2 objects: // - First one is and ObjectIdentifierBER. It holds the OID // - Second is the value of any type VarBind varbind = (varbindlist)[index]; // There is a convenient function to get the OID as a const char const char name = varbind->getName(); if (strcmp(SYSNAME_OID, name) == 0) { // System name is requested. We have to send a response. // Create an SNMP message for response SNMP::Message response = new SNMP::Message(SNMP::VERSION2C, "public", SNMP::TYPE_GETRESPONSE); // The response must have the same request-id as the request response->setRequestID(message->getRequestID()); // SYSNAME // Create an OctetStringBER to hold the variable binding value OctetStringBER value = new OctetStringBER(SYSNAME_VALUE); // Add the variable binding to the message response->add(SYSNAME_OID, value); // Send the response to remote IP and port snmp.send(response, remote, port); // Avoid memory leak delete response; } } }
void setup() { Serial.begin(9600); // Ethernet byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; Ethernet.begin(mac); // SNMP snmp.begin(&udp); snmp.onMessage(onMessage); Serial.println("just started..."); }
void loop() { // Agent loop function must be called to process incoming messages snmp.loop(); } `
OK. What are you using as Ethernet shield and library?
Ethernet shield is W5100, libs only SNMP v1.1.0 a Ethernet v2.0.2
Hello @mareksoldan ,
I just pushed some changes to support Arduino Mega.
The reason why it failed is that Integers were hardcoded to int
so 32 bits on STM32 as willed, but only 16 bits on AVR. Very bad idea.
The example works on my setup (Mega 2560 and W5100). Can you make some test?
BTW I think that this library is not usable with the UNO board as it lacks RAM.
Regards,
Patrick
Hey, Patrick, thank you so much for your efforts and your very quick response. I just tried it and it looks much better. After Mega receives the SNMP request it actually calls the onMessage() function, responds and waits for the next request.
However, the problem I encountered is that the incoming requestID does not match the one sent in the response.
Otherwise, though, it works just fine.
Regards Marek
Hi @mareksoldan , I encountered the same problem. It should be fixed now hopefully with the last commits. I will let you test and if everything is OK, I will publish a new release in a few days. Regards, Patrick
Hi @patricklaf , I tried it and still the same problem (different IDs in request and response). I think the problem is in the _responseID type. Probably too small. Regards, Marek
@mareksoldan , that's strange, it works for me, both for Arduino Mega and one of my STM32 boards.
Commit #2c0559d should have solved the issue caused by the difference of sign between char
and uint8_t
.
@patricklaf , yes, thas's strange. I captured the communication using Wireshark and I see a mismatch in the requestId. There are three different numbers, in the request packet, in the arduino and then in the captured response packet. More detailed information in the attachment.
Hello @mareksoldan , Thank you for the detailed report. It seems from your monitoring that the requestID is well decoded but not correctly encoded. I will try to reproduce and fix this.
Hello @mareksoldan , I have done some progress. This is the code I used to parse the data of the problematic request:
void test() {
unsigned char input[43] = {
0x30, 0x29, 0x02, 0x01, 0x01, 0x04, 0x06, 0x70, 0x75, 0x62, 0x6C, 0x69,
0x63, 0xA0, 0x1C, 0x02, 0x04, 0x3E, 0xE3, 0x95, 0x7B, 0x02, 0x01, 0x00,
0x02, 0x01, 0x00, 0x30, 0x0E, 0x30, 0x0C, 0x06, 0x08, 0x2B, 0x06, 0x01,
0x02, 0x01, 0x01, 0x05, 0x00, 0x05, 0x00
};
unsigned char output[512];
uint32_t size = 0;
SNMP::Message *message = new SNMP::Message();
if (message->parse(input, 43)) {
SNMP::Message *response = new SNMP::Message(SNMP::VERSION2C, "public", SNMP::TYPE_GETRESPONSE);
// The response must have the same request-id as the request
response->setRequestID(message->getRequestID());
// SYSNAME
// Create an OctetStringBER to hold the variable binding value
OctetStringBER* value = new OctetStringBER(SYSNAME_VALUE);
// Add the variable binding to the message
response->add(SYSNAME_OID, value);
// Send the response to remote IP and port
size = response->build(output);
}
Serial.println("request");
hexa.dump(input, 43);
Serial.println();
Serial.println("response");
hexa.dump(output, size);
Serial.println();
}
And I get this:
request
00000000 30 29 02 01 01 04 06 70 75 62 6C 69 63 A0 1C 02 0 ) . . . . . p u b l i c . . .
00000010 04 3E E3 95 7B 02 01 00 02 01 00 30 0E 30 0C 06 . > . . { . . . . . . 0 . 0 . .
00000020 08 2B 06 01 02 01 01 05 00 05 00 . + . . . . . . . . . . . . . .
response
00000000 30 35 02 01 01 04 06 70 75 62 6C 69 63 A2 28 02 0 5 . . . . . p u b l i c . ( .
00000010 04 3E E3 95 7B 02 01 00 02 01 00 30 1A 30 18 06 . > . . { . . . . . . 0 . 0 . .
00000020 08 2B 06 01 02 01 01 05 00 04 0C 41 72 64 75 69 . + . . . . . . . . . A r d u i
00000030 6E 6F 20 4D 65 67 61 n o M e g a . . . . . . . . .
As you can see, the request-id is the same for both 3E E3 95 7B
.
Changes are committed. Can you do some testing? Regards, Patrick
Hi @patricklaf , this looks ABSOLUTELY FANTASTIC. I'm testing like hell and so far it keeps returning the correct answers. I hereby consider this resolved and will keep you posted if anything pops up.
Hi @mareksoldan , Thanks a lot for reporting this issue and your feedback. I will shortly make a new release. Best regards, Patrick
Hi, has anyone used this lib with classic arduino? Without stm32? I try to use but arduino restart every time when receive snmp message. Can somebody help?