summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES22
-rw-r--r--apps/app_voicemail.c253
-rw-r--r--main/say.c543
3 files changed, 787 insertions, 31 deletions
diff --git a/CHANGES b/CHANGES
index 652f50890..aa2d8a1d4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -53,6 +53,28 @@ JACK_HOOK
* The JACK_HOOK function now supports audio with a sample rate higher than
8kHz.
+Say
+------------------
+ * The 'say' family of dialplan applications now support the Japanese
+ language. The 'language' parameter in say.conf now recognizes a setting of
+ 'ja', which will enable Japanese language specific mechanisms for playing
+ back numbers, dates, and other items.
+
+VoiceMail
+------------------
+ * VoiceMail and VoiceMailMain now support the Japanese language. The
+ 'language' parameter in voicemail.conf now recognizes a setting of 'ja',
+ which will enable prompts to be played back using a Japanese grammatical
+ structure. Additional prompts are necessary for this functionality,
+ including:
+ - jb-arimasu: there is
+ - jb-arimasen: there is not
+ - jb-oshitekudasai: please press
+ - jb-ni: article ni
+ - jb-ga: article ga
+ - jb-wa: article wa
+ - jb-wo: article wo
+
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 12.3.0 to Asterisk 12.4.0 ------------
------------------------------------------------------------------------------
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index d392dd515..6adbb5461 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -755,6 +755,15 @@ For vm_intro_it:
\arg \b vm-vecchio old
\arg \b vm-vecchi old plural
+Japanese requires the following additional soundfile:
+\arg \b jp-arimasu there is
+\arg \b jp-arimasen there is not
+\arg \b jp-oshitekudasai please press
+\arg \b jp-ni article ni
+\arg \b jp-ga article ga
+\arg \b jp-wa article wa
+\arg \b jp-wo article wo
+
Chinese (Taiwan) requires the following additional soundfile:
\arg \b vm-tong A class-word for call (tong1)
\arg \b vm-ri A class-word for day (ri4)
@@ -7579,6 +7588,34 @@ static int get_folder(struct ast_channel *chan, int start)
return d;
}
+/* Japanese Syntax */
+static int get_folder_ja(struct ast_channel *chan, int start)
+{
+ int x;
+ int d;
+ char fn[256];
+ for (x = start; x< 5; x++) { /* For all folders */
+ if ((d = ast_say_number(chan, x, AST_DIGIT_ANY, ast_channel_language(chan), (char *) NULL))) {
+ return d;
+ }
+ snprintf(fn, sizeof(fn), "vm-%s", mbox(NULL, x)); /* Folder name */
+ d = vm_play_folder_name(chan, fn);
+ if (d) {
+ return d;
+ }
+ d = ast_waitfordigit(chan, 500);
+ if (d) {
+ return d;
+ }
+ }
+ d = ast_play_and_wait(chan, "vm-tocancel"); /* "or pound to cancel" */
+ if (d) {
+ return d;
+ }
+ d = ast_waitfordigit(chan, 4000);
+ return d;
+}
+
/*!
* \brief plays a prompt and waits for a keypress.
* \param chan
@@ -7600,7 +7637,12 @@ static int get_folder2(struct ast_channel *chan, char *fn, int start)
while (((res < '0') || (res > '9')) &&
(res != '#') && (res >= 0) &&
loops < 4) {
- res = get_folder(chan, 0);
+ /* res = get_folder(chan, 0); */
+ if (!strcasecmp(ast_channel_language(chan),"ja")) { /* Japanese syntax */
+ res = get_folder_ja(chan, 0);
+ } else { /* Default syntax */
+ res = get_folder(chan, 0);
+ }
loops++;
}
if (loops == 4) { /* give up */
@@ -8326,6 +8368,8 @@ static int play_message_datetime(struct ast_channel *chan, struct ast_vm_user *v
res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' q H 'digits/kai' M ", NULL);
} else if (!strncasecmp(ast_channel_language(chan), "it", 2)) { /* ITALIAN syntax */
res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' q 'digits/at' 'digits/hours' k 'digits/e' M 'digits/minutes'", NULL);
+ } else if (!strcasecmp(ast_channel_language(chan),"ja")) { /* Japanese syntax */
+ res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "PHM q 'jp-ni' 'vm-received'", NULL);
} else if (!strncasecmp(ast_channel_language(chan), "nl", 2)) { /* DUTCH syntax */
res = ast_say_date_with_format(chan, t, AST_DIGIT_ANY, ast_channel_language(chan), "'vm-received' q 'digits/nl-om' HM", NULL);
} else if (!strncasecmp(ast_channel_language(chan), "no", 2)) { /* NORWEGIAN syntax */
@@ -8891,6 +8935,19 @@ static int vm_play_folder_name_gr(struct ast_channel *chan, char *box)
}
}
+static int vm_play_folder_name_ja(struct ast_channel *chan, char *box)
+{
+ int cmd;
+
+ if (!strcasecmp(box, "vm-INBOX") || !strcasecmp(box, "vm-Old")) {
+ cmd = ast_play_and_wait(chan, box);
+ return cmd ? cmd : ast_play_and_wait(chan, "vm-messages");
+ } else {
+ cmd = ast_play_and_wait(chan, box);
+ return cmd;
+ }
+}
+
static int vm_play_folder_name_pl(struct ast_channel *chan, char *box)
{
int cmd;
@@ -8933,6 +8990,8 @@ static int vm_play_folder_name(struct ast_channel *chan, char *box)
return vm_play_folder_name_gr(chan, box);
} else if (!strncasecmp(ast_channel_language(chan), "he", 2)) { /* Hebrew syntax */
return ast_play_and_wait(chan, box);
+ } else if (!strncasecmp(ast_channel_language(chan), "ja", 2)) { /* Japanese syntax */
+ return vm_play_folder_name_ja(chan, box);
} else if (!strncasecmp(ast_channel_language(chan), "pl", 2)) {
return vm_play_folder_name_pl(chan, box);
} else if (!strncasecmp(ast_channel_language(chan), "ua", 2)) { /* Ukrainian syntax */
@@ -9156,6 +9215,45 @@ static int vm_intro_he(struct ast_channel *chan, struct vm_state *vms)
}
return res;
}
+
+/* Japanese syntax */
+static int vm_intro_ja(struct ast_channel *chan,struct vm_state *vms)
+{
+ /* Introduce messages they have */
+ int res;
+ if (vms->newmessages) {
+ res = ast_play_and_wait(chan, "vm-INBOX");
+ if (!res)
+ res = ast_play_and_wait(chan, "vm-message");
+ if (!res)
+ res = ast_play_and_wait(chan, "jp-ga");
+ if (!res)
+ res = say_and_wait(chan, vms->newmessages, ast_channel_language(chan));
+ if (vms->oldmessages && !res)
+ res = ast_play_and_wait(chan, "silence/1");
+
+ }
+ if (vms->oldmessages) {
+ res = ast_play_and_wait(chan, "vm-Old");
+ if (!res)
+ res = ast_play_and_wait(chan, "vm-message");
+ if (!res)
+ res = ast_play_and_wait(chan, "jp-ga");
+ if (!res)
+ res = say_and_wait(chan, vms->oldmessages, ast_channel_language(chan));
+ }
+ if (!vms->oldmessages && !vms->newmessages) {
+ res = ast_play_and_wait(chan, "vm-messages");
+ if (!res)
+ res = ast_play_and_wait(chan, "jp-wa");
+ if (!res)
+ res = ast_play_and_wait(chan, "jp-arimasen");
+ }
+ else {
+ res = ast_play_and_wait(chan, "jp-arimasu");
+ }
+ return res;
+} /* Japanese */
/* Default English syntax */
static int vm_intro_en(struct ast_channel *chan, struct vm_state *vms)
@@ -9880,6 +9978,8 @@ static int vm_intro(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm
return vm_intro_he(chan, vms);
} else if (!strncasecmp(ast_channel_language(chan), "it", 2)) { /* ITALIAN syntax */
return vm_intro_it(chan, vms);
+ } else if (!strncasecmp(ast_channel_language(chan), "ja", 2)) { /* JAPANESE syntax */
+ return vm_intro_ja(chan, vms);
} else if (!strncasecmp(ast_channel_language(chan), "nl", 2)) { /* DUTCH syntax */
return vm_intro_nl(chan, vms);
} else if (!strncasecmp(ast_channel_language(chan), "no", 2)) { /* NORWEGIAN syntax */
@@ -9993,6 +10093,102 @@ static int vm_instructions_en(struct ast_channel *chan, struct ast_vm_user *vmu,
return res;
}
+static int vm_instructions_ja(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
+{
+ int res = 0;
+ /* Play instructions and wait for new command */
+ while (!res) {
+ if (vms->starting) {
+ if (vms->lastmsg > -1) {
+ res = vm_play_folder_name(chan, vms->vmbox);
+ if (!res)
+ res = ast_play_and_wait(chan, "jp-wa");
+ if (!res)
+ res = ast_play_and_wait(chan, "digits/1");
+ if (!res)
+ res = ast_play_and_wait(chan, "jp-wo");
+ if (!res)
+ res = ast_play_and_wait(chan, "silence/1");
+ }
+ if (!res)
+ res = ast_play_and_wait(chan, "vm-opts");
+ } else {
+ /* Added for additional help */
+ if (skipadvanced) {
+ res = vm_play_folder_name(chan, vms->vmbox);
+ if (!res)
+ res = ast_play_and_wait(chan, "jp-wa");
+ if (!res)
+ res = ast_play_and_wait(chan, "digits/1");
+ if (!res)
+ res = ast_play_and_wait(chan, "jp-wo");
+ if (!res)
+ res = ast_play_and_wait(chan, "silence/1");
+ res = ast_play_and_wait(chan, "vm-opts-full");
+ }
+ /* Logic:
+ * If the current message is not the first OR
+ * if we're listening to the first new message and there are
+ * also urgent messages, then prompt for navigation to the
+ * previous message
+ */
+ if (vms->curmsg || (!in_urgent && vms->urgentmessages > 0) || (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0)) {
+ res = ast_play_and_wait(chan, "vm-prev");
+ }
+ if (!res && !skipadvanced)
+ res = ast_play_and_wait(chan, "vm-advopts");
+ if (!res)
+ res = ast_play_and_wait(chan, "vm-repeat");
+ /* Logic:
+ * If we're not listening to the last message OR
+ * we're listening to the last urgent message and there are
+ * also new non-urgent messages, then prompt for navigation
+ * to the next message
+ */
+ if (!res && ((vms->curmsg != vms->lastmsg) || (in_urgent && vms->newmessages > 0) ||
+ (ast_test_flag(vmu, VM_MESSAGEWRAP) && vms->lastmsg > 0) )) {
+ res = ast_play_and_wait(chan, "vm-next");
+ }
+ if (!res) {
+ int curmsg_deleted;
+#ifdef IMAP_STORAGE
+ ast_mutex_lock(&vms->lock);
+#endif
+ curmsg_deleted = vms->deleted[vms->curmsg];
+#ifdef IMAP_STORAGE
+ ast_mutex_unlock(&vms->lock);
+#endif
+ if (!curmsg_deleted) {
+ res = ast_play_and_wait(chan, "vm-delete");
+ } else {
+ res = ast_play_and_wait(chan, "vm-undelete");
+ }
+ if (!res) {
+ res = ast_play_and_wait(chan, "vm-toforward");
+ }
+ if (!res) {
+ res = ast_play_and_wait(chan, "vm-savemessage");
+ }
+ }
+ }
+
+ if (!res) {
+ res = ast_play_and_wait(chan, "vm-helpexit");
+ }
+ if (!res)
+ res = ast_waitfordigit(chan, 6000);
+ if (!res) {
+ vms->repeats++;
+ if (vms->repeats > 2) {
+ res = 't';
+ }
+ }
+
+ }
+
+ return res;
+}
+
static int vm_instructions_zh(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
{
int res = 0;
@@ -10019,7 +10215,9 @@ static int vm_instructions_zh(struct ast_channel *chan, struct ast_vm_user *vmu,
static int vm_instructions(struct ast_channel *chan, struct ast_vm_user *vmu, struct vm_state *vms, int skipadvanced, int in_urgent)
{
- if (vms->starting && !strncasecmp(ast_channel_language(chan), "zh", 2)) { /* CHINESE (Taiwan) syntax */
+ if (!strncasecmp(ast_channel_language(chan), "ja", 2)) { /* Japanese syntax */
+ return vm_instructions_ja(chan, vmu, vms, skipadvanced, in_urgent);
+ } else if (vms->starting && !strncasecmp(ast_channel_language(chan), "zh", 2)) { /* CHINESE (Taiwan) syntax */
return vm_instructions_zh(chan, vmu, vms, skipadvanced, in_urgent);
} else { /* Default to ENGLISH */
return vm_instructions_en(chan, vmu, vms, skipadvanced, in_urgent);
@@ -10440,6 +10638,33 @@ static int vm_browse_messages_it(struct ast_channel *chan, struct vm_state *vms,
return cmd;
}
+/*!
+ * \brief Japanese syntax for 'You have N messages' greeting.
+ * \param chan
+ * \param vms
+ * \param vmu
+ *
+ * \return zero on success, -1 on error.
+ */
+static int vm_browse_messages_ja(struct ast_channel *chan, struct vm_state *vms, struct ast_vm_user *vmu)
+{
+ int cmd = 0;
+
+ if (vms->lastmsg > -1) {
+ cmd = play_message(chan, vmu, vms);
+ } else {
+ snprintf(vms->fn, sizeof(vms->fn), "vm-%s", vms->curbox);
+ cmd = ast_play_and_wait(chan, vms->fn);
+ if (!cmd)
+ cmd = ast_play_and_wait(chan, "vm-messages");
+ if (!cmd)
+ cmd = ast_play_and_wait(chan, "jp-wa");
+ if (!cmd)
+ cmd = ast_play_and_wait(chan, "jp-arimasen");
+ }
+ return cmd;
+}
+
/*!
* \brief Spanish syntax for 'You have N messages' greeting.
* \param chan
@@ -10565,6 +10790,8 @@ static int vm_browse_messages(struct ast_channel *chan, struct vm_state *vms, st
return vm_browse_messages_he(chan, vms, vmu);
} else if (!strncasecmp(ast_channel_language(chan), "it", 2)) { /* ITALIAN */
return vm_browse_messages_it(chan, vms, vmu);
+ } else if (!strncasecmp(ast_channel_language(chan), "ja", 2)) { /* JAPANESE */
+ return vm_browse_messages_ja(chan, vms, vmu);
} else if (!strncasecmp(ast_channel_language(chan), "pt", 2)) { /* PORTUGUESE */
return vm_browse_messages_pt(chan, vms, vmu);
} else if (!strncasecmp(ast_channel_language(chan), "vi", 2)) { /* VIETNAMESE */
@@ -11510,6 +11737,22 @@ static int vm_execmain(struct ast_channel *chan, const char *data)
break;
case '*': /* Help */
if (!vms.starting) {
+ if (!strncasecmp(ast_channel_language(chan), "ja", 2)) {
+ cmd = vm_play_folder_name(chan, vms.vmbox);
+ if (!cmd)
+ cmd = ast_play_and_wait(chan, "jp-wa");
+ if (!cmd)
+ cmd = ast_play_and_wait(chan, "digits/1");
+ if (!cmd)
+ cmd = ast_play_and_wait(chan, "jp-wo");
+ if (!cmd)
+ cmd = ast_play_and_wait(chan, "silence/1");
+ if (!cmd)
+ cmd = ast_play_and_wait(chan, "vm-opts");
+ if (!cmd)
+ cmd = vm_instructions(chan, vmu, &vms, 1, in_urgent);
+ break;
+ }
cmd = ast_play_and_wait(chan, "vm-onefor");
if (!strncasecmp(ast_channel_language(chan), "he", 2)) {
cmd = ast_play_and_wait(chan, "vm-for");
@@ -12092,9 +12335,7 @@ static int acf_vm_info(struct ast_channel *chan, const char *cmd, char *args, ch
} else if (!strncasecmp(arg.attribute, "pager", 5)) {
ast_copy_string(buf, vmu->pager, len);
} else if (!strncasecmp(arg.attribute, "language", 8)) {
- const char *lang = S_OR(vmu->language, chan ?
- ast_channel_language(chan) : ast_defaultlanguage);
- ast_copy_string(buf, lang, len);
+ ast_copy_string(buf, S_OR(vmu->language, ast_channel_language(chan)), len);
} else if (!strncasecmp(arg.attribute, "locale", 6)) {
ast_copy_string(buf, vmu->locale, len);
} else if (!strncasecmp(arg.attribute, "tz", 2)) {
@@ -13804,7 +14045,7 @@ AST_TEST_DEFINE(test_voicemail_vmsayname)
break;
}
- if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, NULL,
+ if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
NULL, NULL, 0, 0, "TestChannel1"))) {
goto exit_vmsayname_test;
}
diff --git a/main/say.c b/main/say.c
index bda1da3c3..ef80dfa7d 100644
--- a/main/say.c
+++ b/main/say.c
@@ -381,6 +381,7 @@ static int ast_say_number_full_pt(struct ast_channel *chan, int num, const char
static int ast_say_number_full_se(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
static int ast_say_number_full_zh(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
+static int ast_say_number_full_ja(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
static int ast_say_number_full_ru(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
static int ast_say_number_full_ka(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
static int ast_say_number_full_hu(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
@@ -403,6 +404,7 @@ static int ast_say_date_fr(struct ast_channel *chan, time_t t, const char *ints,
static int ast_say_date_nl(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_date_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+static int ast_say_date_ja(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_date_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_date_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_date_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
@@ -420,6 +422,7 @@ static int ast_say_date_with_format_pl(struct ast_channel *chan, time_t t, const
static int ast_say_date_with_format_pt(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone);
static int ast_say_date_with_format_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone);
static int ast_say_date_with_format_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone);
+static int ast_say_date_with_format_ja(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone);
static int ast_say_date_with_format_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone);
static int ast_say_date_with_format_vi(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone);
@@ -431,6 +434,7 @@ static int ast_say_time_pt(struct ast_channel *chan, time_t t, const char *ints,
static int ast_say_time_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_time_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+static int ast_say_time_ja(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_time_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_time_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_time_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
@@ -444,6 +448,7 @@ static int ast_say_datetime_pt(struct ast_channel *chan, time_t t, const char *i
static int ast_say_datetime_pt_BR(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_zh(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
+static int ast_say_datetime_ja(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_ka(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_hu(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
static int ast_say_datetime_th(struct ast_channel *chan, time_t t, const char *ints, const char *lang);
@@ -500,6 +505,8 @@ static int say_number_full(struct ast_channel *chan, int num, const char *ints,
return ast_say_number_full_ka(chan, num, ints, language, options, audiofd, ctrlfd);
} else if (!strncasecmp(language, "gr", 2)) { /* Greek syntax */
return ast_say_number_full_gr(chan, num, ints, language, audiofd, ctrlfd);
+ } else if (!strncasecmp(language, "ja", 2)) { /* Japanese syntax */
+ return ast_say_number_full_ja(chan, num, ints, language, audiofd, ctrlfd);
} else if (!strncasecmp(language, "he", 2)) { /* Hebrew syntax */
return ast_say_number_full_he(chan, num, ints, language, options, audiofd, ctrlfd);
} else if (!strncasecmp(language, "hu", 2)) { /* Hungarian syntax */
@@ -1929,31 +1936,31 @@ static void powiedz(struct ast_channel *chan, const char *language, int audiofd,
m100 = m1000 % 100;
i100 = m1000 / 100;
- if (i100>0)
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->setki[i100]);
-
- if (m100 > 0 && m100 <= 9) {
- if (m1000 > 0)
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100]);
- else
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry[m100]);
- } else if (m100 % 10 == 0 && m100 != 0) {
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
- } else if (m100 > 10 && m100 <= 19) {
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->nastki[m100 % 10]);
- } else if (m100 > 20) {
- if (odm->separator_dziesiatek[0] == ' ') {
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100 % 10]);
- } else {
- char buf[10];
- char *b = buf;
- b = pl_append(b, odm->dziesiatki[m100 / 10]);
- b = pl_append(b, odm->separator_dziesiatek);
- pl_append(b, odm->cyfry2[m100 % 10]);
- pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, buf);
- }
- }
+ if (i100>0)
+ pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->setki[i100]);
+
+ if (m100 > 0 && m100 <= 9) {
+ if (m1000 > 0)
+ pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100]);
+ else
+ pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry[m100]);
+ } else if (m100 % 10 == 0 && m100 != 0) {
+ pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
+ } else if (m100 > 10 && m100 <= 19) {
+ pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->nastki[m100 % 10]);
+ } else if (m100 > 20) {
+ if (odm->separator_dziesiatek[0] == ' ') {
+ pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->dziesiatki[m100 / 10]);
+ pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, odm->cyfry2[m100 % 10]);
+ } else {
+ char buf[10];
+ char *b = buf;
+ b = pl_append(b, odm->dziesiatki[m100 / 10]);
+ b = pl_append(b, odm->separator_dziesiatek);
+ pl_append(b, odm->cyfry2[m100 % 10]);
+ pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, buf);
+ }
+ }
if (rzad > 0) {
pl_odtworz_plik(chan, language, audiofd, ctrlfd, ints, pl_rzad_na_tekst(odm, i, rzad));
@@ -3340,6 +3347,8 @@ static int say_date(struct ast_channel *chan, time_t t, const char *ints, const
return ast_say_date_ka(chan, t, ints, lang);
} else if (!strncasecmp(lang, "gr", 2)) { /* Greek syntax */
return ast_say_date_gr(chan, t, ints, lang);
+ } else if (!strncasecmp(lang, "ja", 2)) { /* Japanese syntax */
+ return ast_say_date_ja(chan, t, ints, lang);
} else if (!strncasecmp(lang, "he", 2)) { /* Hebrew syntax */
return ast_say_date_he(chan, t, ints, lang);
} else if (!strncasecmp(lang, "hu", 2)) { /* Hungarian syntax */
@@ -3689,6 +3698,8 @@ static int say_date_with_format(struct ast_channel *chan, time_t t, const char *
return ast_say_date_with_format_fr(chan, t, ints, lang, format, tzone);
} else if (!strncasecmp(lang, "gr", 2)) { /* Greek syntax */
return ast_say_date_with_format_gr(chan, t, ints, lang, format, tzone);
+ } else if (!strncasecmp(lang, "ja", 2)) { /* Japanese syntax */
+ return ast_say_date_with_format_ja(chan, t, ints, lang, format, tzone);
} else if (!strncasecmp(lang, "it", 2)) { /* Italian syntax */
return ast_say_date_with_format_it(chan, t, ints, lang, format, tzone);
} else if (!strncasecmp(lang, "mx", 2)) { /* deprecated Mexican syntax */
@@ -6321,6 +6332,8 @@ static int say_time(struct ast_channel *chan, time_t t, const char *ints, const
return ast_say_time_ka(chan, t, ints, lang);
} else if (!strncasecmp(lang, "gr", 2)) { /* Greek syntax */
return ast_say_time_gr(chan, t, ints, lang);
+ } else if (!strncasecmp(lang, "ja", 2)) { /* Japanese syntax */
+ return ast_say_time_ja(chan, t, ints, lang);
} else if (!strncasecmp(lang, "he", 2)) { /* Hebrew syntax */
return ast_say_time_he(chan, t, ints, lang);
} else if (!strncasecmp(lang, "hu", 2)) { /* Hungarian syntax */
@@ -6652,6 +6665,8 @@ static int say_datetime(struct ast_channel *chan, time_t t, const char *ints, co
return ast_say_datetime_ka(chan, t, ints, lang);
} else if (!strncasecmp(lang, "gr", 2)) { /* Greek syntax */
return ast_say_datetime_gr(chan, t, ints, lang);
+ } else if (!strncasecmp(lang, "ja", 2)) { /* Japanese syntax */
+ return ast_say_datetime_ja(chan, t, ints, lang);
} else if (!strncasecmp(lang, "he", 2)) { /* Hebrew syntax */
return ast_say_datetime_he(chan, t, ints, lang);
} else if (!strncasecmp(lang, "hu", 2)) { /* Hungarian syntax */
@@ -7394,6 +7409,71 @@ static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char
return res;
}
+/* Japanese syntax */
+static int ast_say_number_full_ja(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
+{
+ int res = 0;
+ int playh = 0;
+ char fn[256] = "";
+ if (!num)
+ return ast_say_digits_full(chan, 0, ints, language, audiofd, ctrlfd);
+
+ while (!res && (num || playh)) {
+ if (num < 0) {
+ ast_copy_string(fn, "digits/minus", sizeof(fn));
+ if ( num > INT_MIN ) {
+ num = -num;
+ } else {
+ num = 0;
+ }
+ } else if (playh) {
+ ast_copy_string(fn, "digits/hundred", sizeof(fn));
+ playh = 0;
+ } else if (num < 20) {
+ snprintf(fn, sizeof(fn), "digits/%d", num);
+ num = 0;
+ } else if (num < 100) {
+ snprintf(fn, sizeof(fn), "digits/%d", (num /10) * 10);
+ num %= 10;
+ } else {
+ if (num < 1000){
+ snprintf(fn, sizeof(fn), "digits/%d", (num/100));
+ playh++;
+ num %= 100;
+ } else {
+ if (num < 1000000) { /* 1,000,000 */
+ res = ast_say_number_full_en(chan, num / 1000, ints, language, audiofd, ctrlfd);
+ if (res)
+ return res;
+ num %= 1000;
+ snprintf(fn, sizeof(fn), "digits/thousand");
+ } else {
+ if (num < 1000000000) { /* 1,000,000,000 */
+ res = ast_say_number_full_en(chan, num / 1000000, ints, language, audiofd, ctrlfd);
+ if (res)
+ return res;
+ num %= 1000000;
+ ast_copy_string(fn, "digits/million", sizeof(fn));
+ } else {
+ ast_debug(1, "Number '%d' is too big for me\n", num);
+ res = -1;
+ }
+ }
+ }
+ }
+ if (!res) {
+ if (!ast_streamfile(chan, fn, language)) {
+ if ((audiofd > -1) && (ctrlfd > -1))
+ res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+ else
+ res = ast_waitstream(chan, ints);
+ }
+ ast_stopstream(chan);
+ }
+ }
+ return res;
+}
+
/*! \brief Greek support
*
@@ -7439,6 +7519,39 @@ static int ast_say_date_gr(struct ast_channel *chan, time_t t, const char *ints,
}
+/* Japanese syntax */
+int ast_say_date_ja(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+{
+ struct ast_tm tm;
+ struct timeval tv = { t, 0 };
+ char fn[256];
+ int res = 0;
+ ast_localtime(&tv, &tm, NULL);
+ if (!res)
+ res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
+ if (!res)
+ res = ast_waitstream(chan, ints);
+ if (!res)
+ res = ast_streamfile(chan, "digits/nen", lang);
+ if (!res) {
+ snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
+ res = ast_streamfile(chan, fn, lang);
+ if (!res)
+ res = ast_waitstream(chan, ints);
+ }
+ if (!res)
+ res = ast_say_number(chan, tm.tm_mday, ints, lang, (char * ) NULL);
+ if (!res)
+ res = ast_streamfile(chan, "digits/nichi", lang);
+ if (!res) {
+ snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
+ res = ast_streamfile(chan, fn, lang);
+ if (!res)
+ res = ast_waitstream(chan, ints);
+ }
+ return res;
+}
+
/*! \brief Greek support
*
@@ -7496,6 +7609,52 @@ static int ast_say_time_gr(struct ast_channel *chan, time_t t, const char *ints,
}
+/* Japanese */
+static int ast_say_time_ja(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+{
+
+ struct timeval tv = { t, 0 };
+ struct ast_tm tm;
+ int res = 0;
+ int hour, pm=0;
+
+ ast_localtime(&tv, &tm, NULL);
+ hour = tm.tm_hour;
+
+ if (!hour)
+ hour = 12;
+ else if (hour == 12)
+ pm = 1;
+ else if (hour > 12) {
+ hour -= 12;
+ pm = 1;
+ }
+
+ if (pm) {
+ if (!res)
+ res = ast_streamfile(chan, "digits/p-m", lang);
+ } else {
+ if (!res)
+ res = ast_streamfile(chan, "digits/a-m", lang);
+ }
+ if (hour == 9 || hour == 21) {
+ if (!res)
+ res = ast_streamfile(chan, "digits/9_2", lang);
+ } else {
+ if (!res)
+ res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
+ }
+ if (!res)
+ res = ast_streamfile(chan, "digits/ji", lang);
+ if (!res)
+ res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
+ if (!res)
+ res = ast_streamfile(chan, "digits/fun", lang);
+ if (!res)
+ res = ast_waitstream(chan, ints);
+ return res;
+}
+
/*! \brief Greek support
*/
@@ -7531,6 +7690,72 @@ static int ast_say_datetime_gr(struct ast_channel *chan, time_t t, const char *i
return res;
}
+/* Japanese syntax */
+int ast_say_datetime_ja(struct ast_channel *chan, time_t t, const char *ints, const char *lang)
+{
+ struct timeval tv = { t, 0 };
+ struct ast_tm tm;
+ char fn[256];
+ int res = 0;
+ int hour, pm=0;
+
+ ast_localtime(&tv, &tm, NULL);
+
+ if (!res)
+ res = ast_say_number(chan, tm.tm_year + 1900, ints, lang, (char *) NULL);
+ if (!res)
+ res = ast_streamfile(chan, "digits/nen", lang);
+ if (!res) {
+ snprintf(fn, sizeof(fn), "digits/mon-%d", tm.tm_mon);
+ res = ast_streamfile(chan, fn, lang);
+ if (!res)
+ res = ast_waitstream(chan, ints);
+ }
+ if (!res)
+ res = ast_say_number(chan, tm.tm_mday, ints, lang, (char *) NULL);
+ if (!res)
+ res = ast_streamfile(chan, "digits/nichi", lang);
+ if (!res) {
+ snprintf(fn, sizeof(fn), "digits/day-%d", tm.tm_wday);
+ res = ast_streamfile(chan, fn, lang);
+ if (!res)
+ res = ast_waitstream(chan, ints);
+ }
+
+ hour = tm.tm_hour;
+ if (!hour)
+ hour = 12;
+ else if (hour == 12)
+ pm = 1;
+ else if (hour > 12) {
+ hour -= 12;
+ pm = 1;
+ }
+ if (pm) {
+ if (!res)
+ res = ast_streamfile(chan, "digits/p-m", lang);
+ } else {
+ if (!res)
+ res = ast_streamfile(chan, "digits/a-m", lang);
+ }
+ if (hour == 9 || hour == 21) {
+ if (!res)
+ res = ast_streamfile(chan, "digits/9_2", lang);
+ } else {
+ if (!res)
+ res = ast_say_number(chan, hour, ints, lang, (char *) NULL);
+ }
+ if (!res)
+ res = ast_streamfile(chan, "digits/ji", lang);
+ if (!res)
+ res = ast_say_number(chan, tm.tm_min, ints, lang, (char *) NULL);
+ if (!res)
+ res = ast_streamfile(chan, "digits/fun", lang);
+ if (!res)
+ res = ast_waitstream(chan, ints);
+ return res;
+}
+
/*! \brief Greek support
*/
static int ast_say_date_with_format_gr(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
@@ -7704,6 +7929,274 @@ static int ast_say_date_with_format_gr(struct ast_channel *chan, time_t t, const
return res;
}
+/* Japanese syntax */
+int ast_say_date_with_format_ja(struct ast_channel *chan, time_t time, const char *ints, const char *lang, const char *format, const char *timezone)
+{
+ struct timeval tv = { time, 0 };
+ struct ast_tm tm;
+ int res=0, offset, sndoffset;
+ char sndfile[256], nextmsg[256];
+
+ if (!format)
+ format = "YbdAPIMS";
+
+ ast_localtime(&tv, &tm, timezone);
+
+ for (offset=0 ; format[offset] != '\0' ; offset++) {
+ ast_log(LOG_DEBUG, "Parsing %c (offset %d) in %s\n", format[offset], offset, format);
+ switch (format[offset]) {
+ /* NOTE: if you add more options here, please try to be consistent with strftime(3) */
+ case '\'':
+ /* Literal name of a sound file */
+ sndoffset=0;
+ for (sndoffset=0 ; (format[++offset] != '\'') && (sndoffset < 256) ; sndoffset++)
+ sndfile[sndoffset] = format[offset];
+ sndfile[sndoffset] = '\0';
+ res = wait_file(chan,ints,sndfile,lang);
+ break;
+ case 'A':
+ case 'a':
+ /* Sunday - Saturday */
+ snprintf(nextmsg,sizeof(nextmsg), "digits/day-%d", tm.tm_wday);
+ res = wait_file(chan,ints,nextmsg,lang);
+ break;
+ case 'B':
+ case 'b':
+ case 'h':
+ /* January - December */
+ snprintf(nextmsg,sizeof(nextmsg), "digits/mon-%d", tm.tm_mon);
+ res = wait_file(chan,ints,nextmsg,lang);
+ break;
+ case 'd':
+ case 'e':
+ /* First - Thirtyfirst */
+ if (tm.tm_mday < 21) {
+ snprintf(nextmsg,sizeof(nextmsg), "digits/h-%d_2", tm.tm_mday);
+ res = wait_file(chan,ints,nextmsg,lang);
+ } else if (tm.tm_mday < 30) {
+ /* Between 21 and 29 - two sounds */
+ res = wait_file(chan,ints, "digits/20",lang);
+ if (!res) {
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_mday - 20);
+ res = wait_file(chan,ints,nextmsg,lang);
+ }
+ res = wait_file(chan,ints, "digits/nichi",lang);
+ } else if (tm.tm_mday == 30) {
+ /* 30 */
+ res = wait_file(chan,ints, "digits/h-30_2",lang);
+ } else {
+ /* 31 */
+ res = wait_file(chan,ints, "digits/30",lang);
+ res = wait_file(chan,ints, "digits/1",lang);
+ res = wait_file(chan,ints, "digits/nichi",lang);
+ }
+ break;
+ case 'Y':
+ /* Year */
+ if (tm.tm_year > 99) {
+ res = wait_file(chan,ints, "digits/2",lang);
+ if (!res) {
+ res = wait_file(chan,ints, "digits/thousand",lang);
+ }
+ if (tm.tm_year > 100) {
+ if (!res) {
+ /* This works until the end of 2020 */
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year - 100);
+ res = wait_file(chan,ints,nextmsg,lang);
+ }
+ }
+ } else {
+ if (tm.tm_year < 1) {
+ /* I'm not going to handle 1900 and prior */
+ /* We'll just be silent on the year, instead of bombing out. */
+ } else {
+ res = wait_file(chan,ints, "digits/19",lang);
+ if (!res) {
+ if (tm.tm_year <= 9) {
+ /* 1901 - 1909 */
+ res = wait_file(chan,ints, "digits/oh",lang);
+ if (!res) {
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
+ res = wait_file(chan,ints,nextmsg,lang);
+ }
+ } else if (tm.tm_year <= 20) {
+ /* 1910 - 1920 */
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_year);
+ res = wait_file(chan,ints,nextmsg,lang);
+ } else {
+ /* 1921 - 1999 */
+ int ten, one;
+ ten = tm.tm_year / 10;
+ one = tm.tm_year % 10;
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten * 10);
+ res = wait_file(chan,ints,nextmsg,lang);
+ if (!res) {
+ if (one != 0) {
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
+ res = wait_file(chan,ints,nextmsg,lang);
+ }
+ }
+ }
+ }
+ }
+ }
+ res = wait_file(chan,ints, "digits/nen",lang);
+ break;
+ case 'P':
+ case 'p':
+ /* AM/PM */
+ if (tm.tm_hour > 11)
+ snprintf(nextmsg,sizeof(nextmsg), "digits/p-m");
+ else
+ snprintf(nextmsg,sizeof(nextmsg), "digits/a-m");
+ res = wait_file(chan,ints,nextmsg,lang);
+ break;
+ case 'I':
+ case 'l':
+ /* 12-Hour */
+ if (tm.tm_hour == 0)
+ snprintf(nextmsg,sizeof(nextmsg), "digits/12");
+ else if (tm.tm_hour == 9 || tm.tm_hour == 21)
+ snprintf(nextmsg,sizeof(nextmsg), "digits/9_2");
+ else if (tm.tm_hour > 12)
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour - 12);
+ else
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_hour);
+ res = wait_file(chan,ints,nextmsg,lang);
+ if(!res) res = wait_file(chan,ints, "digits/ji",lang);
+ break;
+ case 'H':
+ case 'k':
+ if (!res) {
+ if (tm.tm_hour != 0) {
+ int remainder = tm.tm_hour;
+ if (tm.tm_hour > 20) {
+ res = wait_file(chan,ints, "digits/20",lang);
+ remainder -= 20;
+ }
+ if (!res) {
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", remainder);
+ res = wait_file(chan,ints,nextmsg,lang);
+ }
+ }
+ }
+ res = wait_file(chan,ints, "digits/ji",lang);
+ break;
+ case 'M':
+ /* Minute */
+ if ((tm.tm_min < 21) || (tm.tm_min % 10 == 0)) {
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_min);
+ res = wait_file(chan,ints,nextmsg,lang);
+ } else {
+ int ten, one;
+ ten = (tm.tm_min / 10) * 10;
+ one = (tm.tm_min % 10);
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
+ res = wait_file(chan,ints,nextmsg,lang);
+ if (!res) {
+ /* Fifty, not fifty-zero */
+ if (one != 0) {
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
+ res = wait_file(chan,ints,nextmsg,lang);
+ }
+ }
+ }
+ res = wait_file(chan,ints, "digits/fun",lang);
+ break;
+ case 'Q':
+ /* Shorthand for "Today", "Yesterday", or ABdY */
+ {
+ struct timeval now;
+ struct ast_tm tmnow;
+ time_t beg_today;
+
+ gettimeofday(&now,NULL);
+ ast_localtime(&now,&tmnow,timezone);
+ /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
+ /* In any case, it saves not having to do ast_mktime() */
+ beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
+ if (beg_today < time) {
+ /* Today */
+ res = wait_file(chan,ints, "digits/today",lang);
+ } else if (beg_today - 86400 < time) {
+ /* Yesterday */
+ res = wait_file(chan,ints, "digits/yesterday",lang);
+ } else {
+ res = ast_say_date_with_format(chan, time, ints, lang, "ABdY", timezone);
+ }
+ }
+ break;
+ case 'q':
+ /* Shorthand for "" (today), "Yesterday", A (weekday), or ABdY */
+ {
+ struct timeval now;
+ struct ast_tm tmnow;
+ time_t beg_today;
+
+ gettimeofday(&now,NULL);
+ ast_localtime(&now,&tmnow,timezone);
+ /* This might be slightly off, if we transcend a leap second, but never more off than 1 second */
+ /* In any case, it saves not having to do ast_mktime() */
+ beg_today = now.tv_sec - (tmnow.tm_hour * 3600) - (tmnow.tm_min * 60) - (tmnow.tm_sec);
+ if (beg_today < time) {
+ /* Today */
+ } else if ((beg_today - 86400) < time) {
+ /* Yesterday */
+ res = wait_file(chan,ints, "digits/yesterday",lang);
+ } else if (beg_today - 86400 * 6 < time) {
+ /* Within the last week */
+ res = ast_say_date_with_format(chan, time, ints, lang, "A", timezone);
+ } else {
+ res = ast_say_date_with_format(chan, time, ints, lang, "ABdY", timezone);
+ }
+ }
+ break;
+ case 'R':
+ res = ast_say_date_with_format(chan, time, ints, lang, "HM", timezone);
+ break;
+ case 'S':
+ /* Seconds */
+ if (tm.tm_sec == 0) {
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
+ res = wait_file(chan,ints,nextmsg,lang);
+ } else if ((tm.tm_sec < 21) || (tm.tm_sec % 10 == 0)) {
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", tm.tm_sec);
+ res = wait_file(chan,ints,nextmsg,lang);
+ } else {
+ int ten, one;
+ ten = (tm.tm_sec / 10) * 10;
+ one = (tm.tm_sec % 10);
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", ten);
+ res = wait_file(chan,ints,nextmsg,lang);
+ if (!res) {
+ /* Fifty, not fifty-zero */
+ if (one != 0) {
+ snprintf(nextmsg,sizeof(nextmsg), "digits/%d", one);
+ res = wait_file(chan,ints,nextmsg,lang);
+ }
+ }
+ }
+ res = wait_file(chan,ints, "digits/byou",lang);
+ break;
+ case 'T':
+ res = ast_say_date_with_format(chan, time, ints, lang, "HMS", timezone);
+ break;
+ case ' ':
+ case ' ':
+ /* Just ignore spaces and tabs */
+ break;
+ default:
+ /* Unknown character */
+ ast_log(LOG_WARNING, "Unknown character in datetime format %s: %c at pos %d\n", format, format[offset], offset);
+ }
+ /* Jump out on DTMF */
+ if (res) {
+ break;
+ }
+ }
+ return res;
+}
+
/*! \brief Vietnamese syntax */
int ast_say_date_with_format_vi(struct ast_channel *chan, time_t t, const char *ints, const char *lang, const char *format, const char *tzone)
{