?? dp_call.c
字號:
/* * Call handling stuff, mostly to do with dialling. * * Copyright 1999 Pavel Machek * Copyright 1999 Jamie Lokier * Copyright 1999 R.J.M. Close * * Can be distributed under GPL */#include "dp_call.h"void dp_DTMF_dial_cmd (unsigned char digit){ dp_write_dsp_ram (0x17, S_DTMF_dial_speed); dp_write_dsp_ram (0x18, S_DTMF_dial_speed); //PRINTF ("dial_speed = %d\n", S_DTMF_dial_speed); if (cell_active) { dp_write_dsp_ram (0x11, 5 + H_DTMF_high_tone_level_ndB); dp_write_dsp_ram (0x12, 5 + H_DTMF_high_tone_level_ndB + H_DTMF_high_low_tone_level_difference_dB); } else { dp_write_dsp_ram (0x11, H_DTMF_high_tone_level_ndB); dp_write_dsp_ram (0x12, H_DTMF_high_tone_level_ndB + H_DTMF_high_low_tone_level_difference_dB); } dp_modem_command (0x0a, digit, 0);}// Pulse dial!void dp_pulse_dial_cmd(int arg){ int al, bl; printf( "Dialing %d: ", arg ); al = homol[1]; bl = homol[2]; if (1 /* byte_59E6E & 0x40 */) { al >>= 1; bl = 0x32; bl -= al; } dp_write_dsp_ram(0x19, al); dp_write_dsp_ram(0x1a, bl); dp_write_dsp_ram(0x1b, (1 ? 0x384 : 0x2f3 )); dp_modem_command(0x0b, arg, 0); printf( "\n" );}void dp_set_lb_filter (void){ unsigned char al, bl; if (dp_threshold < 0x23) dp_write_dsp_ram (0x760, dp_threshold + 2); else dp_write_dsp_ram (0x760, dp_threshold + 4); switch (H_dial_tone_or_call_progress_filter) { case 0: al = 0; case 2: al = 0x20; case 3: al = 0x30; case 4: al = 0x40; case 5: al = 0x50; case 6: al = 0x60; default: al = 0x10; } //if (S(0x40) != 0) // this is set from read_eeprom(1), well dodgy! // al = 0x70; // Yuk, look up table. // lea esi, loc_iircoef[eax*2], array of unsigned short. for (bl = 0; bl < 16; bl++) { // catch any errors as array has 128 elements. if(al > 128) { printf ("dp_set_lb_filter: error: max size of iircoef exceeded!\n"); break; } // Write word to DSP. dp_write_dsp_ram (bl + 0x764, iircoef[al]); // Point to next word. al++; }}// Set up tone detection.void dp_detect_tones_cmd (void){ dp_set_lb_filter(); dp_write_dsp_ram(0x26, H_data_or_fax_answer_detection_threshold_dB); dp_write_dsp_ram(0x1c, 0x2b9b); dp_write_dsp_ram(0x1d, 0x11cd); dp_write_dsp_ram(0x1e, 0x3d0a); dp_write_dsp_ram(0x1f, 0x3b57); dp_write_dsp_ram(0x20, 0x0851); dp_write_dsp_ram(0x21, 0xf190); dp_write_dsp_ram(0x22, 0xedc8); dp_write_dsp_ram(0x23, 0xef70); dp_write_dsp_ram(0x24, 0xe8ce); dp_write_dsp_ram(0x25, 0xe782); if (S(0x38) != 0xA) { dp_write_dsp_ram(0x0fc0, 0x172b); dp_write_dsp_ram(0x0fc1, 0xf4bc); dp_modem_command (8, 0xc, 0); } else dp_modem_command (8, 0xa, 0); dp_dial_tone_timer = x_current_time(); dp_quiet_answer_timer = x_current_time(); dp_busy_tone_timer = x_current_time(); dp_busy_state = 0; dp_tone_state = 0; peak_energy = 0; peak_busy_energy = 0;}// Detects the dial tone. // Currently doesn't work quite right! Needs tidying up.bool dp_dial_tone_detected (void){ unsigned int eax, ecx; unsigned int energy1, energy2; bool state_changed = false; energy2 = dp_read_dsp_ram(0x354); energy1 = dp_read_dsp_ram(0x794); #if LT_DEBUG_TONES // Diagnostics. printf ("dp_dial_tone_detected: dp_tone_state = %d, energy2 = %x, energy1 = %x, peak = %x.\n", dp_tone_state, energy2, energy1, peak_energy); //printf ("H_dial_tone_validation_time is %d.\n", H_dial_tone_validation_time); // normally it is 25.#endif switch (dp_tone_state){ case 0: eax = dp_read_dsp_ram(0x3A); //printf("Read %x from DSP RAM(0x3a).\n", eax); if ((eax & 0x1000) != 0) { // Reset some stuff and go on to the next phase of tone detection. dp_tone_on_time = 0; dp_tone_off_time = 0; dp_dialtone_cycles = 0; dp_tone_timer = x_current_time(); dp_tone_state = 1; } loc_2A989: // printf ("Reset dp_dial_tone_timer!\n"); dp_dial_tone_timer = x_current_time(); goto loc_2A994; case 1: eax = dp_read_dsp_ram (0x3a);#if LT_DEBUG_TONES // Diagnostics. printf ("dp_dial_tone_detected: dp_read_dsp_ram (0x3a) = %x\n", eax);#endif //if ((dp_read_dsp_ram (0x3a) & 0x1000) == 0) goto loc_2A8EB; if ((eax & 0x1000) == 0) goto loc_2A8EB; if ((unsigned int)(peak_energy / 2) >= energy1) goto loc_2A909; loc_2A8EB: dp_tone_on_time = x_elapsed_time(dp_tone_timer); dp_tone_state = 2; state_changed = true; loc_2A909: if ((country_code != COUNTRY_ITALY) && (energy1 > (unsigned int)(peak_energy / 4)) && ((energy2 / (energy1 + 1)) > 5)) { dp_dial_tone_timer = x_current_time(); peak_energy = energy1; } if (energy1 > peak_energy) { peak_energy = energy1; } goto loc_2A994; case 2: goto loc_2A994; default: //test bp, ax if (dp_read_dsp_ram (0x3A) & 0x1000) goto loc_2A89C; eax = peak_energy; eax = eax / 2; if (energy1 > eax) { eax = x_elapsed_time(dp_tone_timer);printf ("Oh Shit!\n"); peak_energy = 0; dp_tone_off_time = eax; dp_tone_state = 1; state_changed = true; goto loc_2A994; } if ((country_code == 7) | (country_code == 8)) goto loc_2A994; if (x_elapsed_time(dp_tone_timer) > 500) { printf ("Reset peak_energy on 500ms timeout!\n"); peak_energy = energy1; } goto loc_2A994; }loc_2A89C: eax = x_elapsed_time(dp_tone_timer); if ((country_code != 8) && (eax > H_dial_tone_hole_time)) goto loc_2A989; if (eax <= 1250) goto loc_2A994; goto loc_2A989;loc_2A994: if (state_changed == false) goto loc_2AA49; // State has changed. // Reset tone timer. dp_tone_timer = x_current_time(); ecx = H_dial_tone_hole_time; eax = dp_tone_off_time; if (eax <= ecx) goto loc_2AA49; if (country_code !=8) goto loc_2AA3E; energy2 = 180; if (eax <= 210) goto loc_2A9D9; if (eax < 830) goto loc_2AA07;loc_2A9D9: if (eax < energy2) goto loc_2AA07; if (eax > 1155) goto loc_2AA07; ecx = dp_tone_on_time; if (ecx <= 230) goto loc_2A9F9; if (ecx <= 530) goto loc_2AA07;loc_2A9F9: if (ecx < 190) goto loc_2AA07; if (ecx < 680) goto loc_2AA1F;loc_2AA07: ecx = dp_tone_on_time; // printf ("Reset dp_dial_tone_timer!\n"); dp_dial_tone_timer = x_current_time(); eax = dp_tone_off_time;loc_2AA1F: if (eax <= energy2) goto loc_2AA2A; if (eax < 220) goto loc_2AA36; loc_2AA2A: if (ecx <= energy2) goto loc_2AA49; if (ecx >= 220) goto loc_2AA49;loc_2AA36: dp_dialtone_cycles++; goto loc_2AA49;loc_2AA3E: // printf ("Reset dp_dial_tone_timer!\n"); dp_dial_tone_timer = x_current_time(); loc_2AA49: // If state is 2 and there hasn't been a state change then this // is the only code (of interest!) that will be executed. eax = x_elapsed_time(dp_dial_tone_timer); // printf ("dp_dial_tone_timer, elapsed time is now: %d\n", eax); if (eax < (unsigned int)(H_dial_tone_validation_time * 100)) return false; // *Bodge* dp_read_dsp_ram(0x3A) always seems to return 0x1000. //if (dp_read_dsp_ram(0x3A) & 0x1000) return false; if (energy1 <= (unsigned int)(H_dialtone_level * 2) ) return false; if ((country_code != COUNTRY_ITALY) || (dp_dialtone_cycles <= 2)) return true; else return false;}// Returns True if the tone is detected when the call is answered.bool dp_answer_tone_detected(void){#if LT_DEBUG_TONES // Diagnostics. printf (">> dp_answer_tone_detected: answer state = %d, on time = %d, off time = %d.\n", dp_answer_state, x_elapsed_time(dp_answer_on_timer), x_elapsed_time(dp_answer_off_timer));#endif switch(dp_answer_state) { case 0: // Initial answer state. if (dp_read_dsp_ram(0x28) & 0x3f0) { dp_answer_on_timer = x_current_time(); dp_answer_off_timer = x_current_time(); dp_answer_state = 1; } return false; case 1: if ((dp_read_dsp_ram(0x28) & 0x3f0) == 0) { dp_answer_off_timer = x_current_time(); dp_answer_state = 2; return false; } if ((S(0x6a) == 2) && (x_elapsed_time(dp_answer_on_timer) >= 100)) return true; //loc_2AB17: { int validationPeriod = (H_answer_tone_validation_time * 10); if (x_elapsed_time(dp_answer_on_timer) >= validationPeriod) return true; else return false; } case 2: if (dp_read_dsp_ram (0x28) & 0x3f0) { if (x_elapsed_time(dp_answer_off_timer) > 50) dp_answer_on_timer = x_current_time(); dp_answer_state = 1; } return false; } return false;}bool dp_busy_tone_detected (void){ unsigned short energy2 = dp_read_dsp_ram (0x354); // Haven't a clue! unsigned short energy = dp_read_dsp_ram (0x794); // This flag causes the dp_busy_tone_timer to be reset and the cadance checked. bool flag_1 = false;#if LT_DEBUG_TONES // Diagnostics. printf ("dp_busy_tone_detected: busy state = %d, energy2 = %x, energy = %x, peak busy = %x.\n", dp_busy_state, energy2, energy, peak_busy_energy); // Diagnostics. printf ("on cad = %u, off cad = %u cycles=%u, DSP RAM = %4x\n", dp_busy_on_cadence, dp_busy_off_cadence, dp_busy_cycles, dp_read_dsp_ram(0x3a));#endif switch (dp_busy_state) { case 0: if (ELAPSED_TIME (dp_busy_tone_timer) > 3) { if (dp_read_dsp_ram (0x3a) & 0x1000) { dp_busy_on_cadence = 0; dp_busy_off_cadence = 1; dp_busy_state = 1; } else { dp_busy_on_cadence = 1; dp_busy_off_cadence = 0; dp_busy_state = 2; } } break; case 1: if ((dp_read_dsp_ram(0x3a) & 0x1000) == 0) goto loc_2AC11; if (energy >= (peak_busy_energy/2)) goto loc_2AC46; loc_2AC11: if (x_elapsed_time(dp_busy_tone_timer) <= 30) goto loc_2AC46; dp_busy_on_cadence = x_elapsed_time(dp_busy_tone_timer); dp_busy_state = 2; //loc_2AC3F: flag_1 = true; break; loc_2AC46: if ((x_modem_mode != 2) && (S_data_calling_tone == true) && (dp_calling_tone_disable == 0) && (x_elapsed_time(dp_timer1) >= 0x708)) { dp_busy_on_cadence = x_elapsed_time(dp_busy_tone_timer); flag_1 = true; } //loc_2AC87: if (energy2 > (energy * 3)) dp_continous_busy_timer = x_current_time (); break; case 2: if ((dp_read_dsp_ram (0x3a) & 0x1000) && (energy > (peak_busy_energy / 2))) { dp_busy_off_cadence = ELAPSED_TIME (dp_busy_tone_timer); dp_busy_state = 1; flag_1 = true; } START_TIMER (dp_continuous_busy_timer); break; } //loc_2ACF0: if (ELAPSED_TIME (dp_busy_tone_timer) > 900) { dp_busy_cycles = 0; dp_busy_on_cadence = 0; dp_busy_off_cadence = 0; } if (flag_1) { START_TIMER (dp_busy_tone_timer); // problem may be in here? if ((country_code != COUNTRY_NORTH_AMERICA && country_code != COUNTRY_CANADA) ? ((H_max_busy_cadence_on_time != 0 /* Parameterised busy tone detection. */ ? (dp_busy_on_cadence >= 10 * H_min_busy_cadence_on_time && dp_busy_on_cadence <= 10 * H_max_busy_cadence_on_time && dp_busy_off_cadence >= 10 * H_min_busy_cadence_off_time && dp_busy_off_cadence <= 10 * H_max_busy_cadence_off_time) /* Default algorithm. */ : (dp_busy_on_cadence >= 100 && dp_busy_on_cadence <= 850 && ((dp_busy_on_cadence <= 150 && (dp_busy_on_cadence + dp_busy_off_cadence > 250)) || (dp_busy_on_cadence >= 150 && (dp_busy_on_cadence <= (75 + dp_busy_off_cadence + (dp_busy_off_cadence / 2)))))))) /* American/Canadian busy tone detection. */ : ((dp_busy_on_cadence >= 195 && dp_busy_on_cadence <= 305 && dp_busy_off_cadence >= 195 && dp_busy_off_cadence <= 305) || (dp_busy_on_cadence >= 420 && dp_busy_on_cadence <= 580 && dp_busy_off_cadence >= 420 && dp_busy_off_cadence <= 580))) { dp_busy_cycles++; dp_busy_on_cadence = 0; dp_busy_off_cadence = 0; } } if (dp_busy_cycles >= H_busy_cycles_threshold) { dp_busy_cycles = 0; return true; } if (energy > peak_busy_energy) peak_busy_energy = energy; return false;}// Detect incoming ring.bool dp_ring_detected(void){ if (dp_read_dsp_ram (0x3a) & 0x20) return true; else return false; }// Ringback initialisation.void dp_ringback_init(void){ dp_no_ringback_timer = x_current_time(); dp_ringback_on_timer = x_current_time(); dp_ringback_off_timer = x_current_time(); dp_ringback_state = 2; dp_ringback_on_cadence = 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -