First of all, thank you for your help.
I have made a program that monitors some parameters and sends SNMP traps. My problem is that the program launches all traps, except the coldstart. Does anyone know what the problem is?
Best regards
First of all, thank you for your help.
I have made a program that monitors some parameters and sends SNMP traps. My problem is that the program launches all traps, except the coldstart. Does anyone know what the problem is?
Best regards
What error messages are you getting? What version of Dynamic C are you using? Do you see this issue when running a sample program?
I use Dynamic c 10.72. I don´t have any error but when i check the data in the network with the program wireshark i don´t see this trap. But if another trap command while the program is running, the trap is sent.
Also, what board are you running this on and can you show us your code?
are you seeing the same when running a sample program?
I think the problem is that I start network with the function sock_init(), but I don´t wait to the interface come up. For that reason, the first trap wasn’t sent but the rest of them were sent correctly. I know that exist another function to start the interface and wait to come up sock_init_or_exit, but I can´t use it, because I need to have operative the console. Is there any function to check if the interface is come up?
MargaretK I don´t see the same that the sample, but I do the software following the sample.
The differences are: I comment the code inside the function scale and I delete the line #define DISABLE_TCP because I use a telnet console.
int scale(snmp_parms * p, int wr, int commit, long * v, word * len, word maxlen)
{
/*printf("Callback: wr=%d commit=%d v(in)=%ld "), wr, commit, *v);
if (wr) {
// On write by agent, we ensure that the variable is within bounds.
if (*v > 200000000)
return SNMP_ERR_badValue;
if (*v < -200000000)
return SNMP_ERR_badValue;
// OK, scale it up to internal representation.
*v *= 10;
}
else
// Read by the agent: scale it down.
*v /= 10;
printf("v(out)=%ld
", v);/
return 0;
}
I did some test and I think that I found the bug. I need send the coldstart to two computers. I am changed the sample code SNMP1.C for send two coldstart to two differents IPs. If I send the coldstart only to one computer, work well, but when I send to both computers aren’t receive any trap in no pc.
The code that I test is the following
/*
on the particular software, but will typically involve compiling
the SMI/MIB definition files. The files are located in the
"mibs" subdirectory of the snmp samples.
RABBITSEMI-SMI.txt - top level Rabbit Semiconductor
RABBITSEMI-PRODUCTS-MIB.txt - listing of products (boards)
RABBITSEMI-DEMO-SNMP1.txt - describes this demo.
The management agent can use this information to allow browsing
of the available managed objects.
the correct network configuration set (TCPCONFIG).
call to snmp_set_dflt_communities().
modify some of the objects (the ones under the demoRWObjects
subtree). If you modify rw_int to be greater than 3000, then
trap messages will be sent to the agent.
*/
/*
#memmap xmem
#define USE_SNMP 1 // This is necessary for all SNMP applications
#define SNMP_TRAPS // This must be defined to support trap sending
#define SNMP_INTERFACE IF_ANY // Support all incoming interfaces
#define DISABLE_TCP // Do not require TCP (SNMP uses only UDP)
// Set the IP address of your management agent.
#define MANAGER_IP “10.10.6.50”
#define MANAGER_IP2 “10.10.6.177”
// For this demo only, send trap every 5 sec (optional)
//#define SEND_TRAPS
// Optional definitions to enable Dynamic C debugging and/or extra messages.
//#define DCRTCP_DEBUG
//#define DCRTCP_VERBOSE
//#define MIB_DEBUG
//#define MIB_VERBOSE
#define SNMP_ENTERPRISE 12807 // Rabbit Semiconductor (do not change)
#use “dcrtcp.lib”
/*
/*
/*
This function will be used as a callback function for one of the
read/write variables (rw_long). It demonstrates how to “scale” a variable
from internal units into the units expected by the management
agent. In this case, the variable appears as 1/10th of its internal
value. Note that the transformation needs to work both ways if the
variable is writable by the agent.
*/
int scale(snmp_parms * p, int wr, int commit, long * v, word * len, word maxlen)
{
printf("Callback: wr=%d commit=%d v(in)=%ld ", wr, commit, *v);
if (wr) {
// On write by agent, we ensure that the variable is within bounds.
if (*v > 200000000)
return SNMP_ERR_badValue;
if (*v < -200000000)
return SNMP_ERR_badValue;
// OK, scale it up to internal representation.
*v *= 10;
}
else
// Read by the agent: scale it down.
*v /= 10;
printf("v(out)=%ld
", *v);
return 0;
}
int main()
{
auto snmp_parms _p;
auto snmp_parms * p;
auto word tt;
auto word trapindices[2];
auto word monindex;
// Set the community passwords
snmp_set_dflt_communities("public", "private", "trap");
// Set p to be a pointer to _p, for calling convenience.
p = &_p;
// Set parameter structure to default initial state (required).
snmp_init_parms(p);
// Create the MIB tree. The following functions all operate on the parameter structure.
// "p" is passed to all functions, and also set to the return value. This is the recommended
// way of doing the MIB tree setup, since if any step fails it will return NULL. Passing the
// NULL on to subsequent functions is harmless, and avoids the need to do error checking
// after each call. Only at the end of sequence sould "p" be tested for NULL.
// Set the "root" of the MIB tree for following calls. Note that the entire MIB
// tree can be rooted at a different point simply by changing this one call.
p = snmp_append_parse_stem(p, "3.1.1"); // Set to SNMP_ENTERPRISE.oemExperiments.demos
// Read/write access - the following is set by default so no need to call.
p = snmp_set_access(p, SNMP_PUBLIC_MASK|SNMP_PRIVATE_MASK, SNMP_PRIVATE_MASK);
p = snmp_add_int(p, "1.1.0", &rw_int);
monindex = snmp_last_index(p); // Save index for later monitor call
p = snmp_set_callback(p, scale);
p = snmp_add_long(p, "1.2.0", &rw_long); // This variable has a callback function, scale().
p = snmp_set_callback(p, NULL);
p = snmp_add_foct(p, "1.3.0", rw_fixed, 20);
p = snmp_add_str(p, "1.4.0", rw_str, 20);
p = snmp_add_oct(p, "1.5.0", rw_oct, 22);
p = snmp_add_objectID(p, "1.6.0", &rw_oid);
p = snmp_add_ipaddr(p, "1.7.0", &trapdest_ip);
p = snmp_add_timeticks(p, "1.8.0", &rw_tt);
// Read-only access for following additions
p = snmp_set_access(p, SNMP_PUBLIC_MASK|SNMP_PRIVATE_MASK, 0);
p = snmp_add_int(p, "2.1.0", &r_int);
trapindices[0] = snmp_last_index(p);
p = snmp_add_long(p, "2.2.0", &r_long);
p = snmp_add_foct(p, "2.3.0", r_fixed, 20);
p = snmp_add_str(p, "2.4.0", r_str, 20);
p = snmp_add_oct(p, "2.5.0", r_oct, 22);
trapindices[1] = snmp_last_index(p);
p = snmp_add_objectID(p, "2.6.0", &r_oid);
// Initialize the variables.
rw_int = 1001;
rw_long = 1000002;
memcpy(rw_fixed, "rw_fixed abcdefghijk", 20);
strcpy(rw_str, "rw_str");
memcpy(rw_oct, "\x06\x00rw_oct", 8);
memcpy(&rw_oid, &_p, sizeof(snmp_oid));
trapdest_ip = aton(MANAGER_IP);
trapdest_ip2 = aton(MANAGER_IP2);
rw_tt = snmp_timeticks(); // Set base epoch
r_int = 2001;
r_long = 2000002;
memcpy(r_fixed, "r_fixed abcdefghijkl", 20);
strcpy(r_str, "r_str");
memcpy(r_oct, "\x05\x00r_oct", 7);
memcpy(&r_oid, &_p, sizeof(snmp_oid));
// Finally, we check that the MIB tree was constructed without error.
// If there was any error, p will be set to NULL.
if (!p) {
printf("There was an error constructing the MIB.
");
exit(1);
}
// Monitor the rw_int variable (whose MIB tree index was saved in monindex).
// trapindices was set up with the indices for r_int and r_oct.
snmp_monitor(monindex, 0, 3000, 1, 16, 6, &trapdest_ip, SNMP_TRAPDEST, 30, 2, trapindices);
// See what we've got.
snmp_print_tree();
printf("MIB tree: used %ld out of %ld bytes
", snmp_used(), (long)SNMP_MIB_SIZE);
// Start network and wait for interface to come up (or error exit).
sock_init_or_exit(1);
// Print interfaces
ip_print_ifs();
// Print routers
router_printall();
tt = _SET_SHORT_TIMEOUT(5000);
snmp_trap(trapdest_ip, SNMP_TRAPDEST, 1, 0, trapindices);
tcp_tick(NULL);
//snmp_trap(trapdest_ip2, SNMP_TRAPDEST , 1, 0, trapindices);
//tcp_tick(NULL);
for (; {
if (_CHK_SHORT_TIMEOUT(tt)) {
#ifdef SEND_TRAPS
snmp_trap(trapdest_ip, SNMP_TRAPDEST, 20, 2, trapindices);
#endif
tt = _SET_SHORT_TIMEOUT(5000);
}
tcp_tick(NULL);
}
}
Have a look at the ifpending() and ifstatus() functions. These will allow you see the current status of the network interface so that you can hold of sending the trap until everything is up and running.
Thank you petermcs. I put this, but I loss the traps too
while (ifpending(IF_DEFAULT) == IF_COMING_UP)
{
tcp_tick(NULL);
}
snmp_trap(IP1, SNMP_TRAPDEST , 1, 0, trapindices);
tcp_tick(NULL);
snmp_trap(IP2, SNMP_TRAPDEST , 1, 0, trapindices);
tcp_tick(NULL);
I wonder if you are calling tcp_tick() frequently enough to allow the TCP/IP stack get its work done? I use a different approach in my product as I use uCOS II and have a separate tcp task which mainly just calls tcp_tick() to keep things going in the background. If tcp_tick() is not called frequently, the data transfer may not happen properly.
In the main function y put some tcp_tick() and always after send a trap put a tcp_tick(). Do you refer to use a costate like this?
costate{
tcp_tick();
}
costate{
while (ifpending(IF_DEFAULT) == IF_COMING_UP)
{
//tcp_tick(NULL);
}
snmp_trap(IP1, SNMP_TRAPDEST , 1, 0, trapindices);
snmp_trap(IP2, SNMP_TRAPDEST , 1, 0, trapindices);
}
Yesterday I put the sample’s code SNMP1.C modified for send two coldstart’s traps. If I only send one coldstart it work well, but when I try to send two coldstart, don´t work it. Can you modified this sample for check it?
I do something similar but using uCos II instead of the costates to manage my tasks. It works quite well and I don’t have to litter my code with tcp_task() calls.