diff --git a/examples/ESP32_SNMP/ESP32_SNMP.ino b/examples/ESP32_SNMP/ESP32_SNMP.ino index 8a0f60f..444238c 100644 --- a/examples/ESP32_SNMP/ESP32_SNMP.ino +++ b/examples/ESP32_SNMP/ESP32_SNMP.ino @@ -106,6 +106,28 @@ void setup(){ snmp.sortHandlers(); } +void calbackStatusFunction(SendStatus status) +{ + switch (status) + { + case ssNone: + Serial.println("Status: None"); + break; + + case ssOk: + Serial.println("Status: Ok"); + break; + + case ssError: + Serial.println("Status: Error"); + break; + + default: + Serial.println("Status: Unknow"); + break; + } +} + void loop(){ snmp.loop(); // must be called as often as possible if(settableNumberOID->setOccurred){ @@ -130,7 +152,7 @@ void loop(){ // Send the trap to the specified IP address // If INFORM is set, snmp.loop(); needs to be called in order for the acknowledge mechanism to work. IPAddress destinationIP = IPAddress(192, 168, 1, 243); - if(snmp.sendTrapTo(settableNumberTrap, destinationIP, true, 2, 5000) != INVALID_SNMP_REQUEST_ID){ + if(snmp.sendTrapTo(settableNumberTrap, destinationIP, calbackStatusFunction, true, 2, 5000) != INVALID_SNMP_REQUEST_ID){ Serial.println("Sent SNMP Trap"); } else { Serial.println("Couldn't send SNMP Trap"); diff --git a/src/SNMPInform.cpp b/src/SNMPInform.cpp index 532bc1b..1fa0bab 100644 --- a/src/SNMPInform.cpp +++ b/src/SNMPInform.cpp @@ -23,7 +23,7 @@ static void remove_inform_from_list(std::list &list, snmp_request_id_t queue_and_send_trap(std::list &informList, SNMPTrap *trap, const IPAddress& ip, bool replaceQueuedRequests, - int retries, int delay_ms) { + int retries, int delay_ms, CallbackFunctionSendStatus callbackFunctionSendStatus) { bool buildStatus = trap->buildForSending(); if(!buildStatus) { SNMP_LOGW("Couldn't build trap\n"); @@ -34,6 +34,14 @@ queue_and_send_trap(std::list &informList, SNMPTrap *trap, if(replaceQueuedRequests){ SNMP_LOGD("Removing any outstanding informs for this trap\n"); remove_inform_from_list(informList, [trap](struct InformItem* informItem) -> bool { + if (informItem->callbackFunctionSendStatus){ + SNMP_LOGD("callbackFunctionSendStatus is set\n"); + delay(1);//If delete callback not working :( + informItem->callbackFunctionSendStatus(ssUnknow); + } + else{ + SNMP_LOGW("callbackFunctionSendStatus not set\n"); + } return informItem->trap == trap; }); } @@ -48,6 +56,7 @@ queue_and_send_trap(std::list &informList, SNMPTrap *trap, item->lastSent = millis(); item->trap = trap; item->missed = false; + item->callbackFunctionSendStatus = callbackFunctionSendStatus; SNMP_LOGD("Adding Inform request to queue: %lu\n", item->requestID); @@ -69,6 +78,14 @@ void inform_callback(std::list &informList, snmp_request_id //TODO: if we ever want to keep received informs, change this logic remove_inform_from_list(informList, [requestID](struct InformItem* informItem) -> bool { + if (informItem->callbackFunctionSendStatus){ + SNMP_LOGD("callbackFunctionSendStatus is set\n"); + delay(1);//If delete callback not working :( + informItem->callbackFunctionSendStatus(ssOk); + } + else{ + SNMP_LOGW("callbackFunctionSendStatus not set\n"); + } return informItem->requestID == requestID; }); @@ -77,6 +94,7 @@ void inform_callback(std::list &informList, snmp_request_id void handle_inform_queue(std::list &informList) { auto thisLoop = millis(); + bool flagRemove = false; for(auto informItem : informList){ if(!informItem->received && thisLoop - informItem->lastSent > informItem->delay_ms){ SNMP_LOGD("Missed Inform receive\n"); @@ -84,6 +102,7 @@ void handle_inform_queue(std::list &informList) { informItem->missed = true; if(!informItem->retries){ SNMP_LOGD("No more retries for inform: %lu, removing\n", informItem->requestID); + flagRemove = true; continue; } if(informItem->trap){ @@ -95,7 +114,15 @@ void handle_inform_queue(std::list &informList) { } } } - remove_inform_from_list(informList, [](struct InformItem* informItem) -> bool { + if (flagRemove) remove_inform_from_list(informList, [](struct InformItem* informItem) -> bool { + if (informItem->callbackFunctionSendStatus){ + SNMP_LOGD("callbackFunctionSendStatus is set\n"); + delay(1);//If delete callback not working :( + informItem->callbackFunctionSendStatus(ssError); + } + else{ + SNMP_LOGW("callbackFunctionSendStatus not set\n"); + } return informItem->received || (informItem->retries == 0 && informItem->missed); }); } @@ -103,6 +130,14 @@ void handle_inform_queue(std::list &informList) { void mark_trap_deleted(std::list &informList, SNMPTrap *trap) { SNMP_LOGD("Removing waiting Informs tied to Trap.\n"); remove_inform_from_list(informList, [trap](struct InformItem* informItem) -> bool { + if (informItem->callbackFunctionSendStatus){ + SNMP_LOGD("callbackFunctionSendStatus is set\n"); + delay(1);//If delete callback not working :( + informItem->callbackFunctionSendStatus(ssUnknow); + } + else{ + SNMP_LOGW("callbackFunctionSendStatus not set\n"); + } return informItem->trap == trap; }); } diff --git a/src/SNMP_Agent.cpp b/src/SNMP_Agent.cpp index 708e67c..3e1c86e 100644 --- a/src/SNMP_Agent.cpp +++ b/src/SNMP_Agent.cpp @@ -170,8 +170,8 @@ bool SNMPAgent::sortHandlers(){ return true; } -snmp_request_id_t SNMPAgent::sendTrapTo(SNMPTrap* trap, const IPAddress& ip, bool replaceQueuedRequests, int retries, int delay_ms){ - return queue_and_send_trap(this->informList, trap, ip, replaceQueuedRequests, retries, delay_ms); +snmp_request_id_t SNMPAgent::sendTrapTo(SNMPTrap* trap, const IPAddress& ip, CallbackFunctionSendStatus callbackFunctionSendStatus, bool replaceQueuedRequests, int retries, int delay_ms){ + return queue_and_send_trap(this->informList, trap, ip, replaceQueuedRequests, retries, delay_ms, callbackFunctionSendStatus); } void SNMPAgent::informCallback(void* ctx, snmp_request_id_t requestID, bool responseReceiveSuccess){ diff --git a/src/SNMP_Agent.h b/src/SNMP_Agent.h index 2c32a35..4354812 100644 --- a/src/SNMP_Agent.h +++ b/src/SNMP_Agent.h @@ -86,7 +86,7 @@ class SNMPAgent { bool removeHandler(ValueCallback* callback); bool sortHandlers(); - snmp_request_id_t sendTrapTo(SNMPTrap* trap, const IPAddress& ip, bool replaceQueuedRequests = true, int retries = 0, int delay_ms = 30000); + snmp_request_id_t sendTrapTo(SNMPTrap* trap, const IPAddress& ip, CallbackFunctionSendStatus callbackFunctionSendStatus, bool replaceQueuedRequests = true, int retries = 0, int delay_ms = 30000); static void markTrapDeleted(SNMPTrap* trap); private: diff --git a/src/include/SNMPInform.h b/src/include/SNMPInform.h index 35b5ef5..5f4c204 100644 --- a/src/include/SNMPInform.h +++ b/src/include/SNMPInform.h @@ -12,6 +12,16 @@ #include #include +enum SendStatus +{ + ssNone = 0, + ssOk = 1, + ssError = -1, + ssUnknow = -100 +}; + +typedef std::function CallbackFunctionSendStatus; + struct InformItem { snmp_request_id_t requestID; int retries; @@ -21,9 +31,10 @@ struct InformItem { unsigned long lastSent; SNMPTrap* trap; bool missed; + CallbackFunctionSendStatus callbackFunctionSendStatus = nullptr; }; -snmp_request_id_t queue_and_send_trap(std::list &informList, SNMPTrap* trap, const IPAddress& ip, bool replaceQueuedRequests, int retries, int delay_ms); +snmp_request_id_t queue_and_send_trap(std::list &informList, SNMPTrap* trap, const IPAddress& ip, bool replaceQueuedRequests, int retries, int delay_ms, CallbackFunctionSendStatus callbackFunctionSendStatus); void inform_callback(std::list &informList, snmp_request_id_t requestID, bool responseReceiveSuccess); void handle_inform_queue(std::list &informList); void mark_trap_deleted(std::list &informList, SNMPTrap* trap);