int main (int argc, char *argv[]) { struct misc_config_s config; dwgps_info_t info; memset (&config, 0, sizeof(config)); strlcpy (config.gpsnmea_port, "COM22", sizeof(config.gpsnmea_port)); dwgps_init (&config, 3); while (1) { dwfix_t fix; fix = dwgps_read (&info) ; text_color_set (DW_COLOR_INFO); switch (fix) { case DWFIX_2D: case DWFIX_3D: dw_printf ("%.6f %.6f", info.dlat, info.dlon); dw_printf (" %.1f knots %.0f degrees", info.speed_knots, info.track); if (fix==3) dw_printf (" altitude = %.1f meters", info.altitude); dw_printf ("\n"); break; case DWFIX_NOT_SEEN: case DWFIX_NO_FIX: dw_printf ("Location currently not available.\n"); break; case DWFIX_NOT_INIT: dw_printf ("GPS Init failed.\n"); exit (1); case DWFIX_ERROR: default: dw_printf ("ERROR getting GPS information.\n"); break; } SLEEP_SEC (3); }
int main (int argc, char *argv[]) { int e; failed = 0; char message[256]; dedupe_init (4); /* * Compile the patterns. */ e = regcomp (&alias_re, "^WIDE[4-7]-[1-7]|CITYD$", REG_EXTENDED|REG_NOSUB); if (e != 0) { regerror (e, &alias_re, message, sizeof(message)); text_color_set(DW_COLOR_ERROR); dw_printf ("\n%s\n\n", message); exit (1); } e = regcomp (&wide_re, "^WIDE[1-7]-[1-7]$|^TRACE[1-7]-[1-7]$|^MA[1-7]-[1-7]$", REG_EXTENDED|REG_NOSUB); if (e != 0) { regerror (e, &wide_re, message, sizeof(message)); text_color_set(DW_COLOR_ERROR); dw_printf ("\n%s\n\n", message); exit (1); } /* * Let's start with the most basic cases. */ test ( "W1ABC>TEST01,TRACE3-3:", "W1ABC>TEST01,WB2OSZ-9*,TRACE3-2:"); test ( "W1ABC>TEST02,WIDE3-3:", "W1ABC>TEST02,WB2OSZ-9*,WIDE3-2:"); test ( "W1ABC>TEST03,WIDE3-2:", "W1ABC>TEST03,WB2OSZ-9*,WIDE3-1:"); test ( "W1ABC>TEST04,WIDE3-1:", "W1ABC>TEST04,WB2OSZ-9*:"); /* * Look at edge case of maximum number of digipeaters. */ test ( "W1ABC>TEST11,R1,R2,R3,R4,R5,R6*,WIDE3-3:", "W1ABC>TEST11,R1,R2,R3,R4,R5,R6,WB2OSZ-9*,WIDE3-2:"); test ( "W1ABC>TEST12,R1,R2,R3,R4,R5,R6,R7*,WIDE3-3:", "W1ABC>TEST12,R1,R2,R3,R4,R5,R6,R7*,WIDE3-2:"); test ( "W1ABC>TEST13,R1,R2,R3,R4,R5,R6,R7*,WIDE3-1:", "W1ABC>TEST13,R1,R2,R3,R4,R5,R6,R7,WB2OSZ-9*:"); /* * "Trap" large values of "N" by repeating only once. */ test ( "W1ABC>TEST21,WIDE4-4:", "W1ABC>TEST21,WB2OSZ-9*:"); test ( "W1ABC>TEST22,WIDE7-7:", "W1ABC>TEST22,WB2OSZ-9*:"); /* * Only values in range of 1 thru 7 are valid. */ test ( "W1ABC>TEST31,WIDE0-4:", ""); test ( "W1ABC>TEST32,WIDE8-4:", ""); test ( "W1ABC>TEST33,WIDE2:", ""); /* * and a few cases actually heard. */ test ( "WA1ENO>FN42ND,W1MV-1*,WIDE3-2:", "WA1ENO>FN42ND,W1MV-1,WB2OSZ-9*,WIDE3-1:"); test ( "W1ON-3>BEACON:", ""); test ( "W1CMD-9>TQ3Y8P,N1RCW-2,W1CLA-1,N8VIM,WIDE2*:", ""); test ( "W1CLA-1>APX192,W1GLO-1,WIDE2*:", ""); test ( "AC1U-9>T2TX4S,AC1U,WIDE1,N8VIM*,WIDE2-1:", "AC1U-9>T2TX4S,AC1U,WIDE1,N8VIM,WB2OSZ-9*:"); /* * Someone is still using the old style and will probably be disappointed. */ test ( "K1CPD-1>T2SR5R,RELAY*,WIDE,WIDE,SGATE,WIDE:", ""); /* * Change destination SSID to normal digipeater if none specified. */ test ( "W1ABC>TEST-3:", "W1ABC>TEST,WB2OSZ-9*,WIDE3-2:"); test ( "W1DEF>TEST-3,WIDE2-2:", "W1DEF>TEST-3,WB2OSZ-9*,WIDE2-1:"); /* * Drop duplicates within specified time interval. * Only the first 1 of 3 should be retransmitted. */ test ( "W1XYZ>TEST,R1*,WIDE3-2:info1", "W1XYZ>TEST,R1,WB2OSZ-9*,WIDE3-1:info1"); test ( "W1XYZ>TEST,R2*,WIDE3-2:info1", ""); test ( "W1XYZ>TEST,R3*,WIDE3-2:info1", ""); /* * Allow same thing after adequate time. */ SLEEP_SEC (5); test ( "W1XYZ>TEST,R3*,WIDE3-2:info1", "W1XYZ>TEST,R3,WB2OSZ-9*,WIDE3-1:info1"); /* * Although source and destination match, the info field is different. */ test ( "W1XYZ>TEST,R1*,WIDE3-2:info4", "W1XYZ>TEST,R1,WB2OSZ-9*,WIDE3-1:info4"); test ( "W1XYZ>TEST,R1*,WIDE3-2:info5", "W1XYZ>TEST,R1,WB2OSZ-9*,WIDE3-1:info5"); test ( "W1XYZ>TEST,R1*,WIDE3-2:info6", "W1XYZ>TEST,R1,WB2OSZ-9*,WIDE3-1:info6"); /* * New in version 0.8. * "Preemptive" digipeating looks ahead beyond the first unused digipeater. */ test ( "W1ABC>TEST11,CITYA*,CITYB,CITYC,CITYD,CITYE:off", ""); preempt = PREEMPT_DROP; test ( "W1ABC>TEST11,CITYA*,CITYB,CITYC,CITYD,CITYE:drop", "W1ABC>TEST11,WB2OSZ-9*,CITYE:drop"); preempt = PREEMPT_MARK; test ( "W1ABC>TEST11,CITYA*,CITYB,CITYC,CITYD,CITYE:mark1", "W1ABC>TEST11,CITYA,CITYB,CITYC,WB2OSZ-9*,CITYE:mark1"); test ( "W1ABC>TEST11,CITYA*,CITYB,CITYC,WB2OSZ-9,CITYE:mark2", "W1ABC>TEST11,CITYA,CITYB,CITYC,WB2OSZ-9*,CITYE:mark2"); preempt = PREEMPT_TRACE; test ( "W1ABC>TEST11,CITYA*,CITYB,CITYC,CITYD,CITYE:trace1", "W1ABC>TEST11,CITYA,WB2OSZ-9*,CITYE:trace1"); test ( "W1ABC>TEST11,CITYA*,CITYB,CITYC,CITYD:trace2", "W1ABC>TEST11,CITYA,WB2OSZ-9*:trace2"); test ( "W1ABC>TEST11,CITYB,CITYC,CITYD:trace3", "W1ABC>TEST11,WB2OSZ-9*:trace3"); test ( "W1ABC>TEST11,CITYA*,CITYW,CITYX,CITYY,CITYZ:nomatch", ""); #if 0 /* changed strategy */ /* * New in version 1.2. */ // no filter. if (filter_by_type ("CWAPID", ":NWS-TTTTT:DDHHMMz,ADVISETYPE,zcs{seq#", "") != 1) { text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 1\n"); failed++; } // message should not match psqt if (filter_by_type ("CWAPID", ":NWS-TTTTT:DDHHMMz,ADVISETYPE,zcs{seq#", "pqst") != 0) { text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 2\n"); failed++; } // This should match position if (filter_by_type ("N3LEE-7", "`cHDl <0x1c>[/\"5j}", "qstp") != 1) { text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 3\n"); failed++; } // This should match nws if (filter_by_type ("CWAPID", ":NWS-TTTTT:DDHHMMz,ADVISETYPE,zcs{seq#", "n") != 1) { text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 4\n"); failed++; } // But not this. if (filter_by_type ("CWAPID", ":zzz-TTTTT:DDHHMMz,ADVISETYPE,zcs{seq#", "n") != 0) { text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 5\n"); failed++; } // This should match nws if (filter_by_type ("CWAPID", ";CWAttttz *DDHHMMzLATLONICONADVISETYPE{seq#", "n") != 1) { text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 6\n"); failed++; } // But not this due do addressee prefix mismatch if (filter_by_type ("CWAPID", ";NWSttttz *DDHHMMzLATLONICONADVISETYPE{seq#", "n") != 0) { text_color_set(DW_COLOR_ERROR); dw_printf ("filter_by_type case 7\n"); failed++; } /* * Filtering integrated with rest of process... */ strlcpy (typefilter, "w", sizeof(typefilter)); test ( "N8VIM>APN391,WIDE2-1:$ULTW00000000010E097D2884FFF389DC000102430002033400000000", "N8VIM>APN391,WB2OSZ-9*:$ULTW00000000010E097D2884FFF389DC000102430002033400000000"); test ( "AB1OC-10>APWW10,WIDE1-1,WIDE2-1:>FN42er/# Hollis, NH iGate Operational", ""); strlcpy (typefilter, "s", sizeof(typefilter)); test ( "AB1OC-10>APWW10,WIDE1-1,WIDE2-1:>FN42er/# Hollis, NH iGate Operational", "AB1OC-10>APWW10,WB2OSZ-9*,WIDE2-1:>FN42er/# Hollis, NH iGate Operational"); test ( "K1ABC-9>TR4R8R,WIDE1-1:`c6LlIb>/`\"4K}_%", ""); strlcpy (typefilter, "up", sizeof(typefilter)); test ( "K1ABC-9>TR4R8R,WIDE1-1:`c6LlIb>/`\"4K}_%", "K1ABC-9>TR4R8R,WB2OSZ-9*:`c6LlIb>/`\"4K}_%"); strlcpy (typefilter, "", sizeof(typefilter)); #endif /* * Did I miss any cases? */ if (failed == 0) { dw_printf ("SUCCESS -- All digipeater tests passed.\n"); } else { text_color_set(DW_COLOR_ERROR); dw_printf ("ERROR - %d digipeater tests failed.\n", failed); } return ( failed != 0 ); } /* end main */
static void * beacon_thread (void *arg) #endif { int j; time_t earliest; time_t now; /* * Information from GPS. */ int fix = 0; /* 0 = none, 2 = 2D, 3 = 3D */ double my_lat = 0; /* degrees */ double my_lon = 0; float my_course = 0; /* degrees */ float my_speed_knots = 0; float my_speed_mph = 0; float my_alt = 0; /* meters */ /* * SmartBeaconing state. */ time_t sb_prev_time = 0; /* Time of most recent transmission. */ float sb_prev_course = 0; /* Most recent course reported. */ //float sb_prev_speed_mph; /* Most recent speed reported. */ int sb_every; /* Calculated time between transmissions. */ #if DEBUG struct tm tm; char hms[20]; now = time(NULL); localtime_r (&now, &tm); strftime (hms, sizeof(hms), "%H:%M:%S", &tm); text_color_set(DW_COLOR_DEBUG); dw_printf ("beacon_thread: started %s\n", hms); #endif now = time(NULL); while (1) { assert (g_misc_config_p->num_beacons >= 1); /* * Sleep until time for the earliest scheduled or * the soonest we could transmit due to corner pegging. */ earliest = g_misc_config_p->beacon[0].next; for (j=1; j<g_misc_config_p->num_beacons; j++) { if (g_misc_config_p->beacon[j].btype == BEACON_IGNORE) continue; earliest = MIN(g_misc_config_p->beacon[j].next, earliest); } if (g_misc_config_p->sb_configured && g_using_gps) { earliest = MIN(now + g_misc_config_p->sb_turn_time, earliest); earliest = MIN(now + g_misc_config_p->sb_fast_rate, earliest); } if (earliest > now) { SLEEP_SEC (earliest - now); } /* * Woke up. See what needs to be done. */ now = time(NULL); #if DEBUG localtime_r (&now, &tm); strftime (hms, sizeof(hms), "%H:%M:%S", &tm); text_color_set(DW_COLOR_DEBUG); dw_printf ("beacon_thread: woke up %s\n", hms); #endif /* * Get information from GPS if being used. * This needs to be done before the next scheduled tracker * beacon because corner pegging make it sooner. */ #if DEBUG_SIM FILE *fp; char cs[40]; fp = fopen ("c:\\cygwin\\tmp\\cs", "r"); if (fp != NULL) { fscanf (fp, "%f %f", &my_course, &my_speed_knots); fclose (fp); } else { fprintf (stderr, "Can't read /tmp/cs.\n"); } fix = 3; my_speed_mph = KNOTS_TO_MPH * my_speed_knots; my_lat = 42.99; my_lon = 71.99; my_alt = 100; #else if (g_using_gps) { fix = dwgps_read (&my_lat, &my_lon, &my_speed_knots, &my_course, &my_alt); my_speed_mph = KNOTS_TO_MPH * my_speed_knots; /* Don't complain here for no fix. */ /* Possibly at the point where about to transmit. */ } #endif /* * Run SmartBeaconing calculation if configured and GPS data available. */ if (g_misc_config_p->sb_configured && g_using_gps && fix >= 2) { if (my_speed_mph > g_misc_config_p->sb_fast_speed) { sb_every = g_misc_config_p->sb_fast_rate; } else if (my_speed_mph < g_misc_config_p->sb_slow_speed) { sb_every = g_misc_config_p->sb_slow_rate; } else { /* Can't divide by 0 assuming sb_slow_speed > 0. */ sb_every = ( g_misc_config_p->sb_fast_rate * g_misc_config_p->sb_fast_speed ) / my_speed_mph; } #if DEBUG_SIM text_color_set(DW_COLOR_DEBUG); dw_printf ("SB: fast %d %d slow %d %d speed=%.1f every=%d\n", g_misc_config_p->sb_fast_speed, g_misc_config_p->sb_fast_rate, g_misc_config_p->sb_slow_speed, g_misc_config_p->sb_slow_rate, my_speed_mph, sb_every); #endif /* * Test for "Corner Pegging" if moving. */ if (my_speed_mph >= 1.0) { int turn_threshold = g_misc_config_p->sb_turn_angle + g_misc_config_p->sb_turn_slope / my_speed_mph; #if DEBUG_SIM text_color_set(DW_COLOR_DEBUG); dw_printf ("SB-moving: course %.0f prev %.0f thresh %d\n", my_course, sb_prev_course, turn_threshold); #endif if (heading_change(my_course, sb_prev_course) > turn_threshold && now >= sb_prev_time + g_misc_config_p->sb_turn_time) { /* Send it now. */ for (j=0; j<g_misc_config_p->num_beacons; j++) { if (g_misc_config_p->beacon[j].btype == BEACON_TRACKER) { g_misc_config_p->beacon[j].next = now; } } } /* significant change in direction */ } /* is moving */ } /* apply SmartBeaconing */ for (j=0; j<g_misc_config_p->num_beacons; j++) { if (g_misc_config_p->beacon[j].btype == BEACON_IGNORE) continue; if (g_misc_config_p->beacon[j].next <= now) { int strict = 1; /* Strict packet checking because they will go over air. */ char stemp[20]; char info[AX25_MAX_INFO_LEN]; char beacon_text[AX25_MAX_PACKET_LEN]; packet_t pp = NULL; char mycall[AX25_MAX_ADDR_LEN]; /* * Obtain source call for the beacon. * This could potentially be different on different channels. * When sending to IGate server, use call from first radio channel. * * Check added in version 1.0a. Previously used index of -1. */ strcpy (mycall, "NOCALL"); if (g_misc_config_p->beacon[j].chan == -1) { strcpy (mycall, g_digi_config_p->mycall[0]); } else { strcpy (mycall, g_digi_config_p->mycall[g_misc_config_p->beacon[j].chan]); } if (strlen(mycall) == 0 || strcmp(mycall, "NOCALL") == 0) { text_color_set(DW_COLOR_ERROR); dw_printf ("MYCALL not set for beacon in config file line %d.\n", g_misc_config_p->beacon[j].lineno); continue; } /* * Prepare the monitor format header. */ strcpy (beacon_text, mycall); strcat (beacon_text, ">"); sprintf (stemp, "%s%1d%1d", APP_TOCALL, MAJOR_VERSION, MINOR_VERSION); strcat (beacon_text, stemp); if (g_misc_config_p->beacon[j].via) { strcat (beacon_text, ","); strcat (beacon_text, g_misc_config_p->beacon[j].via); } strcat (beacon_text, ":"); /* * Add the info part depending on beacon type. */ switch (g_misc_config_p->beacon[j].btype) { case BEACON_POSITION: encode_position (g_misc_config_p->beacon[j].compress, g_misc_config_p->beacon[j].lat, g_misc_config_p->beacon[j].lon, g_misc_config_p->beacon[j].symtab, g_misc_config_p->beacon[j].symbol, g_misc_config_p->beacon[j].power, g_misc_config_p->beacon[j].height, g_misc_config_p->beacon[j].gain, g_misc_config_p->beacon[j].dir, 0, 0, /* course, speed */ g_misc_config_p->beacon[j].freq, g_misc_config_p->beacon[j].tone, g_misc_config_p->beacon[j].offset, g_misc_config_p->beacon[j].comment, info); strcat (beacon_text, info); g_misc_config_p->beacon[j].next = now + g_misc_config_p->beacon[j].every; break; case BEACON_OBJECT: encode_object (g_misc_config_p->beacon[j].objname, g_misc_config_p->beacon[j].compress, 0, g_misc_config_p->beacon[j].lat, g_misc_config_p->beacon[j].lon, g_misc_config_p->beacon[j].symtab, g_misc_config_p->beacon[j].symbol, g_misc_config_p->beacon[j].power, g_misc_config_p->beacon[j].height, g_misc_config_p->beacon[j].gain, g_misc_config_p->beacon[j].dir, 0, 0, /* course, speed */ g_misc_config_p->beacon[j].freq, g_misc_config_p->beacon[j].tone, g_misc_config_p->beacon[j].offset, g_misc_config_p->beacon[j].comment, info); strcat (beacon_text, info); g_misc_config_p->beacon[j].next = now + g_misc_config_p->beacon[j].every; break; case BEACON_TRACKER: if (fix >= 2) { int coarse; /* APRS encoder wants 1 - 360. */ /* 0 means none or unknown. */ coarse = (int)roundf(my_course); if (coarse == 0) { coarse = 360; } encode_position (g_misc_config_p->beacon[j].compress, my_lat, my_lon, g_misc_config_p->beacon[j].symtab, g_misc_config_p->beacon[j].symbol, g_misc_config_p->beacon[j].power, g_misc_config_p->beacon[j].height, g_misc_config_p->beacon[j].gain, g_misc_config_p->beacon[j].dir, coarse, (int)roundf(my_speed_knots), g_misc_config_p->beacon[j].freq, g_misc_config_p->beacon[j].tone, g_misc_config_p->beacon[j].offset, g_misc_config_p->beacon[j].comment, info); strcat (beacon_text, info); /* Remember most recent tracker beacon. */ sb_prev_time = now; sb_prev_course = my_course; //sb_prev_speed_mph = my_speed_mph; /* Calculate time for next transmission. */ if (g_misc_config_p->sb_configured) { g_misc_config_p->beacon[j].next = now + sb_every; } else { g_misc_config_p->beacon[j].next = now + g_misc_config_p->beacon[j].every; } } else { g_misc_config_p->beacon[j].next = now + 2; continue; /* No fix. Try again in a couple seconds. */ } break; case BEACON_CUSTOM: if (g_misc_config_p->beacon[j].custom_info != NULL) { strcat (beacon_text, g_misc_config_p->beacon[j].custom_info); } else { text_color_set(DW_COLOR_ERROR); dw_printf ("Internal error. custom_info is null. %s %d\n", __FILE__, __LINE__); continue; } g_misc_config_p->beacon[j].next = now + g_misc_config_p->beacon[j].every; break; case BEACON_IGNORE: default: break; } /* switch beacon type. */ /* * Parse monitor format into form for transmission. */ pp = ax25_from_text (beacon_text, strict); if (pp != NULL) { /* Send to IGate server or radio. */ if (g_misc_config_p->beacon[j].chan == -1) { #if 1 text_color_set(DW_COLOR_XMIT); dw_printf ("[ig] %s\n", beacon_text); #endif igate_send_rec_packet (0, pp); ax25_delete (pp); } else { tq_append (g_misc_config_p->beacon[j].chan, TQ_PRIO_1_LO, pp); } } else { text_color_set(DW_COLOR_ERROR); dw_printf ("Config file: Failed to parse packet constructed from line %d.\n", g_misc_config_p->beacon[j].lineno); dw_printf ("%s\n", beacon_text); } } /* if time to send it */ } /* for each configured beacon */ } /* do forever */ } /* end beacon_thread */
int main(int argc, char **argv) { int opt; int o_Sndbuf_set; int num_parms; int test_num; char equiv_cmd[1024]; char *buff; char cmdbuf[512]; SOCKET sock; struct sockaddr_in sin; struct timeval tv = {1,0}; unsigned int wttl; int burst_num; /* number of bursts so far */ int msg_num; /* number of messages so far */ int send_len; /* size of datagram to send */ int sz, default_sndbuf_sz, check_size, i; int send_rtn; #if defined(_WIN32) unsigned long int iface_in; #else struct in_addr iface_in; #endif /* _WIN32 */ msend_opts opts; memset(&opts, sizeof(opts), 0); opts.prog_name = argv[0]; buff = malloc(65536); if (buff == NULL) { mprintf((&opts), "malloc failed\n"); exit(1); } memset(buff, 0, 65536); #if defined(_WIN32) { WSADATA wsadata; int wsstatus; if ((wsstatus = WSAStartup(MAKEWORD(2,2), &wsadata)) != 0) { mprintf((&opts),"%s: WSA startup error - %d\n", argv[0], wsstatus); exit(1); } } #else signal(SIGPIPE, SIG_IGN); #endif /* _WIN32 */ /* Find out what the system default socket buffer size is. */ if((sock = socket(PF_INET,SOCK_DGRAM,0)) == INVALID_SOCKET) { mprintf((&opts), "ERROR: "); perror((&opts), "socket"); exit(1); } sz = sizeof(default_sndbuf_sz); if (getsockopt(sock,SOL_SOCKET,SO_SNDBUF,(char *)&default_sndbuf_sz, (socklen_t *)&sz) == SOCKET_ERROR) { mprintf((&opts), "ERROR: "); perror((&opts), "getsockopt - SO_SNDBUF"); exit(1); } CLOSESOCKET(sock); /* default option values (declared as module globals) */ opts.o_burst_count = 1; /* 1 message per "burst" */ opts.o_decimal = 0; /* hex numbers in message text */ opts.o_loops = 1; /* number of time to loop test */ opts.o_msg_len = 0; /* variable */ opts.o_num_bursts = 0; /* infinite */ opts.o_pause = 1000; /* seconds between bursts */ opts.o_Payload = NULL; opts.o_quiet = 0; opts.o_quiet_equiv_opt = " "; opts.o_stat_pause = 0; /* no stat message */ opts.o_Sndbuf_size = MIN_DEFAULT_SENDBUF_SIZE; o_Sndbuf_set = 0; opts.o_tcp = 0; /* 0 for udp (multicast or unicast) */ opts.o_unicast_udp = 0; /* 0 for multicast or tcp */ /* default values for optional positional parms. */ opts.ttlvar = 2; opts.bind_if = NULL; test_num = -1; while ((opt = tgetopt(argc, argv, "12345b:dhl:m:n:p:P:qs:S:tu")) != EOF) { switch (opt) { case '1': test_num = 1; opts.o_burst_count = 1; opts.o_loops = 1; opts.o_msg_len = 20; opts.o_num_bursts = 600; /* 10 min */ opts.o_pause = 1000; opts.o_quiet = 1; opts.o_quiet_equiv_opt = " -q "; opts.o_stat_pause = 2000; opts.o_Sndbuf_size = MIN_DEFAULT_SENDBUF_SIZE; o_Sndbuf_set = 1; break; case '2': test_num = 2; opts.o_burst_count = 1; opts.o_loops = 1; opts.o_msg_len = 5000; opts.o_num_bursts = 5; /* 5 sec */ opts.o_pause = 1000; opts.o_quiet = 1; opts.o_quiet_equiv_opt = " -q "; opts.o_stat_pause = 2000; opts.o_Sndbuf_size = MIN_DEFAULT_SENDBUF_SIZE; o_Sndbuf_set = 1; break; case '3': test_num = 3; opts.o_burst_count = 100; opts.o_loops = 1; opts.o_msg_len = 8*1024; opts.o_num_bursts = 50; /* 5 sec */ opts.o_pause = 100; opts.o_quiet = 1; opts.o_quiet_equiv_opt = " -q "; opts.o_stat_pause = 2000; opts.o_Sndbuf_size = MIN_DEFAULT_SENDBUF_SIZE; o_Sndbuf_set = 1; break; case '4': test_num = 4; opts.o_burst_count = 5000; opts.o_loops = 1; opts.o_msg_len = 20; opts.o_num_bursts = 1; opts.o_pause = 1000; opts.o_quiet = 1; opts.o_quiet_equiv_opt = " -q "; opts.o_stat_pause = 2000; opts.o_Sndbuf_size = MIN_DEFAULT_SENDBUF_SIZE; o_Sndbuf_set = 1; break; case '5': test_num = 5; opts.o_burst_count = 50000; opts.o_loops = 1; opts.o_msg_len = 800; opts.o_num_bursts = 1; opts.o_pause = 1000; opts.o_quiet = 1; opts.o_quiet_equiv_opt = " -q "; opts.o_stat_pause = 2000; opts.o_Sndbuf_size = default_sndbuf_sz; o_Sndbuf_set = 0; break; case 'b': opts.o_burst_count = atoi(toptarg); break; case 'd': opts.o_decimal = 1; break; case 'h': help((&opts), NULL); exit(0); break; case 'l': opts.o_loops = atoi(toptarg); break; case 'm': opts.o_msg_len = atoi(toptarg); if (opts.o_msg_len > 65536) { opts.o_msg_len = 65536; mprintf((&opts), "warning, msg_len lowered to 65536\n"); } break; case 'n': opts.o_num_bursts = atoi(toptarg); break; case 'p': opts.o_pause = atoi(toptarg); break; case 'P': opts.o_msg_len = strlen(toptarg); if (opts.o_msg_len > 65536) { mprintf((&opts), "Error, payload too big\n"); exit(1); } if (opts.o_msg_len % 2 > 0) { mprintf((&opts), "Error, payload must be even number of hex digits\n"); exit(1); } opts.o_Payload = strdup(toptarg); opts.o_msg_len /= 2; /* num bytes worth of binary payload */ for (i = 0; i < opts.o_msg_len; ++i) { /* convert 2 hex digits to binary byte */ char c = opts.o_Payload[i*2]; if (c >= '0' && c <= '9') buff[i] = c - '0'; else if (c >= 'a' && c <= 'f') buff[i] = c - 'a' + 10; else if (c >= 'A' && c <= 'F') buff[i] = c - 'A' + 10; else { mprintf((&opts), "Error, invalid hex digit in payload\n"); exit(1); } c = opts.o_Payload[i*2 + 1]; if (c >= '0' && c <= '9') buff[i] = 16*buff[i] + c - '0'; else if (c >= 'a' && c <= 'f') buff[i] = 16*buff[i] + c - 'a' + 10; else if (c >= 'A' && c <= 'F') buff[i] = 16*buff[i] + c - 'A' + 10; else { mprintf((&opts), "Error, invalid hex digit in payload\n"); exit(1); } } break; case 'q': ++ opts.o_quiet; if (opts.o_quiet == 1) opts.o_quiet_equiv_opt = " -q "; else if (opts.o_quiet == 2) opts.o_quiet_equiv_opt = " -qq "; else opts.o_quiet = 2; /* never greater than 2 */ break; case 's': opts.o_stat_pause = atoi(toptarg); break; case 'S': opts.o_Sndbuf_size = atoi(toptarg); o_Sndbuf_set = 1; break; case 't': if (opts.o_unicast_udp) { mprintf((&opts), "Error, -t and -u are mutually exclusive\n"); exit(1); } opts.o_tcp = 1; break; case 'u': if (opts.o_tcp) { mprintf((&opts), "Error, -t and -u are mutually exclusive\n"); exit(1); } opts.o_unicast_udp = 1; break; default: usage((&opts), "unrecognized option"); exit(1); break; } /* switch */ } /* while opt */ /* prevent careless usage from killing the network */ if (opts.o_num_bursts == 0 && (opts.o_burst_count > 50 || opts.o_pause < 100)) { usage((&opts), "Danger - heavy traffic chosen with infinite num bursts.\nUse -n to limit execution time"); exit(1); } num_parms = argc - toptind; strcpy(equiv_cmd, "CODE BUG!!! 'equiv_cmd' not initialized"); /* handle positional parameters */ if (num_parms == 2) { opts.groupaddr = inet_addr(argv[toptind]); opts.groupport = (unsigned short)atoi(argv[toptind+1]); if (opts.o_quiet < 2) sprintf(equiv_cmd, "msend -b%d%s-m%d -n%d -p%d%s-s%d -S%d%s%s %s", opts.o_burst_count, (opts.o_decimal)?" -d ":" ", opts.o_msg_len, opts.o_num_bursts, opts.o_pause, opts.o_quiet_equiv_opt, opts.o_stat_pause, opts.o_Sndbuf_size, (opts.o_tcp) ? " -t " : ((opts.o_unicast_udp) ? " -u " : " "), argv[toptind],argv[toptind+1]); mprintf((&opts), "Equiv cmd line: %s\n", equiv_cmd); } else if (num_parms == 3) { char c; int i; opts.groupaddr = inet_addr(argv[toptind]); opts.groupport = (unsigned short)atoi(argv[toptind+1]); for (i = 0; (c = *(argv[toptind+2] + i)) != '\0'; ++i) { if (c < '0' || c > '9') { mprintf((&opts), "ERROR: third positional argument '%s' has non-numeric. Should be TTL.\n", argv[toptind+2]); exit(1); } } opts.ttlvar = (unsigned char)atoi(argv[toptind+2]); if (opts.o_quiet < 2) sprintf(equiv_cmd, "msend -b%d%s-m%d -n%d -p%d%s-s%d -S%d%s%s %s %s", opts.o_burst_count, (opts.o_decimal)?" -d ":" ", opts.o_msg_len, opts.o_num_bursts, opts.o_pause, opts.o_quiet_equiv_opt, opts.o_stat_pause, opts.o_Sndbuf_size, (opts.o_tcp) ? " -t " : ((opts.o_unicast_udp) ? " -u " : " "), argv[toptind],argv[toptind+1],argv[toptind+2]); printf("Equiv cmd line: %s\n", equiv_cmd); fflush(stdout); } else if (num_parms == 4) { opts.groupaddr = inet_addr(argv[toptind]); opts.groupport = (unsigned short)atoi(argv[toptind+1]); opts.ttlvar = (unsigned char)atoi(argv[toptind+2]); opts.bind_if = argv[toptind+3]; if (opts.o_quiet < 2) sprintf(equiv_cmd, "msend -b%d%s-m%d -n%d -p%d%s-s%d -S%d%s%s %s %s %s", opts.o_burst_count, (opts.o_decimal)?" -d ":" ", opts.o_msg_len, opts.o_num_bursts, opts.o_pause, opts.o_quiet_equiv_opt, opts.o_stat_pause, opts.o_Sndbuf_size, (opts.o_tcp) ? " -t " : ((opts.o_unicast_udp) ? " -u " : " "), argv[toptind],argv[toptind+1],argv[toptind+2],opts.bind_if); mprintf((&opts), "Equiv cmd line: %s\n", equiv_cmd); } else { usage((&opts), "need 2-4 positional parameters"); exit(1); } /* Only warn about small default send buf if no sendbuf option supplied */ if (default_sndbuf_sz < MIN_DEFAULT_SENDBUF_SIZE && o_Sndbuf_set == 0) mprintf((&opts), "NOTE: system default SO_SNDBUF only %d (%d preferred)\n", default_sndbuf_sz, MIN_DEFAULT_SENDBUF_SIZE); if (opts.o_tcp) { if((sock = socket(PF_INET,SOCK_STREAM,0)) == INVALID_SOCKET) { mprintf((&opts), "ERROR: "); perror((&opts), "socket"); exit(1); } } else { if((sock = socket(PF_INET,SOCK_DGRAM,0)) == INVALID_SOCKET) { mprintf((&opts), "ERROR: "); perror((&opts), "socket"); exit(1); } } /* Try to set send buf size and check to see if it took */ if (setsockopt(sock,SOL_SOCKET,SO_SNDBUF,(const char *)&opts.o_Sndbuf_size, sizeof(opts.o_Sndbuf_size)) == SOCKET_ERROR) { mprintf((&opts), "WARNING: "); perror((&opts), "setsockopt - SO_SNDBUF"); } sz = sizeof(check_size); if (getsockopt(sock,SOL_SOCKET,SO_SNDBUF,(char *)&check_size, (socklen_t *)&sz) == SOCKET_ERROR) { mprintf((&opts), "ERROR: "); perror((&opts), "getsockopt - SO_SNDBUF"); exit(1); } if (check_size < opts.o_Sndbuf_size) { mprintf((&opts), "WARNING: tried to set SO_SNDBUF to %d, only got %d\n", opts.o_Sndbuf_size, check_size); } memset((char *)&sin,0,sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = opts.groupaddr; sin.sin_port = htons(opts.groupport); if (! opts.o_unicast_udp && ! opts.o_tcp) { #if defined(_WIN32) wttl = opts.ttlvar; if (setsockopt(sock,IPPROTO_IP,IP_MULTICAST_TTL,(char *)&wttl, sizeof(wttl)) == SOCKET_ERROR) { mprintf((&opts), "ERROR: "); perror((&opts), "setsockopt - TTL"); exit(1); } #else if (setsockopt(sock,IPPROTO_IP,IP_MULTICAST_TTL,(char *)&opts.ttlvar, sizeof(opts.ttlvar)) == SOCKET_ERROR) { mprintf((&opts), "ERROR: "); perror((&opts), "setsockopt - TTL"); exit(1); } #endif /* _WIN32 */ } if (opts.bind_if != NULL) { #if !defined(_WIN32) memset((char *)&iface_in,0,sizeof(iface_in)); iface_in.s_addr = inet_addr(opts.bind_if); #else iface_in = inet_addr(opts.bind_if); #endif /* !_WIN32 */ if(setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (const char*)&iface_in, sizeof(iface_in)) == SOCKET_ERROR) { mprintf((&opts), "ERROR: "); perror((&opts), "setsockopt - IP_MULTICAST_IF"); exit(1); } } if (opts.o_tcp) { if((connect(sock,(struct sockaddr *)&sin,sizeof(sin))) == INVALID_SOCKET) { mprintf((&opts), "ERROR: "); perror((&opts), "connect"); exit(1); } } /* Loop the test "opts.o_loops" times (-l option) */ MAIN_LOOP: if (opts.o_num_bursts != 0) { if (opts.o_msg_len == 0) { if (opts.o_quiet < 2) { printf("Sending %d bursts of %d variable-length messages\n", opts.o_num_bursts, opts.o_burst_count); fflush(stdout); } } else { if (opts.o_quiet < 2) { printf("Sending %d bursts of %d %d-byte messages\n", opts.o_num_bursts, opts.o_burst_count, opts.o_msg_len); fflush(stdout); } } } /* 1st msg: give network hardware time to establish mcast flow */ if (test_num >= 0) sprintf(cmdbuf, "echo test %d, sender equiv cmd %s", test_num, equiv_cmd); else sprintf(cmdbuf, "echo sender equiv cmd: %s", equiv_cmd); if (opts.o_tcp) { send_rtn = send(sock,cmdbuf,strlen(cmdbuf)+1,0); } else { send_rtn = sendto(sock,cmdbuf,strlen(cmdbuf)+1,0,(struct sockaddr *)&sin,sizeof(sin)); } if (send_rtn == SOCKET_ERROR) { mprintf((&opts), "ERROR: "); perror((&opts), "send"); exit(1); } SLEEP_SEC(1); burst_num = 0; msg_num = 0; while (opts.o_num_bursts == 0 || burst_num < opts.o_num_bursts) { if (opts.o_pause > 0 && msg_num > 0) SLEEP_MSEC(opts.o_pause); /* send burst */ for (i = 0; i < opts.o_burst_count; ++i) { send_len = opts.o_msg_len; if (! opts.o_Payload) { if (opts.o_decimal) sprintf(buff,"Message %d",msg_num); else sprintf(buff,"Message %x",msg_num); if (opts.o_msg_len == 0) send_len = strlen(buff); } if (i == 0) { /* first msg in batch */ if (opts.o_quiet == 0) { /* not quiet */ if (opts.o_burst_count == 1) printf("Sending %d bytes\n", send_len); else printf("Sending burst of %d msgs\n", opts.o_burst_count); } else if (opts.o_quiet == 1) { /* pretty quiet */ printf("."); fflush(stdout); } /* else opts.o_quiet > 1; very quiet */ } send_rtn = sendto(sock,buff,send_len,0,(struct sockaddr *)&sin,sizeof(sin)); if (send_rtn == SOCKET_ERROR) { mprintf((&opts), "ERROR: "); perror((&opts), "send"); exit(1); } else if (send_rtn != send_len) { mprintf((&opts), "ERROR: sendto returned %d, expected %d\n", send_rtn, send_len); exit(1); } ++msg_num; } /* for i */ ++ burst_num; } /* while */ if (opts.o_stat_pause > 0) { /* send 'stat' message */ if (opts.o_quiet < 2) printf("Pausing before sending 'stat'\n"); SLEEP_MSEC(opts.o_stat_pause); if (opts.o_quiet < 2) printf("Sending stat\n"); sprintf(cmdbuf, "stat %d", msg_num); send_len = strlen(cmdbuf); send_rtn = sendto(sock,cmdbuf,send_len,0,(struct sockaddr *)&sin,sizeof(sin)); if (send_rtn == SOCKET_ERROR) { mprintf((&opts), "ERROR: "); perror((&opts), "send"); exit(1); } else if (send_rtn != send_len) { mprintf((&opts), "ERROR: sendto returned %d, expected %d\n", send_rtn, send_len); exit(1); } if (opts.o_quiet < 2) printf("%d messages sent (not including 'stat')\n", msg_num); } else { if (opts.o_quiet < 2) printf("%d messages sent\n", msg_num); } /* Loop the test "opts.o_loops" times (-l option) */ -- opts.o_loops; if (opts.o_loops > 0) goto MAIN_LOOP; CLOSESOCKET(sock); return(0); } /* main */
ptmr_t ctl_process_utt(const char *uttfile, int32 count, void (*func) (void *kb, utt_res_t * ur, int32 sf, int32 ef, char *uttid), void *kb) { char utterance_file[16384]; char uttid[4096]; const char *base; int32 i, c; int32 ts, newts; ptmr_t tm; utt_res_t *ur; ptmr_init(&tm); ur = new_utt_res(); base = path2basename(uttfile); /* strip_fileext() copies base to uttid. So, copying uttid to base * is redundant if strip_fileext() is not called. */ /* strip_fileext (base, uttid); strcpy (base, uttid); */ ts = -1; for (c = 0; c < count; c++) { /* Wait for uttfile to change from previous iteration */ for (i = 0;; i++) { newts = stat_mtime(uttfile); if ((newts >= 0) && (newts != ts)) break; if (i == 0) E_INFO("Waiting for %s, count %d, c %d\n", uttfile, count, c); SLEEP_SEC(1); } ts = newts; /* Form uttid */ sprintf(uttid, "%s_%08d", base, c); strncpy(utterance_file, uttfile, sizeof(utterance_file) - 1); utterance_file[sizeof(utterance_file) - 1] = 0; /* Process this utterance */ ptmr_start(&tm); if (func) { utt_res_set_uttfile(ur, utterance_file); (*func) (kb, ur, 0, -1, uttid); } ptmr_stop(&tm); E_INFO ("%s: %6.1f sec CPU, %6.1f sec Clk; TOT: %8.1f sec CPU, %8.1f sec Clk\n\n", uttid, tm.t_cpu, tm.t_elapsed, tm.t_tot_cpu, tm.t_tot_elapsed); ptmr_reset(&tm); } if (ur) free_utt_res(ur); return tm; }