mirror of
https://github.com/asterisk/asterisk.git
synced 2026-07-27 16:07:15 -07:00
Merge changes from team/russell/iax2_osp
This set of changes adds OSP support to chan_iax2. However, I have modified the patch a bit from what was submitted. You now use the CHANNEL() function to get and set the OSP token for IAX2. (issue #8531, reported by and original patch by homesick, patch updated by me) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61702 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -577,6 +577,8 @@ struct chan_iax2_pvt {
|
||||
AST_STRING_FIELD(accountcode);
|
||||
AST_STRING_FIELD(mohinterpret);
|
||||
AST_STRING_FIELD(mohsuggest);
|
||||
/*! received OSP token */
|
||||
AST_STRING_FIELD(osptoken);
|
||||
);
|
||||
|
||||
/*! permitted authentication methods */
|
||||
@@ -851,6 +853,9 @@ static void realtime_update_peer(const char *peername, struct sockaddr_in *sin,
|
||||
static void destroy_user(struct iax2_user *user);
|
||||
static void prune_peers(void);
|
||||
|
||||
static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
|
||||
static int acf_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value);
|
||||
|
||||
static const struct ast_channel_tech iax2_tech = {
|
||||
.type = "IAX2",
|
||||
.description = tdesc,
|
||||
@@ -874,6 +879,8 @@ static const struct ast_channel_tech iax2_tech = {
|
||||
.bridge = iax2_bridge,
|
||||
.transfer = iax2_transfer,
|
||||
.fixup = iax2_fixup,
|
||||
.func_channel_read = acf_channel_read,
|
||||
.func_channel_write = acf_channel_write,
|
||||
};
|
||||
|
||||
static void insert_idle_thread(struct iax2_thread *thread)
|
||||
@@ -2890,6 +2897,11 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
|
||||
struct parsed_dial_string pds;
|
||||
struct create_addr_info cai;
|
||||
struct ast_var_t *var;
|
||||
const char* osp_token_ptr;
|
||||
unsigned int osp_token_length;
|
||||
unsigned char osp_block_index;
|
||||
unsigned int osp_block_length;
|
||||
unsigned char osp_buffer[256];
|
||||
|
||||
if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
|
||||
ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
|
||||
@@ -3010,6 +3022,25 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
|
||||
iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
|
||||
}
|
||||
|
||||
/* Check if there is an OSP token set by IAXCHANINFO function */
|
||||
osp_token_ptr = iaxs[callno]->osptoken;
|
||||
if (!ast_strlen_zero(osp_token_ptr)) {
|
||||
if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
|
||||
osp_block_index = 0;
|
||||
while (osp_token_length > 0) {
|
||||
osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
|
||||
osp_buffer[0] = osp_block_index;
|
||||
memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
|
||||
iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
|
||||
osp_block_index++;
|
||||
osp_token_ptr += osp_block_length;
|
||||
osp_token_length -= osp_block_length;
|
||||
}
|
||||
} else
|
||||
ast_log(LOG_WARNING, "OSP token is too long\n");
|
||||
} else if (option_debug && iaxdebug)
|
||||
ast_log(LOG_DEBUG, "OSP token is undefined\n");
|
||||
|
||||
/* send the command using the appropriate socket for this peer */
|
||||
iaxs[callno]->sockfd = cai.sockfd;
|
||||
|
||||
@@ -6316,6 +6347,36 @@ static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
|
||||
iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
|
||||
}
|
||||
|
||||
static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
|
||||
{
|
||||
int i;
|
||||
unsigned int length, offset = 0;
|
||||
char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
|
||||
|
||||
for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
|
||||
length = ies->ospblocklength[i];
|
||||
if (length != 0) {
|
||||
if (length > IAX_MAX_OSPBLOCK_SIZE) {
|
||||
/* OSP token block length wrong, clear buffer */
|
||||
offset = 0;
|
||||
break;
|
||||
} else {
|
||||
memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
|
||||
offset += length;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(full_osptoken + offset) = '\0';
|
||||
if (strlen(full_osptoken) != offset) {
|
||||
/* OSP token length wrong, clear buffer */
|
||||
*full_osptoken = '\0';
|
||||
}
|
||||
|
||||
ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
|
||||
}
|
||||
|
||||
static int socket_read(int *id, int fd, short events, void *cbdata)
|
||||
{
|
||||
struct iax2_thread *thread;
|
||||
@@ -6940,6 +7001,8 @@ retryowner:
|
||||
ast_mutex_lock(&iaxsl[fr->callno]);
|
||||
} else
|
||||
exists = 0;
|
||||
/* Get OSP token if it does exist */
|
||||
save_osptoken(fr, &ies);
|
||||
if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
|
||||
if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
|
||||
memset(&ied0, 0, sizeof(ied0));
|
||||
@@ -9824,6 +9887,61 @@ struct ast_custom_function iaxpeer_function = {
|
||||
"\n"
|
||||
};
|
||||
|
||||
static int acf_channel_write(struct ast_channel *chan, const char *function, char *args, const char *value)
|
||||
{
|
||||
struct chan_iax2_pvt *pvt;
|
||||
unsigned int callno;
|
||||
int res = 0;
|
||||
|
||||
if (!chan || chan->tech != &iax2_tech) {
|
||||
ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
callno = PTR_TO_CALLNO(chan->tech_pvt);
|
||||
ast_mutex_lock(&iaxsl[callno]);
|
||||
if (!(pvt = iaxs[callno])) {
|
||||
ast_mutex_unlock(&iaxsl[callno]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!strcasecmp(args, "osptoken"))
|
||||
ast_string_field_set(pvt, osptoken, value);
|
||||
else
|
||||
res = -1;
|
||||
|
||||
ast_mutex_unlock(&iaxsl[callno]);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
|
||||
{
|
||||
struct chan_iax2_pvt *pvt;
|
||||
unsigned int callno;
|
||||
int res = 0;
|
||||
|
||||
if (!chan || chan->tech != &iax2_tech) {
|
||||
ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
callno = PTR_TO_CALLNO(chan->tech_pvt);
|
||||
ast_mutex_lock(&iaxsl[callno]);
|
||||
if (!(pvt = iaxs[callno])) {
|
||||
ast_mutex_unlock(&iaxsl[callno]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!strcasecmp(args, "osptoken"))
|
||||
ast_copy_string(buf, pvt->osptoken, buflen);
|
||||
else
|
||||
res = -1;
|
||||
|
||||
ast_mutex_unlock(&iaxsl[callno]);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*! \brief Part of the device state notification system ---*/
|
||||
static int iax2_devicestate(void *data)
|
||||
|
||||
@@ -264,6 +264,7 @@ static struct iax2_ie {
|
||||
{ IAX_IE_RR_DROPPED, "RR_DROPPED", dump_int },
|
||||
{ IAX_IE_RR_OOO, "RR_OUTOFORDER", dump_int },
|
||||
{ IAX_IE_VARIABLE, "VARIABLE", dump_string },
|
||||
{ IAX_IE_OSPTOKEN, "OSPTOKEN" },
|
||||
};
|
||||
|
||||
static struct iax2_ie prov_ies[] = {
|
||||
@@ -617,6 +618,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
|
||||
int ie;
|
||||
char tmp[256], *tmp2;
|
||||
struct ast_variable *var, *var2, *prev;
|
||||
unsigned int count;
|
||||
memset(ies, 0, (int)sizeof(struct iax_ies));
|
||||
ies->msgcount = -1;
|
||||
ies->firmwarever = -1;
|
||||
@@ -930,6 +932,15 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
|
||||
ies->vars = var;
|
||||
}
|
||||
break;
|
||||
case IAX_IE_OSPTOKEN:
|
||||
if ((count = data[2]) < IAX_MAX_OSPBLOCK_NUM) {
|
||||
ies->osptokenblock[count] = (char *)data + 2 + 1;
|
||||
ies->ospblocklength[count] = len - 1;
|
||||
} else {
|
||||
snprintf(tmp, (int)sizeof(tmp), "Expected OSP token block index to be 0~%d but was %d\n", IAX_MAX_OSPBLOCK_NUM - 1, count);
|
||||
errorf(tmp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len);
|
||||
outputf(tmp);
|
||||
|
||||
@@ -74,6 +74,8 @@ struct iax_ies {
|
||||
unsigned int rr_dropped;
|
||||
unsigned int rr_ooo;
|
||||
struct ast_variable *vars;
|
||||
char *osptokenblock[IAX_MAX_OSPBLOCK_NUM];
|
||||
unsigned int ospblocklength[IAX_MAX_OSPBLOCK_NUM];
|
||||
};
|
||||
|
||||
#define DIRECTION_INGRESS 1
|
||||
|
||||
@@ -129,7 +129,12 @@
|
||||
#define IAX_IE_RR_DROPPED 50 /* Dropped frames (presumably by jitterbuf) u32 */
|
||||
#define IAX_IE_RR_OOO 51 /* Frames received Out of Order u32 */
|
||||
#define IAX_IE_VARIABLE 52 /* Remote variables */
|
||||
#define IAX_IE_OSPTOKEN 53 /* OSP token */
|
||||
|
||||
#define IAX_MAX_OSPBLOCK_SIZE 254 /* Max OSP token block size, 255 bytes - 1 byte OSP token block index */
|
||||
#define IAX_MAX_OSPBLOCK_NUM 4
|
||||
#define IAX_MAX_OSPTOKEN_SIZE (IAX_MAX_OSPBLOCK_SIZE * IAX_MAX_OSPBLOCK_NUM)
|
||||
#define IAX_MAX_OSPBUFF_SIZE (IAX_MAX_OSPTOKEN_SIZE + 16)
|
||||
|
||||
#define IAX_AUTH_PLAINTEXT (1 << 0)
|
||||
#define IAX_AUTH_MD5 (1 << 1)
|
||||
|
||||
@@ -182,6 +182,9 @@ static struct ast_custom_function channel_function = {
|
||||
" rtt Round trip time\n"
|
||||
" all All statistics (in a form suited to logging, but not for parsing)\n"
|
||||
"\n"
|
||||
"chan_iax2 provides the following additional options:\n"
|
||||
"R/W osptoken Get or set the OSP token information for a call\n"
|
||||
"\n"
|
||||
"Additional items may be available from the channel driver providing\n"
|
||||
"the channel; see its documentation for details.\n"
|
||||
"\n"
|
||||
|
||||
Reference in New Issue
Block a user