en otra ventana

Anuncio
Apendice A
dialogue_serv.c
/*----------------------------------------------------------------------- *
*
*
*
CSLR Communicator Dialogue Manager
*
*
Hub Dialog Server Main
*
*
*
*
*
*
Wayne Ward ([email protected])
*
*
Center for Spoken Language Research
*
*
University of Colorado at Boulder
*
*
(c) 1999 All Rights Reserved
*
*
*
*----------------------------------------------------------------------- */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<unistd.h>
<string.h>
<ctype.h>
<malloc.h>
<fcntl.h>
<errno.h>
<signal.h>
<sys/wait.h>
<strings.h>
<math.h>
<pconf.h>
<parse.h>
<dm.h>
<dm_globals.h>
"task.h"
"task_glob_defs.h"
#include <galaxy/galaxy_all.h>
#define SERVER_FUNCTIONS_INCLUDE "server.h"
#define USE_SERVER_DATA
#include <galaxy/server_functions.h>
#define NO_RESPONSE_TIMEOUT 15000
void no_response_from_user(void *server_data);
extern char
*dir;
#define NL_QUE_LEN
10
typedef struct frame_que {
Gal_Frame
frame;
int
enable_input;
void
*sd;
}FrameQue;
struct frame_que nl_que[NL_QUE_LEN];
static int
enable_input_ok= 0;
static int
user_logged_on = 0;
static int
pricing = 0;
static Gal_Frame result_frame;
static Gal_Frame save_gf;
static struct db_query db_result;
char *ambiguity;
char *ambiguity_choices;
int ambiguity_leg;
static char
voice[LABEL_LEN];
/* Data Structure for Reading User Profiles */
struct user_profile{
char id_number[10];
char first_name[50];
char
char
char
char
char
char
char
last_name[50];
affiliation[100];
email[100];
phone_area[10];
phone_num[10];
seat_preference[10];
meal_preference[10];
char first_airline[10];
char second_airline[10];
char third_airline[10];
char air_select_first[10];
char air_select_second[10];
char air_select_t hird[10];
char
char
char
char
char
hotel_choice[10];
hotel_location[10];
hotel_rate[20];
hotel_amenity[10];
smoking[10];
char car_rental_company[10];
char car_rental_type[10];
};
struct user_profile current_user;
stru ct db_row *set_selection();
void build_dbq();
void build_price_sql();
void str2upper();
Gal_Frame package_db_data();
Gal_Frame package_leg_structure();
Gal_Frame package_air_legs();
void que_nl();
void play_que();
void get_stdin_parse();
void process_parse();
void log_session_end();
/* functions to implement script calls */
void play_scene( char *filename )
{
Gal_Frame f_new;
f_new = Gal_MakeFrame("main", GAL_CLAUSE);
Gal_SetProp(f_new, ":play_scene", Gal_IntObject(1));
Gal_SetProp(f_new, ":file", Gal_StringObject(filename));
}
void speak_text( char *arg)
{
sscanf(arg, "%s %[^;];", voice, prompt_text);
prompt= prompt_text;
nl_request("prompt_user", prompt, NULL, 1, main_server_data, voice);
prompt= (char *)0;
}
void prompt_key( c har *arg)
{
aFrame *frame;
char fname[LABEL_LEN],
kname[LABEL_LEN];
sscanf(arg, " %s %[^:]: %[^;];", voice, fname, kname);
if( !(frame= get_current_frame(fname)) ) {
if( !(frame= createFrame(fname)) ) return;
addFr ame(context, frame);
}
prompt= prompt_for_key(frame,kname, "data");
nl_request("prompt_user", prompt, NULL, 1, main_server_data, voice);
prompt= (char *)0;
}
void get_parse()
{
wait_for_parse= 1;
}
/*----------------------------------------------------------------------- *
* Routine which receives a parse from Phoenix from the Hub
*
*----------------------------------------------------------------------- */
Gal_Frame receive_parse(Gal_Frame f, void *server_data)
{
char *pars e_in;
/* input which was sent to Phoenix */
char *parse_out; /* output returned from Phoenix
*/
wait_for_parse= 0;
Gal_RemoveTimedTask(no_response_from_user, NULL);
/* get the input and output strings from Phoenix */
parse_in = Gal_GetString(f, ":parse_input");
parse_out = Gal_GetString(f, ":parse_output");
/* set up to return the result */
strcpy(parse_result.parse_in, parse_in);
strcpy(parse_result.parse_out, parse_out);
/* remove newline */
parse_result.parse_out[strlen(parse_result.parse_out)-1] = '\0';
prompt= (char *)0;
prompt_text[0]= (char)0;
action= (char *)0;
/*
if( !scmp("[cellphone]", prompted.key) ) {
prompt = "What are your travel plans?";*/
prompt = "Cuales son sus planes de viaje?";
prompted.key= (char *)0;
nl_request("prompt_user", prompt, NULL, 1, server_data, (char *)0);
return(f);
}
/* if no parse */
if( !scmp("No Parse", parse_result.parse_out) ) {
/*
prompt= "I don't understand";*/
prompt= "Perdon, no le entiendo";
nl_request("prompt_user", prompt, NULL, 1, server_data, (char *)0);
return(f);
}
task= (char *)0;
/*
/* extract information and set global variables */
if( extract_values(parse_result.parse_out) < 0 ) {
prompt= "I don't understa nd";*/
prompt= "Perdon, no le entiendo";
nl_request("prompt_user", prompt, NULL, 1, server_data, (char *)0);
return(f);
}
if( !task && focus ) set_task(focus->name);
/* merge extracted frames with current context frames */
merge _context(context, extracts);
if( focus ) action= focus->name;
action_switch(server_data);
return(f);
}
/*----------------------------------------------------------------------- *
* Routine which sends an NL generation request to the Hub
*
*----------------------------------------------------------------------- */
void nl_request(char *spch_act, char *prompt, char *task,
int enable_input_after_prompt, void *server_data, char *voice){
char prompt_string[5000];
char prompt_slot[100];
char speech_act[LINE_LEN];
Gal_Frame f_new, db_frame;
f_new = Gal_MakeFrame("main", GAL_CLAUSE);
Gal_SetProp(f_new, ":nl_request", Gal_IntObject(1));
if (!spch_act) return;
strcpy(speech_act, spch_act);
if( !scmp("summarize_alt", spch_act) ) strcpy(speech_act,"summarize");
if (strcmp(speech_act,"prompt_user")==0){
/* if filename */
if( *prompt == '<' ) {
sscanf(prompt, "<%[^>]", prompt_string);
Gal_SetProp(f_new, ":play_file", Gal_StringObject(prompt_string));
}
else {
strcpy(prompt_string, prompt);
str2upper(prompt_string);
Gal_SetProp(f_new, ":prompt", Gal_StringObject(prompt_string));
}
if( !prompted.frame || !prompted.key ) strc py(prompt_slot, "none");
else sprintf(prompt_slot, "%s.%s", prompted.frame->name, prompted.key);
Gal_SetProp(f_new, ":slot", Gal_StringObject(prompt_slot));
}
else if (strcmp(speech_act,"error_msg")==0){
strcpy(speech_act, "prompt_user");
strcpy(prompt_string, prompt);
str2upper(prompt_string);
Gal_SetProp(f_new, ":prompt", Gal_StringObject(prompt_string));
Gal_SetProp(f_new, ":error_msg", Gal_IntObject(1));
}
else if ((strcmp(speech_act, "summarize")==0) ) {
Gal_SetProp(f_new, ":task", Gal_StringObject(task));
db_frame = package_db_data(row_in_focus);
Gal_SetProp(f_new, ":db_info", Gal_FrameObject(db_frame));
Gal_SetProp(f_new, ":prepend_string", Gal_StringObject(prompt_text));
}
else if ((strcmp(speech_act, "summarize_price")==0) ) {
Gal_SetProp(f_new, ":task", Gal_StringObject(task));
db_frame = package_db_data(row_in_focus);
Gal_SetProp(f_new, ":db_info", Gal_FrameObject(db_frame));
prompt_text[0]= (char)0;
Gal_SetProp(f_new, ":prepend_string", Gal_StringObject(prompt_text));
}
else if ((strcmp(speech_act, "summarize_flight_segment")==0) ) {
Gal_SetProp(f_new, ":task", Gal_StringObject(task));
db_frame = package_db_dat a(row_in_focus);
Gal_SetProp(f_new, ":db_info", Gal_FrameObject(db_frame));
Gal_SetProp(f_new, ":prepend_string", Gal_StringObject(prompt_text));
}
else if( !strcmp(speech_act, "summarize_itinerary") ) {
db_frame = package_leg_structure();
Gal_SetProp(f_new, ":leg_structure", Gal_FrameObject(db_frame));
}
else if (strcmp(speech_act, "clarify")==0){
Gal_SetProp(f_new, ":ambiguity", Gal_StringObject(ambiguity));
Gal_SetProp(f_new,":ambiguity_choices",
Gal_StringObject(ambiguity_choices));
Gal_SetProp(f_new, ":ambiguity_leg", Gal_IntObject(ambiguity_leg));
}
else if (!strcmp(speech_act, "inquiry")){
Gal_SetProp(f_new, ":task", Gal_StringObject(task));
db_frame = package_db_data(row_in_focus);
Gal_SetProp(f_new, ":db_info", Gal_FrameObject(db_frame));
strcpy(prompt_string, prompt);
Gal_SetProp(f_new, ":prompt", Gal_StringObject(prompt_string));
}
else if (!strcmp(speech_act, "repeat")){
/* nothing needed h ere, copied in speech_act below */
printf("nl_request: repeat\n");
}
else if (!strcmp(speech_act, "send_email")){
db_frame = package_leg_structure();
Gal_SetProp(f_new, ":leg_structure", Gal_FrameObject(db_frame));
Gal_SetProp(f_new, ":email_address",Gal_StringObject(current_user.email));
Gal_SetProp(f_new, ":first_name",
Gal_StringObject(current_user.first_name));
Gal_SetProp(f_new, ":last_name",Gal_StringObject(current_user.last_name));
Gal_SetProp(f_new, ":user_id", Gal_StringObject(current_user.id_number));
Gal_SetProp(f_new, ":speech_act", Gal_StringObject(speech_act));
GalIO_CommWriteFrame(GalIO_GetUniqueConnection((GalIO_ServerStruct *)
main_server_data), f_new, 0);
return;
}
Gal_SetProp(f_new, ":speech_act", Gal_StringObject(speech_act));
if( audio_busy ){
que_nl(f_new, server_data, enable_input_after_prompt);
}
else {
audio_busy= 1;
enable_input_ok= enable_input_after_prompt;
GalIO_CommWriteFrame(GalIO_GetUniqueConnection((GalIO_ServerStruct *)
main_server_data), f_new, 0);
}
}
void price_request()
{
Gal_Frame f_new, gf;
pricing= 1;
build_price_sql(db_buf, main_server_data);
f_new = Gal_MakeFrame("main", GAL_CLAUSE);
gf= package_air_legs();
Gal_SetProp(f_new, ":db_info", Gal_FrameObject(gf));
Gal_SetProp(f_new, ":price_itinerary", Gal_IntObject(1));
Gal_SetProp(f_new, ":task", Gal_StringObject("air"));
Gal_SetProp(f_new, ":access_web", Gal_IntObject(2));
Gal_SetProp(f_new, ":db_query", Gal_StringObject(db_buf));
save_gf= f_new;
save_task= task;
save_prompted= prompted;
GalIO_CommWriteFrame(GalIO_GetUniqueConnection((GalIO_ServerStruct *)
main_server_data), f_new, 0);
}
/*----------------------------------------------------------------------- *
* No response dispatch function
*
*----------------------------------------------------------------------- */
void no_response_from_user(void *server_data){
Gal_Frame f_new, f_x;
printf("NO RESPONSE FROM USER\n"); fflush(stdout);
Gal_RemoveTimedTask(no_response_from_user, NULL);
/* send timeout event */
f_x = Gal_MakeFrame("main", GAL_CLAUSE);
Gal_SetProp(f_x, ":timeout", Gal_StringObject("no_response_from_user"));
GalIO_CommWriteFrame((GalIO_CommStruct *)server_data, f_x, 0);
f_new = Gal_MakeFrame("main", GAL_CLAUSE);
Gal_SetProp(f_new, ":nl_request", Gal_IntObject(1));
Gal_SetProp(f_new, ":speech_act", Gal_StringObject("repeat"));
enable_input_ok = 1;
GalIO_ CommWriteFrame((GalIO_CommStruct *)server_data, f_new, 0);
}
/*----------------------------------------------------------------------- *
* Routine which sends a database query request to the Hub
*
*----------------------------------------------------------------------- */
void query_database(sql_query, frame, server_data, access_web)
char *sql_query;
aFrame *frame;
void *server_data;
int access_web;
{
Gal_Frame f_new;
char
*val;
char
*leg;
aFrame
*f;
char
key[LINE_LEN];
int
xx;
/* build frame for db request */
f_new = Gal_MakeFrame("main", GAL_CLAUSE);
Gal_SetProp(f_new, ":access_web", Gal_IntObject(access_web));
Gal_SetProp(f_new, ":db_query", Gal_StringObject(sql_query));
Gal_SetProp(f_new, ":task", Gal_StringObject(task));
if( !strcmp(frame->name, "Air") ) {
if( !scmp("nine_best", airmode) ) {
for(f=getFrame(context, "Air", "first", &xx);f;
(f= getFrame(context, "Air", "next", &xx))){
if( !(val= getVal(f, "[web _query]")) ){
printf("no web query\n");fflush(stdout);
continue;
}
if( !(leg= getVal(f, "[leg_num]")) ) {
printf("no leg value\n");fflush(stdout);
continue;
}
printf("leg %s webq %s\n", l eg, val); fflush(stdout);
sprintf(key, ":leg%s", leg);
Gal_SetProp(f_new, key, Gal_StringObject(val));
}
Gal_SetProp(f_new, ":flights_by_schedule", Gal_IntObject(0));
}
else if( !pricing ) {
if( (val= getVal (frame, "[web_query]")) ) Gal_SetProp(f_new, ":leg1",
Gal_StringObject(val));
leg= getVal(frame, "[leg_num]");
xx= atoi(leg);
Gal_SetProp(f_new, ":leg_num", Gal_IntObject(xx));
Gal_SetProp(f_new, ":flights_by_schedule", Gal_IntObject(1));
}
}
else if( !strcmp(frame->name, "Hotel") ) {
if( (val= getVal(frame, "[web_query]")) )
Gal_SetProp(f_new, ":hotel", Gal_StringObject(val));
}
else if( !strcmp(frame->name, "Car") ) {
if( (val= getVal(frame, "[web_query]")) )
Gal_SetProp(f_new, ":car", Gal_StringObject(val));
}
/* save in case of retry */
save_task= task;
save_sql= sql_query;
save_frame= frame;
save_prompted= prompted;
save_gf= f_new;
/*
/* play hold on message */
if( !backoff_cnt ) {
prompt= "Please let me check availability and see what I can find";*/
prompt= "Dejeme verificar disponibilidad para ver que puedo encontrar";
nl_request("prompt_user", prompt, NULL, 0, server_data, (char *)0);
prompt= (char *)0;
}
/* send to hub */
GalIO_CommWriteFrame(GalIO_GetUniqueConnection((GalIO_ServerStruct *)
main_server_data), f_new, 0);
}
void retry_query()
{
Gal_Frame f_new;
if( !save_gf ) return;
f_new= save_gf;
/* send to hub */
GalIO_CommWriteFrame(GalIO_GetUniqueConnection((GalIO_ServerStruct *)
main_server_data), f_new, 0);
}
/*----------------------------------------------------------------------- *
* Routine which receives a database query result from the Hub
*
*----------------------------------------------------------------------- */
Gal_Frame receive_db_result(Gal_Frame f, void *server_data){
char *task;
char *frame_name;
int num_keys;
char **props;
inti;
int ambiguous_input =0;
intxx;
task = NULL;
db_rows= 0;
row_in_focus= -1;
/* get frame of db results */
result_frame = Gal_GetFrame(f, ":query_result");
/* check for ambiguity */
props = Gal_GetProperties(result_frame, &num_keys);
for(i=0;i<num_keys;i++){
if (strcmp(props[i],":ambiguity")==0){
ambiguity = Gal_GetString(result_frame, ":ambiguity");
ambiguity_choices = Gal_GetString(result_frame, ":ambiguity_choices");
ambiguity_leg = Gal_GetInt(result_frame, ":ambiguity_leg");
ambiguous_input = 1;
}
}
if (ambiguous_input){
nl_request("clarify",NULL,NULL,1,server_data, (char *)0);
return(f);
}
task = Gal_GetString(f, ":task");
if( !scmp("air", task) ) frame_name= "Air";
else if( !scmp("hotel", task) ) frame_name= "Hotel";
else if( !scmp("car", task) ) frame_name= "Car";
else frame_name= (char *)0;
db_result.num_rows = Gal_GetInt(result_frame, ":nfound");
printf("%d database records incoming\n", db_result.num_rows) ;
fflush(stdout);
db_rows= 0;
if( db_result.num_rows == -2) {
/*
prompt= "There was no response from the internet. Would you like me to try
again";*/
prompt= "No hubo respuesta de Internet, quiere que intente otra vez? ";
set_prompted( (aFrame *)0, "[retry]", "yes");
nl_request("prompt_user",prompt, NULL, 1, server_data, (char *)0);
return(f);
}
if( db_result.num_rows == -1 ) {
prompt= "The web site is not responding. Please call again later.";
prompt= "El sitio website no esta respondiendo, Porfavor llame otra vez mas tarde.
";
nl_request("error_msg",prompt, NULL, 1, server_data, (char *)0);
return(f);
}
db_rows= db_result.num_rows;
if( db_rows == 0 ) {
/* relax constraints and try again*/
if( !strcmp(task, "air") ) {
if( (backoff_cnt <2) && !pricing ) {
backoff_cnt++;
if( !scmp("nine_best", airmode) ) {
build_air(db_buf, server_data);
focus= getFrame(context, "Air", "first", &xx);
}
else {
if( data_current ) focus= data_current;
else focus= getFrame(context, "Air", "first", &xx);
build_dbq(db_buf, focus, server_data);
}
action= "data";
set_prompted( focus, "[accept]", "yes");
return(f);
}
/* if pricing itinerary */
if( pricing ) {
pricing= 0;
/*
prompt= "Prices for these flights are not currently available. Please
call the airline company directly for pricing information."; */
prompt= "Los precios de las lineas aereas no estan disponibles por el
momento, porfavor llame directamente a la linea aerea para obtener esta informacion .";
nl_request("error_msg",prompt, NULL, 1, server_data, (char *)0);
prompt= (char *)0;
action_switch( main_server_data);
return(f);
}
/*
strcpy(prompt_text, "No records satisfy your request.");*/
strcpy(prompt_text, "No hay registros que cumplan con sus preferencias.");
strcat(prompt_text,
" Would you like to depart on a different date?");*/
" Quiere salir en una fecha diferente?");
/*
backoff_cnt= 0;
backoff_tried= 1;
focus= getFrame(context, "Air", "first", &xx);
prompted.frame= focus;
prompted.key= "[date_str]";
nl_request("prompt_user",prompt_text, NULL, 1, server_data, (char *)0);
data_current= (aFrame *)0;
return(f);
}
else if( !strcmp(task, "hotel") ) {
strcpy(prompt_text, "No records satisf y your request.");*/
strcpy(prompt_text, "No hay registros que cumplan con sus preferencias.");
/*
strcat(prompt_text,
" Would you like to try a different hotel?");*/
" Le gustaria intentar con un hotel diferente ? ");
/*
if( data_current ) focus= data_current;
else if(!scmp("Hotel", prompted.frame->name)) focus= prompted.frame;
else focus= getFrame(context, "Hotel", "last", &xx);
prompted.frame= focus;
prompted.key= "[Hotel_Name]";
backoff_tried= 1;
nl_request("prompt_user",prompt_text, NULL, 1, server_data, (char *)0);
data_current= (aFrame *)0;
return(f);
}
else if( !strcmp(task, "car") ) {
strcpy(prompt_text, "No records satisfy your request.");*/
strcpy(prompt_text, "No hay registros que cumplan con sus preferencias.");
/*
strcat(prompt_text,
" Would you like to try a different company?");*/
" Le gustaria intentar con una compania diferente");
if( data_current ) focus= data_current;
else if(!scmp("Car", prompted.frame->name)) focus= prompted.frame;
else focus= getFrame(context, "Car", "last", &xx);
prompted.frame= focus;
prompted.key= "[Rental_Company]";
backoff_tried= 1;
nl_request ("prompt_user",prompt_text, NULL, 1, server_data, (char *)0);
data_current= (aFrame *)0;
return(f);
/*
}
}
/* if we get here, must have some data */
printf("%d database records received\n", db_result.num_rows);
row_in_focus= 0;
/* unpack the returned data */
{
int i, r, c, nrows, ncols;
Gal_Object *column_list, *row, *records;
/* put the column headings into the data structure */
column_list = Gal_GetList(result_frame, ":column_names", &ncols);
db_result.num_cols = ncols;
for(i=0;i<ncols;i++){
strcpy(db_result.headings[i], Gal_StringValue(column_list[i]));
}
/* get the rows placed into the data structure */
records = Gal_GetList(result_frame, ":values", &nrows);
for(r=0;r<nrows;r++){
row = Gal_ListValue(records[r], 0);
for(c=0;c<ncols;c++)
strcpy(db_result.item[r][c], Gal_StringValue(row[c]));
}
printf("%d database records received\n", db_result.num_rows);
}
/* generate prompt string */
prompt_text[0]= (char) 0; /* clear prepend string */
if( !(strcmp(task, "air")) ) {
if( backoff_cnt ) {
strcpy(prompt_text,
/*
"Though I wasn't able to find any flights meeting your
");*/
"Lo siento pero no pude encontrar ningun registro que
con sus preferencias ");
/*
strcat(prompt_text,"Here is a list of closest options.
strcat(prompt_text,"Aqui hay una lista de las opciones
exact requirements
cumpla exactamente
");*/
mas cercanas. ");
}
else if( row_in_focus == 0 ) {
if( db_rows > 1 ) sprintf(prompt_text,
"I found %d flights meeting your requirements.", db_rows);*/
"Encontre %d vuelos que cumplen sus restricciones ", db_rows);
else sprintf(prompt_text, "1 OPTION WAS RETURNED. ");*/
else sprintf(prompt_text, "Solo encontre una opcion ");
/*
/*
}
}
/* set frame in focus */
if( !(focus= data_current) ) {
if( frame_name ) focus= getFrame(context, frame_name, "first", &xx);
}
/* set prompted to accept */
if( focus ) {
one_row= set_selection(focus, row_in_focus);
if( scmp("summarize_price", nl_task) )
set_prompted(focus, "[accept]", "yes");
}
/* send to nlg server for output */
if( !nl_task ) nl_task= "summarize";
nl_request(nl_task, NULL, task, 1, server_data, (char *)0);
/* if pricing info */
if( !scmp("summarize_price", nl_task) ) {
/* clear pricing flag */
pricing= 0;
if( offer_alts && (db_rows > 1) ) {
prompt= "I have priced the cheapest alternative. Would you like to hear it?";
/*
prompt= "I have priced the cheapest alternative. Would you like to hear
it?";*/
set_prompted( (aFrame *)0, "_alternates", "yes");
}
else data_current= (aFrame *)0;
nl_task= (char *)0;
action_switch( main_server_data);
}
backoff_cnt= 0;
backoff_tried= 0;
return(f);
}
/*----------------------------------------------------------------------- *
* Routine which ends the session
*
*------- ---------------------------------------------------------------- */
void hangup_phone(void *server_data){
Gal_Frame f_new = Gal_MakeFrame("audio", GAL_CLAUSE);
Gal_SetProp(f_new, ":call_finished", Gal_IntObject(1));
GalIO_CommWriteFrame(GalIO_GetUniqueConnection((GalIO_ServerStruct *)
main_server_data), f_new, 0);
Gal_RemoveTimedTask(no_response_from_user, NULL);
}
/*----------------------------------------------------------------------- *
* server reinitialization routine. This is called on ce the server is
*
* started.
*
*----------------------------------------------------------------------- */
Gal_Frame reinitialize(Gal_Frame f, void *server_data)
{
printf("Resetting dm\n"); fflush(stdout);
Gal_RemoveTimedTask(no_response_from_user, NULL);
enable_input_ok = 0;
user_logged_on = 0;
reset_dm();
reset_task();
return(f);
}
Gal_Frame start_task(Gal_Frame f, void *server_data)
{
enable_input_ok = 0;
user_logged_on = 0;
reset_dm();
reset_task();
return(f);
}
void *init_server(Gal_Server *s, int argc, char **argv)
{
main_server_data = s;
config(argc, argv);
init_dm(dir);
return (void *) NULL;
}
/*----------------------------------------------------------------------- *
* Routine which *
*----------------------------------------------------------------------- */
Gal_Frame notify_playing_has_ended(Gal_Frame f, void *server_data){
int uid;
Gal_Frame f_new;
int enable_input;
/* if session done, log to hub */
if( session_done && !session_done_logged ) {
log_session_end(server_data);
session_done_logged= 1;
}
audio_busy= 0;
/* if frame queued for nlg */
if(nl_que[0].sd) { enable_input= 0;}
else enable_input= enable_input_ok;
if( enable_input ) {
uid = Gal_GetInt(f, ":utterance_id");
f_new = Gal_MakeFrame("main", GAL_CLAUSE);
Gal_SetProp(f_new, ":enable_input_ok", Gal_IntObject(enable_input));
Gal_SetProp(f_new, ":user_logged_on", Gal_IntObject(user_logged_on));
Gal_SetProp(f_new, ":utterance_id", Gal_IntObject(uid));
GalIO_CommWriteFrame(GalIO_GetUniqueConnection((GalIO_ServerStruct *)
main_server_data), f_new, 0);
Gal_AddTimedTask(no_response_from_user, (void *) GalSS_EnvComm((GalSS_Environment
*)server_data), NO_RESPONSE_TIMEOUT);
}
if(nl_que[0].sd) play_que();
return(f);
}
/*----------------------------------------------------------------------- *
* Puts column names from header and puts them in a list object.
*
*----------------------------------------------------------------------- */
Gal_Object build_column_list(){
int i;
Gal_Object colnames[MAX_COLS];
Gal_Object collist;
for(i=0;i<db_result.num_cols;i++)
colnames[i] = Gal_StringObject(db_result.headings[i]);
collist = Gal_ListObject(colnames, db_result.num_cols);
return(collist);
}
/*----------------------------------------------------------------------- *
* Puts column info from ith row into a list object.
*
*----------------------------------------------------------------------- */
Gal_Object list_from_line(int i){
Gal_Object no[MAX_COLS], nf;
int j;
for(j=0;j<db_result.num_cols;j++)
no[j] = Gal_StringObject(db_result.item[i][j]);
nf = Gal_L istObject(no, db_result.num_cols);
return(nf);
}
/*----------------------------------------------------------------------- *
* This routine packs up the DB information so that it can be sent as a *
* frame to the NL server
*
*----------------------------------------------------------------------- */
Gal_Frame package_db_data(int row_in_focus){
int nlines, i;
Gal_Frame nf;
Gal_Object column_list;
Gal_Object tlist[MAX_ROWS];
nlines = 0;
nf = Gal_MakeFrame("result", GAL_CLAUSE);
column_list = build_column_list();
for(i=0;i<db_result.num_rows;i++){
tlist[nlines++]= list_from_line(i);
}
Gal_SetProp(nf,":column_names", column_list);
Gal_SetProp(nf,":nrows",Gal_IntObject(db_result.num_rows));
Gal_SetProp(nf,":ncols",Gal_IntObject(db_result.num_cols));
Gal_SetProp(nf,":row_in_focus",Gal_IntObject(row_in_focus));
if (nlines > 0) Gal_SetProp(nf,":values",Gal_ListObject(tlist,nlines));
return(nf);
}
/*------- ---------------------------------------------------------------- *
* This routine packages up the internal "leg" structure and prepares a *
* frame to be transmitted to the NL server.
*
*----------------------------------------------------------------------- */
Gal_Frame package_db_row(struct db_row *row, char *name){
Gal_Frame nf;
int ncols, j;
Gal_Object tlist[MAX_ROWS];
Gal_Object column_list, no[MAX_COLS], colnames[MAX_COLS];
nf = Gal_MakeFrame(name, GAL_CLAUSE);
ncols = row->num_cols;
for(j=0;j<ncols;j++)
colnames[j] = Gal_StringObject(row->headings[j]);
column_list = Gal_ListObject(colnames, ncols);
for(j=0;j<ncols;j++)
no[j] = Gal_StringObject(row->item[j]);
tlist[0]= Gal_ListO bject(no, ncols);
Gal_SetProp(nf,":column_names", column_list);
Gal_SetProp(nf,":nrows",Gal_IntObject(1));
Gal_SetProp(nf,":ncols",Gal_IntObject(ncols));
Gal_SetProp(nf,":values",Gal_ListObject(tlist,1));
return(nf);
}
/*----------------------------------------------------------------------- *
* This routine packages up the internal "leg" structure and prepares a *
* frame to be transmitted to the NL server.
*
*------------------------------------------------ ----------------------- */
Gal_Frame package_leg_structure(){
char name[50];
Gal_Frame nf, nf2;
aFrame *f;
char *val;
struct db_row *dbrow;
inti,
xx;
nf = Gal_MakeFrame("main", GAL_CLAUSE);
i=1;
for(f=getFrame(context, "Car", "first", &xx);f;
(f= getFrame(context, "Car", "next", &xx)), i++){
dbrow= (struct db_row *) getVal(f, "[selection]");
if (dbrow != NULL){
if( !(val= getVal(f, "[leg_num]")) ) {
sprintf(name, ":leg_%d_car", i);
}
else sprintf(name, ":leg_%s_car", val);
nf2 = package_db_row(dbrow, name);
Gal_SetProp(nf, name, Gal_FrameObject(nf2));
}
}
i=1;
for(f=getFrame(context, "Hotel", "first", &xx);f;
(f= getFrame(context, "Hotel", "next", &xx)), i++){
dbrow= (struct db_row *) getVal(f, "[selection]");
if ( dbrow != NULL){
if( !(val= getVal(f, "[leg_num]")) ) {
sprintf(name, ":leg_%d_hotel", i);
}
else sprintf(name, ":leg_%s_hotel", val);
nf2 = package_db_row(dbrow, name);
Gal_SetProp(nf, name, Gal_FrameObject(nf2));
}
}
for(f=getFrame(context, "Air", "first", &xx);f;
(f= getFrame(context, "Air", "next", &xx))){
dbrow= (struct db_row *) getVal(f, "[selection]");
if ( dbrow != NULL){
sprintf(name, ":leg_%d_air", 1);
nf2 = package_db_row(dbrow, name);
Gal_SetProp(nf, name, Gal_FrameObject(nf2));
}
break;
}
return(nf);
}
Gal_Frame package_air_legs(){
Gal_Frame nf;
aFrame *f;
struct db_row *dbrow;
inti,
j,
xx;
i=0;
for(f=getFrame(context, "Air", "first", &xx);f;
(f= getFrame(context, "Air", "next", &xx))){
dbrow= (struct db_row *) getVal(f, "[selection]");
for( j=0; j < dbrow->num_cols; j++) strcpy(db_result.item[i][j], dbrow->item[j]);
db_result.num_cols= dbrow ->num_cols;
i++;
}
db_result.num_rows= i;
nf= package_db_data(0);
return(nf);
}
/*----------------------------------------------------------------------- *
* This routine unpacks a db result frame into a matrix
*
* ----------------------------------------------------------------------- */
void unpack_db_data( ){
Gal_Object *column_list, *row;
Gal_Object *records;
int
i, r, c, nrows, ncols;
/* put the column headings into the d ata structure */
column_list = Gal_GetList(result_frame, ":column_names", &ncols);
db_result.num_cols = ncols;
for(i=0;i<ncols;i++){
strcpy(db_result.headings[i], Gal_StringValue(column_list[i]));
}
/* get the rows placed into the data structure */
records = Gal_GetList(result_frame, ":values", &nrows);
for(r=0;r<nrows;r++){
row = Gal_ListValue(records[r], 0);
for(c=0;c<ncols;c++)
strcpy(db_result.item[r][c], Gal_StringValue(row[c]));
}
}
/*----------------------------------------------------------------------- *
* Converts a string to uppercase
*
*----------------------------------------------------------------------- */
void str2upper(char *text){
int i, len;
len = strlen(text);
if (text == NULL) return;
for(i=0;i<len;i++){
if ((text[i] >= 'a') && (text[i] <= 'z'))
text[i] = 'A' + text[i] - 'a';
}
}
/*----------------------------------------------------------------------- *
* Routine which logs the end of the session
*
*----------------------------------------------------------------------- */
void log_session_end(void *server_data){
Gal_Frame f_new = Gal_MakeFrame("main", GAL_CLAUSE);
Gal_SetProp(f_new, ":end_task", Gal_IntObject(1));
GalIO_CommWriteFrame(GalIO_GetUniqueConnection((GalIO_ServerStruct *)
main_server_data), f_new, 0);
}
/*----------------------------------------------------------------------- *
* Routine which receives the user profile values from the hub
*
*----------------------------------------------------------------------- */
Gal_Frame receive_profile(Gal_Frame f, void *server_data){
char *stmp;
Gal_Frame f_new;
stmp = Gal_GetString(f, ":user_idnum");
strcpy (current_user.id_number, stmp);
stmp = Gal_GetString(f, ":first_name");
strcpy(current_user.first_name, stmp);
stmp = Gal_GetString(f, ":last_name");
strcpy(current_user.last_name, stmp);
stmp = Gal_GetString(f, ":affiliation");
strcpy(current_user.affiliation, stmp);
stmp = Gal_GetString(f, ":email");
strcpy(current_user.email, stmp);
stmp = Gal_GetString(f, ":phone_area");
strcpy(current_user.phone_area,stmp);
stmp = Gal_GetString(f, ":phone_num");
strcpy(current_user.phone_num, stmp);
stmp = Gal_GetString(f, ":seat_preference");
strcpy(current_user.seat_preference, stmp);
stmp = Gal_GetString(f, ":meal_preference");
strcpy(current_user.meal_preference, stmp);
stmp = Gal_GetString(f, ":first_airline");
strcpy(current_user.first_airline, stmp);
stmp = Gal_GetString(f, ":second_airline");
strcpy(current_user.second_airline, stmp);
stmp = Gal_GetString(f, ":third_airline");
strcpy(current_user.third_airline, stmp);
stmp = Gal_GetString(f, ":air_select_first");
strcpy(current_user.air_select_first, stmp);
stmp = Gal_GetString(f, ":air_select_second");
strcpy(current_user.air_select_second, stmp);
stmp = Gal_GetString(f, ":air_select_third");
strcpy(current_user.air_select_third, stmp);
stmp = Gal_GetString(f, ":hotel_choice");
strcpy(current_user.hotel_choice, stmp);
stmp = Gal_GetString(f, ":hotel_location");
strcpy(current_user.hotel_location, stmp);
stmp = Gal_GetString(f, ":hotel_rate");
strcpy(current_user.hotel_rate, stmp);
stmp = Gal_GetString(f, ":hotel_amenity");
strcpy(current_user.hotel_amenity, stmp);
stmp = Gal_GetString(f, ":smoking");
strcpy(current_user.smoking, stmp);
stmp = Gal_GetString(f, ":car_rental_company");
strcpy(current_user.car_rental_company, stmp);
stmp = Gal_GetString(f, ":car_rental_type");
strcpy(current_user.car_rental_type, stmp);
user_logged_on = 1;
/* send start_task signal */
f_new = Gal_MakeFrame("main", GAL_CLAUSE);
Gal_SetProp(f_new, ":start_task", Gal_IntObject(1));
GalIO_CommWriteFrame(GalIO_GetUniqueConnection((GalIO_ServerStruct *)
main_server_data), f_new, 0);
/* generate initial prompt */
/*
strcpy(prompt_text, "Please remember to speak after the tone. If you get confused at
any point you can say start over to cancel your current itinerary. Are you calling from a
cellular phone?");*/
strcpy(prompt_text, "Por favor recuerde hablar despues del beep. Si en algun momento
usted se pierde en la conversacion puede decir start over para cancelar el plan actual.
Esta usted hablando desde un telefono celular ?");
prompt= prompt_text;
set_prompted( (aFrame *)0, "[cellphone]", "yes");
enable_input_ok= 1;
nl_request("prompt_user", prompt, NULL, 1, server_data, (char *)0);
return(f);
}
/*----------------------------------------------------------------------- *
* Malloc routine for char ** structure
*
*----------------------------------------------------------------------- */
void cCreateMatrix(char ***m, int a, int b){
int
i;
*m = (char **) malloc( sizeof(char *) * a );
for (i = 0; i < a; i++){
(*m)[i] = (char *) malloc( sizeof(char) * b );
}
}
void cFreeMatrix(char **m, int a){
int
i;
for (i = 0; i < a; i++)
free(m[i]);
free(m);
}
/*----------------------------------------------------------------------- *
* Routine to free up a row structure
*
*----------------------------------------------------------------------- */
void free_db_row(struct db_row *row){
cFreeMatrix(row->headings, MAX_COLS);
cFreeMatrix(row->item, MAX_COLS);
free(row);
}
/*----------------------------------------------------------------------- *
* Routine to copy a row to a db_row structure
*
*----------------------------------------------------------------------- */
struct db_row * copy_db_row(int row_index){
struct db_row *row;
int i;
row = (struct db_row *)malloc(sizeof(struct db_row));
row->num_cols = db_result.num_cols;
cCreateMatrix(&(row ->headings), MAX_COLS, MAX_STR_LENGTH);
cCreateMatrix(&(row ->item), MAX_COLS, MAX_STR_LENGTH);
for(i=0;i<row->num_cols;i++){
strcpy(row->headings[i], db_result.headings[i]);
strcpy(row->item[i], db_result.item[row_index][i]);
}
return(row);
}
/*----------------------------------------------------------------------- *
* Routine which returns the column string information in the "out"
*
* variable given a particular DB row and column heading.
*
*----------------------------------------------------------------------- */
void get_column_info(struct db_row *row, char *heading_name, char *out){
int index;
for(index=0;index<row->num_cols;index++)
if (!strcmp(row->headings[index], heading_name)) break;
if (index == row->num_cols) out[0] = ' \0';
else strcpy(out,row ->item[index]);
}
void get_col_info(int row, char *heading_name, char *out)
{
struct db_row *one_row;
out[0]= ' \0';
if( row >= db_rows ) return;
one_row = copy_db_row(row);
get_column_info(one_row, heading_name, out);
free_db_row(one_row);
}
struct db_row *set_selection(aFrame *frame, int row)
{
struct db_row *one_row;
char *s;
char **kp;
if( !(kp=getKeyPtr(frame, "[selection]")) ) return( (struct db_row *)0 );
one_row = copy_db_row(row);
/* copy row into struct */
if( (s= getVal(frame, "[selection]")) ) free_db_row( (struct db_row *) s);
*kp= (char *) one_row;
return(on e_row);
}
void que_nl( Gal_Frame frame, void *server_data, int enable_input)
{
int i;
for( i=0; i < 10; i++) if( !nl_que[i].sd ) break;
if( i >= 10) return;
nl_que[i].frame= frame;
nl_que[i].sd= server_data;
nl_que[i].enable_input= enable_input;
}
void play_que()
{
int i;
if( !nl_que[0].sd ) return;
audio_busy= 1;
enable_input_ok= nl_que[0].enable_input;
GalIO_CommWriteFrame(GalIO_GetUniqueConnection((GalIO_ServerStruct *)
main_server_data), nl_que[0].frame, 0);
nl_que[0].sd= (void *)0;
for( i=1; i < NL_QUE_LEN; i++) {
nl_que[i-1]= nl_que[i];
if( !nl_que[i].sd ) break;
}
}
void reset_dmserver()
{
int i;
audio_busy= 0;
for(i=0; i < NL_QUE_LEN; i++) nl_que[i].sd= (void *)0;
pricing= 0;
}
Documentos relacionados
Descargar