Commit d4613652 by zacharyc

Added better error recovery code.


git-svn-id: https://bucket.mit.edu/svn/nilm/acquisition/ethstream@7314 ddd99763-3ecb-0310-9145-efcb8ce7c51f
parent a4eede14
Showing with 42 additions and 32 deletions
...@@ -141,12 +141,12 @@ main (int argc, char *argv[]) ...@@ -141,12 +141,12 @@ main (int argc, char *argv[])
tmp = strtol (optarg, &endp, 0); tmp = strtol (optarg, &endp, 0);
if (*endp != '\0' && *endp != ',') if (*endp != '\0' && *endp != ',')
{ {
//|| tmp < 0 || tmp >= UE9_CHANNELS) {
info ("bad channel number: %s\n", optarg); info ("bad channel number: %s\n", optarg);
goto printhelp; goto printhelp;
} }
//We do not want to overflow channel_list, so we need the check here //We do not want to overflow channel_list, so we need the check here
//The rest of the sanity checking can come later after we know whether this is a //The rest of the sanity checking can come later after we know
//whether this is a
//LabJack or a NerdJack //LabJack or a NerdJack
#if UE9_CHANNELS > NERDJACK_CHANNELS #if UE9_CHANNELS > NERDJACK_CHANNELS
if (channel_count >= UE9_CHANNELS) if (channel_count >= UE9_CHANNELS)
...@@ -225,8 +225,9 @@ main (int argc, char *argv[]) ...@@ -225,8 +225,9 @@ main (int argc, char *argv[])
verb_count++; verb_count++;
break; break;
case 'V': case 'V':
printf ("ljstream " VERSION "\n"); printf ("etherstream " VERSION "\n");
printf ("Written by Jim Paris <jim@jtan.com>\n"); printf ("Written by Jim Paris <jim@jtan.com>\n");
printf ("and Zachary Clifford <zacharyc@mit.edu>\n");
printf ("This program comes with no warranty and is " printf ("This program comes with no warranty and is "
"provided under the GPLv2.\n"); "provided under the GPLv2.\n");
return 0; return 0;
...@@ -315,7 +316,6 @@ doneparse: ...@@ -315,7 +316,6 @@ doneparse:
{ {
info ("error: can't achieve requested scan rate (%lf Hz)\n", info ("error: can't achieve requested scan rate (%lf Hz)\n",
desired_rate); desired_rate);
//return 1;
} }
} }
else else
...@@ -325,7 +325,6 @@ doneparse: ...@@ -325,7 +325,6 @@ doneparse:
{ {
info ("error: can't achieve requested scan rate (%lf Hz)\n", info ("error: can't achieve requested scan rate (%lf Hz)\n",
desired_rate); desired_rate);
//return 1;
} }
} }
...@@ -425,9 +424,9 @@ nerdDoStream (const char *address, int *channel_list, int channel_count, ...@@ -425,9 +424,9 @@ nerdDoStream (const char *address, int *channel_list, int channel_count,
getPacket command; getPacket command;
static unsigned short currentcount = 0; static unsigned short currentcount = 0;
//usleep(1000000); //If this is the first time, set up acquisition
//Otherwise try to resume the previous one
if (first_call) if (started == 0)
{ {
if (nerd_generate_command if (nerd_generate_command
(&command, channel_list, channel_count, precision, period) < 0) (&command, channel_list, channel_count, precision, period) < 0)
...@@ -436,7 +435,6 @@ nerdDoStream (const char *address, int *channel_list, int channel_count, ...@@ -436,7 +435,6 @@ nerdDoStream (const char *address, int *channel_list, int channel_count,
goto out; goto out;
} }
if (nerd_send_command (address, "STOP", 4) < 0) if (nerd_send_command (address, "STOP", 4) < 0)
{ {
if (first_call) if (first_call)
...@@ -445,28 +443,34 @@ nerdDoStream (const char *address, int *channel_list, int channel_count, ...@@ -445,28 +443,34 @@ nerdDoStream (const char *address, int *channel_list, int channel_count,
goto out; goto out;
} }
//We've tried communicating, so this is not the first call anymore
first_call = 0;
if (nerd_send_command (address, &command, sizeof (command)) < 0) if (nerd_send_command (address, &command, sizeof (command)) < 0)
{ {
info ("Failed to send GET command\n"); info ("Failed to send GET command\n");
goto out; goto out;
} }
} } else {
//We have sent the configuration commands. If we retry later, don't resend them. We would like
//to resume the interrupted transmission
first_call = 0;
//If we had a transmission in progress, send a command to resume from there //If we had a transmission in progress, send a command to resume from there
if (started == 1)
{
char cmdbuf[10]; char cmdbuf[10];
sprintf (cmdbuf, "SETC%05hd", currentcount); sprintf (cmdbuf, "SETC%05hd", currentcount);
if (nerd_send_command (address, cmdbuf, strlen (cmdbuf)) < 0) retval = nerd_send_command (address, cmdbuf, strlen (cmdbuf));
{ if(retval == -4) {
info("NerdJack was reset\n");
//Assume we have not started yet, reset on this side.
//If this routine is retried, start over
printf("# NerdJack was reset here\n");
currentcount = 0;
started = 0;
goto out;
} else if(retval < 0) {
info ("Failed to send SETC command\n"); info ("Failed to send SETC command\n");
goto out; goto out;
} }
} }
//The transmission has begun
started = 1; started = 1;
/* Open connection */ /* Open connection */
......
...@@ -60,20 +60,20 @@ nerdjack_choose_scan (double desired_rate, double *actual_rate, ...@@ -60,20 +60,20 @@ nerdjack_choose_scan (double desired_rate, double *actual_rate,
info ("Cannot sample that slowly\n"); info ("Cannot sample that slowly\n");
*actual_rate = (double) NERDJACK_CLOCK_RATE / (double) 0x0ffffe; *actual_rate = (double) NERDJACK_CLOCK_RATE / (double) 0x0ffffe;
*period = 0x0ffffe; *period = 0x0ffffe;
//info("Sampling at slowest rate:%f\n",*actual_rate);
return -1; return -1;
} }
//Period holds the period register for the NerdJack, so it needs to be right //Period holds the period register for the NerdJack, so it needs to be right
*actual_rate = (double) NERDJACK_CLOCK_RATE / (double) *period; *actual_rate = (double) NERDJACK_CLOCK_RATE / (double) *period;
if (*actual_rate != desired_rate) if (*actual_rate != desired_rate)
{ {
//info("Sampling at nearest rate:%f\n",*actual_rate);
return -1; return -1;
} }
return 0; return 0;
} }
/* Perform autodetection. Returns 0 on success, -1 on error
* Sets ipAddress to the detected address
*/
int int
nerdjack_detect (char *ipAddress) nerdjack_detect (char *ipAddress)
{ {
...@@ -163,6 +163,10 @@ nerdjack_detect (char *ipAddress) ...@@ -163,6 +163,10 @@ nerdjack_detect (char *ipAddress)
return 0; return 0;
} }
/* Send the given command to address. The command should be something
* of the specified length. This expects the NerdJack to reply with OK
* or NO
*/
int int
nerd_send_command (const char *address, void *command, int length) nerd_send_command (const char *address, void *command, int length)
{ {
...@@ -200,13 +204,15 @@ nerd_send_command (const char *address, void *command, int length) ...@@ -200,13 +204,15 @@ nerd_send_command (const char *address, void *command, int length)
if (0 != strcmp ("OK", buf)) if (0 != strcmp ("OK", buf))
{ {
verb ("Did not receive OK. Received %s\n", buf); verb ("Did not receive OK. Received %s\n", buf);
return -1; return -4;
} }
return 0; return 0;
} }
//Initialize the channel structure to distill how data should be displayed /*
* Initialize the channel structure to distill how data should be displayed
*/
static void static void
nerd_init_channels (deststruct * destination, int numChannels, nerd_init_channels (deststruct * destination, int numChannels,
int numChannelsSampled, int *channel_list) int numChannelsSampled, int *channel_list)
...@@ -238,8 +244,6 @@ nerd_init_channels (deststruct * destination, int numChannels, ...@@ -238,8 +244,6 @@ nerd_init_channels (deststruct * destination, int numChannels,
} }
} }
//If this channel is wanted, set it up. //If this channel is wanted, set it up.
if (currentalign > 0) if (currentalign > 0)
{ {
...@@ -284,6 +288,8 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, ...@@ -284,6 +288,8 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list,
int numgroups = 0; int numgroups = 0;
long double volts; long double volts;
//The timeout should be the expected time plus two seconds
//This permits slower speeds to work properly
unsigned int expectedtimeout = unsigned int expectedtimeout =
(period * NERDJACK_NUM_SAMPLES / NERDJACK_CLOCK_RATE) + 2; (period * NERDJACK_NUM_SAMPLES / NERDJACK_CLOCK_RATE) + 2;
...@@ -297,7 +303,8 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, ...@@ -297,7 +303,8 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list,
int numChannelsSampled = channel_list[0] + 1; int numChannelsSampled = channel_list[0] + 1;
//The number sampled will be the highest channel requested plus 1 (i.e. channel 0 requested means 1 sampled) //The number sampled will be the highest channel requested plus 1
//(i.e. channel 0 requested means 1 sampled)
for (i = 0; i < numChannels; i++) for (i = 0; i < numChannels; i++)
{ {
if (channel_list[i] + 1 > numChannelsSampled) if (channel_list[i] + 1 > numChannelsSampled)
...@@ -309,6 +316,7 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, ...@@ -309,6 +316,7 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list,
nerd_init_channels (destination, numChannels, numChannelsSampled, nerd_init_channels (destination, numChannels, numChannelsSampled,
channel_list); channel_list);
//If this is the first time called, warn the user if we're too fast
if (linesdumped == 0) if (linesdumped == 0)
{ {
if (period < (numChannelsSampled * 100 + 300)) if (period < (numChannelsSampled * 100 + 300))
...@@ -320,7 +328,6 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, ...@@ -320,7 +328,6 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list,
//Now destination structure array is set as well as numDuplicates. //Now destination structure array is set as well as numDuplicates.
//int numChannelsSampled = numChannels - numDuplicates;
int numGroups = NERDJACK_NUM_SAMPLES / numChannelsSampled; int numGroups = NERDJACK_NUM_SAMPLES / numChannelsSampled;
...@@ -332,7 +339,6 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, ...@@ -332,7 +339,6 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list,
.tv_sec = expectedtimeout}))) .tv_sec = expectedtimeout})))
{ {
//We want a complete packet, so take the chars so far and keep waiting
if (charsread != NERDJACK_PACKET_SIZE) if (charsread != NERDJACK_PACKET_SIZE)
{ {
//There was a problem getting data. Probably a closed //There was a problem getting data. Probably a closed
...@@ -350,7 +356,6 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, ...@@ -350,7 +356,6 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list,
//Check counter info to make sure not out of order //Check counter info to make sure not out of order
tempshort = ntohs (buf.packetNumber); tempshort = ntohs (buf.packetNumber);
//tempshort = (buf[2] << 8) | buf[3];
if (tempshort != *currentcount) if (tempshort != *currentcount)
{ {
info ("Count wrong. Expected %hd but got %hd\n", *currentcount, info ("Count wrong. Expected %hd but got %hd\n", *currentcount,
...@@ -425,6 +430,7 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list, ...@@ -425,6 +430,7 @@ nerd_data_stream (int data_fd, int numChannels, int *channel_list,
//Since channel data is packed, we need to know when to insert a newline //Since channel data is packed, we need to know when to insert a newline
if (alignment == numChannelsSampled) if (alignment == numChannelsSampled)
{ {
//We want to dump the first line because it's usually spurious
if (linesdumped != 0) if (linesdumped != 0)
{ {
switch (convert) switch (convert)
...@@ -492,6 +498,7 @@ bad: ...@@ -492,6 +498,7 @@ bad:
} }
/* Open a connection to the NerdJack */
int int
nerd_open (const char *address, int port) nerd_open (const char *address, int port)
{ {
...@@ -560,7 +567,6 @@ nerd_generate_command (getPacket * command, int *channel_list, ...@@ -560,7 +567,6 @@ nerd_generate_command (getPacket * command, int *channel_list,
channelbit = channelbit | (0x1 << channel_list[i]); channelbit = channelbit | (0x1 << channel_list[i]);
} }
//command->word = "GETD";
command->word[0] = 'G'; command->word[0] = 'G';
command->word[1] = 'E'; command->word[1] = 'E';
command->word[2] = 'T'; command->word[2] = 'T';
...@@ -570,8 +576,6 @@ nerd_generate_command (getPacket * command, int *channel_list, ...@@ -570,8 +576,6 @@ nerd_generate_command (getPacket * command, int *channel_list,
command->period = htonl (period); command->period = htonl (period);
command->prescaler = 0; command->prescaler = 0;
//sprintf(command,"GETD%3.3X%d%5.5d", channelbit,precision,period);
return 0; return 0;
} }
...@@ -583,3 +587,4 @@ nerd_close_conn (int data_fd) ...@@ -583,3 +587,4 @@ nerd_close_conn (int data_fd)
close (data_fd); close (data_fd);
return 0; return 0;
} }
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#define NERDJACK_PACKET_SIZE 1460 #define NERDJACK_PACKET_SIZE 1460
#define NERDJACK_NUM_SAMPLES 724 #define NERDJACK_NUM_SAMPLES 724
/* Packet structure used in message to start sampling on NerdJack */
typedef struct __attribute__ ((__packed__)) typedef struct __attribute__ ((__packed__))
{ {
char word[4]; char word[4];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment