[unix-pc.sources] unix-pc

doj@ihlpf.ATT.COM (James) (01/10/89)

I'm posting the source to WX, my IVRS/TIBS retriever for the unix-pc (7300),
since more people asked for it (ok.. 8) than I expected.  I'm cross-
posting to unix-pc sources because I think the same idea can be used
for other services by touch-tone phone, e.g., "paying bills by phone".

Basically, this uses the unix-pc's speaker, dialer, and windows/forms
to provide a interface allowing the user to enter text data and pick
item(s) from menus instead of having to translate everything to 12 keys.

This has hardcoded phone numbers for two Chicago-local FAA aviation weather 
services: IVRS (Interim Voice Reponse System) and TIBS (Telephone Information
Briefing Service). Change the numbers for you area or pay long distance bills!!
(NOTE: for TIBS, use (<EXIT> to hangup after the recorded message is played,
but before the real briefer comes on the line!!)

Send comments, bug reports, or enhancements to att!ihlpf!doj.

----------------------- cut here ---------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  ivrs.c makefile phone.c tibs.c wx.c
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'ivrs.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ivrs.c'\"
else
echo shar: Extracting \"'ivrs.c'\" \(4359 characters\)
sed "s/^X//" >'ivrs.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <tam.h>
X#include <menu.h>
X#include <form.h>
X#include <string.h>
X
X#define SW		79
X#define SA		72
X#define FT		38
X#define GF		43
X#define	IVRSPNUM	"7674800"
X
Xmitem_t wpc_items[] = {
X	"Surface Observations (SA)", M_MARKED, SA,
X	"Terminal Forecasts (FT)", M_MARKED, FT,
X	"Winds Aloft Forecasts (GF)", M_MARKED, GF,
X	0, 0, 0
X};
X
Xmenu_t wpc_menu = {
X	"IVRS Menu",
X	NULL,
X	"Use <MARK> and <ENTER> to pick one or more weather products.",
X	0, 1, 0, 0,
X	M_NOMOVE|M_NOHELP|M_NORESIZE,
X	{0},
X	0,0,0,0,0,
X	wpc_items,
X	wpc_items,
X	0,
X};
X
Xmitem_t type_items[] = {
X	"LOCID", 0, 0,
X	"TWEB", 0, 1,
X	0, 0, 0
X};
X
Xmenu_t type_menu = {
X	"IVRS Types",
X	0,
X	"Select IVRS Type",
X	0,1,0,0,
X	M_SINGLE,
X	{0},
X	0,0,0,0,0,
X	type_items,
X	type_items,
X	0
X};
X
Xfield_t locfields[] = {
X	"Identifier Type:", 0, 0, 16, 8, F_MONLY,
X	"LOCID ", &type_menu,
X	"Use <CMD> to chose Identifer Type",
X
X	"Identifier Name:", 1, 0, 16, 8, F_CLEARIT,
X	"      ", 0,
X	"Enter Location ID, TWEB Route Number (<ret> to end TWEBs), or y/n",
X
X	0,0,0,0,0,0,0,0,0
X};
X
Xform_t locform = {
X	"Location",
X	NULL,
X	0,0,0,
X	locfields,
X	&(locfields[1])
X};
X
X
Xfield_t hafields[] = {
X	"Hours from Now:", 0, 0, 16, 8, F_CLEARIT,
X	"        ", &type_menu,
X	"Enter Number of Hours from current time for winds aloft forcast.",
X
X	"Altitude:", 1, 0, 16, 8, F_CLEARIT,
X	"        ", 0,
X	"Enter altitude for winds aloft (hundreds of feet)",
X
X	0,0,0,0,0,0,0,0,0
X};
X
Xform_t haform = {
X	"Hours/Altitude",
X	NULL,
X	0,0,0,
X	hafields,
X	hafields
X};
X
Xivrs()
X{
X	int i;
X	int loc_ret;
X
X	/* go offhook and dial number
X	*/
X	poffhook();
X	pdial(IVRSPNUM);
X	sleep(14);
X
X	/* get into unprompted mode
X	*/
X	pdial("*6");
X
X	/* get location type (LOCID or TWEB route) from user
X	*/
X	form(&locform,M_BEGIN);
X	while(form(&locform,M_INPUT) == Enter) {
X
X		/* if TWEB, no translation required
X		*/
X		if (locform.f_fields->fl_menu->m_curi->mi_val == 1) {
X
X			/* check for blank location field
X			*/
X			for(i=0; locform.f_fields[1].fl_value[i]==' '; i++);
X
X			switch(locform.f_fields[1].fl_value[i]) {
X
X			/* if blank location field (user is done entering TWEBs)
X			 * send out TWEB request
X			*/
X			case '\0':
X				pdial("87##");
X				break;
X
X			/* else, see if this is an answer to yes/no question
X			*/
X			case 'y':
X				pdial("9##");
X				*(locform.f_fields[1].fl_value) = '\0';
X				break;
X			case 'n':
X				pdial("6##");
X				*(locform.f_fields[1].fl_value) = '\0';
X				break;
X
X			/* else, send out TWEB location, then zero out
X			 * and go back for another
X			*/
X			default:
X				pdial(locform.f_fields[1].fl_value);
X				*(locform.f_fields[1].fl_value) = '\0';
X				locform.f_curfl=&(locform.f_fields[1]);
X				pdial("#");
X				continue;
X			}
X		}
X
X		/* else, LOCID. get user's choice of weather products
X		*/
X		else {
X			xpdial(locform.f_fields[1].fl_value);
X
X			/* get user's pick of weather products
X			*/
X			menu(&wpc_menu,M_BEGIN);
X			if (menu(&wpc_menu,(M_INPUT|M_DESEL)) != Enter) {
X				menu(&wpc_menu,M_END);
X
X				/* "begin session" again message
X				*/
X				pdial("*2");
X				continue;
X			};
X			i = 0;
X
X			/* request for selected weather warnings (SW) always.
X			 * its easier than having to be asked..
X			*/ 
X			pdial("#79");
X
X			/* search through the list finding picked items
X			*/
X			while (wpc_menu.m_items[i].mi_name != NULL) {
X
X				/* search for the next marked item
X				*/
X				while ((wpc_menu.m_items[i].mi_name != NULL)
X				&& !(wpc_menu.m_items[i].mi_flags & M_MARKED)) i++;
X
X				/* if end of list, break out
X				*/
X				if (wpc_menu.m_items[i].mi_name == NULL) 
X					break;
X	
X				/* marked item found
X				*/
X				switch(wpc_menu.m_items[i].mi_val)  {
X				case SA:
X					pdial("#72");
X					break;
X				case FT:
X					pdial("#38");
X					break;
X				case GF:
X
X					/* winds aloft requires hours from
X					 * current time and desired altitude
X					*/
X					pdial("#43");
X					form(&haform,M_BEGIN|M_INPUT|M_END);
X					pdial("#");
X					pdial(haform.f_fields[0].fl_value);
X					pdial("#");
X					pdial(haform.f_fields[1].fl_value);
X					break;
X				default:
X					break;
X				}
X				i++;
X			}
X
X			/* end of marked weather products for this LOCID
X			*/
X			menu(&wpc_menu,M_END);
X			pdial("##");
X
X		/* end if TWEB or LOCID
X		*/
X		}
X
X	/* end while user is entering Locations (TWEBs or LOCIDs)
X	*/
X	}
X
X	/* get "terminate session" message, wait for response
X	*/
X	pdial("*8");
X	sleep(10);
X
X	/* kill form and hangup
X	*/
X	form(&locform,M_END);
X	phangup();
X}
END_OF_FILE
if test 4359 -ne `wc -c <'ivrs.c'`; then
    echo shar: \"'ivrs.c'\" unpacked with wrong size!
fi
# end of 'ivrs.c'
fi
if test -f 'makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'makefile'\"
else
echo shar: Extracting \"'makefile'\" \(217 characters\)
sed "s/^X//" >'makefile' <<'END_OF_FILE'
Xwx: wx.o ivrs.o tibs.o phone.o
X	cc -o wx wx.o ivrs.o tibs.o phone.o -l tam -l curses
Xwx.o: wx.c
X	cc -c wx.c
Xivrs.o: ivrs.c
X	cc -c ivrs.c
Xtibs.o: tibs.c
X	cc -c tibs.c
Xphone.o: phone.c makefile
X	cc -c -DPHTRACE phone.c
END_OF_FILE
if test 217 -ne `wc -c <'makefile'`; then
    echo shar: \"'makefile'\" unpacked with wrong size!
fi
# end of 'makefile'
fi
if test -f 'phone.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'phone.c'\"
else
echo shar: Extracting \"'phone.c'\" \(1916 characters\)
sed "s/^X//" >'phone.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <sys/phone.h>
X#include <fcntl.h>
X#define PHLINE "/dev/ph0"
X
Xint fd;
Xstruct updata phdata;
X
Xpoffhook()
X{
X#ifdef PHTRACE
X	printf("poffhook going offhook and turning speaker on\n");
X#endif
X#ifndef PHDEBUG
X	if((fd = open(PHLINE, O_RDONLY|O_RDWR|O_NDELAY)) == -1)
X		fprintf(stderr, "can't open phone\n");
X
X	if((ioctl(fd, PIOCGETP, &phdata)) != 0)
X		fprintf(stderr, "can't ioctl PIOCGETP\n");
X
X	phdata.c_feedback |= (unsigned short) SPEAKERON;
X
X	if((ioctl(fd, PIOCOFFHOOK, &phdata)) != 0)
X		fprintf(stderr, "can't ioctl PIOCOFFHOOK\n");
X	if((ioctl(fd, PIOCSETP, &phdata)) != 0)
X		fprintf(stderr, "can't ioctl PIOCSETP\n");
X#endif
X}
X
Xpdial(s)
Xchar *s;
X{
X#ifdef PHTRACE
X	printf("pdial dialing %s\n", s);
X#endif
X#ifndef PHDEBUG
X	while(*s != '\0') {
X		if((ioctl(fd, PIOCDIAL, s)) != 0)
X			fprintf(stderr, "can't ioctl PIOCDIAL\n");
X		s++;
X	}
X#endif
X}
X
Xxpdial(s)
Xchar *s;
X{
X	static char *codes[] = {
X		"a21", "b22", "c23",
X		"d31", "e32", "f33",
X		"g41", "h42", "i42",
X		"j51", "k52", "l53",
X		"m61", "n62", "o63",
X		"p71", "r72", "s73",
X		"t81", "u82", "v83",
X		"w91", "x82", "y83",
X		"q11", "z13", "000",
X		"101", "202", "303",
X		"404", "505", "606",
X		"707", "808", "909"
X	};
X
X	char buf[20];
X	char *c;
X	int i = 0;
X
X#ifdef PHTRACE
X	printf("xpdial gets %s\n", s);
X#endif
X
X	buf[0] = '\0';
X
X	while (*s != '\0') {
X
X		/* ignore out-of-range characters
X		*/
X		if(*s < 'a' && *s > 'z' && *s < '0' && *s > '9')
X			continue;
X
X		/* find the character in the static array
X		*/
X		i = -1;
X		while (*codes[++i] != *s) ;
X
X		/* concatenate all but the first char of the found entry
X		 * onto buf
X		*/
X		c = codes[i];
X		c++;
X		strcat(buf, c);
X
X		/* get next character in original string
X		*/
X		s++;
X	}
X
X
X	pdial(buf);
X}
X		
X
Xphangup()
X{
X#ifdef PHTRACE
X	printf("phangup hanging up\n");
X#endif
X#ifndef PHDEBUG
X	if((ioctl(fd, PIOCDISC, &phdata)) != 0) 
X		fprintf(stderr, "can't ioctl PIOCDISC\n");
X	close(fd);
X#endif
X}
END_OF_FILE
if test 1916 -ne `wc -c <'phone.c'`; then
    echo shar: \"'phone.c'\" unpacked with wrong size!
fi
# end of 'phone.c'
fi
if test -f 'tibs.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tibs.c'\"
else
echo shar: Extracting \"'tibs.c'\" \(960 characters\)
sed "s/^X//" >'tibs.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <tam.h>
X#include <menu.h>
X#include <string.h>
X
X#define TIBSPNUM	"18003225552"
X
Xchar *tibs_nums[] = {
X	"#*301",
X	"#*302",
X	"#*303",
X	"#*304",
X	"#*305",
X	"#*306"
X};
X
Xmitem_t tibs_items[] = {
X	"Adverse Conditions/Synopsis of the N IL, S WI and NE IN Area", 0, 0,
X	"Chicago, DuPage, IL Area (50 nautical mile Radius", 0, 1,
X	"Chicago - South Bend, IN Route", 0, 2,
X	"Chicago - Decatur, IL Route", 0, 3,
X	"Chicago - Rockford - Moline, IL Route", 0, 4,
X	"Chicago - Milwaukee, WI Route", 0, 5,
X	0,0,0
X};
X
Xmenu_t tibs_menu = {	"TIBS Menu:",
X			NULL,
X			"Choose an area.  Be sure to <EXIT> before a human answers",
X			0, 1, 0, 0,
X			M_SINGLE|M_NOMOVE|M_NOHELP|M_NORESIZE,
X			{0},
X			0,0,0,0,0,
X			tibs_items,
X			tibs_items,
X			0,
X};
X
Xtibs()
X{
X	poffhook();
X	pdial(TIBSPNUM);
X	
X	menu(&tibs_menu,M_BEGIN);
X	while (menu(&tibs_menu,(M_INPUT|M_DESEL)) == Enter)
X		pdial(tibs_nums[tibs_menu.m_curi->mi_val]);
X	menu(&tibs_menu,M_END);
X	phangup();
X}
END_OF_FILE
if test 960 -ne `wc -c <'tibs.c'`; then
    echo shar: \"'tibs.c'\" unpacked with wrong size!
fi
# end of 'tibs.c'
fi
if test -f 'wx.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'wx.c'\"
else
echo shar: Extracting \"'wx.c'\" \(722 characters\)
sed "s/^X//" >'wx.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <tam.h>
X#include <menu.h>
X#include <string.h>
X
Xmitem_t main_items[] = {
X	"TIBS (Telephone Information Briefing Service)", M_MARKED, 0,
X	"IVRS (Interim Voice Response System)", M_MARKED, 1,
X	0,0,0
X};
Xmenu_t main_menu = {	"WX - 1989 - D. O. James",
X			NULL,
X			"Choose a weather service",
X			0, 1, 0, 0,
X			M_SINGLE|M_NOMOVE|M_NOHELP|M_NORESIZE,
X			{0},
X			0,0,0,0,0,
X			main_items,
X			main_items,
X			0,
X};
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	winit();
X	wcreate(1,0,25,80,NBORDER);
X	keypad(0,1);
X
X	
X	menu(&main_menu,M_BEGIN);
X	while (menu(&main_menu,(M_INPUT|M_DESEL)) == Enter) {
X		if (main_menu.m_curi->mi_val == 0)
X			tibs();
X		else
X			ivrs();
X	}
X	menu(&main_menu,M_END);
X	wexit(0);
X}
END_OF_FILE
if test 722 -ne `wc -c <'wx.c'`; then
    echo shar: \"'wx.c'\" unpacked with wrong size!
fi
# end of 'wx.c'
fi
echo shar: End of shell archive.
exit 0