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