Asterisk の quick hack
Asterisk の FXO と通常の電話をパラ(親子)に繋いでいるのですが、CID 受信後の電話機(留守電)のオフフックを、なんだか極性反転と誤検出してしまう問題に遭遇しました。Asterisk のコードを見ているのですが、どうも極性の変化だけチェックしていて、絶対極性を見てないんですよねー。しょうがないので、インチキ hack してみました。まずは、dahdi-linux-complete-2.7.0+2.7.0 にパッチです。
diff -cwr dahdi-linux-complete-2.7.0+2.7.0/linux/drivers/dahdi/wctdm24xxp/base.c ../dahdi-linux-complete-2.7.0+2.7.0/linux/drivers/dahdi/wctdm24xxp/base.c *** dahdi-linux-complete-2.7.0+2.7.0/linux/drivers/dahdi/wctdm24xxp/base.c 2013-06-08 04:29:39.000000000 +0900 --- ../dahdi-linux-complete-2.7.0+2.7.0/linux/drivers/dahdi/wctdm24xxp/base.c 2013-08-07 16:38:53.957346367 +0900 *************** *** 263,268 **** --- 263,270 ---- static int vpmnlpthresh = DEFAULT_NLPTHRESH; static int vpmnlpmaxsupp = DEFAULT_NLPMAXSUPP; + static int fxopolarity = 1; + static void echocan_free(struct dahdi_chan *chan, struct dahdi_echocan_state *ec); static const struct dahdi_echocan_features vpm_ec_features = { *************** *** 2130,2135 **** --- 2132,2138 ---- dahdi_qevent_lock(get_dahdi_chan(wc, mod), DAHDI_EVENT_POLARITY); if (debug & DEBUG_CARD) { + fxopolarity = 1; dev_info(&wc->vb.pdev->dev, "%s: Polarity NEGATIVE -> POSITIVE\n", get_dahdi_chan(wc, mod)->name); *************** *** 2150,2155 **** --- 2153,2159 ---- dahdi_qevent_lock(get_dahdi_chan(wc, mod), DAHDI_EVENT_POLARITY); if (debug & DEBUG_CARD) { + fxopolarity = 0; dev_info(&wc->vb.pdev->dev, "%s: Polarity POSITIVE -> NEGATIVE\n", get_dahdi_chan(wc, mod)->name); *************** *** 6208,6213 **** --- 6212,6218 ---- module_param(vpmnlpthresh, int, 0400); module_param(vpmnlpmaxsupp, int, 0400); #endif + module_param(fxopolarity, int, 0444); /* Module parameters backed by code in xhfc.c */ module_param(bri_debug, int, 0600);
これだと本当はダメで、FXO が複数チャネルある場合を考えてません。すいません。ちゃんと考えてません。
でもって、Asterisk には次のような修正を。
diff --git a/channels/sig_analog.c b/channels/sig_analog.c index 1b3ea3d..9a160c1 100644 --- a/channels/sig_analog.c +++ b/channels/sig_analog.c @@ -3883,6 +3883,18 @@ void *analog_handle_init_event(struct analog_pvt *i, int i->polarity = POLARITY_REV; } if (i->cid_start == ANALOG_CID_START_POLARITY || i->cid_start == ANALOG + FILE *fp; + int absolute_polarity = -1; + usleep(800000); // 410-680 ms is required for final polarity judgm + fp = fopen("/sys/module/wctdm24xxp/parameters/fxopolarity", "r"); + if (fp) { + (void) fscanf(fp, "%d\n", &absolute_polarity); + fclose(fp); + } else + absolute_polarity = -1; + ast_log(LOG_DEBUG, "YOKOYAMA: pol = %d\n", absolute_polarity); + + if (absolute_polarity == 0) { // true NEGATIVE (REVERSED) i->polarity = POLARITY_REV; ast_verb(2, "Starting post polarity " "CID detection on channel %d\n", @@ -3896,6 +3908,7 @@ void *analog_handle_init_event(struct analog_pvt *i, int e ast_hangup(chan); } } + } ast_callid_threadstorage_auto_clean(callid, callid_created); break; default:
これで、本当に極性反転しているときだけ CID 受信を始められます。