2014-04-09 46 views
2

現狀:如何檢測遠程端拒絕語音呼叫與AT命令

在基於GSM調制解調器,你開始一個語音呼叫ATDxxxxxxxxx;

某些調制解調器在遠程端已應答或其他調制解調器在診斷端口上返回「^ CONN:1,0」時發出「CONNECT」。

但是,如果遠端拒絕了該呼叫,該連接反饋仍然被髮送。

AT + CPAS返回4(正在進行呼叫)。

AT + CIND(支持時)返回呼叫正在運行,並且呼叫沒有振鈴。

某些調制解調器沒有在數據端口上發送數據,但其他調制解調器(通常發送靜音或音調)。

經過時間,網絡斷開呼叫和調制解調器,最後在診斷端口上發出「^ CEND」,或在應用端口上發出「HANGUP:1」。

我想檢測遠端是否儘快拒絕了呼叫,而不是在網絡超時之後。我怎麼做 ?

編輯:順便說一句,我不是講「自動」答錄機,但明確拒絕接聽電話(所以它不會重定向到答錄機)。

此外,我想避免「檢測到數據端口上的鈴聲」,就像解決方案,這將證明棘手和CPU密集度得到正確的解決方案。

回答

1

我回答我自己的問題,所以它服務於其他案件。

檢測取決於網絡。通常情況下,在法國的免費運營商中,網絡在呼叫拒絕時不會斷開您的連接(但可以讓您聽到鈴聲)。在德國,它確實如此。所以我認爲法國網絡的行爲是錯誤的,或者至少沒有幫助。

GSM/3GPP標準沒有什麼特別的用於檢測鈴音,所以唯一的辦法就是以編程方式進行檢測。 它可以通過檢查類似「聲音」值之間的時間距離來「簡單地」完成。 算法是這樣的:

int range = 5, value = 350, periodFound = 0; // Arbitrary 
int period[16] = {}; 
void onDataReceived(int sampleRate, short * data, int len) 
{ 
    for (int i = 0; i < len; i++) 
    { 
     if (data[i] >= value - range && data[i] <= value + range) 
     { 
      period[periodFound++] = i; 
     } 
     if (periodFound == 16) break; 
    } 
    // Compute distance between periods (if it's the same, it's a ring tone) 
    float avg = 0, dev = 0; 
    int prev = period[0]; 
    for (int i = 1; i < periodFound; i++) 
    { 
     avg += (period[i] - prev); 
     prev = period[i]; 
    } 
    avg /= periodFound-1; 
    prev = period[0]; 
    for (int i = 1; i < periodFound; i++) 
    { 
     dev += (period[i] - prev - avg) * (period[i] - prev - avg); 
     prev = period[i] 
    } 

    // Last test 
    if (fabs(avg - expectedPeriod) < range && dev < errorAllowed) 
     printf("Ring tone!"); 
}