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

Add real onReceive() callback that will be called when snmp response is actually parsed #21

Open
damago1 opened this issue Jul 18, 2022 · 4 comments
Labels
enhancement New feature or request

Comments

@damago1
Copy link

damago1 commented Jul 18, 2022

Currently there is no possibility to check if snmp request had been processed. In the examples the call to "uptime" oid is used as sudo check. However many devices are updating this parameter not every 100ms but for instance every 1 second or something like this. And not all devices return this properly anyway.

As I understand the 'callback" classes are not real callbacks because no code is called back upon processing of received packet.

The solution would be to extend the ValueCallback class by "onReceive" field which can be used by the user to store a pointer to function which will be called after snmp request had been fulfilled.

If there is already some method of getting definite information that snmp request had been processed - please let know in a form of an example.

@shortbloke shortbloke added the enhancement New feature or request label Jul 18, 2022
@shortbloke
Copy link
Owner

Your assessment is correct, there currently isn't a way to know if a particular request has been responded to or timeout. This library was created based V1 or the SNMP Agent implementing a similar set of interfaces which has its limitations.

The Agent library is now on V2 which was a substantial change, and I know the author is considering implementing a Manager, see: https://github.com/0neblock/Arduino_SNMP/tree/snmp-manager

I'd welcome a PR if you're willing to implement an onRecieve method as you describe. Otherwise I'll leave the suggestion here and I'll see when I can get to it.

@damago1
Copy link
Author

damago1 commented Jul 18, 2022

I was trying to do this. I have added field to class ValueCallback after line 32:

class ValueCallback
{
...
   onReceive (void *)() = nullptr;
...
}

than you can add the handler in your code just after the "addXXXhandler" like:

...
callbackUptime = snmp.addTimestampHandler(settings.snmpHostRouter, settings.oidUptime.c_str(), (int*)(&routerUptime));
callbackUptime->onReceive = &myFunction;

and I was trying to add handling of this inside the bool SNMPManager::parsePacket() just before the line with //End while, line 391 something like:

         if(callback->onReceive != nullptr) (callback->onReceive)();         
      } // End while
   }     // End if GetResponsePDU

but for unknown reason the field onReceive is magically wiped out at this point. The pointer that I did set in my code is nullptr at this time. I did not have time to investigate it further what is happening to the callback class in the meantime. It seems that it is copied somewhere in the meantime and the new fields are 'lost' in copying but I could not find where and how.

If you point me to the place where the originally set field is lost I can do it, test it and PR.

@allacmc
Copy link

allacmc commented Nov 20, 2023

Can anyone tell me if this evolved at any point?

I have the same problem, I make SNMP calls but I don't know when they are ok, according to the SNMP request.

Here below is an example of code that is not correct...another way I found to know if the request was completed.

`const char * f_ScanDeviceSysName(IPAddress ip){
Serial.println("------------Entrei...");
SNMPManager snmp2 = SNMPManager();
SNMPGet snmpRequest2;

  char sysName[30];
  char *Response = sysName;
  
  ValueCallback *callback;
  callback = snmp2.addStringHandler(ip, ".1.3.6.1.2.1.1.5.0", &Response);

  Serial.println("------------snmpRequest - ok");

  snmp2._community = str_Community.c_str();
  snmp2.setUDP(&udp); 
  snmp2.begin();
  snmpRequest2._community = str_Community.c_str();
  snmpRequest2._version = snmpVersion;
  snmpRequest2.addOIDPointer(callback);
  snmpRequest2.setIP(WiFi.localIP()); 
  snmpRequest2.setPort(SNMP_Port);
  snmpRequest2.setUDP(&udp);
  snmpRequest2.setRequestID(rand() % 5555);
  snmpRequest2.sendTo(ip);
  snmpRequest2.clearOIDList();

  Serial.println("------------snmpRequest - ok");

  bool scanComplete = false;
  int lastTam = -1;
  unsigned long sMillis;  //some global variables available anywhere in the program
  unsigned long cMillis;

  while (!scanComplete) {
        snmp2.loop();
        cMillis = millis();
        if (cMillis - sMillis >= SNMP_TimeOut){
           if (lastTam == strlen(Response)) {                //Pensar no futuro em como ter certeza que recebeu os dados....
              scanComplete = true;
           }
           lastTam = strlen(Response);
           sMillis = cMillis;
        }
  }

        Serial.println("------------------------------------i");
            for (int i = 0; i < strlen(Response); i++) {
                Serial.print(String(Response[i], HEX) + " ");
            }
        Serial.println();    
        Serial.println("------------------------------------i");

  return Response;

}
`

@shortbloke
Copy link
Owner

@allacmc does the device you are querying not support uptime?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants