diff -Nur channels.old/chan_mobile.c channels/chan_mobile.c --- channels.old/chan_mobile.c 2009-07-11 20:49:42.000000000 +0200 +++ channels/chan_mobile.c 2009-07-13 22:03:10.000000000 +0200 @@ -137,6 +137,7 @@ int ring_sched_id; struct ast_dsp *dsp; struct sched_context *sched; + int hangupcause; /* flags */ unsigned int outgoing:1; /*!< outgoing call */ @@ -162,6 +163,9 @@ static int handle_response_cmti(struct mbl_pvt *pvt, char *buf); static int handle_response_cmgr(struct mbl_pvt *pvt, char *buf); static int handle_response_cusd(struct mbl_pvt *pvt, char *buf); +static int handle_response_busy(struct mbl_pvt *pvt); +static int handle_response_no_dialtone(struct mbl_pvt *pvt, char *buf); +static int handle_response_no_carrier(struct mbl_pvt *pvt, char *buf); static int handle_sms_prompt(struct mbl_pvt *pvt, char *buf); /* CLI stuff */ @@ -420,6 +424,9 @@ AT_CMER, AT_CIND_TEST, AT_CUSD, + AT_BUSY, + AT_NO_DIALTONE, + AT_NO_CARRIER, } at_message_t; static int at_match_prefix(char *buf, char *prefix); @@ -963,6 +970,7 @@ ast_log(LOG_ERROR, "error sending ATD command on %s\n", pvt->id); return -1; } + pvt->hangupcause = 0; pvt->needchup = 1; msg_queue_push(pvt, AT_OK, AT_D); } else { @@ -1294,6 +1302,9 @@ if (ast_channel_trylock(pvt->owner)) { DEADLOCK_AVOIDANCE(&pvt->lock); } else { + if (pvt->hangupcause != 0) { + pvt->owner->hangupcause = pvt->hangupcause; + } ast_queue_hangup(pvt->owner); ast_channel_unlock(pvt->owner); break; @@ -1883,6 +1894,12 @@ return AT_VGS; } else if (at_match_prefix(buf, "+CUSD:")) { return AT_CUSD; + } else if (at_match_prefix(buf, "BUSY")) { + return AT_BUSY; + } else if (at_match_prefix(buf, "NO DIALTONE")) { + return AT_NO_DIALTONE; + } else if (at_match_prefix(buf, "NO CARRIER")) { + return AT_NO_CARRIER; } else { return AT_UNKNOWN; } @@ -1927,6 +1944,12 @@ return "SMS PROMPT"; case AT_CMS_ERROR: return "+CMS ERROR"; + case AT_BUSY: + return "BUSY"; + case AT_NO_DIALTONE: + return "NO DIALTONE"; + case AT_NO_CARRIER: + return "NO CARRIER"; /* at commands */ case AT_A: return "ATA"; @@ -3515,6 +3538,49 @@ return 0; } +/*! + * \brief Handle BUSY messages. + * \param pvt a mbl_pvt structure + * \retval 0 success + * \retval -1 error + */ +static int handle_response_busy(struct mbl_pvt *pvt) +{ + pvt->hangupcause = AST_CAUSE_USER_BUSY; + pvt->needchup = 1; + return 0; +} + +/*! + * \brief Handle NO DIALTONE messages. + * \param pvt a mbl_pvt structure + * \param buf a null terminated buffer containing an AT message + * \retval 0 success + * \retval -1 error + */ +static int handle_response_no_dialtone(struct mbl_pvt *pvt, char *buf) +{ + ast_verb(1, "[%s] mobile reports NO DIALTONE\n", pvt->id); + pvt->needchup = 1; + mbl_queue_control(pvt, AST_CONTROL_CONGESTION); + return 0; +} + +/*! + * \brief Handle NO CARRIER messages. + * \param pvt a mbl_pvt structure + * \param buf a null terminated buffer containing an AT message + * \retval 0 success + * \retval -1 error + */ +static int handle_response_no_carrier(struct mbl_pvt *pvt, char *buf) +{ + ast_verb(1, "[%s] mobile reports NO CARRIER\n", pvt->id); + pvt->needchup = 1; + mbl_queue_control(pvt, AST_CONTROL_CONGESTION); + return 0; +} + static void *do_monitor_phone(void *data) { @@ -3673,6 +3739,30 @@ } ast_mutex_unlock(&pvt->lock); break; + case AT_BUSY: + ast_mutex_lock(&pvt->lock); + if (handle_response_busy(pvt)) { + ast_mutex_unlock(&pvt->lock); + goto e_cleanup; + } + ast_mutex_unlock(&pvt->lock); + break; + case AT_NO_DIALTONE: + ast_mutex_lock(&pvt->lock); + if (handle_response_no_dialtone(pvt, buf)) { + ast_mutex_unlock(&pvt->lock); + goto e_cleanup; + } + ast_mutex_unlock(&pvt->lock); + break; + case AT_NO_CARRIER: + ast_mutex_lock(&pvt->lock); + if (handle_response_no_carrier(pvt, buf)) { + ast_mutex_unlock(&pvt->lock); + goto e_cleanup; + } + ast_mutex_unlock(&pvt->lock); + break; case AT_UNKNOWN: ast_debug(1, "[%s] ignoring unknown message: %s\n", pvt->id, buf); break;