Compare commits

...

2 Commits

Author SHA1 Message Date
Andreas Eversberg e1dcbb89db Fixed issue in handling channel offer
When (exclusive or suggested) channel is offered, we must "seize" it, so that
it is linked with call instance. Still the channel might be changed on reply.
2022-05-01 10:15:08 +02:00
Andreas Eversberg ef4950bd66 Updated Libs 2021-11-07 07:28:12 +01:00
9 changed files with 659 additions and 190 deletions

View File

@ -1516,14 +1516,15 @@ void setup_req(call_t *call, osmo_cc_msg_t *msg)
PDEBUG(DDSS1, DEBUG_INFO, "Codec %s selected for transmission.\n", call->codec->payload_name);
/* get channel */
rc = hunt_bchannel_out(call->isdn_ep, &call->b_channel, &call->b_exclusive);
rc = hunt_bchannel_out(call->isdn_ep, &channel, &exclusive);
if (rc < 0) {
PDEBUG(DDSS1, DEBUG_NOTICE, "There is no channel available on the interface.\n");
release_and_destroy(call, -rc, 0, 0);
return;
}
channel = call->b_channel;
exclusive = call->b_exclusive;
/* must seize it, if we gave a channel, so that requested channel is stored in call instance */
if (channel)
seize_bchannel(call, channel, exclusive);
/* creating pid */
call->l3_pid = request_new_pid(call->isdn_ep->ml3);

View File

@ -511,8 +511,8 @@ int open_bchannel_out(call_t *call, unsigned int cmd, int channel, int exclusive
if (channel==-1 || call->b_channel==channel) {
call->b_exclusive = 1; // we are done
/* if channel was accepted, try to get it */
rc = seize_bchannel(call, channel, 1); // exclusively
/* if channel was accepted, seize_bchannel shall simply return, because given channel is already set */
rc = seize_bchannel(call, call->b_channel, 1); // exclusively
if (rc < 0) {
PDEBUG(DISDN, DEBUG_DEBUG, " -> result = replied channel not available\n");
return -47;
@ -531,7 +531,7 @@ int open_bchannel_out(call_t *call, unsigned int cmd, int channel, int exclusive
return -111; // protocol error
}
/* if channel was not accepted, try to get it */
/* if channel was not accepted, try to get a different one */
rc = seize_bchannel(call, channel, 1); // exclusively
if (rc < 0) {
PDEBUG(DISDN, DEBUG_DEBUG, " -> result = replied channel not available\n");

View File

@ -68,11 +68,7 @@ static void print_help()
printf(" --config [~/]<path to config file>\n");
printf(" Give a config file to use. If it starts with '~/', path is at home dir.\n");
printf(" Each line in config file is one option, '-' or '--' must not be given!\n");
printf(" -v --verbose <level> | <level>,<category>[,<category>[,...]] | list\n");
printf(" Use 'list' to get a list of all levels and categories\n");
printf(" Verbose level: digit of debug level (default = '%d')\n", debuglevel);
printf(" Verbose level+category: level digit followed by one or more categories\n");
printf(" -> If no category is specified, all categories are selected\n");
debug_print_help();
printf(" --ulaw\n");
printf(" Use U-LAW for b-channel coding instead of alaw.\n");
printf(" -p --port <portnr> | <portname>\n");

View File

@ -24,7 +24,10 @@
#include <stdint.h>
#include <errno.h>
#include <math.h>
#include <time.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include "debug.h"
const char *debug_level[] = {
@ -53,6 +56,7 @@ struct debug_cat {
{ "mpt1327", "\033[1;34m" },
{ "jollycom", "\033[1;34m" },
{ "eurosignal", "\033[1;34m" },
{ "pocsag", "\033[1;34m" },
{ "frame", "\033[0;36m" },
{ "call", "\033[0;37m" },
{ "cc", "\033[1;32m" },
@ -89,6 +93,7 @@ struct debug_cat {
};
int debuglevel = DEBUG_INFO;
int debug_date = 0;
uint64_t debug_mask = ~0;
extern int num_kanal;
@ -97,6 +102,9 @@ void (*print_console_text)(void) = NULL;
int debug_limit_scroll = 0;
static int lock_initialized = 0;
static pthread_mutex_t debug_mutex;
void get_win_size(int *w, int *h)
{
struct winsize win;
@ -120,10 +128,22 @@ void _printdebug(const char *file, const char __attribute__((unused)) *function,
const char *p;
va_list args;
int w, h;
int rc;
if (debuglevel > level)
return;
if (!(debug_mask & ((uint64_t)1 << cat)))
return;
if (!lock_initialized) {
rc = pthread_mutex_init(&debug_mutex, NULL);
if (rc == 0)
lock_initialized = 1;
}
if (lock_initialized)
pthread_mutex_lock(&debug_mutex);
buffer[sizeof(buffer) - 1] = '\0';
/* if kanal is used, prefix the channel number */
@ -133,9 +153,6 @@ void _printdebug(const char *file, const char __attribute__((unused)) *function,
s -= strlen(buffer);
}
if (!(debug_mask & ((uint64_t)1 << cat)))
return;
va_start(args, fmt);
vsnprintf(b, s, fmt, args);
va_end(args);
@ -148,12 +165,24 @@ void _printdebug(const char *file, const char __attribute__((unused)) *function,
get_win_size(&w, &h);
printf("\0337\033[%d;%dr\0338", debug_limit_scroll + 1, h);
}
if (debug_date) {
struct timeval tv;
struct tm *tm;
gettimeofday(&tv, NULL);
tm = localtime(&tv.tv_sec);
printf("%04d-%02d-%02d %02d:%02d:%02d.%03d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 10000.0));
}
printf("%s%s:%4d %s: %s\033[0;39m", debug_cat[cat].color, file, line, debug_level[level], buffer);
if (debug_limit_scroll)
printf("\0337\033[%d;%dr\0338", 1, h);
if (print_console_text)
print_console_text();
fflush(stdout);
if (lock_initialized)
pthread_mutex_unlock(&debug_mutex);
}
const char *debug_amplitude(double level)
@ -190,6 +219,17 @@ const char *debug_db(double level_db)
return text;
}
void debug_print_help(void)
{
printf(" -v --verbose <level> | <level>,<category>[,<category>[,...]] | list\n");
printf(" Use 'list' to get a list of all levels and categories\n");
printf(" Verbose level: digit of debug level (default = '%d')\n", debuglevel);
printf(" Verbose level+category: level digit followed by one or more categories\n");
printf(" -> If no category is specified, all categories are selected\n");
printf(" -v --verbose date\n");
printf(" Show date with debug output\n");
}
void debug_list_cat(void)
{
int i;
@ -210,6 +250,11 @@ int parse_debug_opt(const char *optarg)
int i, max_level = 0;
char *dup, *dstring, *p;
if (!strcasecmp(optarg, "date")) {
debug_date = 1;
return 0;
}
for (i = 0; debug_level[i]; i++)
max_level = i;

View File

@ -18,38 +18,39 @@
#define DMPT1327 11
#define DJOLLY 12
#define DEURO 13
#define DFRAME 14
#define DCALL 15
#define DCC 16
#define DDB 17
#define DTRANS 18
#define DDMS 19
#define DSMS 20
#define DSDR 21
#define DUHD 22
#define DSOAPY 23
#define DWAVE 24
#define DRADIO 25
#define DAM791X 26
#define DUART 27
#define DDEVICE 28
#define DDATENKLO 29
#define DZEIT 30
#define DSIM1 31
#define DSIM2 32
#define DSIMI 33
#define DSIM7 34
#define DMTP2 35
#define DMTP3 36
#define DMUP 37
#define DROUTER 38
#define DSTDERR 39
#define DSS5 40
#define DISDN 41
#define DMISDN 42
#define DDSS1 43
#define DSIP 44
#define DTEL 45
#define DPOCSAG 14
#define DFRAME 15
#define DCALL 16
#define DCC 17
#define DDB 18
#define DTRANS 19
#define DDMS 20
#define DSMS 21
#define DSDR 22
#define DUHD 23
#define DSOAPY 24
#define DWAVE 25
#define DRADIO 26
#define DAM791X 27
#define DUART 28
#define DDEVICE 29
#define DDATENKLO 30
#define DZEIT 31
#define DSIM1 32
#define DSIM2 33
#define DSIMI 34
#define DSIM7 35
#define DMTP2 36
#define DMTP3 37
#define DMUP 38
#define DROUTER 39
#define DSTDERR 40
#define DSS5 41
#define DISDN 42
#define DMISDN 43
#define DDSS1 44
#define DSIP 45
#define DTEL 46
void get_win_size(int *w, int *h);
@ -60,6 +61,7 @@ void _printdebug(const char *file, const char *function, int line, int cat, int
const char *debug_amplitude(double level);
const char *debug_db(double level_db);
void debug_print_help(void);
void debug_list_cat(void);
int parse_debug_opt(const char *opt);

View File

@ -360,7 +360,7 @@ void attach_req(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
rel:
/* change to REL_REQ */
msg->type = OSMO_CC_MSG_REL_IND;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_name(msg->type));
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
/* message to socket */
forward_to_ul(call, msg);
@ -391,7 +391,7 @@ rel:
/* changing to confirm message */
msg->type = OSMO_CC_MSG_ATTACH_CNF;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_name(msg->type));
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
/* message to socket */
forward_to_ul(call, msg);
@ -642,7 +642,7 @@ static void disc_collision_ind(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
/* change to REL_REQ */
msg->type = OSMO_CC_MSG_REL_REQ;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_name(msg->type));
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
/* to lower layer */
forward_to_ll(call, msg);
@ -663,7 +663,7 @@ static void disc_collision_req(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
if (call->lower_layer_released) {
/* change to REL_REQ */
msg->type = OSMO_CC_MSG_REL_IND;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_name(msg->type));
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
/* to upper layer */
forward_to_ul(call, msg);
@ -701,7 +701,7 @@ static void rej_ind_disc(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
/* change to REL_IND */
msg->type = OSMO_CC_MSG_REL_IND;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_name(msg->type));
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
/* to upper layer */
forward_to_ul(call, msg);
@ -717,7 +717,7 @@ static void rej_req_disc(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
/* change to REL_REQ */
msg->type = OSMO_CC_MSG_REL_REQ;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_name(msg->type));
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
/* to lower layer */
forward_to_ll(call, msg);
@ -746,7 +746,7 @@ static void rel_ind_other(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
/* change to DISC_IND */
msg->type = OSMO_CC_MSG_DISC_IND;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_name(msg->type));
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
call->lower_layer_released = 1;
/* to upper layer */
@ -773,7 +773,7 @@ static void rel_req_other(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
/* change to DISC_REQ */
msg->type = OSMO_CC_MSG_DISC_REQ;
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_name(msg->type));
PDEBUG(DCC, DEBUG_INFO, "Changing message to %s.\n", osmo_cc_msg_value2name(msg->type));
call->upper_layer_released = 1;
/* to lower layer */
@ -923,13 +923,15 @@ static void handle_msg(osmo_cc_call_t *call, osmo_cc_msg_t *msg)
break;
if (i == STATEMACHINE_LEN) {
PDEBUG(DCC, DEBUG_INFO, "Message %s unhandled at state %s (callref %d)\n",
osmo_cc_msg_name(msg->type), state_names[call->state], call->callref);
osmo_cc_msg_value2name(msg->type), state_names[call->state], call->callref);
osmo_cc_free_msg(msg);
return;
}
PDEBUG(DCC, DEBUG_INFO, "Handle message %s at state %s (callref %d)\n",
osmo_cc_msg_name(msg->type), state_names[call->state], call->callref);
osmo_cc_msg_value2name(msg->type), state_names[call->state], call->callref);
if (debuglevel <= DEBUG_INFO)
osmo_cc_debug_ie(msg, DEBUG_INFO);
statemachine_list[i].action(call, msg);
}

View File

@ -25,6 +25,337 @@
#include "../libdebug/debug.h"
#include "message.h"
#define _OSMO_CC_VALUE2NAME(array) { \
if (value < 0 || (size_t)value >= (sizeof(array) / sizeof(array[0])) || array[value] == NULL) \
return "<unknown>"; \
else \
return array[value]; \
}
#define _OSMO_CC_NAME2VALUE(array) { \
for (int value = 0; (size_t)value < (sizeof(array) / sizeof(array[0])); value++) { \
if (!strcasecmp(array[value], name)) \
return value; \
} \
return -1; \
}
static const char *osmo_cc_msg_name[OSMO_CC_MSG_NUM] = {
[OSMO_CC_MSG_SETUP_REQ] = "CC-SETUP-REQ",
[OSMO_CC_MSG_SETUP_IND] = "CC-SETUP-IND",
[OSMO_CC_MSG_REJ_REQ] = "CC-REJ-REQ",
[OSMO_CC_MSG_REJ_IND] = "CC-REJ-IND",
[OSMO_CC_MSG_SETUP_ACK_REQ] = "CC-SETUP-ACK-REQ",
[OSMO_CC_MSG_SETUP_ACK_IND] = "CC-SETUP-ACK-IND",
[OSMO_CC_MSG_PROC_REQ] = "CC-PROC-REQ",
[OSMO_CC_MSG_PROC_IND] = "CC-PROC-IND",
[OSMO_CC_MSG_ALERT_REQ] = "CC-ALERT-REQ",
[OSMO_CC_MSG_ALERT_IND] = "CC-ALERT-IND",
[OSMO_CC_MSG_SETUP_RSP] = "CC-SETUP-RSP",
[OSMO_CC_MSG_SETUP_CNF] = "CC-SETUP-CNF",
[OSMO_CC_MSG_SETUP_COMP_REQ] = "CC-SETUP-COMP-REQ",
[OSMO_CC_MSG_SETUP_COMP_IND] = "CC-SETUP-COMP-IND",
[OSMO_CC_MSG_DISC_REQ] = "CC-DISC-REQ",
[OSMO_CC_MSG_DISC_IND] = "CC-DISC-IND",
[OSMO_CC_MSG_REL_REQ] = "CC-REL-REQ",
[OSMO_CC_MSG_REL_CNF] = "CC-REL-CNF",
[OSMO_CC_MSG_REL_IND] = "CC-REL-IND",
[OSMO_CC_MSG_PROGRESS_REQ] = "CC-PROGRESS-REQ",
[OSMO_CC_MSG_PROGRESS_IND] = "CC-PROGRESS-IND",
[OSMO_CC_MSG_NOTIFY_REQ] = "CC-NOTIFY-REQ",
[OSMO_CC_MSG_NOTIFY_IND] = "CC-NOTIFY-IND",
[OSMO_CC_MSG_INFO_REQ] = "CC-INFO-REQ",
[OSMO_CC_MSG_INFO_IND] = "CC-INFO-IND",
[OSMO_CC_MSG_ATTACH_REQ] = "CC-ATTACH-REQ",
[OSMO_CC_MSG_ATTACH_IND] = "CC-ATTACH-IND",
[OSMO_CC_MSG_ATTACH_RSP] = "CC-ATTACH-RSP",
[OSMO_CC_MSG_ATTACH_CNF] = "CC-ATTACH-CNF",
};
const char *osmo_cc_msg_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_msg_name)
int osmo_cc_msg_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_msg_name)
static const char *osmo_cc_ie_name[OSMO_CC_IE_NUM] = {
[OSMO_CC_IE_CALLED] = "IE_CALLED",
[OSMO_CC_IE_CALLED_SUB] = "IE_CALLED_SUB",
[OSMO_CC_IE_CALLED_NAME] = "IE_CALLED_NAME",
[OSMO_CC_IE_CALLED_INTERFACE] = "IE_CALLED_INTERFACE",
[OSMO_CC_IE_DTMF] = "IE_DTMF",
[OSMO_CC_IE_KEYPAD] = "IE_KEYPAD",
[OSMO_CC_IE_COMPLETE] = "IE_COMPLETE",
[OSMO_CC_IE_CALLING] = "IE_CALLING",
[OSMO_CC_IE_CALLING_SUB] = "IE_CALLING_SUB",
[OSMO_CC_IE_CALLING_NAME] = "IE_CALLING_NAME",
[OSMO_CC_IE_CALLING_INTERFACE] = "IE_CALLING_INTERFACE",
[OSMO_CC_IE_CALLING_NETWORK] = "IE_CALLING_NETWORK",
[OSMO_CC_IE_REDIR] = "IE_REDIR",
[OSMO_CC_IE_PROGRESS] = "IE_PROGRESS",
[OSMO_CC_IE_NOTIFY] = "IE_NOTIFY",
[OSMO_CC_IE_DISPLAY] = "IE_DISPLAY",
[OSMO_CC_IE_CAUSE] = "IE_CAUSE",
[OSMO_CC_IE_BEARER] = "IE_BEARER",
[OSMO_CC_IE_SDP] = "IE_SDP",
[OSMO_CC_IE_SOCKET_ADDRESS] = "IE_SOCKET_ADDRESS",
[OSMO_CC_IE_PRIVATE] = "IE_PRIVATE",
};
const char *osmo_cc_ie_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_ie_name)
int osmo_cc_ie_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_ie_name)
static const char *osmo_cc_type_name[OSMO_CC_TYPE_NUM] = {
[OSMO_CC_TYPE_UNKNOWN] = "unknown",
[OSMO_CC_TYPE_INTERNATIONAL] = "international",
[OSMO_CC_TYPE_NATIONAL] = "national",
[OSMO_CC_TYPE_NETWORK] = "network",
[OSMO_CC_TYPE_SUBSCRIBER] = "subscriber",
[OSMO_CC_TYPE_ABBREVIATED] = "abbreviated",
[OSMO_CC_TYPE_RESERVED] = "reserved",
};
const char *osmo_cc_type_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_type_name)
int osmo_cc_type_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_type_name)
static const char *osmo_cc_plan_name[OSMO_CC_PLAN_NUM] = {
[OSMO_CC_PLAN_UNKNOWN] = "unknown",
[OSMO_CC_PLAN_TELEPHONY] = "telephony",
[OSMO_CC_PLAN_DATA] = "data",
[OSMO_CC_PLAN_TTY] = "tty",
[OSMO_CC_PLAN_NATIONAL_STANDARD] = "national standard",
[OSMO_CC_PLAN_PRIVATE] = "private",
[OSMO_CC_PLAN_RESERVED] = "reserved",
};
const char *osmo_cc_plan_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_plan_name)
int osmo_cc_plan_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_plan_name)
static const char *osmo_cc_present_name[OSMO_CC_PRESENT_NUM] = {
[OSMO_CC_PRESENT_ALLOWED] = "allowed",
[OSMO_CC_PRESENT_RESTRICTED] = "restricted",
[OSMO_CC_PRESENT_NOT_AVAIL] = "not available",
[OSMO_CC_PRESENT_RESERVED] = "reserved",
};
const char *osmo_cc_present_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_present_name)
int osmo_cc_present_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_present_name)
static const char *osmo_cc_screen_name[OSMO_CC_SCREEN_NUM] = {
[OSMO_CC_SCREEN_USER_UNSCREENED] = "unscreened",
[OSMO_CC_SCREEN_USER_VERIFIED_PASSED] = "user provided and passed",
[OSMO_CC_SCREEN_USER_VERIFIED_FAILED] = "user provided an failed",
[OSMO_CC_SCREEN_NETWORK] = "network provided",
};
const char *osmo_cc_screen_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_screen_name)
int osmo_cc_screen_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_screen_name)
static const char *osmo_cc_redir_reason_name[OSMO_CC_REDIR_REASON_NUM] = {
[OSMO_CC_REDIR_REASON_UNKNOWN] = "unknown",
[OSMO_CC_REDIR_REASON_CFB] = "call forward busy",
[OSMO_CC_REDIR_REASON_CFNR] = "call forward no response",
[OSMO_CC_REDIR_REASON_CD] = "call deflect",
[OSMO_CC_REDIR_REASON_CF_OUTOFORDER] = "call forward out of order",
[OSMO_CC_REDIR_REASON_CF_BY_DTE] = "call froward by dte",
[OSMO_CC_REDIR_REASON_CFU] = "call forward unconditional",
};
const char *osmo_cc_redir_reason_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_redir_reason_name)
int osmo_cc_redir_reason_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_redir_reason_name)
static const char *osmo_cc_notify_name[OSMO_CC_NOTIFY_NUM] = {
[OSMO_CC_NOTIFY_USER_SUSPENDED] = "user suspended",
[OSMO_CC_NOTIFY_USER_RESUMED] = "user resumed",
[OSMO_CC_NOTIFY_BEARER_SERVICE_CHANGE] = "bearer service change",
[OSMO_CC_NOTIFY_CALL_COMPLETION_DELAY] = "call completion delay",
[OSMO_CC_NOTIFY_CONFERENCE_ESTABLISHED] = "conference established",
[OSMO_CC_NOTIFY_CONFERENCE_DISCONNECTED] = "conference disconnected",
[OSMO_CC_NOTIFY_OTHER_PARTY_ADDED] = "ohter party added",
[OSMO_CC_NOTIFY_ISOLATED] = "isolated",
[OSMO_CC_NOTIFY_REATTACHED] = "reattached",
[OSMO_CC_NOTIFY_OTHER_PARTY_ISOLATED] = "ohter party isolated",
[OSMO_CC_NOTIFY_OTHER_PARTY_REATTACHED] = "ohter party reattached",
[OSMO_CC_NOTIFY_OTHER_PARTY_SPLIT] = "other party split",
[OSMO_CC_NOTIFY_OTHER_PARTY_DISCONNECTED] = "other party disconnected",
[OSMO_CC_NOTIFY_CONFERENCE_FLOATING] = "confernce floating",
[OSMO_CC_NOTIFY_CONFERENCE_DISC_PREEMPT] = "confernce disconnect preemption",
[OSMO_CC_NOTIFY_CONFERENCE_FLOATING_SUP] = "conference floating sup",
[OSMO_CC_NOTIFY_CALL_IS_A_WAITING_CALL] = "call is a waiting call",
[OSMO_CC_NOTIFY_DIVERSION_ACTIVATED] = "diversion activated",
[OSMO_CC_NOTIFY_RESERVED_CT_1] = "reserved CT 1",
[OSMO_CC_NOTIFY_RESERVED_CT_2] = "reserved CT 2",
[OSMO_CC_NOTIFY_REVERSE_CHARGING] = "reverse charging",
[OSMO_CC_NOTIFY_REMOTE_HOLD] = "remote hold",
[OSMO_CC_NOTIFY_REMOTE_RETRIEVAL] = "remote retrieval",
[OSMO_CC_NOTIFY_CALL_IS_DIVERTING] = "call is diverting",
};
const char *osmo_cc_notify_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_notify_name)
int osmo_cc_notify_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_notify_name)
static const char *osmo_cc_coding_name[OSMO_CC_CODING_NUM] = {
[OSMO_CC_CODING_ITU_T] = "ITU-T",
[OSMO_CC_CODING_ISO_IEC] = "ISO/IEC",
[OSMO_CC_CODING_NATIONAL] = "national",
[OSMO_CC_CODING_STANDARD_SPECIFIC] = "standard specific",
};
const char *osmo_cc_coding_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_coding_name)
int osmo_cc_coding_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_coding_name)
static const char *osmo_cc_isdn_cause_name[OSMO_CC_ISDN_CAUSE_NUM] = {
[0] = "unset",
[OSMO_CC_ISDN_CAUSE_UNASSIGNED_NR] = "unsassigned number",
[OSMO_CC_ISDN_CAUSE_NO_ROUTE_TRANSIT] = "no route to transit network",
[OSMO_CC_ISDN_CAUSE_NO_ROUTE] = "no route",
[OSMO_CC_ISDN_CAUSE_CHAN_UNACCEPT] = "channel unacceptable",
[OSMO_CC_ISDN_CAUSE_OP_DET_BARRING] = "detected barring",
[OSMO_CC_ISDN_CAUSE_NORM_CALL_CLEAR] = "normal call clearing",
[OSMO_CC_ISDN_CAUSE_USER_BUSY] = "user busy",
[OSMO_CC_ISDN_CAUSE_USER_NOTRESPOND] = "user not responding",
[OSMO_CC_ISDN_CAUSE_USER_ALERTING_NA] = "user does not answer",
[OSMO_CC_ISDN_CAUSE_CALL_REJECTED] = "call rejected",
[OSMO_CC_ISDN_CAUSE_NUMBER_CHANGED] = "number changed",
[OSMO_CC_ISDN_CAUSE_PRE_EMPTION] = "pre-emption",
[OSMO_CC_ISDN_CAUSE_NONSE_USER_CLR] = "non-selected user clearing",
[OSMO_CC_ISDN_CAUSE_DEST_OOO] = "destination out-of-order",
[OSMO_CC_ISDN_CAUSE_INV_NR_FORMAT] = "invalid number format",
[OSMO_CC_ISDN_CAUSE_FACILITY_REJ] = "facility rejected",
[OSMO_CC_ISDN_CAUSE_RESP_STATUS_INQ] = "response to status enquiery",
[OSMO_CC_ISDN_CAUSE_NORMAL_UNSPEC] = "normal, uspecified",
[OSMO_CC_ISDN_CAUSE_NO_CIRCUIT_CHAN] = "no circuit/channel available",
[OSMO_CC_ISDN_CAUSE_NETWORK_OOO] = "network out of order",
[OSMO_CC_ISDN_CAUSE_TEMP_FAILURE] = "temporary failure",
[OSMO_CC_ISDN_CAUSE_SWITCH_CONG] = "switching equipment congested",
[OSMO_CC_ISDN_CAUSE_ACC_INF_DISCARD] = "access information discarded",
[OSMO_CC_ISDN_CAUSE_REQ_CHAN_UNAVAIL] = "requested circuit/channel unavailable",
[OSMO_CC_ISDN_CAUSE_RESOURCE_UNAVAIL] = "resource unavailable",
[OSMO_CC_ISDN_CAUSE_QOS_UNAVAIL] = "quality of service unavailable",
[OSMO_CC_ISDN_CAUSE_REQ_FAC_NOT_SUBSC] = "requested facility not subscribed",
[OSMO_CC_ISDN_CAUSE_INC_BARRED_CUG] = "inc barred in closed user group",
[OSMO_CC_ISDN_CAUSE_BEARER_CAP_UNAUTH] = "bearer capability unauthorized",
[OSMO_CC_ISDN_CAUSE_BEARER_CA_UNAVAIL] = "bearer capability not available",
[OSMO_CC_ISDN_CAUSE_SERV_OPT_UNAVAIL] = "service or option not available",
[OSMO_CC_ISDN_CAUSE_BEARERSERV_UNIMPL] = "bearer service unimplemented",
[OSMO_CC_ISDN_CAUSE_ACM_GE_ACM_MAX] = "acm ge ach max",
[OSMO_CC_ISDN_CAUSE_REQ_FAC_NOTIMPL] = "requrested facility not implemented",
[OSMO_CC_ISDN_CAUSE_RESTR_BCAP_AVAIL] = "restricted bearer capabilitey available",
[OSMO_CC_ISDN_CAUSE_SERV_OPT_UNIMPL] = "service or option unimplemented",
[OSMO_CC_ISDN_CAUSE_INVAL_CALLREF] = "invalid call reference",
[OSMO_CC_ISDN_CAUSE_USER_NOT_IN_CUG] = "user not in closed user group",
[OSMO_CC_ISDN_CAUSE_INCOMPAT_DEST] = "incompatible destination",
[OSMO_CC_ISDN_CAUSE_INVAL_TRANS_NET] = "invalid transit network",
[OSMO_CC_ISDN_CAUSE_SEMANTIC_INCORR] = "semantically incorrect",
[OSMO_CC_ISDN_CAUSE_INVAL_MAND_INF] = "invalid mandatory information",
[OSMO_CC_ISDN_CAUSE_MSGTYPE_NOTEXIST] = "message type does not exist",
[OSMO_CC_ISDN_CAUSE_MSGTYPE_INCOMPAT] = "message type incompatible",
[OSMO_CC_ISDN_CAUSE_IE_NOTEXIST] = "informaton element does not exits",
[OSMO_CC_ISDN_CAUSE_COND_IE_ERR] = "conditional information element error",
[OSMO_CC_ISDN_CAUSE_MSG_INCOMP_STATE] = "message at incompatlible state",
[OSMO_CC_ISDN_CAUSE_RECOVERY_TIMER] = "recovery on time expiery",
[OSMO_CC_ISDN_CAUSE_PROTO_ERR] = "protocol error",
[OSMO_CC_ISDN_CAUSE_INTERWORKING] = "interworking, unspecified",
};
const char *osmo_cc_isdn_cause_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_isdn_cause_name)
int osmo_cc_isdn_cause_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_isdn_cause_name)
static const char *osmo_cc_location_name[OSMO_CC_LOCATION_NUM] = {
[OSMO_CC_LOCATION_USER] = "user",
[OSMO_CC_LOCATION_PRIV_SERV_LOC_USER] = "private network serving local user",
[OSMO_CC_LOCATION_PUB_SERV_LOC_USER] = "public network serving local user",
[OSMO_CC_LOCATION_TRANSIT] = "transit network",
[OSMO_CC_LOCATION_PUB_SERV_REM_USER] = "public network serving remote user",
[OSMO_CC_LOCATION_PRIV_SERV_REM_USER] = "private network serving remote user",
[OSMO_CC_LOCATION_BEYOND_INTERWORKING] = "beyond interworking",
};
const char *osmo_cc_location_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_location_name)
int osmo_cc_location_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_location_name)
static const char *osmo_cc_progress_name[OSMO_CC_PROGRESS_NUM] = {
[OSMO_CC_PROGRESS_NOT_END_TO_END_ISDN] = "not end-to-end ISDN",
[OSMO_CC_PROGRESS_DEST_NOT_ISDN] = "destination not ISDN",
[OSMO_CC_PROGRESS_ORIG_NOT_ISDN] = "originator not ISDN",
[OSMO_CC_PROGRESS_RETURN_TO_ISDN] = "return to ISDN",
[OSMO_CC_PROGRESS_INTERWORKING] = "interworking",
[OSMO_CC_PROGRESS_INBAND_INFO_AVAILABLE] = "inmand information available (audio)",
};
const char *osmo_cc_progress_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_progress_name)
int osmo_cc_progress_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_progress_name)
static const char *osmo_cc_capability_name[OSMO_CC_CAPABILITY_NUM] = {
[OSMO_CC_CAPABILITY_SPEECH] = "speech",
[OSMO_CC_CAPABILITY_DATA] = "data",
[OSMO_CC_CAPABILITY_DATA_RESTRICTED] = "data restricted",
[OSMO_CC_CAPABILITY_AUDIO] = "audio",
[OSMO_CC_CAPABILITY_DATA_WITH_TONES] = "data with tones",
[OSMO_CC_CAPABILITY_VIDEO] = "video",
};
const char *osmo_cc_capability_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_capability_name)
int osmo_cc_capability_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_capability_name)
static const char *osmo_cc_mode_name[OSMO_CC_MODE_NUM] = {
[OSMO_CC_MODE_CIRCUIT] = "circuit",
[OSMO_CC_MODE_PACKET] = "packet",
};
const char *osmo_cc_mode_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_mode_name)
int osmo_cc_mode_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_mode_name)
static const char *osmo_cc_dtmf_mode_name[OSMO_CC_DTMF_MODE_NUM] = {
[OSMO_CC_DTMF_MODE_OFF] = "off",
[OSMO_CC_DTMF_MODE_ON] = "on",
[OSMO_CC_DTMF_MODE_DIGITS] = "digit",
};
const char *osmo_cc_dtmf_mode_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_dtmf_mode_name)
int osmo_cc_dtmf_mode_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_dtmf_mode_name)
static const char *osmo_cc_socket_cause_name[OSMO_CC_SOCKET_CAUSE_NUM] = {
[0] = "unset",
[OSMO_CC_SOCKET_CAUSE_VERSION_MISMATCH] = "version mismatch",
[OSMO_CC_SOCKET_CAUSE_FAILED] = "socket failed",
[OSMO_CC_SOCKET_CAUSE_BROKEN_PIPE] = "broken pipe",
[OSMO_CC_SOCKET_CAUSE_TIMEOUT] = "keepalive timeout",
};
const char *osmo_cc_socket_cause_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_socket_cause_name)
int osmo_cc_socket_cause_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_socket_cause_name)
static const char *osmo_cc_network_name[OSMO_CC_NETWORK_NUM] = {
[OSMO_CC_NETWORK_UNDEFINED] = "undefined",
[OSMO_CC_NETWORK_ALSA_NONE] = "alsa",
[OSMO_CC_NETWORK_POTS_NONE] = "pots",
[OSMO_CC_NETWORK_ISDN_NONE] = "isdn",
[OSMO_CC_NETWORK_SIP_NONE] = "sip",
[OSMO_CC_NETWORK_GSM_IMSI] = "gsm-imsi",
[OSMO_CC_NETWORK_GSM_IMEI] = "gsm-imei",
[OSMO_CC_NETWORK_WEB_NONE] = "web",
[OSMO_CC_NETWORK_DECT_NONE] = "decs",
[OSMO_CC_NETWORK_BLUETOOTH_NONE] = "bluetooth",
[OSMO_CC_NETWORK_SS5_NONE] = "ss5",
[OSMO_CC_NETWORK_ANETZ_NONE] = "anetz",
[OSMO_CC_NETWORK_BNETZ_MUENZ] = "bnetz",
[OSMO_CC_NETWORK_CNETZ_NONE] = "cnetz",
[OSMO_CC_NETWORK_NMT_NONE] = "nmt",
[OSMO_CC_NETWORK_R2000_NONE] = "radiocom2000",
[OSMO_CC_NETWORK_AMPS_ESN] = "amps",
[OSMO_CC_NETWORK_MTS_NONE] = "mts",
[OSMO_CC_NETWORK_IMTS_NONE] = "imts",
[OSMO_CC_NETWORK_EUROSIGNAL_NONE] = "eurosignal",
[OSMO_CC_NETWORK_JOLLYCOM_NONE] = "jollycom",
[OSMO_CC_NETWORK_MPT1327_PSTN] = "mpt1327-pstn",
[OSMO_CC_NETWORK_MPT1327_PBX] = "mpt1327-pbx",
};
const char *osmo_cc_network_value2name(int value) _OSMO_CC_VALUE2NAME(osmo_cc_network_name)
int osmo_cc_network_name2value(const char *name) _OSMO_CC_NAME2VALUE(osmo_cc_network_name)
/*
*
*/
static uint32_t new_callref = 0;
uint32_t osmo_cc_new_callref(void)
@ -32,126 +363,6 @@ uint32_t osmo_cc_new_callref(void)
return (++new_callref);
}
const char *osmo_cc_msg_name(uint8_t msg_type)
{
switch (msg_type) {
case OSMO_CC_MSG_SETUP_REQ:
return "CC-SETUP-REQ";
case OSMO_CC_MSG_SETUP_IND:
return "CC-SETUP-IND";
case OSMO_CC_MSG_REJ_REQ:
return "CC-REJ-REQ";
case OSMO_CC_MSG_REJ_IND:
return "CC-REJ-IND";
case OSMO_CC_MSG_SETUP_ACK_REQ:
return "CC-SETUP-ACK-REQ";
case OSMO_CC_MSG_SETUP_ACK_IND:
return "CC-SETUP-ACK-IND";
case OSMO_CC_MSG_PROC_REQ:
return "CC-PROC-REQ";
case OSMO_CC_MSG_PROC_IND:
return "CC-PROC-IND";
case OSMO_CC_MSG_ALERT_REQ:
return "CC-ALERT-REQ";
case OSMO_CC_MSG_ALERT_IND:
return "CC-ALERT-IND";
case OSMO_CC_MSG_SETUP_RSP:
return "CC-SETUP-RSP";
case OSMO_CC_MSG_SETUP_CNF:
return "CC-SETUP-CNF";
case OSMO_CC_MSG_SETUP_COMP_REQ:
return "CC-SETUP-COMP-REQ";
case OSMO_CC_MSG_SETUP_COMP_IND:
return "CC-SETUP-COMP-IND";
case OSMO_CC_MSG_DISC_REQ:
return "CC-DISC-REQ";
case OSMO_CC_MSG_DISC_IND:
return "CC-DISC-IND";
case OSMO_CC_MSG_REL_REQ:
return "CC-REL-REQ";
case OSMO_CC_MSG_REL_CNF:
return "CC-REL-CNF";
case OSMO_CC_MSG_REL_IND:
return "CC-REL-IND";
case OSMO_CC_MSG_PROGRESS_REQ:
return "CC-PROGRESS-REQ";
case OSMO_CC_MSG_PROGRESS_IND:
return "CC-PROGRESS-IND";
case OSMO_CC_MSG_NOTIFY_REQ:
return "CC-NOTIFY-REQ";
case OSMO_CC_MSG_NOTIFY_IND:
return "CC-NOTIFY-IND";
case OSMO_CC_MSG_INFO_REQ:
return "CC-INFO-REQ";
case OSMO_CC_MSG_INFO_IND:
return "CC-INFO-IND";
case OSMO_CC_MSG_ATTACH_REQ:
return "CC-ATTACH-REQ";
case OSMO_CC_MSG_ATTACH_IND:
return "CC-ATTACH-IND";
case OSMO_CC_MSG_ATTACH_RSP:
return "CC-ATTACH-RSP";
case OSMO_CC_MSG_ATTACH_CNF:
return "CC-ATTACH-CNF";
default:
return "<unknown>";
}
}
const char *osmo_cc_network_type_name(uint8_t type)
{
switch (type) {
case OSMO_CC_NETWORK_UNDEFINED:
return "";
case OSMO_CC_NETWORK_ALSA_NONE:
return "alsa";
case OSMO_CC_NETWORK_POTS_NONE:
return "pots";
case OSMO_CC_NETWORK_ISDN_NONE:
return "isdn";
case OSMO_CC_NETWORK_SIP_NONE:
return "sip";
case OSMO_CC_NETWORK_GSM_IMSI:
return "gsm-imsi";
case OSMO_CC_NETWORK_GSM_IMEI:
return "gsm-imei";
case OSMO_CC_NETWORK_WEB_NONE:
return "web";
case OSMO_CC_NETWORK_DECT_NONE:
return "decs";
case OSMO_CC_NETWORK_BLUETOOTH_NONE:
return "bluetooth";
case OSMO_CC_NETWORK_SS5_NONE:
return "ss5";
case OSMO_CC_NETWORK_ANETZ_NONE:
return "anetz";
case OSMO_CC_NETWORK_BNETZ_MUENZ:
return "bnetz";
case OSMO_CC_NETWORK_CNETZ_NONE:
return "cnetz";
case OSMO_CC_NETWORK_NMT_NONE:
return "nmt";
case OSMO_CC_NETWORK_R2000_NONE:
return "radiocom2000";
case OSMO_CC_NETWORK_AMPS_ESN:
return "amps";
case OSMO_CC_NETWORK_MTS_NONE:
return "mts";
case OSMO_CC_NETWORK_IMTS_NONE:
return "imts";
case OSMO_CC_NETWORK_EUROSIGNAL_NONE:
return "eurosignal";
case OSMO_CC_NETWORK_JOLLYCOM_NONE:
return "jollycom";
case OSMO_CC_NETWORK_MPT1327_PSTN:
return "mpt1327-pstn";
case OSMO_CC_NETWORK_MPT1327_PBX:
return "mpt1327-pbx";
default:
return "<unknown>";
}
}
/* create message with maximum size */
osmo_cc_msg_t *osmo_cc_new_msg(uint8_t msg_type)
{
@ -217,16 +428,24 @@ void osmo_cc_free_msg(osmo_cc_msg_t *msg)
free(msg);
}
static void osmo_cc_debug_ie(osmo_cc_msg_t *msg, int level)
void osmo_cc_debug_ie(osmo_cc_msg_t *msg, int level)
{
uint16_t msg_len, len;
uint8_t *p;
osmo_cc_ie_t *ie;
int rc;
int ie_repeat[256];
uint8_t type, plan, present, screen, coding, capability, mode, progress, reason, duration_ms, pause_ms, dtmf_mode, location, notify, isdn_cause, socket_cause;
uint16_t sip_cause;
uint32_t unique;
char string[65536];
int i;
memset(ie_repeat, 0, sizeof(ie_repeat));
msg_len = ntohs(msg->length_networkorder);
p = msg->data;
PDEBUG(DCC, level, "Debugging Message: type=0x%02x length=%d value=%s\n", msg->type, msg_len, debug_hex(p, msg_len));
while (msg_len) {
ie = (osmo_cc_ie_t *)p;
/* check for minimum IE length */
@ -241,7 +460,143 @@ static void osmo_cc_debug_ie(osmo_cc_msg_t *msg, int level)
PDEBUG(DCC, level, "****** IE: type=0x%02x length=%d would exceed the rest length of message (%d bytes left)\n", ie->type, len, msg_len - (int)sizeof(*ie));
return;
}
PDEBUG(DCC, level, "IE: type=0x%02x length=%d value=%s\n", ie->type, len, debug_hex(ie->data, len));
switch (ie->type) {
case OSMO_CC_IE_CALLED:
rc = osmo_cc_get_ie_called(msg, ie_repeat[ie->type], &type, &plan, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s type=%d(%s) plan=%d(%s) number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), plan, osmo_cc_plan_value2name(plan), string);
break;
case OSMO_CC_IE_CALLED_SUB:
rc = osmo_cc_get_ie_called_sub(msg, ie_repeat[ie->type], &type, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s type=%d(%s) number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), string);
break;
case OSMO_CC_IE_CALLED_NAME:
rc = osmo_cc_get_ie_called_name(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s name='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_CALLED_INTERFACE:
rc = osmo_cc_get_ie_called_interface(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s name='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_COMPLETE:
rc = osmo_cc_get_ie_complete(msg, ie_repeat[ie->type]);
if (rc < 0)
break;
PDEBUG(DCC, level, " %s\n", osmo_cc_ie_value2name(ie->type));
break;
case OSMO_CC_IE_CALLING:
rc = osmo_cc_get_ie_calling(msg, ie_repeat[ie->type], &type, &plan, &present, &screen, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s type=%d(%s) plan=%d(%s), presentation=%d(%s), screening=%d(%s), number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), plan, osmo_cc_plan_value2name(plan), present, osmo_cc_present_value2name(present), screen, osmo_cc_screen_value2name(screen), string);
break;
case OSMO_CC_IE_CALLING_SUB:
rc = osmo_cc_get_ie_calling_sub(msg, ie_repeat[ie->type], &type, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s type=%d(%s) number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), string);
break;
case OSMO_CC_IE_CALLING_NAME:
rc = osmo_cc_get_ie_calling_name(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s name='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_CALLING_INTERFACE:
rc = osmo_cc_get_ie_calling_interface(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s name='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_CALLING_NETWORK:
rc = osmo_cc_get_ie_calling_network(msg, ie_repeat[ie->type], &type, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s type=%d(%s) id='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_network_value2name(type), string);
break;
case OSMO_CC_IE_BEARER:
rc = osmo_cc_get_ie_bearer(msg, ie_repeat[ie->type], &coding, &capability, &mode);
if (rc < 0)
break;
PDEBUG(DCC, level, " %s coding=%d(%s) capability=%d(%s) mode=%d(%s)\n", osmo_cc_ie_value2name(ie->type), coding, osmo_cc_coding_value2name(coding), capability, osmo_cc_capability_value2name(capability), mode, osmo_cc_mode_value2name(mode));
break;
case OSMO_CC_IE_REDIR:
rc = osmo_cc_get_ie_redir(msg, ie_repeat[ie->type], &type, &plan, &present, &screen, &reason, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s type=%d(%s) plan=%d(%s) presentation=%d(%s) screening=%d(%s) reason=%d(%s) number='%s'\n", osmo_cc_ie_value2name(ie->type), type, osmo_cc_type_value2name(type), plan, osmo_cc_plan_value2name(plan), present, osmo_cc_present_value2name(present), screen, osmo_cc_screen_value2name(screen), reason, osmo_cc_redir_reason_value2name(reason), string);
break;
case OSMO_CC_IE_DTMF:
rc = osmo_cc_get_ie_dtmf(msg, ie_repeat[ie->type], &duration_ms, &pause_ms, &dtmf_mode, string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s duration=%dms pause=%dms mode=%d(%s)\n", osmo_cc_ie_value2name(ie->type), duration_ms, pause_ms, dtmf_mode, osmo_cc_dtmf_mode_value2name(dtmf_mode));
break;
case OSMO_CC_IE_KEYPAD:
rc = osmo_cc_get_ie_keypad(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s digits='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_PROGRESS:
rc = osmo_cc_get_ie_progress(msg, ie_repeat[ie->type], &coding, &location, &progress);
if (rc < 0)
break;
PDEBUG(DCC, level, " %s coding=%d(%s) location=%d(%s) progress=%d(%s)\n", osmo_cc_ie_value2name(ie->type), coding, osmo_cc_coding_value2name(coding), location, osmo_cc_location_value2name(location), progress, osmo_cc_progress_value2name(progress));
break;
case OSMO_CC_IE_NOTIFY:
rc = osmo_cc_get_ie_notify(msg, ie_repeat[ie->type], &notify);
if (rc < 0)
break;
PDEBUG(DCC, level, " %s indicator=%d(%s)\n", osmo_cc_ie_value2name(ie->type), notify, osmo_cc_notify_value2name(notify));
break;
case OSMO_CC_IE_CAUSE:
rc = osmo_cc_get_ie_cause(msg, ie_repeat[ie->type], &location, &isdn_cause, &sip_cause, &socket_cause);
if (rc < 0)
break;
PDEBUG(DCC, level, " %s location=%d(%s) isdn_cause=%d(%s) sip_cause=%d socket_cause=%d(%s)\n", osmo_cc_ie_value2name(ie->type), location, osmo_cc_location_value2name(location), isdn_cause, osmo_cc_isdn_cause_value2name(isdn_cause), sip_cause, socket_cause, osmo_cc_socket_cause_value2name(socket_cause));
break;
case OSMO_CC_IE_DISPLAY:
rc = osmo_cc_get_ie_display(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s info='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_SDP:
rc = osmo_cc_get_ie_sdp(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
for (i = 0; string[i]; i++) {
if (string[i] == '\r')
string[i] = '\\';
if (string[i] == '\n')
string[i] = 'n';
}
PDEBUG(DCC, level, " %s payload=%s\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_SOCKET_ADDRESS:
rc = osmo_cc_get_ie_socket_address(msg, ie_repeat[ie->type], string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s address='%s'\n", osmo_cc_ie_value2name(ie->type), string);
break;
case OSMO_CC_IE_PRIVATE:
rc = osmo_cc_get_ie_private(msg, ie_repeat[ie->type], &unique, (uint8_t *)string, sizeof(string));
if (rc < 0)
break;
PDEBUG(DCC, level, " %s unique=%u=0x%08x private=%s\n", osmo_cc_ie_value2name(ie->type), unique, unique, debug_hex((uint8_t *)string, rc));
break;
default:
PDEBUG(DCC, level, " %s type=0x%02x length=%d value=%s\n", osmo_cc_ie_value2name(ie->type), ie->type, len, debug_hex(ie->data, len));
}
ie_repeat[ie->type]++;
p += sizeof(*ie) + len;
msg_len -= sizeof(*ie) + len;
}
@ -927,7 +1282,9 @@ int osmo_cc_get_ie_private(osmo_cc_msg_t *msg, int ie_repeat, uint32_t *unique,
if (rc < 0)
return rc;
*unique = ntohl(ie_private->unique_networkorder);
memcpy(data, ie_private->data, (rc < (int)data_size) ? rc : (int)data_size);
if (rc > (int)data_size)
rc = data_size;
memcpy(data, ie_private->data, rc);
return rc;
}

View File

@ -36,6 +36,7 @@ enum osmo_cc_msg_type {
OSMO_CC_MSG_ATTACH_CNF = 0xfb,
OSMO_CC_MSG_DUMMY_REQ = 0xfc,
};
#define OSMO_CC_MSG_NUM 0x100
#define OSMO_CC_MSG_MASK 0x03,
#define OSMO_CC_MSG_REQ 0x00,
@ -43,6 +44,9 @@ enum osmo_cc_msg_type {
#define OSMO_CC_MSG_RSP 0x02,
#define OSMO_CC_MSG_CNF 0x03,
const char *osmo_cc_msg_value2name(int value);
int osmo_cc_msg_name2value(const char *name);
/* information elements */
enum osmo_cc_ie_type {
OSMO_CC_IE_CALLED = 0x11,
@ -67,6 +71,10 @@ enum osmo_cc_ie_type {
OSMO_CC_IE_SOCKET_ADDRESS = 0x5e,
OSMO_CC_IE_PRIVATE = 0x5f,
};
#define OSMO_CC_IE_NUM 0x100
const char *osmo_cc_ie_value2name(int value);
int osmo_cc_ie_name2value(const char *name);
/* type of number, see ITU-T Rec. Q.931 */
#define OSMO_CC_TYPE_UNKNOWN 0
@ -76,6 +84,10 @@ enum osmo_cc_ie_type {
#define OSMO_CC_TYPE_SUBSCRIBER 4
#define OSMO_CC_TYPE_ABBREVIATED 5
#define OSMO_CC_TYPE_RESERVED 7
#define OSMO_CC_TYPE_NUM 8
const char *osmo_cc_type_value2name(int value);
int osmo_cc_type_name2value(const char *name);
/* numbering plan, see ITU-T Rec. Q.931 */
#define OSMO_CC_PLAN_UNKNOWN 0
@ -85,18 +97,30 @@ enum osmo_cc_ie_type {
#define OSMO_CC_PLAN_NATIONAL_STANDARD 8
#define OSMO_CC_PLAN_PRIVATE 9
#define OSMO_CC_PLAN_RESERVED 15
#define OSMO_CC_PLAN_NUM 16
const char *osmo_cc_plan_value2name(int value);
int osmo_cc_plan_name2value(const char *name);
/* presentation indicator, see ITU-T Rec. Q.931 */
#define OSMO_CC_PRESENT_ALLOWED 0
#define OSMO_CC_PRESENT_RESTRICTED 1
#define OSMO_CC_PRESENT_NOT_AVAIL 2
#define OSMO_CC_PRESENT_RESERVED 3
#define OSMO_CC_PRESENT_NUM 4
const char *osmo_cc_present_value2name(int value);
int osmo_cc_present_name2value(const char *name);
/* screening indicator, see ITU-T Rec. Q.931 */
#define OSMO_CC_SCREEN_USER_UNSCREENED 0
#define OSMO_CC_SCREEN_USER_VERIFIED_PASSED 1
#define OSMO_CC_SCREEN_USER_VERIFIED_FAILED 2
#define OSMO_CC_SCREEN_NETWORK 3
#define OSMO_CC_SCREEN_NUM 4
const char *osmo_cc_screen_value2name(int value);
int osmo_cc_screen_name2value(const char *name);
/* screening indicator, see ITU-T Rec. Q.931 */
#define OSMO_CC_REDIR_REASON_UNKNOWN 0
@ -106,6 +130,10 @@ enum osmo_cc_ie_type {
#define OSMO_CC_REDIR_REASON_CF_OUTOFORDER 9
#define OSMO_CC_REDIR_REASON_CF_BY_DTE 10
#define OSMO_CC_REDIR_REASON_CFU 15
#define OSMO_CC_REDIR_REASON_NUM 16
const char *osmo_cc_redir_reason_value2name(int value);
int osmo_cc_redir_reason_name2value(const char *name);
/* notification indicator, see ITU-T Rec. Q.931 ff. */
#define OSMO_CC_NOTIFY_USER_SUSPENDED 0x00
@ -132,15 +160,24 @@ enum osmo_cc_ie_type {
#define OSMO_CC_NOTIFY_REMOTE_HOLD 0x79
#define OSMO_CC_NOTIFY_REMOTE_RETRIEVAL 0x7a
#define OSMO_CC_NOTIFY_CALL_IS_DIVERTING 0x7b
#define OSMO_CC_NOTIFY_NUM 0x100
const char *osmo_cc_notify_value2name(int value);
int osmo_cc_notify_name2value(const char *name);
/* coding standard, see ITU-T Rec. Q.931 */
#define OSMO_CC_CODING_ITU_T 0
#define OSMO_CC_CODING_ISO_IEC 1
#define OSMO_CC_CODING_NATIONAL 2
#define OSMO_CC_CODING_STANDARD_SPECIFIC 3
#define OSMO_CC_CODING_NUM 4
const char *osmo_cc_coding_value2name(int value);
int osmo_cc_coding_name2value(const char *name);
/* cause, see ITU-T Rec. Q.850 */
#define OSMO_CC_ISDN_CAUSE_UNASSIGNED_NR 1
#define OSMO_CC_ISDN_CAUSE_NO_ROUTE_TRANSIT 2
#define OSMO_CC_ISDN_CAUSE_NO_ROUTE 3
#define OSMO_CC_ISDN_CAUSE_CHAN_UNACCEPT 6
#define OSMO_CC_ISDN_CAUSE_OP_DET_BARRING 8
@ -189,6 +226,10 @@ enum osmo_cc_ie_type {
#define OSMO_CC_ISDN_CAUSE_RECOVERY_TIMER 102
#define OSMO_CC_ISDN_CAUSE_PROTO_ERR 111
#define OSMO_CC_ISDN_CAUSE_INTERWORKING 127
#define OSMO_CC_ISDN_CAUSE_NUM 128
const char *osmo_cc_isdn_cause_value2name(int value);
int osmo_cc_isdn_cause_name2value(const char *name);
/* location, see ITU-T Rec. Q.931 */
#define OSMO_CC_LOCATION_USER 0
@ -198,6 +239,10 @@ enum osmo_cc_ie_type {
#define OSMO_CC_LOCATION_PUB_SERV_REM_USER 4
#define OSMO_CC_LOCATION_PRIV_SERV_REM_USER 5
#define OSMO_CC_LOCATION_BEYOND_INTERWORKING 10
#define OSMO_CC_LOCATION_NUM 16
const char *osmo_cc_location_value2name(int value);
int osmo_cc_location_name2value(const char *name);
/* progress description, see ITU-T Rec. Q.931 */
#define OSMO_CC_PROGRESS_NOT_END_TO_END_ISDN 1
@ -206,6 +251,10 @@ enum osmo_cc_ie_type {
#define OSMO_CC_PROGRESS_RETURN_TO_ISDN 4
#define OSMO_CC_PROGRESS_INTERWORKING 5
#define OSMO_CC_PROGRESS_INBAND_INFO_AVAILABLE 8
#define OSMO_CC_PROGRESS_NUM 16
const char *osmo_cc_progress_value2name(int value);
int osmo_cc_progress_name2value(const char *name);
/* information transfer capability, see ITU-T Rec. Q.931 */
#define OSMO_CC_CAPABILITY_SPEECH 0
@ -214,20 +263,36 @@ enum osmo_cc_ie_type {
#define OSMO_CC_CAPABILITY_AUDIO 16
#define OSMO_CC_CAPABILITY_DATA_WITH_TONES 17
#define OSMO_CC_CAPABILITY_VIDEO 24
#define OSMO_CC_CAPABILITY_NUM 32
const char *osmo_cc_capability_value2name(int value);
int osmo_cc_capability_name2value(const char *name);
/* transfer mode, see ITU-T Rec. Q.931 */
#define OSMO_CC_MODE_CIRCUIT 0
#define OSMO_CC_MODE_PACKET 2
#define OSMO_CC_MODE_NUM 4
const char *osmo_cc_mode_value2name(int value);
int osmo_cc_mode_name2value(const char *name);
#define OSMO_CC_DTMF_MODE_OFF 0 /* stop tone */
#define OSMO_CC_DTMF_MODE_ON 1 /* start tone */
#define OSMO_CC_DTMF_MODE_DIGITS 2 /* play tone(s) with duration and pauses */
#define OSMO_CC_DTMF_MODE_NUM 3
const char *osmo_cc_dtmf_mode_value2name(int value);
int osmo_cc_dtmf_mode_name2value(const char *name);
#define OSMO_CC_SOCKET_CAUSE_VERSION_MISMATCH 1 /* version mismatch */
#define OSMO_CC_SOCKET_CAUSE_FAILED 2 /* connection failed */
#define OSMO_CC_SOCKET_CAUSE_BROKEN_PIPE 3 /* connected socket failed */
#define OSMO_CC_SOCKET_CAUSE_TIMEOUT 4 /* keepalive packets timeout */
// if you add causes here, add them in process_cause.c also!
#define OSMO_CC_SOCKET_CAUSE_NUM 5
const char *osmo_cc_socket_cause_value2name(int value);
int osmo_cc_socket_cause_name2value(const char *name);
/* network type (network IE) and meaning of 'id' */
#define OSMO_CC_NETWORK_UNDEFINED 0x00
@ -253,6 +318,10 @@ enum osmo_cc_ie_type {
#define OSMO_CC_NETWORK_JOLLYCOM_NONE 0x89 /* call from JollyCom... */
#define OSMO_CC_NETWORK_MPT1327_PSTN 0x8a /* call from MPT1327 */
#define OSMO_CC_NETWORK_MPT1327_PBX 0x8b /* id is selected PBX number */
#define OSMO_CC_NETWORK_NUM 0x100
const char *osmo_cc_network_value2name(int value);
int osmo_cc_network_name2value(const char *name);
typedef struct osmo_cc_msg {
uint8_t type;
@ -380,13 +449,12 @@ struct osmo_cc_ie_private {
} __attribute__((packed));
uint32_t osmo_cc_new_callref(void);
const char *osmo_cc_msg_name(uint8_t msg_type);
const char *osmo_cc_network_type_name(uint8_t type);
osmo_cc_msg_t *osmo_cc_new_msg(uint8_t msg_type);
osmo_cc_msg_t *osmo_cc_clone_msg(osmo_cc_msg_t *msg);
osmo_cc_msg_t *osmo_cc_msg_list_dequeue(osmo_cc_msg_list_t **mlp, uint32_t *callref_p);
osmo_cc_msg_list_t *osmo_cc_msg_list_enqueue(osmo_cc_msg_list_t **mlp, osmo_cc_msg_t *msg, uint32_t callref);
void osmo_cc_free_msg(osmo_cc_msg_t *msg);
void osmo_cc_debug_ie(osmo_cc_msg_t *msg, int level);
int osmo_cc_get_ie_struct(osmo_cc_msg_t *msg, uint8_t ie_type, int ie_repeat, int ie_len, const osmo_cc_ie_t **ie_struct);
int osmo_cc_get_ie_data(osmo_cc_msg_t *msg, uint8_t ie_type, int ie_repeat, int ie_len, const void **ie_data);
int osmo_cc_has_ie(osmo_cc_msg_t *msg, uint8_t ie_type, int ie_repeat);

View File

@ -21,7 +21,9 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
//#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include "timer.h"
static struct timer *timer_head = NULL;
@ -29,11 +31,11 @@ static struct timer **timer_tail_p = &timer_head;
double get_time(void)
{
struct timeval tv;
static struct timespec tv;
gettimeofday(&tv, NULL);
clock_gettime(CLOCK_REALTIME, &tv);
return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
return (double)tv.tv_sec + (double)tv.tv_nsec / 1000000000.0;
}
void timer_init(struct timer *timer, void (*fn)(struct timer *timer), void *priv)
@ -66,15 +68,11 @@ void timer_exit(struct timer *timer)
void timer_start(struct timer *timer, double duration)
{
struct timeval tv;
if (!timer->linked) {
fprintf(stderr, "Timer is not initialized, aborting!\n");
abort();
}
gettimeofday(&tv, NULL);
timer->duration = duration;
timer->timeout = get_time() + duration;
}