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 受信を始められます。