From 2d4d1ba5d41fe0818de6763cb17e7261623d8ffd Mon Sep 17 00:00:00 2001 From: Grzegorz Sluja <grzegorz.sluja@iopsys.eu> Date: Wed, 8 Sep 2021 11:04:48 +0200 Subject: [PATCH] Implementation for new ubus call to get call_status Call Status for each line can be get by: ubus call asterisk call_status '{ "line" : X }', where X is line: {0, 1, 2, or 3} callStatus is set in chan_brcm according to TR-104 requirements: Idle: no ongoing calls Dialing: the process of collecting digits for the calling number in an outgoing call, and ringing in outgoing call. Delivered: N/A Connected: a call is established Alerting: ringing when an incoming call is received Disconnected: the remote party has ended a call. but the local party has not gone on-hook. --- channels/chan_brcm.c | 63 ++++++++++++++++++++++++++++++++++++++++++++ channels/chan_brcm.h | 2 ++ 2 files changed, 65 insertions(+) diff --git a/channels/chan_brcm.c b/channels/chan_brcm.c index 1e82c66d52..ad9b5f5af2 100644 --- a/channels/chan_brcm.c +++ b/channels/chan_brcm.c @@ -211,6 +211,11 @@ enum { __EVENT_MAX, }; +enum { + CALL_STATUS_LINE_ID, + __CALL_STATUS_MAX, +}; + enum { // New ubus objects in global context OBJ_ID, // UBUS ID of object OBJ_PATH, // String path of object @@ -265,6 +270,10 @@ static const struct blobmsg_policy asterisk_event_policy[] = { [EVENT_LINE_ID] = { .name = "line", .type = BLOBMSG_TYPE_INT32 }, }; +static const struct blobmsg_policy asterisk_call_status_policy[] = { + [CALL_STATUS_LINE_ID] = { .name = "line", .type = BLOBMSG_TYPE_INT32 }, +}; + static const struct blobmsg_policy new_obj_policy[] = { [OBJ_ID] = { .name = "id", .type = BLOBMSG_TYPE_INT32 }, // UBUS ID of object [OBJ_PATH] = { .name = "path", .type = BLOBMSG_TYPE_STRING }, // String path of object @@ -828,6 +837,7 @@ static int brcm_call(struct ast_channel *chan, const char *dest, int timeout) pvt_lock(sub->parent, "brcm_call"); p = sub->parent; + strncpy(p->callStatus, "Alerting", CALL_STATUS_MAX_LEN); sub_peer = brcm_subchannel_get_peer(sub); if (!line_config[p->line_id].enabled) { ast_debug(1, "tel_line %d disabled!\n", p->line_id); @@ -897,6 +907,12 @@ static int brcm_hangup(struct ast_channel *ast) } pvt_lock(sub->parent, "TELCHAN hangup"); p = sub->parent; + + if (!strcasecmp(p->callStatus, "Connected") || !strcasecmp(p->callStatus, "Dialing")) + strncpy(p->callStatus, "Disconnected", CALL_STATUS_MAX_LEN); + else + strncpy(p->callStatus, "Idle", CALL_STATUS_MAX_LEN); + sub_peer = brcm_subchannel_get_peer(sub); ast_debug(1, "brcm_hangup(%s) line_id=%d connection_id=%d dialtone=%s channel_state=%s\n", ast_channel_name(ast), p->line_id, sub->connection_id, dialtone_map[p->dialtone].str, @@ -1023,6 +1039,7 @@ static int brcm_answer(struct ast_channel *ast) ast_debug(1, "brcm_answer(%s)\n", ast_channel_name(ast)); pvt_lock(pvt, "TELCHAN answer"); + strncpy(pvt->callStatus, "Connected", CALL_STATUS_MAX_LEN); /* For attended call transfer, if the transfer target has accepted the call initiated by * us as the tranferee, we can terminate the original call with the transferor */ @@ -1672,6 +1689,7 @@ static int handle_dialtone_timeout(const void *data) struct brcm_pvt *p = (struct brcm_pvt *) data; pvt_lock(p, "dialtone timeout"); + strncpy(p->callStatus, "Disconnected", CALL_STATUS_MAX_LEN); //ast_mutex_lock(&p->lock); p->dialtone_timeout_timer_id = -1; @@ -2394,6 +2412,10 @@ static void *brcm_process_event(struct endpt_event *ev) switch (ev->event) { case EVENT_OFFHOOK: { ast_debug(9, "EVENT_OFFHOOK detected\n"); + if (!strlen(p->callStatus) || !strcasecmp(p->callStatus, "Idle")) + strncpy(p->callStatus, "Dialing", CALL_STATUS_MAX_LEN); + else if (!strcasecmp(p->callStatus, "Alerting")) + strncpy(p->callStatus, "Connected", CALL_STATUS_MAX_LEN); /* Reset the dtmf buffer */ memset(p->dtmfbuf, 0, sizeof(p->dtmfbuf)); @@ -2456,6 +2478,7 @@ static void *brcm_process_event(struct endpt_event *ev) } case EVENT_ONHOOK: { ast_debug(9, "EVENT_ONHOOK detected\n"); + strncpy(p->callStatus, "Idle", CALL_STATUS_MAX_LEN); if (sub->channel_state == OFFHOOK || sub->channel_state == AWAITONHOOK) { /* Received EVENT_ONHOOK in state OFFHOOK/AWAITONHOOK, stop dial/congestion tone */ brcm_stop_dialtone(p); @@ -3707,8 +3730,48 @@ static int asterisk_event(struct ubus_context *ctx, struct ubus_object *obj, return UBUS_STATUS_OK; } +// Reception of RPC call +// ubus call asterisk call_status '{ "line" : 1 }' +static int asterisk_call_status(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, + struct blob_attr *msg) +{ + struct blob_attr *tb[__EVENT_MAX]; + enum ubus_msg_status res = UBUS_STATUS_UNKNOWN_ERROR; + struct blob_buf blob; + int line; + + blobmsg_parse(asterisk_call_status_policy, __CALL_STATUS_MAX, + tb, blob_data(msg), blob_len(msg)); + + if (!tb[CALL_STATUS_LINE_ID] ) + return UBUS_STATUS_INVALID_ARGUMENT; + + memset(&blob, 0, sizeof(blob)); + if(blob_buf_init(&blob, 0)) + return UBUS_STATUS_UNKNOWN_ERROR; + + line = blobmsg_get_u32(tb[CALL_STATUS_LINE_ID]); + + struct brcm_pvt *p = iflist; + while(p) { + if (line == p->line_id) { + blobmsg_add_u32(&blob, "line", p->line_id); + blobmsg_add_string(&blob, "call_status", strlen(p->callStatus) ? p->callStatus : "Idle"); + res = UBUS_STATUS_OK; + break; + } + p = brcm_get_next_pvt(p); + } + + ubus_send_reply(ctx, req, blob.head); + blob_buf_free(&blob); + return res; +} + static struct ubus_method asterisk_methods[] = { UBUS_METHOD("event", asterisk_event, asterisk_event_policy), + UBUS_METHOD("call_status", asterisk_call_status, asterisk_call_status_policy), }; static struct ubus_object_type asterisk_obj_type = UBUS_OBJECT_TYPE("asterisk", asterisk_methods); diff --git a/channels/chan_brcm.h b/channels/chan_brcm.h index 33a7da3fa1..375d1dd78c 100644 --- a/channels/chan_brcm.h +++ b/channels/chan_brcm.h @@ -10,6 +10,7 @@ #define DEFAULT_CALLER_ID "Unknown" #define PHONE_MAX_BUF 480 +#define CALL_STATUS_MAX_LEN 14 #define TIMEMSEC 1000 @@ -145,6 +146,7 @@ struct brcm_pvt { char language[MAX_LANGUAGE]; char cid_num[AST_MAX_EXTENSION]; char cid_name[AST_MAX_EXTENSION]; + char callStatus[CALL_STATUS_MAX_LEN]; struct brcm_subchannel *sub[NUM_SUBCHANNELS]; /* List of sub-channels, needed for callwaiting and 3-way support */ int hf_detected; /* Hook flash detected */ -- GitLab