#include #include #include #include #include #include #include #include #define MAX_SEARCH_LENGTH 128 #define MAX_COMMAND_LENGTH 256 #define MAXLINE 512 #define AGI_STDIN_LENGTH 128 #define STDIN_VARCOUNT 18 struct variables { char name[AGI_STDIN_LENGTH]; char value[AGI_STDIN_LENGTH]; } agi_vars[STDIN_VARCOUNT]; int agiNow_setlanguage(const char *lang) { char res_line[MAXLINE]; printf("EXEC SET CHANNEL(language)=%s\n", lang); fgets(res_line, (int)sizeof(res_line), stdin); return 0; } int agiNow_getoption(long *endpos, const char *filename, const char *escdigits, const char *format, ...) { char line[MAXLINE]; char user_args[256]; va_list arg_pointer; int i, pos, res; char tmp[64]; va_start(arg_pointer, format); vsnprintf(user_args, sizeof(user_args), format, arg_pointer); va_end(arg_pointer); printf("GET OPTION %s \"%s\" %s\n", filename, escdigits, user_args); fgets(line, (int)sizeof(line), stdin); // Save value after result= as character string in tmp. for (i = 0, pos = strcspn(line, "=") + 1; (tmp[i] = line[pos]) != ' '; pos++, i++) ; tmp[++i] = '\0'; res = atoi(tmp); // Save position of next = character in pos while (line[pos] != '=') pos++; pos++; // Save value after endpos= as character string in tmp. for (i = 0; (tmp[i] = line[pos]) != '\0'; pos++, i++) ; tmp[++i] = '\0'; *endpos = atol(tmp); return res; } int agiNow_sayalpha(char *word, const char *escdigits) { int i, pos; char tmp[64]; char line[MAXLINE]; printf("SAY ALPHA \"%s\" \"%s\"\n", word, escdigits); fgets(line, (int)sizeof(line), stdin); // Save value after result= as character string in tmp. pos = ((int)strcspn(line, "=") + 1); for (i = 0; (tmp[i] = line[pos]) != '\n'; pos++, i++) ; tmp[++i] = '\0'; return atoi(tmp); } int agiNow_waitfordigit(int timeout) { char line[32]; fprintf(stdout, "WAIT FOR DIGIT %d\n", timeout); fgets(line, (int)sizeof(line), stdin); line[strlen(line)-1] = '\0'; strtok(line, "="); return atoi(strtok(NULL, "=")); } int agiNow_streamfile(long *endpos, const char *filename, const char *escdigits, const char *format, ...) { char line[MAXLINE]; char user_args[256]; va_list arg_pointer; int i, pos, res; char tmp[64]; va_start(arg_pointer, format); vsnprintf(user_args, sizeof(user_args), format, arg_pointer); va_end(arg_pointer); printf("STREAM FILE %s \"%s\" %s\n", filename, escdigits, user_args); fgets(line, (int)sizeof(line), stdin); // Save value after result= as character string in tmp. for (i = 0, pos = strcspn(line, "=") + 1; (tmp[i] = line[pos]) != ' '; pos++, i++) ; tmp[++i] = '\0'; res = atoi(tmp); // Save position of next = character in pos while (line[pos] != '=') pos++; pos++; // Save value after endpos= as character string in tmp. for (i = 0; (tmp[i] = line[pos]) != '\0'; pos++, i++) ; tmp[++i] = '\0'; *endpos = atol(tmp); return res; } int agiNow_verbose(char *msg, const char *format, ...) { char res_line[MAXLINE]; char user_args[256]; va_list arg_pointer; va_start(arg_pointer, format); vsnprintf(user_args, sizeof(user_args), format, arg_pointer); va_end(arg_pointer); printf("VERBOSE \"%s\" %s\n", msg, user_args); fgets(res_line, (int)sizeof(res_line), stdin); return 0; } int agiNow_get_word_from_user(char search_this[], int array_length) { int timeout = 60000, digit1_pressed, digit2_pressed, pos_in_search_this = 0; char tmp[3], word[8]; bool repeat = true; long endpos; --array_length; search_this[0] = '\0'; while (repeat) { if (pos_in_search_this == array_length) { // Say: You have reached the maximum allowed input length agiNow_streamfile(&endpos, "max-input-length-reached", "", ""); repeat = false; } else if (35 == (digit1_pressed = agiNow_waitfordigit(timeout))) { // User entered #. So he wants to confirm his entry. repeat = false; } else if (digit1_pressed == 42) { // User entered *. So he wants to delete last char in search_this. if (0 == strlen(search_this)) { // Say: No character available for deletion agiNow_streamfile(&endpos, "no_char_for_del", "", ""); } else { pos_in_search_this--; // Say: Deleted Character agiNow_streamfile(&endpos, "deleted_character", "", ""); snprintf(word, sizeof(word), "%c", search_this[pos_in_search_this]); agiNow_sayalpha(word, ""); search_this[pos_in_search_this] = '\0'; } } else if (('0' <= (char)digit1_pressed) && ('3' >= (char)digit1_pressed)) { bool entry_valid = true; digit2_pressed = agiNow_waitfordigit(timeout); tmp[0] = (char)digit1_pressed; tmp[1] = (char)digit2_pressed; tmp[2] = '\0'; if ((atoi(tmp) > 0) && (atoi(tmp) < 27)) { search_this[pos_in_search_this] = (char)atoi(tmp)+96; } else if (atoi(tmp) == 27) { // User wants to enter a-Umlaut search_this[pos_in_search_this] = (char)atoi(tmp)+201; } else if (atoi(tmp) == 28) { // User wants to enter o-Umlaut search_this[pos_in_search_this] = (char)atoi(tmp)+218; } else if (atoi(tmp) == 29) { // User wants to enter u-Umlaut search_this[pos_in_search_this] = (char)atoi(tmp)+223; } else if (atoi(tmp) == 30) { // User wants to enter szlig (sharp s) search_this[pos_in_search_this] = (char)atoi(tmp)+193; } else if (atoi(tmp) == 31) { // User wants to enter space search_this[pos_in_search_this] = (char)atoi(tmp)+1; } else { entry_valid = false; } if (entry_valid) { snprintf(word, sizeof(word), "%c", search_this[pos_in_search_this]); agiNow_sayalpha(word, ""); pos_in_search_this++; search_this[pos_in_search_this] = '\0'; entry_valid = false; } else { // Say: invalid number agiNow_streamfile(&endpos, "invalid-number", "", ""); } } else { // Say: invalid number agiNow_streamfile(&endpos, "invalid-number", "", ""); } } return 0; } int read_initial_agi_vars() { char c, line[256]; int line_pos, var_pos, struct_count = 0; while (strcmp(fgets(line, (int)sizeof(line), stdin), "\n")) { // Save the variable name in agi_vars[struct_count].name. for (line_pos = var_pos = 0; (c = line[line_pos]) != ':'; line_pos++, var_pos++) { agi_vars[struct_count].name[var_pos] = c; if ((AGI_STDIN_LENGTH-1) == var_pos) break; } var_pos++; agi_vars[struct_count].name[var_pos] = '\0'; // Skip colon and space. line_pos += 2; // Save the variable's value in agi_vars[struct_count].value for (var_pos = 0; (c = line[line_pos]) != '\n'; line_pos++, var_pos++) { agi_vars[struct_count].value[var_pos] = c; if ((AGI_STDIN_LENGTH-1) == var_pos) break; } var_pos++; agi_vars[struct_count].value[var_pos] = '\0'; // Save next line in the next struct in the array. struct_count++; } return 0; } char *agiNow_get_var(char *var) { int i; for (i = 0; i < STDIN_VARCOUNT; i++) { if (!strcmp(var, agi_vars[i].name)) { return agi_vars[i].value; } } return ""; } int main(int argc, char *argv[]) { FILE *tmp_file; char msg[256]; char search_this[MAX_SEARCH_LENGTH]; char command[MAX_COMMAND_LENGTH]; char file_name[64]; char file_name_without_ext[64]; long endpos; int res, lang = 0; bool repeat = true; setvbuf(stdout, (char *)NULL, (int)_IOLBF, 0); read_initial_agi_vars(); snprintf(msg, sizeof(msg), "Mmmh ... Lecker Anruf auf channel %s!", agiNow_get_var("agi_channel")); agiNow_verbose(msg, ""); res = agiNow_getoption(&endpos, "01", "12", "%d", 4000); while (repeat) { if ('1' == (char)res) { agiNow_setlanguage("de"); lang = 1; repeat = false; } else if ('2' == (char)res) { agiNow_setlanguage("en"); lang = 2; repeat = false; } else { res = agiNow_getoption(&endpos, "02", "12", "%d", 4000); } } agiNow_streamfile(&endpos, "03", "", ""); agiNow_streamfile(&endpos, "beep", "", ""); while(true) { repeat = true; while (repeat) { agiNow_get_word_from_user(search_this, MAX_SEARCH_LENGTH); if (0 == strlen(search_this)) { agiNow_streamfile(&endpos, "08", "", ""); agiNow_streamfile(&endpos, "beep", "", ""); } else { repeat = false; } } agiNow_streamfile(&endpos, "04", "", ""); sprintf(file_name_without_ext, "%s", tmpnam(NULL)); sprintf(file_name, "%s.wav", file_name_without_ext); if (2 == lang) { sprintf(command, "wikipedia2speech.php --lang=en --search=\"%s\" --file=%s", search_this, file_name); } else if (1 == lang) { sprintf(command, "wikipedia2speech.php --lang=de --search=\"%s\" --file=%s", search_this, file_name); } system(command); // If audiofile available play it back. Otherwise inform the // user that no article was found. if ((tmp_file = fopen(file_name, "r")) == NULL) { agiNow_streamfile(&endpos, "05", "", ""); } else { fclose(tmp_file); agiNow_streamfile(&endpos, file_name_without_ext, "#", ""); // Was the audiofile really played back? if (0 < endpos) { agiNow_streamfile(&endpos, "06", "", ""); } else { agiNow_streamfile(&endpos, "07", "", ""); } remove(file_name); } agiNow_streamfile(&endpos, "beep", "", ""); } return 0; }