+
+ p_g_rtp_bridge = 0;
+}
+
+void Pgsm_ms::dtmf_statemachine(struct gsm_mncc *mncc)
+{
+ struct gsm_mncc *dtmf;
+
+ switch (p_g_dtmf_state) {
+ case DTMF_ST_SPACE:
+ case DTMF_ST_IDLE:
+ /* end of string */
+ if (!p_g_dtmf[p_g_dtmf_index]) {
+ PDEBUG(DEBUG_GSM, "done with DTMF\n");
+ p_g_dtmf_state = DTMF_ST_IDLE;
+ return;
+ }
+ gsm_trace_header(p_g_interface_name, this, MNCC_START_DTMF_REQ, DIRECTION_OUT);
+ dtmf = create_mncc(MNCC_START_DTMF_REQ, p_g_callref);
+ dtmf->keypad = p_g_dtmf[p_g_dtmf_index++];
+ p_g_dtmf_state = DTMF_ST_START;
+ PDEBUG(DEBUG_GSM, "start DTMF (keypad %c)\n",
+ dtmf->keypad);
+ end_trace();
+ send_and_free_mncc(p_g_lcr_gsm, dtmf->msg_type, dtmf);
+ return;
+ case DTMF_ST_START:
+ if (mncc->msg_type != MNCC_START_DTMF_RSP) {
+ PDEBUG(DEBUG_GSM, "DTMF was rejected\n");
+ return;
+ }
+ schedule_timer(&p_g_dtmf_timer, 0, 70 * 1000);
+ p_g_dtmf_state = DTMF_ST_MARK;
+ PDEBUG(DEBUG_GSM, "DTMF is on\n");
+ break;
+ case DTMF_ST_MARK:
+ gsm_trace_header(p_g_interface_name, this, MNCC_STOP_DTMF_REQ, DIRECTION_OUT);
+ dtmf = create_mncc(MNCC_STOP_DTMF_REQ, p_g_callref);
+ p_g_dtmf_state = DTMF_ST_STOP;
+ end_trace();
+ send_and_free_mncc(p_g_lcr_gsm, dtmf->msg_type, dtmf);
+ return;
+ case DTMF_ST_STOP:
+ schedule_timer(&p_g_dtmf_timer, 0, 120 * 1000);
+ p_g_dtmf_state = DTMF_ST_SPACE;
+ PDEBUG(DEBUG_GSM, "DTMF is off\n");
+ break;
+ }
+}
+
+static int dtmf_timeout(struct lcr_timer *timer, void *instance, int index)
+{
+ class Pgsm_ms *pgsm_ms = (class Pgsm_ms *)instance;
+
+ PDEBUG(DEBUG_GSM, "DTMF timer has fired\n");
+ pgsm_ms->dtmf_statemachine(NULL);
+
+ return 0;
+}
+
+/* MESSAGE_DTMF */
+void Pgsm_ms::message_dtmf(unsigned int epoint_id, int message_id, union parameter *param)
+{
+ char digit = param->dtmf;
+
+ if (digit >= 'a' && digit <= 'c')
+ digit = digit - 'a' + 'A';
+ if (!strchr("01234567890*#ABC", digit))
+ return;
+
+ /* schedule */
+ if (p_g_dtmf_state == DTMF_ST_IDLE) {
+ p_g_dtmf_index = 0;
+ p_g_dtmf[0] = '\0';
+ }
+ SCCAT(p_g_dtmf, digit);
+ if (p_g_dtmf_state == DTMF_ST_IDLE)
+ dtmf_statemachine(NULL);
+}
+
+/* MESSAGE_INFORMATION */
+void Pgsm_ms::message_information(unsigned int epoint_id, int message_id, union parameter *param)
+{
+ char digit;
+ int i;
+
+ for (i = 0; i < (int)strlen(param->information.id); i++) {
+ digit = param->information.id[i];
+ if (digit >= 'a' && digit <= 'c')
+ digit = digit - 'a' + 'A';
+ if (!strchr("01234567890*#ABC", digit))
+ continue;
+
+ /* schedule */
+ if (p_g_dtmf_state == DTMF_ST_IDLE) {
+ p_g_dtmf_index = 0;
+ p_g_dtmf[0] = '\0';
+ }
+ SCCAT(p_g_dtmf, digit);
+ if (p_g_dtmf_state == DTMF_ST_IDLE)
+ dtmf_statemachine(NULL);
+ }