freeswitch/libs/sipcc/core/gsm/ccapi.c

1750 lines
54 KiB
C
Executable File

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "cpr_types.h"
#include "cpr_stdio.h"
#include "cpr_string.h"
#include "cpr_memory.h"
#include "cpr_stdlib.h"
#include "ccapi.h"
#include "ccsip_task.h"
#include "debug.h"
#include "phone_debug.h"
#include "phntask.h"
#include "phone.h"
#include "text_strings.h"
#include "string_lib.h"
#include "gsm.h"
#include "vcm.h"
#include "sip_common_regmgr.h"
#include "util_string.h"
static const char *cc_src_names[] = {
"GSM",
"UI",
"SIP",
"MISC_APP",
"CCAPP"
};
#define CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, msg) \
DEF_DEBUG(DEB_L_C_F_PREFIX"%s -> %s: %-20s\n",\
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__),\
cc_src_name(src_id), cc_src_name(dst_id), msg)
callid_t cc_get_new_call_id (void)
{
static callid_t call_id = CC_NO_CALL_ID;
if (++call_id == 0) {
call_id = 1;
}
return call_id;
}
const char *
cc_src_name (cc_srcs_t id)
{
if ((id <= CC_SRC_MIN) || (id >= CC_SRC_MAX)) {
return get_debug_string(GSM_UNDEFINED);
}
return cc_src_names[id];
}
static void
cc_print_msg (char *pData, int len)
{
int ix;
int msg_id = *((int *) pData);
buginf("\n" CCA_F_PREFIX "cc_msg= %s, 0x=", __FUNCTION__,
cc_msg_name((cc_msgs_t) msg_id));
for (ix = 0; ix < len; ix++) {
if ((ix % 8 == 0) && ix) {
buginf(" ");
}
if (ix % 24 == 0) {
buginf("\n");
}
buginf("%02x ", *pData++);
}
buginf("\n");
}
/*
* Return a SysBuf and initialize
* Parameters supplied by application:
* - MinSize: size of buffer requested
*/
cprBuffer_t
cc_get_msg_buf (int min_size)
{
cprBuffer_t buf;
if (min_size > CPR_MAX_MSG_SIZE) {
/* Size requested exceeds maximum ethernet buffer */
GSM_ERR_MSG(get_debug_string(DEBUG_MSG_BUFFER_TOO_BIG),
__FUNCTION__, min_size);
return (cprBuffer_t)NULL;
}
buf = gsm_get_buffer((uint16_t) min_size);
if (!buf) {
GSM_ERR_MSG(get_debug_string(DEBUG_SYSBUF_UNAVAILABLE), __FUNCTION__);
return (cprBuffer_t)NULL;
}
/* Clean out the data region of the message */
memset(buf, 0, min_size);
CC_DEBUG(DEB_F_PREFIX "Msg id = 0x%0x\n", DEB_F_PREFIX_ARGS(CC_API, __FUNCTION__), buf);
return buf;
}
static cc_rcs_t
cc_send_cmd_msg (uint32_t cmd, cprBuffer_t buf, uint16_t len, cc_srcs_t dst_id)
{
cpr_status_e rc;
CC_DEBUG_MSG cc_print_msg((char *) buf, len);
switch (dst_id) {
case CC_SRC_GSM:
rc = gsm_send_msg(cmd, buf, len);
if (rc == CPR_FAILURE) {
cc_free_msg_data((cc_msg_t *) buf);
cpr_free(buf);
}
break;
case CC_SRC_SIP:
rc = SIPTaskSendMsg(cmd, buf, len, NULL);
if (rc == CPR_FAILURE) {
cc_free_msg_data((cc_msg_t *) buf);
cpr_free(buf);
}
break;
default:
rc = CPR_FAILURE;
break;
}
return (rc == CPR_SUCCESS) ? CC_RC_SUCCESS : CC_RC_ERROR;
}
static cc_rcs_t
cc_send_msg (cprBuffer_t buf, uint16_t len, cc_srcs_t dst_id)
{
cpr_status_e rc;
CC_DEBUG_MSG cc_print_msg((char *) buf, len);
switch (dst_id) {
case CC_SRC_GSM:
rc = gsm_send_msg(GSM_SIP, buf, len);
if (rc == CPR_FAILURE) {
cc_free_msg_data((cc_msg_t *) buf);
cpr_free(buf);
}
break;
case CC_SRC_SIP:
rc = SIPTaskSendMsg(SIP_GSM, buf, len, NULL);
if (rc == CPR_FAILURE) {
cc_free_msg_data((cc_msg_t *) buf);
cpr_free(buf);
}
break;
default:
rc = CPR_FAILURE;
break;
}
return (rc == CPR_SUCCESS) ? CC_RC_SUCCESS : CC_RC_ERROR;
}
/*
* ROUTINE: cc_initialize_msg_body_parts_info
*
* DESCRIPTION: Initializes the msg body part.
*
* PARAMETERS:
* msg_body - pointer to cc_msgbody_info_t to be initialized.
*
* RETURNS:
* None.
*
* NOTES: None
*/
void
cc_initialize_msg_body_parts_info (cc_msgbody_info_t *msg_body)
{
if (msg_body == NULL) {
return;
}
msg_body->num_parts = 0;
memset(&msg_body->parts[0], 0, sizeof(msg_body->parts));
}
/*
* ROUTINE: cc_mv_msg_body_parts
*
* DESCRIPTION: Move the body parts from source to destination.
*
* PARAMETERS:
* dst_msg - pointer to destination cc_msgbody_info_t
* src_msg - pointer to source cc_msgbody_info_t
*
* RETURNS:
* None
*
* NOTES: The function attempts to free the message bodies
* that might be in the destination to prevent
* memory leak from overridden the destination by
* moving the new message source.
*
* The dst_msg must be pointed to the initialized
* message block either with all zero or at least
* number of parts is set to zero to prevent
* freeing an invalid address.
*/
void
cc_mv_msg_body_parts (cc_msgbody_info_t *dst_msg, cc_msgbody_info_t *src_msg)
{
if (dst_msg == NULL) {
GSM_ERR_MSG(CCA_F_PREFIX "dst is NULL\n", __FUNCTION__);
return;
}
/* Free the msg. bodies that might be in the dest first */
cc_free_msg_body_parts(dst_msg);
if (src_msg != NULL) {
/* copy all of the parts */
*dst_msg = *src_msg;
src_msg->num_parts = 0;
}
}
/*
* ROUTINE: cc_free_msg_body_parts
*
* DESCRIPTION: Free elements in the msg body part structure.
*
* PARAMETERS:
* msg_body - pointer to cc_msgbody_info_t for freeing.
*
* RETURNS:
* None
*
* NOTES: None
*/
void
cc_free_msg_body_parts (cc_msgbody_info_t *msg_body)
{
cc_msgbody_t *part;
if ((msg_body == NULL) || (msg_body->num_parts == 0)) {
/* Nothing to be freed */
return;
}
/* Free all of the bodies and their contents */
part = &msg_body->parts[0];
for (; msg_body->num_parts; msg_body->num_parts--, part++) {
if (part->body != NULL) {
cpr_free(part->body);
part->body = NULL;
}
if (part->content_id != NULL) {
cpr_free(part->content_id);
part->content_id = NULL;
}
}
}
/*
* ROUTINE: cc_get_msg_body_info_ptr_from_feature_data
*
* DESCRIPTION: The function gets msg pointer from a cc_feature_data_t
* structure if there is one. The msg body
* info does not aways attach to all features
* i.e. only certain feature IDs have msg body
* in the feature data. The function returns
* pointer to the msg body if the feature has
* valid data and for those features that contain
* msg body.
*
* PARAMETERS:
* id - cc_feature_t.
* data - pointer to cc_feature_data_t of the feature data to
* whose embedded resources need to be freed.
*
* RETURNS:
* msg_body - pointer to msg_body_info_t if there is
* a msg.
*
* NOTES: None
*/
static cc_msgbody_info_t *
cc_get_msg_body_info_ptr_from_feature_data (cc_features_t id,
cc_feature_data_t *data)
{
cc_msgbody_info_t *msg_body = NULL;
if (data == NULL) {
return (NULL);
}
switch (id) {
case CC_FEATURE_HOLD:
msg_body = &data->hold.msg_body;
break;
case CC_FEATURE_RESUME:
case CC_FEATURE_MEDIA:
msg_body = &data->resume.msg_body;
break;
case CC_FEATURE_UPDATE:
msg_body = &data->update.msg_body;
break;
default:
/*
* Other ones do not have msg body info yet, add the handling here
* when adding feature that needs msg body info.
*/
break;
}
return (msg_body);
}
/*
* ROUTINE: cc_cp_caller
*
* DESCRIPTION: Copy caller ID and other fields from source to destination.
*
* PARAMETERS:
* dst_caller - pointer to destination cc_caller_id_t
* src_caller - pointer to source cc_caller_id_t
*
* RETURNS:
* None
*
* Note: See also cc_mv_caller_id() cc_free_caller().
*/
static void
cc_cp_caller (cc_caller_id_t *dst_caller, cc_caller_id_t *src_caller)
{
if ((src_caller == NULL) || (dst_caller == NULL)) {
return;
}
dst_caller->calling_name = strlib_empty();
if (src_caller->calling_name != NULL) {
dst_caller->calling_name = strlib_update(dst_caller->calling_name,
src_caller->calling_name);
}
dst_caller->calling_number = strlib_empty();
if (src_caller->calling_number != NULL) {
dst_caller->calling_number = strlib_update(dst_caller->calling_number,
src_caller->calling_number);
}
dst_caller->alt_calling_number = strlib_empty();
if (src_caller->alt_calling_number != NULL) {
dst_caller->alt_calling_number = strlib_update(dst_caller->alt_calling_number,
src_caller->alt_calling_number);
}
dst_caller->called_name = strlib_empty();
if (src_caller->called_name != NULL) {
dst_caller->called_name = strlib_update(dst_caller->called_name,
src_caller->called_name);
}
dst_caller->called_number = strlib_empty();
if (src_caller->called_number != NULL) {
dst_caller->called_number = strlib_update(dst_caller->called_number,
src_caller->called_number);
}
dst_caller->orig_called_name = strlib_empty();
if (src_caller->orig_called_name != NULL) {
dst_caller->orig_called_name =
strlib_update(dst_caller->orig_called_name,
src_caller->orig_called_name);
}
dst_caller->orig_called_number = strlib_empty();
if (src_caller->orig_called_number != NULL) {
dst_caller->orig_called_number =
strlib_update(dst_caller->orig_called_number,
src_caller->orig_called_number);
}
dst_caller->last_redirect_name = strlib_empty();
if (src_caller->last_redirect_name != NULL) {
dst_caller->last_redirect_name =
strlib_update(dst_caller->last_redirect_name,
src_caller->last_redirect_name);
}
dst_caller->last_redirect_number = strlib_empty();
if (src_caller->last_redirect_number) {
dst_caller->last_redirect_number =
strlib_update(dst_caller->last_redirect_number,
src_caller->last_redirect_number);
}
dst_caller->orig_rpid_number = strlib_empty();
if (src_caller->orig_rpid_number != NULL) {
dst_caller->orig_rpid_number =
strlib_update(dst_caller->orig_rpid_number,
src_caller->orig_rpid_number);
}
dst_caller->display_calling_number = src_caller->display_calling_number;
dst_caller->display_called_number = src_caller->display_called_number;
dst_caller->call_type = src_caller->call_type;
dst_caller->call_instance_id = src_caller->call_instance_id;
}
/*
* ROUTINE: cc_mv_caller_id
*
* DESCRIPTION: Move caller ID fields from source to destination.
* The caller ID fields from the destination will be
* freed if necessary prior to the move. This allows
* caller to replace the older IDs with the new IDs
* without data duplication.
*
* PARAMETERS:
* dst_caller - pointer to destination cc_caller_id_t
* src_caller - pointer to source cc_caller_id_t
*
* RETURNS:
* None
*
* Note: See also cc_cp_caller() cc_free_caller().
*/
void
cc_mv_caller_id (cc_caller_id_t *dst_caller, cc_caller_id_t *src_caller)
{
if ((src_caller == NULL) || (dst_caller == NULL)) {
return;
}
/*
* Move the IDs from the source to the destination.
* After moved the IDs from the source to the destination then
* the source needs to be NULL.
*/
if (src_caller->calling_name != NULL) {
if (dst_caller->calling_name != NULL) {
strlib_free(dst_caller->calling_name);
}
dst_caller->calling_name = src_caller->calling_name;
src_caller->calling_name = NULL;
}
if (src_caller->calling_number != NULL) {
if (dst_caller->calling_number != NULL) {
strlib_free(dst_caller->calling_number);
}
dst_caller->calling_number = src_caller->calling_number;
src_caller->calling_number = NULL;
}
if (src_caller->alt_calling_number != NULL) {
if (dst_caller->alt_calling_number != NULL) {
strlib_free(dst_caller->alt_calling_number);
}
dst_caller->alt_calling_number = src_caller->alt_calling_number;
src_caller->alt_calling_number = NULL;
}
if (src_caller->called_name != NULL) {
if (dst_caller->called_name != NULL) {
strlib_free(dst_caller->called_name);
}
dst_caller->called_name = src_caller->called_name;
src_caller->called_name = NULL;
}
if (src_caller->called_number != NULL) {
if (dst_caller->called_number != NULL) {
strlib_free(dst_caller->called_number);
}
dst_caller->called_number = src_caller->called_number;
src_caller->called_number = NULL;
}
if (src_caller->orig_called_name != NULL) {
if (dst_caller->orig_called_name != NULL) {
strlib_free(dst_caller->orig_called_name);
}
dst_caller->orig_called_name = src_caller->orig_called_name;
src_caller->orig_called_name = NULL;
}
if (src_caller->orig_called_number != NULL) {
if (dst_caller->orig_called_number != NULL) {
strlib_free(dst_caller->orig_called_number);
}
dst_caller->orig_called_number = src_caller->orig_called_number;
src_caller->orig_called_number = NULL;
}
if (src_caller->last_redirect_name != NULL) {
if (dst_caller->last_redirect_name != NULL) {
strlib_free(dst_caller->last_redirect_name);
}
dst_caller->last_redirect_name = src_caller->last_redirect_name;
src_caller->last_redirect_name = NULL;
}
if (src_caller->last_redirect_number != NULL) {
if (dst_caller->last_redirect_number != NULL) {
strlib_free(dst_caller->last_redirect_number);
}
dst_caller->last_redirect_number = src_caller->last_redirect_number;
src_caller->last_redirect_number = NULL;
}
if (src_caller->orig_rpid_number != NULL) {
if (dst_caller->orig_rpid_number != NULL) {
strlib_free(dst_caller->orig_rpid_number);
}
dst_caller->orig_rpid_number = src_caller->orig_rpid_number;
src_caller->orig_rpid_number = NULL;
}
dst_caller->display_calling_number = src_caller->display_calling_number;
dst_caller->display_called_number = src_caller->display_called_number;
}
/*
* ROUTINE: cc_free_caller_id
*
* DESCRIPTION: Free caller ID fields. The IDs that are not NULL IDs will be
* freed because others might have been moved already.
*
* PARAMETERS:
* caller - pointer to destination cc_caller_id_t
*
* RETURNS:
* None
*
* Note: See also cc_cp_caller() cc_mv_caller().
*/
static void
cc_free_caller_id (cc_caller_id_t *caller)
{
if (caller == NULL) {
return;
}
if (caller->calling_name != NULL) {
strlib_free(caller->calling_name);
}
if (caller->calling_number != NULL) {
strlib_free(caller->calling_number);
}
if (caller->alt_calling_number != NULL) {
strlib_free(caller->alt_calling_number);
}
if (caller->called_name != NULL) {
strlib_free(caller->called_name);
}
if (caller->called_number != NULL) {
strlib_free(caller->called_number);
}
if (caller->orig_called_name != NULL) {
strlib_free(caller->orig_called_name);
}
if (caller->orig_called_number != NULL) {
strlib_free(caller->orig_called_number);
}
if (caller->last_redirect_name != NULL) {
strlib_free(caller->last_redirect_name);
}
if (caller->last_redirect_number) {
strlib_free(caller->last_redirect_number);
}
if (caller->orig_rpid_number != NULL) {
strlib_free(caller->orig_rpid_number);
}
}
/*
* ROUTINE: cc_free_msg_data
*
* DESCRIPTION: Free resources embedded in CCAPI msg. data
* structure.
*
* PARAMETERS:
* data - pointer to cc_msg_t whose embedded resources
* need to be freed.
*
* RETURNS:
* None
*/
void
cc_free_msg_data (cc_msg_t *msg)
{
cc_msgbody_info_t *msg_body = NULL;
cc_caller_id_t *caller_id = NULL;
if (msg == NULL) {
return;
}
switch (msg->msg.setup.msg_id) {
case CC_MSG_SETUP:
msg_body = &msg->msg.setup.msg_body;
caller_id = &msg->msg.setup.caller_id;
strlib_free(msg->msg.setup.recv_info_list);
break;
case CC_MSG_SETUP_ACK:
msg_body = &msg->msg.setup_ack.msg_body;
caller_id = &msg->msg.setup_ack.caller_id;
break;
case CC_MSG_PROCEEDING:
caller_id = &msg->msg.proceeding.caller_id;
break;
case CC_MSG_ALERTING:
msg_body = &msg->msg.alerting.msg_body;
caller_id = &msg->msg.alerting.caller_id;
break;
case CC_MSG_CONNECTED:
msg_body = &msg->msg.connected.msg_body;
caller_id = &msg->msg.connected.caller_id;
strlib_free(msg->msg.connected.recv_info_list);
break;
case CC_MSG_CONNECTED_ACK:
msg_body = &msg->msg.connected_ack.msg_body;
caller_id = &msg->msg.connected_ack.caller_id;
break;
case CC_MSG_FEATURE:
if (msg->msg.feature.data_valid) {
msg_body = cc_get_msg_body_info_ptr_from_feature_data(
msg->msg.feature.feature_id,
&msg->msg.feature.data);
if (msg->msg.feature.feature_id == CC_FEATURE_CALLINFO) {
caller_id = &msg->msg.feature.data.call_info.caller_id;
}
}
break;
case CC_MSG_FEATURE_ACK:
if (msg->msg.feature_ack.data_valid) {
msg_body = cc_get_msg_body_info_ptr_from_feature_data(
msg->msg.feature_ack.feature_id,
&msg->msg.feature_ack.data);
}
break;
case CC_MSG_OPTIONS_ACK:
msg_body = &msg->msg.options_ack.msg_body;
break;
case CC_MSG_AUDIT_ACK:
msg_body = &msg->msg.audit_ack.msg_body;
break;
case CC_MSG_INFO:
strlib_free(msg->msg.info.message_body);
strlib_free(msg->msg.info.content_type);
strlib_free(msg->msg.info.info_package);
break;
default:
return;
}
cc_free_msg_body_parts(msg_body);
cc_free_caller_id(caller_id);
}
/*
* ROUTINE: cc_cp_msg_body_parts
*
* DESCRIPTION: Copy elements in the msg body part structure.
*
* PARAMETERS:
* dst_msg - pointer to destination cc_msgbody_info_t
* src_msg - pointer to source cc_msgbody_info_t
*
* RETURNS:
* CC_RC_ERROR
* CC_RC_SUCCESS
*
* NOTES: The function attempts to free the message bodies
* that might be in the destination to prevent
* memory leak from overridden the destination by
* moving the new message source.
*
* The dst_msg must be pointed to the initialized
* message block either with all zero or at least
* number of parts is set to zero to prevent
* freeing an invalid address.
*/
cc_rcs_t
cc_cp_msg_body_parts (cc_msgbody_info_t *dst_msg, cc_msgbody_info_t *src_msg)
{
uint32_t i, body_length;
cc_msgbody_t *src_part, *dst_part;
cc_rcs_t status;
int len;
if ((dst_msg == NULL) || (src_msg == NULL)) {
return CC_RC_ERROR;
}
/* Free the msg. bodies that might be in the dest first */
cc_free_msg_body_parts(dst_msg);
src_part = &src_msg->parts[0];
dst_part = &dst_msg->parts[0];
/* Copy all of the fields of all body parts */
status = CC_RC_SUCCESS;
for (i = 0; i < src_msg->num_parts; i++, src_part++, dst_part++) {
dst_part->content_type = src_part->content_type;
dst_part->content_disposition = src_part->content_disposition;
/* Copy body */
dst_part->body = NULL;
dst_part->body_length = 0;
if ((src_part->body != NULL) && (src_part->body_length > 0)) {
body_length = src_part->body_length;
dst_part->body = (char *) cpr_malloc(body_length);
if (dst_part->body == NULL) {
/* Unable to allocate memory for body */
status = CC_RC_ERROR;
break;
} else {
/*
* Copy body including NULL char but the length field
* does not include the extra NULL char.
*/
memcpy(dst_part->body, src_part->body, body_length);
dst_part->body_length = src_part->body_length;
}
}
dst_part->content_id = NULL;
/* Copy content ID */
if (src_part->content_id != NULL) {
len = strlen(src_part->content_id) + 1;
dst_part->content_id = (char *) cpr_malloc(len);
if (dst_part->content_id != NULL) {
memcpy(dst_part->content_id, src_part->content_id, len);
} else {
/* Unable to allocate memory for content ID */
status = CC_RC_ERROR;
break;
}
}
}
dst_msg->num_parts = i; /* number of part copied */
dst_msg->content_type = src_msg->content_type;
if (status != CC_RC_SUCCESS) {
/*
* Unable to duplicate the body parts, free all of the allocated
* resources
*/
cc_free_msg_body_parts(dst_msg);
}
return status;
}
void
cc_int_setup (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, cc_caller_id_t *caller_id,
cc_alerting_type alert_info, vcm_ring_mode_t alerting_ring,
vcm_tones_t alerting_tone, cc_redirect_t *redirect,
cc_call_info_t *call_info_p, boolean replaces,
string_t recv_info_list, cc_msgbody_info_t *msg_body)
{
cc_setup_t *pmsg;
if (caller_id == NULL) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG("%s: caller id is NULL\n", __FUNCTION__);
return;
}
CC_DEBUG(DEB_L_C_F_PREFIX " CGPD= %s, CGPN= %s,\n CDPD= %s, CDPN= %s\n",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__),
caller_id->calling_name, caller_id->calling_number,
caller_id->called_name, caller_id->called_number);
pmsg = (cc_setup_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_SETUP;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
pmsg->alert_info = alert_info;
pmsg->alerting_ring = alerting_ring;
pmsg->alerting_tone = alerting_tone;
cc_cp_caller(&pmsg->caller_id, caller_id);
pmsg->call_info.type = CC_FEAT_NONE;
if (call_info_p) {
pmsg->call_info = *call_info_p;
}
pmsg->replaces = replaces;
if (redirect != NULL) {
pmsg->redirect = *redirect;
}
/* Info Package */
if (recv_info_list && (*recv_info_list != '\0')) {
pmsg->recv_info_list = strlib_copy(recv_info_list);
} else {
pmsg->recv_info_list = strlib_empty();
}
/* Move body parts if there are any */
pmsg->msg_body.num_parts = 0;
cc_mv_msg_body_parts(&pmsg->msg_body, msg_body);
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_setup_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, cc_caller_id_t *caller_id,
cc_msgbody_info_t *msg_body)
{
cc_setup_ack_t *pmsg;
pmsg = (cc_setup_ack_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_SETUP_ACK;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
if (caller_id != NULL) {
cc_cp_caller(&pmsg->caller_id, caller_id);
}
/* Move body parts if there are any */
pmsg->msg_body.num_parts = 0;
cc_mv_msg_body_parts(&pmsg->msg_body, msg_body);
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
}
void
cc_int_proceeding (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, cc_caller_id_t *caller_id)
{
cc_proceeding_t *pmsg;
pmsg = (cc_proceeding_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_PROCEEDING;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
if (caller_id != NULL) {
cc_cp_caller(&pmsg->caller_id, caller_id);
}
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
if (cc_send_msg(pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_alerting (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, cc_caller_id_t *caller_id,
cc_msgbody_info_t *msg_body, boolean inband)
{
cc_alerting_t *pmsg;
pmsg = (cc_alerting_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_ALERTING;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
if (caller_id != NULL) {
cc_cp_caller(&pmsg->caller_id, caller_id);
}
/* Move body parts if there are any */
pmsg->msg_body.num_parts = 0;
cc_mv_msg_body_parts(&pmsg->msg_body, msg_body);
pmsg->inband = inband;
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
CC_DEBUG(DEB_L_C_F_PREFIX " inband= %d\n",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), inband);
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_connected (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, cc_caller_id_t *caller_id,
string_t recv_info_list, cc_msgbody_info_t *msg_body)
{
cc_connected_t *pmsg;
pmsg = (cc_connected_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_CONNECTED;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
if (caller_id != NULL) {
cc_cp_caller(&pmsg->caller_id, caller_id);
}
/* Info Package */
if (recv_info_list && (*recv_info_list != '\0')) {
pmsg->recv_info_list = strlib_copy(recv_info_list);
} else {
pmsg->recv_info_list = strlib_empty();
}
/* Move body parts if there are any */
pmsg->msg_body.num_parts = 0;
cc_mv_msg_body_parts(&pmsg->msg_body, msg_body);
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_connected_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, cc_caller_id_t *caller_id,
cc_msgbody_info_t *msg_body)
{
cc_connected_ack_t *pmsg;
pmsg = (cc_connected_ack_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_CONNECTED_ACK;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
if (caller_id != NULL) {
cc_cp_caller(&pmsg->caller_id, caller_id);
}
/* Move body parts if there are any */
pmsg->msg_body.num_parts = 0;
cc_mv_msg_body_parts(&pmsg->msg_body, msg_body);
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_release (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, cc_causes_t cause, const char *dialstring,
cc_kfact_t *kfactor)
{
cc_release_t *pmsg;
if (dialstring == NULL) {
CC_DEBUG(DEB_L_C_F_PREFIX " cause= %s\n",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_cause_name(cause));
} else {
CC_DEBUG(DEB_L_C_F_PREFIX " cause= %s, dialstring= %s\n",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_cause_name(cause), dialstring);
}
pmsg = (cc_release_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_RELEASE;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
pmsg->cause = cause;
if (dialstring) {
sstrncpy(pmsg->dialstring, dialstring, CC_MAX_DIALSTRING_LEN);
}
if (kfactor != NULL) {
sstrncpy(pmsg->kfactor.rxstats, kfactor->rxstats, CC_KFACTOR_STAT_LEN);
sstrncpy(pmsg->kfactor.txstats, kfactor->txstats, CC_KFACTOR_STAT_LEN);
}
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_release_complete (cc_srcs_t src_id, cc_srcs_t dst_id,
callid_t call_id, line_t line, cc_causes_t cause,
cc_kfact_t *kfactor)
{
cc_release_complete_t *pmsg;
pmsg = (cc_release_complete_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_RELEASE_COMPLETE;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
pmsg->cause = cause;
if (kfactor != NULL) {
sstrncpy(pmsg->kfactor.rxstats, kfactor->rxstats, CC_KFACTOR_STAT_LEN);
sstrncpy(pmsg->kfactor.txstats, kfactor->txstats, CC_KFACTOR_STAT_LEN);
}
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
CC_DEBUG(DEB_L_C_F_PREFIX " cause= %s\n",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_cause_name(cause));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_feature2 (cc_msgs_t msg_id, cc_srcs_t src_id, cc_srcs_t dst_id,
callid_t call_id, line_t line, cc_features_t feature_id,
cc_feature_data_t *data)
{
cc_feature_t *pmsg;
cc_msgbody_info_t *msg_body;
pmsg = (cc_feature_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG("%s: no buffer available for feat=%s\n", __FUNCTION__,
cc_feature_name(feature_id));
return;
}
pmsg->msg_id = msg_id;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
pmsg->feature_id = feature_id;
pmsg->data_valid = (data == NULL) ? (FALSE) : (TRUE);
if (pmsg->data_valid == TRUE) {
pmsg->data = *data;
/*
* For call Info feature, need to copy the caller ID
*/
if (feature_id == CC_FEATURE_CALLINFO) {
/* Copy the caller ID */
cc_cp_caller(&pmsg->data.call_info.caller_id,
&data->call_info.caller_id);
}
/*
* Clear the msg body from the source now since the msg. bodies
* has been transferred to to the CCAPI msg.
*/
msg_body = cc_get_msg_body_info_ptr_from_feature_data(feature_id, data);
cc_initialize_msg_body_parts_info(msg_body);
}
if ((feature_id == CC_FEATURE_XFER) ||
(feature_id == CC_FEATURE_BLIND_XFER)) {
if (data != NULL) {
CC_DEBUG(DEB_L_C_F_PREFIX
"method= %d, call_id= %d, cause= %s dialstring= %s\n",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__),
data->xfer.method, data->xfer.target_call_id,
cc_cause_name(data->xfer.cause), data->xfer.dialstring);
}
}
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_feature_name(feature_id));
CC_DEBUG(DEB_L_C_F_PREFIX "feature= %s, data= %p\n",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_feature_name(feature_id), data);
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG("%s: unable to send msg for feat=%s\n", __FUNCTION__,
cc_feature_name(feature_id));
}
return;
}
/*
* Helper function for the next six functions that populates and sends
* a feature message
*
*/
static void send_message_helper(
cc_msgs_t msg_id,
cc_srcs_t src_id,
cc_srcs_t dst_id,
callid_t call_id,
line_t line,
cc_features_t feature_id,
cc_feature_data_t *data,
string_t sdp,
cc_jsep_action_t action)
{
cc_feature_t *pmsg;
cc_msgbody_info_t *msg_body;
pmsg = (cc_feature_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
GSM_ERR_MSG("%s: no buffer available for feat=%s\n", __FUNCTION__,
cc_feature_name(feature_id));
return;
}
pmsg->msg_id = msg_id;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
pmsg->feature_id = feature_id;
pmsg->data_valid = (data == NULL) ? (FALSE) : (TRUE);
if (msg_id == CC_MSG_SETLOCALDESC || msg_id == CC_MSG_SETREMOTEDESC) {
pmsg->action = action;
}
if (msg_id == CC_MSG_CREATEANSWER || msg_id == CC_MSG_SETLOCALDESC || msg_id == CC_MSG_SETREMOTEDESC) {
sstrncpy(pmsg->sdp, sdp, sizeof(pmsg->sdp));
}
if (pmsg->data_valid == TRUE) {
pmsg->data = *data;
/*
* For call Info feature, need to copy the caller ID
*/
if (feature_id == CC_FEATURE_CALLINFO) {
/* Copy the caller ID */
cc_cp_caller(&pmsg->data.call_info.caller_id,
&data->call_info.caller_id);
}
/*
* Clear the msg body from the source now since the msg. bodies
* has been transferred to to the CCAPI msg.
*/
msg_body = cc_get_msg_body_info_ptr_from_feature_data(feature_id, data);
cc_initialize_msg_body_parts_info(msg_body);
}
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_feature_name(feature_id));
CC_DEBUG(DEB_L_C_F_PREFIX "feature= %s, data= %p\n",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_feature_name(feature_id), data);
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG("%s: unable to send msg for feat=%s\n", __FUNCTION__,
cc_feature_name(feature_id));
}
return;
}
void
cc_createoffer (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, cc_features_t feature_id, cc_feature_data_t *data)
{
send_message_helper(CC_MSG_CREATEOFFER, src_id, dst_id, call_id, line,
feature_id, data, NULL, 0);
return;
}
void
cc_createanswer (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, cc_features_t feature_id, string_t sdp, cc_feature_data_t *data)
{
send_message_helper(CC_MSG_CREATEANSWER, src_id, dst_id, call_id, line,
feature_id, data, sdp, 0);
return;
}
void cc_setlocaldesc (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line,
cc_features_t feature_id, cc_jsep_action_t action, string_t sdp, cc_feature_data_t *data)
{
send_message_helper(CC_MSG_SETLOCALDESC, src_id, dst_id, call_id, line,
feature_id, data, sdp, action);
return;
}
void cc_setremotedesc (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line,
cc_features_t feature_id, cc_jsep_action_t action, string_t sdp, cc_feature_data_t *data)
{
send_message_helper(CC_MSG_SETREMOTEDESC, src_id, dst_id, call_id, line,
feature_id, data, sdp, action);
return;
}
void cc_localdesc (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line,
cc_features_t feature_id, cc_feature_data_t *data)
{
send_message_helper(CC_MSG_LOCALDESC, src_id, dst_id, call_id, line,
feature_id, data, NULL, 0);
return;
}
void cc_remotedesc (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line,
cc_features_t feature_id, cc_feature_data_t *data)
{
send_message_helper(CC_MSG_REMOTEDESC, src_id, dst_id, call_id, line,
feature_id, data, NULL, 0);
return;
}
void
cc_int_feature_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, cc_features_t feature_id,
cc_feature_data_t *data, cc_causes_t cause)
{
cc_feature_ack_t *pmsg;
cc_msgbody_info_t *msg_body;
pmsg = (cc_feature_ack_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_FEATURE_ACK;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
pmsg->feature_id = feature_id;
pmsg->data_valid = (data == NULL) ? (FALSE) : (TRUE);
if (pmsg->data_valid == TRUE) {
pmsg->data = *data;
/*
* Clear the msg body from the source now since the msg. bodies
* has been transferred to to the CCAPI msg.
*/
msg_body = cc_get_msg_body_info_ptr_from_feature_data(feature_id, data);
cc_initialize_msg_body_parts_info(msg_body);
}
pmsg->cause = cause;
if ((feature_id == CC_FEATURE_XFER) ||
(feature_id == CC_FEATURE_BLIND_XFER)) {
if (data != NULL) {
CC_DEBUG(DEB_L_C_F_PREFIX
"method= %d, call_id= %d, cause= %s dialstring= %s\n",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__),
data->xfer.method, data->xfer.target_call_id,
cc_cause_name(data->xfer.cause), data->xfer.dialstring);
}
}
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
CC_DEBUG(DEB_L_C_F_PREFIX "feature= %s, data= %p, cause= %s\n",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), cc_feature_name(feature_id), data,
cc_cause_name(cause));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_offhook (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t prim_call_id,
cc_hold_resume_reason_e consult_reason, callid_t call_id,
line_t line, char *global_call_id, monitor_mode_t monitor_mode,
cfwdall_mode_t cfwdall_mode)
{
cc_offhook_t *pmsg;
pmsg = (cc_offhook_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_OFFHOOK;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
if (global_call_id != NULL) {
sstrncpy(pmsg->global_call_id, global_call_id, CC_GCID_LEN);
}
pmsg->prim_call_id = prim_call_id;
pmsg->hold_resume_reason = consult_reason;
pmsg->monitor_mode = monitor_mode;
pmsg->cfwdall_mode = cfwdall_mode;
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_line (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line)
{
cc_line_t *pmsg;
pmsg = (cc_line_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_LINE;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_onhook (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t prim_call_id,
cc_hold_resume_reason_e consult_reason, callid_t call_id,
line_t line, boolean softkey, cc_onhook_reason_e active_list)
{
cc_onhook_t *pmsg;
pmsg = (cc_onhook_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_ONHOOK;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
pmsg->softkey = softkey;
pmsg->prim_call_id = prim_call_id;
pmsg->hold_resume_reason = consult_reason;
pmsg->active_list = active_list;
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_digit_begin (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, int digit)
{
cc_digit_begin_t *pmsg;
pmsg = (cc_digit_begin_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_DIGIT_BEGIN;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->digit = digit;
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_dialstring (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, const char *dialstring, const char *g_call_id,
monitor_mode_t monitor_mode)
{
cc_dialstring_t *pmsg;
if (dialstring == NULL) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG("%s: no dialstring\n", __FUNCTION__);
return;
}
CC_DEBUG(DEB_L_C_F_PREFIX "dialstring= %s\n",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__),dialstring);
pmsg = (cc_dialstring_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_DIALSTRING;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
sstrncpy(pmsg->dialstring, dialstring, CC_MAX_DIALSTRING_LEN);
sstrncpy(pmsg->g_call_id, g_call_id, CC_GCID_LEN);
pmsg->monitor_mode = monitor_mode;
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_mwi (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id, line_t line,
boolean on, int type, int newCount, int oldCount, int hpNewCount, int hpOldCount)
{
cc_mwi_t *pmsg;
pmsg = (cc_mwi_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_MWI;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
pmsg->msgSummary.on = on;
pmsg->msgSummary.type = type;
pmsg->msgSummary.newCount = newCount;
pmsg->msgSummary.oldCount = oldCount;
pmsg->msgSummary.hpNewCount = hpNewCount;
pmsg->msgSummary.hpOldCount = hpOldCount;
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
CC_DEBUG(DEB_L_C_F_PREFIX " mwi status= %d\n new count= %d old count= %d",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), on, newCount, oldCount);
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_options_sdp_req (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, void *pMessage)
{
cc_options_sdp_req_t *pmsg;
pmsg = (cc_options_sdp_req_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_OPTIONS;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
pmsg->pMessage = pMessage;
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
CC_DEBUG(DEB_L_C_F_PREFIX " message ptr=%p\n",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), pMessage);
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_options_sdp_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, void *pMessage, cc_msgbody_info_t *msg_body)
{
cc_options_sdp_ack_t *pmsg;
pmsg = (cc_options_sdp_ack_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_OPTIONS_ACK;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
pmsg->pMessage = pMessage;
/* Move body parts if there are any */
pmsg->msg_body.num_parts = 0;
cc_mv_msg_body_parts(&pmsg->msg_body, msg_body);
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
CC_DEBUG(DEB_L_C_F_PREFIX " message ptr=%p\n",
DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__), pMessage);
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_audit_sdp_req (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, boolean apply_ringout)
{
cc_audit_sdp_req_t *pmsg;
pmsg = (cc_audit_sdp_req_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_AUDIT;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
pmsg->apply_ringout = apply_ringout;
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
CC_DEBUG(DEB_L_C_F_PREFIX "\n", DEB_L_C_F_PREFIX_ARGS(CC_API, line, call_id, __FUNCTION__));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_audit_sdp_ack (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, cc_msgbody_info_t *msg_body)
{
cc_audit_sdp_ack_t *pmsg;
pmsg = (cc_audit_sdp_ack_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_AUDIT_ACK;
pmsg->src_id = src_id;
pmsg->call_id = call_id;
pmsg->line = line;
/* Move body parts if there are any */
pmsg->msg_body.num_parts = 0;
cc_mv_msg_body_parts(&pmsg->msg_body, msg_body);
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_fail_fallback (cc_srcs_t src_id, cc_srcs_t dst_id, int rsp_type,
cc_regmgr_rsp_e rsp_id, boolean waited)
{
cc_regmgr_t *pmsg;
pmsg = (cc_regmgr_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_FAILOVER_FALLBACK;
pmsg->src_id = src_id;
pmsg->rsp_type = rsp_type;
pmsg->rsp_id = rsp_id;
pmsg->wait_flag = waited;
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, 0, 0, cc_msg_name(pmsg->msg_id));
CC_DEBUG(DEB_F_PREFIX "rsp_type= %s rsp_id= %s waited = %d\n",
DEB_F_PREFIX_ARGS(CC_API, __FUNCTION__),
rsp_type == RSP_START ? "RSP_START" : "RSP_COMPLETE",
rsp_id == CC_REG_FAILOVER_RSP ? "REG_FAILOVER_RSP" : "REG_FALLBACK_RSP",
waited);
if (cc_send_cmd_msg(REG_MGR_STATE_CHANGE, (cprBuffer_t) pmsg,
sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_int_info (cc_srcs_t src_id, cc_srcs_t dst_id, callid_t call_id,
line_t line, string_t info_package, string_t content_type,
string_t message_body)
{
cc_info_t *pmsg;
pmsg = (cc_info_t *) cc_get_msg_buf(sizeof(*pmsg));
if (!pmsg) {
// nobody checks, CC_RC_ERROR, so generate error message
GSM_ERR_MSG(get_debug_string(CC_NO_MSG_BUFFER), __FUNCTION__);
return;
}
pmsg->msg_id = CC_MSG_INFO;
pmsg->call_id = call_id;
pmsg->line = line;
pmsg->info_package = strlib_copy(info_package);
pmsg->content_type = strlib_copy(content_type);
pmsg->message_body = strlib_copy(message_body);
CC_DEBUG_ENTRY(__FUNCTION__, src_id, dst_id, call_id, line, cc_msg_name(pmsg->msg_id));
if (cc_send_msg((cprBuffer_t) pmsg, sizeof(*pmsg), dst_id) != CC_RC_SUCCESS) {
// nobody checks the return code, so generate error message
GSM_ERR_MSG(get_debug_string(CC_SEND_FAILURE), __FUNCTION__);
}
return;
}
void
cc_init (void)
{
/* Placeholder function for any initialization tasks */
}