diff -Nur channels.old/chan_mobile.c channels/chan_mobile.c --- channels.old/chan_mobile.c 2009-07-13 22:03:10.000000000 +0200 +++ channels/chan_mobile.c 2009-07-13 22:04:10.000000000 +0200 @@ -330,6 +330,7 @@ struct hfp_cind cind_map; /*!< the cind name to index mapping for this AG */ int rsock; /*!< our rfcomm socket */ int rport; /*!< our rfcomm port */ + int sent_alerting; /*!< have we sent alerting? */ }; @@ -427,6 +428,7 @@ AT_BUSY, AT_NO_DIALTONE, AT_NO_CARRIER, + AT_ECAM, } at_message_t; static int at_match_prefix(char *buf, char *prefix); @@ -1900,6 +1902,8 @@ return AT_NO_DIALTONE; } else if (at_match_prefix(buf, "NO CARRIER")) { return AT_NO_CARRIER; + } else if (at_match_prefix(buf, "*ECAV:")) { + return AT_ECAM; } else { return AT_UNKNOWN; } @@ -1977,6 +1981,8 @@ return "AT+CIND=?"; case AT_CUSD: return "AT+CUSD"; + case AT_ECAM: + return "AT*ECAM"; } } @@ -1985,6 +1991,54 @@ * bluetooth handsfree profile helpers */ + /*! + * \brief Parse a ECAV event. + * \param hfp an hfp_pvt struct + * \param buf the buffer to parse (null terminated) + * \return -1 on error (parse error) or a ECAM value on success + */ +static int hfp_parse_ecav(struct hfp_pvt *hfp, char *buf) +{ + char command[] = "*ECAV:"; + char trimmedString[1024]; + int length; + + length = strcspn(buf,command) + strlen(command); + + if (buf[length] == ' ') { + length++; + } + + strncpy(trimmedString, &buf[length], sizeof(trimmedString)); + + char seperator[] = ","; + char *commandValue; + int i=0; + + commandValue = strtok(trimmedString, seperator); + + while(commandValue != NULL) { + if (i==1) + { + return atoi(commandValue); + } + + commandValue = strtok(NULL, seperator); + i++; + } + + return -1; +} + +/*! + * \brief Enable sony erricson extensions / indications. + * \param hfp an hfp_pvt struct + */ +static int hfp_send_ecam(struct hfp_pvt *hfp) +{ + return rfcomm_write(hfp->rsock, "AT*ECAM=1\r"); +} + /*! * \brief Parse a CIEV event. * \param hfp an hfp_pvt struct @@ -3091,6 +3145,14 @@ break; case AT_CLIP: ast_debug(1, "[%s] caling line indication enabled\n", pvt->id); + if (hfp_send_ecam(pvt->hfp) || msg_queue_push(pvt, AT_OK, AT_ECAM)) { + ast_debug(1, "[%s] error synchronizing gain settings\n", pvt->id); + goto e_return; + } + + break; + case AT_ECAM: + ast_debug(1, "[%s] Sony Ericsson call monitoring is active on device\n", pvt->id); if (hfp_send_vgs(pvt->hfp, 15) || msg_queue_push(pvt, AT_OK, AT_VGS)) { ast_debug(1, "[%s] error synchronizing gain settings\n", pvt->id); goto e_return; @@ -3222,6 +3284,21 @@ ast_debug(1, "[%s] error setting CNMI\n", pvt->id); ast_debug(1, "[%s] no SMS support\n", pvt->id); break; + case AT_ECAM: + ast_debug(1, "[%s] does not support Sony Ericsson extensions\n", pvt->id); + + /* this is not a fatal error, let's continue with initilization */ + + if (hfp_send_vgs(pvt->hfp, 15) || msg_queue_push(pvt, AT_OK, AT_VGS)) { + ast_debug(1, "[%s] error synchronizing gain settings\n", pvt->id); + goto e_return; + } + + pvt->timeout = -1; + pvt->hfp->initialized = 1; + ast_verb(3, "Bluetooth Device %s initialized and ready.\n", pvt->id); + + break; /* end initilization stuff */ case AT_A: @@ -3317,6 +3394,9 @@ case HFP_CIND_CALLSETUP_NONE: if (pvt->hfp->cind_state[pvt->hfp->cind_map.call] != HFP_CIND_CALL_ACTIVE) { if (pvt->owner) { + if (pvt->hfp->sent_alerting == 1) { + handle_response_busy(pvt); + } if (mbl_queue_hangup(pvt)) { ast_log(LOG_ERROR, "[%s] error queueing hangup, disconnectiong...\n", pvt->id); return -1; @@ -3335,6 +3415,7 @@ break; case HFP_CIND_CALLSETUP_OUTGOING: if (pvt->outgoing) { + pvt->hfp->sent_alerting = 0; ast_debug(1, "[%s] outgoing call\n", pvt->id); } else { ast_verb(3, "[%s] user dialed from handset, disconnecting\n", pvt->id); @@ -3345,6 +3426,7 @@ if (pvt->outgoing) { ast_debug(1, "[%s] remote alerting\n", pvt->id); mbl_queue_control(pvt, AST_CONTROL_RINGING); + pvt->hfp->sent_alerting = 1; } break; } @@ -3548,6 +3630,7 @@ { pvt->hangupcause = AST_CAUSE_USER_BUSY; pvt->needchup = 1; + mbl_queue_control(pvt, AST_CONTROL_BUSY); return 0; } @@ -3763,6 +3846,16 @@ } ast_mutex_unlock(&pvt->lock); break; + case AT_ECAM: + ast_mutex_lock(&pvt->lock); + if (hfp_parse_ecav(pvt, buf) == 7) { + if (handle_response_busy(pvt)) { + 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;