diff --git a/libvoice/common.c b/libvoice/common.c index f75cdd43852e439bb0e335f5ed536e6a5d40add4..53b46801d4b6964afa85fcb2cf9ed78fed272a96 100644 --- a/libvoice/common.c +++ b/libvoice/common.c @@ -124,7 +124,9 @@ int voice_line_preinit(void) { lines[i].type = terminal_info.voice_ports[i]; ENDPT_DBG("lines[%d].type=%d\n", i, lines[i].type); lines[i].pcm_callid[PCM_0] = CALLID_INVALID; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", i, PCM_0, lines[i].pcm_callid[PCM_0]); lines[i].pcm_callid[PCM_1] = CALLID_INVALID; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", i, PCM_1, lines[i].pcm_callid[PCM_1]); } return 0; diff --git a/line-dect.c b/line-dect.c index 74b3048891fd2948485b16a9c9393f5301dc7578..9064d4402770e3188d8e70b647b268cbb9553505 100644 --- a/line-dect.c +++ b/line-dect.c @@ -216,6 +216,8 @@ int ubus_cb_dectmngr_replied(struct line_req_t *req, enum ubus_msg_status reply_ if(!req) return -1; + struct line_t *line = &lines[req->line]; + ENDPT_DBG("got answer req %p from dectmngr, action: %d, line: %d, pcmId: %d, conId: %d\n", req, req->action, req->line, req->pcm_id, req->connection_id); pcm_states_dump(__func__, req->line); @@ -226,28 +228,40 @@ int ubus_cb_dectmngr_replied(struct line_req_t *req, enum ubus_msg_status reply_ reply_status = UBUS_STATUS_UNKNOWN_ERROR; } break; - case ACTION_CONN_CLOSE: case ACTION_RINGING_STOP: - if (req->pcm_id == PCM_0 || req->pcm_id == PCM_1) { - lines[req->line].pcm_callid[req->pcm_id] = CALLID_INVALID; + if (get_callid_state(line->pcm_callid[req->pcm_id]) == CALLID_ESTABLISHED) + break; // Don't clear if call is already established + // intentional fallthrough + case ACTION_CONN_CLOSE: + if (is_valid_pcm_id(req->pcm_id)) { + line->pcm_callid[req->pcm_id] = CALLID_INVALID; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", req->line, req->pcm_id, line->pcm_callid[req->pcm_id]); } else if (req->pcm_id == -1) { - // Close all calls - lines[req->line].pcm_callid[PCM_0] = CALLID_INVALID; - lines[req->line].pcm_callid[PCM_1] = CALLID_INVALID; + // Clear both PCM slots + for (int i = 0; i <= PCM_1; ++i) { + line->pcm_callid[i] = CALLID_INVALID; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", req->line, i, CALLID_INVALID); + } + } + // If no established calls left, close connection + if (get_callid_state(line->pcm_callid[PCM_0]) != CALLID_ESTABLISHED && + get_callid_state(line->pcm_callid[PCM_1]) != CALLID_ESTABLISHED) { + reply_status = voice_connection_close(req->line, req->line) + ? UBUS_STATUS_UNKNOWN_ERROR + : UBUS_STATUS_OK; } - if (get_callid_state(lines[req->line].pcm_callid[PCM_0]) == CALLID_ESTABLISHED || - get_callid_state(lines[req->line].pcm_callid[PCM_1]) == CALLID_ESTABLISHED) - break; - reply_status = voice_connection_close(req->line, req->line) ? // Close regardless of any dectmngr error. - UBUS_STATUS_UNKNOWN_ERROR : UBUS_STATUS_OK; break; case ACTION_SIG_RING: - if ((req->pcm_id == PCM_0 && get_callid_state(lines[req->line].pcm_callid[PCM_1]) == CALLID_OBTAINING) || - (req->pcm_id == PCM_1 && get_callid_state(lines[req->line].pcm_callid[PCM_0]) == CALLID_OBTAINING)) - break; - if (req->pcm_id == PCM_0 || req->pcm_id == PCM_1) - lines[req->line].pcm_callid[req->pcm_id] = CALLID_OBTAINING; + { + int other_pcm = (req->pcm_id == PCM_0) ? PCM_1 : PCM_0; + if (is_valid_pcm_id(req->pcm_id)) { + if (get_callid_state(line->pcm_callid[other_pcm]) != CALLID_OBTAINING) { + line->pcm_callid[req->pcm_id] = CALLID_OBTAINING; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", req->line, req->pcm_id, CALLID_OBTAINING); + } + } break; + } default: break; } diff --git a/line.c b/line.c index 5f29336d89e5ef65b19547fc51837ef199948669..762568bbc929150e192ee7743a65bed846d5446e 100644 --- a/line.c +++ b/line.c @@ -44,6 +44,11 @@ callid_state get_callid_state(int call_id) { return CALLID_ESTABLISHED; } +bool is_valid_pcm_id(int id) +{ + return id == PCM_0 || id == PCM_1; +} + static int send_dect_event_to_asterisk(int line, struct dect_event_t dectEvnt) { struct line_event_t *msg; @@ -309,6 +314,7 @@ int line_signal(int line, const char *signame, const char *data, struct voice_ub { const struct voice_signal_t *sig; int res = 0; + int pcm = PCM_0; ENDPT_DBG("line=%d(type:%d), signame=%s, data=%s\n", line, lines[line].type, signame, data); @@ -328,8 +334,13 @@ int line_signal(int line, const char *signame, const char *data, struct voice_ub case VOICE_SIG_CALLID: case VOICE_SIG_RINGING: if(atoi(data) == 0) { - res = line_signal_ring(line, get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_OBTAINING ? - PCM_0 : PCM_1, sig->signal, data, ubus_req); + if ( get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_OBTAINING || + get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_INVALID ) + pcm = PCM_0; + else + pcm = PCM_1; + + res = line_signal_ring(line, pcm, sig->signal, data, ubus_req); lines[line].signaled_call_waiting = 0; } else { res = line_signal_ring(line, get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_INVALID ? @@ -430,10 +441,14 @@ int line_new_connection_by_asterisk(int line, int connection, struct voice_ubus_ ENDPT_DBG("%s line: %d, connection: %d\n", __func__, line, connection); pcm_states_dump(__func__, line); - if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_OBTAINING) + if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_OBTAINING) { lines[line].pcm_callid[PCM_0] = connection; - else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_OBTAINING) + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_0, lines[line].pcm_callid[PCM_0]); + } + else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_OBTAINING) { lines[line].pcm_callid[PCM_1] = connection; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_1, lines[line].pcm_callid[PCM_1]); + } if (lines[line].type == VOICE_LINE_DECT) { if (voice_line_is_offhook(line) || voice_line_get_connection_count(line) > 0) { @@ -509,10 +524,12 @@ int line_close_connection_by_asterisk(int line, int connection, struct voice_ubu get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_INVALID) { line_req->pcm_id = PCM_0; lines[line].pcm_callid[PCM_0] = CALLID_INVALID; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_0, lines[line].pcm_callid[PCM_0]); } else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_ESTABLISHED && get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_INVALID) { line_req->pcm_id = PCM_1; lines[line].pcm_callid[PCM_1] = CALLID_INVALID; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_1, lines[line].pcm_callid[PCM_1]); } line_req->action = ACTION_CONN_CLOSE; if (connection == -1) { @@ -527,10 +544,14 @@ int line_close_connection_by_asterisk(int line, int connection, struct voice_ubu break; default: - if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_ESTABLISHED) + if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_ESTABLISHED) { lines[line].pcm_callid[PCM_0] = CALLID_INVALID; - else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_ESTABLISHED) + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_0, lines[line].pcm_callid[PCM_0]); + } + else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_ESTABLISHED) { lines[line].pcm_callid[PCM_1] = CALLID_INVALID; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_1, lines[line].pcm_callid[PCM_1]); + } return voice_connection_close(line, line); } @@ -575,9 +596,11 @@ int line_release_connection_by_asterisk(int line, int connection, struct voice_u if (lines[line].pcm_callid[PCM_0] == connection) { line_req->pcm_id = PCM_0; lines[line].pcm_callid[PCM_0] = CALLID_INVALID; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_0, lines[line].pcm_callid[PCM_0]); } else if (lines[line].pcm_callid[PCM_1] == connection) { line_req->pcm_id = PCM_1; lines[line].pcm_callid[PCM_1] = CALLID_INVALID; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_1, lines[line].pcm_callid[PCM_1]); } line_req->action = ACTION_CONN_CLOSE; memcpy(&line_req->ubus, ubus_req, sizeof(struct voice_ubus_req_t)); @@ -588,10 +611,14 @@ int line_release_connection_by_asterisk(int line, int connection, struct voice_u break; default: - if (lines[line].pcm_callid[PCM_0] == connection) + if (lines[line].pcm_callid[PCM_0] == connection) { lines[line].pcm_callid[PCM_0] = CALLID_INVALID; - else if (lines[line].pcm_callid[PCM_1] == connection) + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_0, lines[line].pcm_callid[PCM_0]); + } + else if (lines[line].pcm_callid[PCM_1] == connection) { lines[line].pcm_callid[PCM_1] = CALLID_INVALID; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_1, lines[line].pcm_callid[PCM_1]); + } return voice_connection_close(line, line); } @@ -610,10 +637,14 @@ int line_update_connection_by_pbx(int line, int pcm_callid) if(lines[line].type != VOICE_LINE_DECT) return 0; - if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_OBTAINING) + if (get_callid_state(lines[line].pcm_callid[PCM_0]) == CALLID_OBTAINING) { lines[line].pcm_callid[PCM_0] = pcm_callid; - else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_OBTAINING) + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_0, lines[line].pcm_callid[PCM_0]); + } + else if (get_callid_state(lines[line].pcm_callid[PCM_1]) == CALLID_OBTAINING) { lines[line].pcm_callid[PCM_1] = pcm_callid; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, PCM_1, lines[line].pcm_callid[PCM_1]); + } return 0; } @@ -632,8 +663,9 @@ int line_new_connection_by_dect(int line, const char *cid, int pcm, struct voice ENDPT_DBG("line=%d, pcm=%d, cid=%s\n", line, pcm, cid); pcm_states_dump(__func__, line); - if (pcm == PCM_0 || pcm == PCM_1) { + if (is_valid_pcm_id(pcm)) { lines[line].pcm_callid[pcm] = CALLID_OBTAINING; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, pcm, lines[line].pcm_callid[pcm]); lines[line].signaled_call_waiting = 0; } @@ -739,8 +771,10 @@ int line_close_connection_by_dect(int line, int pcm, struct voice_ubus_req_t *ub get_callid_state(lines[line].pcm_callid[PCM_1]) <= CALLID_OBTAINING) { if(pcm == CALL_DEFAULT0 || pcm == CALL_DEFAULT1) { lines[line].pcm_callid[pcm] = CALLID_INVALID; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, pcm, lines[line].pcm_callid[pcm]); if (get_callid_state(lines[line].pcm_callid[1-pcm]) == CALLID_OBTAINING) { lines[line].pcm_callid[1-pcm] = CALLID_INVALID; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, 1-pcm, lines[line].pcm_callid[1-pcm]); } } voice_line_simulate_hook(line, VOICE_EVT_ONHOOK); @@ -748,8 +782,10 @@ int line_close_connection_by_dect(int line, int pcm, struct voice_ubus_req_t *ub pcm, UBUS_STATUS_OK); } - if(pcm == CALL_DEFAULT0 || pcm == CALL_DEFAULT1) + if(pcm == CALL_DEFAULT0 || pcm == CALL_DEFAULT1) { lines[line].pcm_callid[pcm] = CALLID_INVALID; + ENDPT_DBG("line: %d set pcm_callid[%d] to %d\n", line, pcm, lines[line].pcm_callid[pcm]); + } if(send_dect_event_to_asterisk(line, dect_event_map[DECT_EVT_RELEASE])) return -1; diff --git a/line.h b/line.h index a289c469c421ef20dba5b4e7d9dc6125779c6ae6..7100a6747e7db085ec13ad115c7b1b40a16fbf10 100644 --- a/line.h +++ b/line.h @@ -67,5 +67,6 @@ int line_close_connection_by_dect(int line, int pcm, struct voice_ubus_req_t *ub int line_signal(int line, const char *signame, const char *data, struct voice_ubus_req_t *ubus_req); void pcm_states_dump(const char* func, int line); callid_state get_callid_state(int call_id); +bool is_valid_pcm_id(int id); #endif