Home Made Rabbitcore Embedded Microcontroller Server Uptime Monitor

I have been having trouble with some web servers going down on me in the middle of the night. I decided I had enough, and am going to make a Server Up-time Monitor. Now, I could dust off one of the old computers I got laying around here (heaven knows I got enough of them), install Linux, and Nagios, but I want the monitor to wake me up in the middle of the night and consume VERY little power.

I decided to build it based of a Rabbit-Semiconductor RabbitCore RCM3100 embedded Micro-controller. This devise is small -about the size of a pack of gum, uses very little power do to it’s size, and can be made to actually DO things, like control X-10 power modules or directly run relays, sound alarms, play .wav files, etc.

Phase 1 is to make it work.
Phase 2 is to make it useful.
Phase 3 is to make it indispensable.

I have completed phase 1 tonight.
I wrote some code, based off of the samples that came with the Ethernet Starter Kit I bought a while ago, and am using to make my automatic fish feeder.
Basically, all it does is ping the server once a minute. If the server fails to reply to the ping 5 times in a row, an email is generated. This will be sent to the email address for my cell phone, effectively paging me.

Some things to make this ‘useful’ and ‘indispensable’. Here is a simple list of what I am thinking it could and should do:

  • Check multiple web servers
  • Page multiple people’s cell phones.
  • Check actual HTTP service by loading a web page and making sure it’s what is expected.
  • Display a simple ‘status’ by some method – a red & green LED display panel, LCD display, etc.
  • Turn on the night light in my bedroom at night
  • Turn on an alarm
  • Play a wave file that indicates the current status

I am going to publish my Dynamic C code, and any future updates, here to my blog in case this is useful to anybody else.

Please feel free to leave any comments/questions/patches/etc.

/*******************************************************************************
Web Server Montitor
Author Mike Creuzer
mike.creuzer.com

Based from the RabbitCore sample files:

Samplestcpipping.c
Z-World, 2000

ICMP demonstration, by pinging a remote host.
Prints a message when the ping response arrives here.
If PING_WHO is not defined, then it pings the default
gateway.

smtp.c
Z-World, 2000

A small program that uses the SMTP library
to send an e-mail.

*******************************************************************************/

/***********************************
* Configuration *
* ------------- *
* All fields in this section must *
* be altered to match your local *
* network settings. *
***********************************/

/*
* Pick the predefined TCP/IP configuration for this sample. See
* LIBRARIESTCP_IPTCP_CONFIG.LIB for instructions on how to set the
* configuration.
*/
#define TCPCONFIG 1

/** Remote interface to send PING to (passed to resolve()): **/
/* Undefine to retrieve default gateway and ping that. */
#define PING_WHO "mike.creuzer.com"

#define FROM "[email protected]"
#define TO "[email protected]"
#define SUBJECT "Monitor Update"
#define DOWNBODY "Server is down."
#define UPBODY "Server is back up."

/*
* The SMTP_SERVER macro tells DCRTCP where your mail server is. This
* mail server MUST be configured to relay mail for your controller.
*
* This value can be the name or the IP address.
*/

/*
* The SMTP_SERVER macro tells DCRTCP where your mail server is. This
* mail server MUST be configured to relay mail for your controller.
*
* This value can be the name or the IP address.
*/

#define SMTP_SERVER "smtp-server.tampabay.rr.com"

/*
* The SMTP_DOMAIN should be the name of your controller. i.e.
* "somecontroller.somewhere.com" Many SMTP servers ignore this
* value, but some SMTP servers use this field. If you have
* problems, turn on the SMTP_DEBUG macro and see were it is
* bombing out. If it is in the HELO command consult the
* person in charge of the mail server for the appropriate value
* for SMTP_DOMAIN. If you do not define this macro it defaults
* to the value in MY_IP_ADDRESS.
*
*/

#define SMTP_DOMAIN "aquaria.serveblog.com"

/*
* The SMTP_VERBOSE macro logs the communications between the mail
* server and your controller. Uncomment this define to begin
* logging
*/

// #define SMTP_VERBOSE

/********************************
* End of configuration section *
********************************/

#use dcrtcp.lib
#use smtp.lib

int main()
{
longword seq,lastpingrecieved,ping_who,tmp_seq,time_out;
char buffer[100];
int down, sentdown, sentup;

sock_init();
// Wait for the interface to come up
while (ifpending(IF_DEFAULT) == IF_COMING_UP) {
tcp_tick(NULL);
}

/* Print who we are... */
printf( "My IP address is %snn", inet_ntoa(buffer, gethostid()) );

/*
* Get the binary ip address for the target of our
* pinging.
*/

#ifdef PING_WHO
/* Ping a specific IP addr: */
ping_who=resolve(PING_WHO);
if(ping_who==0) {
printf("ERROR: unable to resolve %sn",PING_WHO);
return 1;
}
#else
/* Examine our configuration, and ping the default router: */
tmp_seq = ifconfig( IF_ANY, IFG_ROUTER_DEFAULT, & ping_who, IFS_END );
if( tmp_seq != 0 ) {
printf( "ERROR: ifconfig() failed --> %dn", (int) tmp_seq );
return 1;
}
if(ping_who==0) {
printf("ERROR: unable to resolve IF_ROUTER_DEFAULTn");
return 1;
}
#endif

seq=0;
lastpingrecieved = 0;
down = 0;
sentdown = 0;
sentup = 0;
for(;;) {
/*
* It is important to call tcp_tick here because
* ping packets will not get processed otherwise.
*/

tcp_tick(NULL);

/*
* Send one ping per second.
*/

costate {
//waitfor(DelaySec(1));
waitfor(DelaySec(60));
_ping(ping_who,seq++);
}

/*
* Has a ping come in? time_out!=0xfffffff->yes.
*/

time_out=_chk_ping(ping_who,&tmp_seq);
if(time_out!=0xffffffff){
if(down == 1){
printf("Service has been restored. n");
down = 0;
smtp_sendmail(TO, FROM, SUBJECT, UPBODY);

while(smtp_mailtick()==SMTP_PENDING)
continue;

if(smtp_status()==SMTP_SUCCESS)
printf("Message sentn");
else
printf("Error sending messagen");
}
printf("Received Ping: %ld %ldn", tmp_seq, time_out);
lastpingrecieved = tmp_seq;
sentdown = 0;
}else
{
if (seq - lastpingrecieved >= 5 && sentdown == 0){
printf("Host Unavailable. n");
down = 1;
sentdown = 1;

smtp_sendmail(TO, FROM, SUBJECT, DOWNBODY);

while(smtp_mailtick()==SMTP_PENDING)
continue;

if(smtp_status()==SMTP_SUCCESS)
printf("Message sentn");
else
printf("Error sending messagen");
}
}

} // end FOR
}

Join the Conversation

1 Comment

  1. Cool stuff, I like the RabbitCore processors, I just bought the wireless module 5400W. I tried one of the Wifi samples, and it picked up my home network on the first compilation attempt.

Leave a comment

Your email address will not be published. Required fields are marked *

WordPress Appliance - Powered by TurnKey Linux