mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-30 10:33:13 +00:00
moved the asn1 and facility portions of code to mISDNuser, so removing the files here.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@39807 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -104,4 +104,4 @@ chan_misdn.o: CFLAGS+=-Imisdn -DCHAN_MISDN_VERSION=\"0.3.0\" $(EC_CFLAGS)
|
|||||||
misdn_config.o: CFLAGS+=-Imisdn -DCHAN_MISDN_VERSION=\"0.3.0\" $(EC_CFLAGS)
|
misdn_config.o: CFLAGS+=-Imisdn -DCHAN_MISDN_VERSION=\"0.3.0\" $(EC_CFLAGS)
|
||||||
|
|
||||||
chan_misdn.so: chan_misdn.o misdn_config.o misdn/chan_misdn_lib.a
|
chan_misdn.so: chan_misdn.o misdn_config.o misdn/chan_misdn_lib.a
|
||||||
chan_misdn.so: LIBS+=-lisdnnet -lmISDN $(EC_LIBS)
|
chan_misdn.so: LIBS+=-lisdnnet -lmISDN -lsuppserv $(EC_LIBS)
|
||||||
|
@@ -413,20 +413,15 @@ static char *bearer2str(int cap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void print_facility( struct misdn_bchannel *bc)
|
static void print_facility(struct FacReqParm *fac, struct misdn_bchannel *bc)
|
||||||
{
|
{
|
||||||
switch (bc->fac_type) {
|
switch (fac->Function) {
|
||||||
case FACILITY_CALLDEFLECT:
|
case FacReq_CD:
|
||||||
chan_misdn_log(0,bc->port," --> calldeflect: %s\n",
|
chan_misdn_log(0,bc->port," --> calldeflect to: %s, screened: %s\n", fac->u.CDeflection.DeflectedToNumber,
|
||||||
bc->fac.calldeflect_nr);
|
fac->u.CDeflection.PresentationAllowed ? "yes" : "no");
|
||||||
break;
|
|
||||||
case FACILITY_CENTREX:
|
|
||||||
chan_misdn_log(0,bc->port," --> centrex: %s\n",
|
|
||||||
bc->fac.cnip);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
chan_misdn_log(0,bc->port," --> unknown\n");
|
chan_misdn_log(0,bc->port," --> unknown\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1126,11 +1121,16 @@ static int misdn_send_cd (int fd, int argc, char *argv[])
|
|||||||
struct chan_list *tmp=get_chan_by_ast_name(channame);
|
struct chan_list *tmp=get_chan_by_ast_name(channame);
|
||||||
|
|
||||||
if (!tmp) {
|
if (!tmp) {
|
||||||
ast_cli(fd, "Sending CD with nr %s to %s failed Channel does not exist\n",nr, channame);
|
ast_cli(fd, "Sending CD with nr %s to %s failed: Channel does not exist.\n",nr, channame);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
if (strlen(nr) >= 15) {
|
||||||
misdn_lib_send_facility(tmp->bc, FACILITY_CALLDEFLECT, nr);
|
ast_cli(fd, "Sending CD with nr %s to %s failed: Number too long (up to 15 digits are allowed).\n",nr, channame);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
tmp->bc->fac_out.Function = FacReq_CD;
|
||||||
|
strncpy((char *)tmp->bc->fac_out.u.CDeflection.DeflectedToNumber, nr, sizeof(tmp->bc->fac_out.u.CDeflection.DeflectedToNumber));
|
||||||
|
misdn_lib_send_event(tmp->bc, EVENT_FACILITY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4477,30 +4477,34 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case EVENT_FACILITY:
|
case EVENT_FACILITY:
|
||||||
print_facility(bc);
|
print_facility(&(bc->fac_in), bc);
|
||||||
|
|
||||||
switch (bc->fac_type) {
|
switch (bc->fac_in.Function) {
|
||||||
case FACILITY_CALLDEFLECT:
|
case FacReq_CD:
|
||||||
{
|
{
|
||||||
struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
|
struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
|
||||||
struct chan_list *ch;
|
struct chan_list *ch_br;
|
||||||
|
|
||||||
misdn_lib_send_event(bc, EVENT_DISCONNECT);
|
|
||||||
|
|
||||||
if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) {
|
if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) {
|
||||||
ch=MISDN_ASTERISK_TECH_PVT(bridged);
|
ch_br=MISDN_ASTERISK_TECH_PVT(bridged);
|
||||||
/*ch->state=MISDN_FACILITY_DEFLECTED;*/
|
/*ch->state=MISDN_FACILITY_DEFLECTED;*/
|
||||||
if (ch->bc) {
|
if (ch_br->bc) {
|
||||||
/* todo */
|
if (ast_exists_extension(bridged, ch->context, (char *)bc->fac_in.u.CDeflection.DeflectedToNumber, 1, bc->oad)) {
|
||||||
|
ch_br->state=MISDN_DIALING;
|
||||||
|
if (pbx_start_chan(ch_br) < 0) {
|
||||||
|
chan_misdn_log(-1, ch_br->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
misdn_lib_send_event(bc, EVENT_DISCONNECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
chan_misdn_log(0, bc->port," --> not yet handled: facility type:%p\n", bc->fac_type);
|
chan_misdn_log(0, bc->port," --> not yet handled: facility type:%p\n", bc->fac_in.Function);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -4782,8 +4786,13 @@ static int misdn_facility_exec(struct ast_channel *chan, void *data)
|
|||||||
ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n");
|
ast_log(LOG_WARNING, "Facility: Call Defl Requires arguments\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
misdn_lib_send_facility(ch->bc, FACILITY_CALLDEFLECT, tok);
|
if (strlen(tok) >= sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber)) {
|
||||||
|
ast_log(LOG_WARNING, "Facility: Number argument too long (up to 15 digits are allowed). Ignoring.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ch->bc->fac_out.Function = FacReq_CD;
|
||||||
|
strncpy((char *)ch->bc->fac_out.u.CDeflection.DeflectedToNumber, tok, sizeof(ch->bc->fac_out.u.CDeflection.DeflectedToNumber));
|
||||||
|
misdn_lib_send_event(ch->bc, EVENT_FACILITY);
|
||||||
} else {
|
} else {
|
||||||
ast_log(LOG_WARNING, "Unknown Facility: %s\n",tok);
|
ast_log(LOG_WARNING, "Unknown Facility: %s\n",tok);
|
||||||
}
|
}
|
||||||
|
@@ -11,15 +11,13 @@ CFLAGS += -fPIC
|
|||||||
endif
|
endif
|
||||||
SOURCES = isdn_lib.c isdn_msg_parser.c
|
SOURCES = isdn_lib.c isdn_msg_parser.c
|
||||||
OBJDIR = .
|
OBJDIR = .
|
||||||
OBJS = isdn_lib.o isdn_msg_parser.o fac.o asn1.o
|
OBJS = isdn_lib.o isdn_msg_parser.o
|
||||||
|
|
||||||
ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/lib/libbnec.so),)
|
ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/lib/libbnec.so),)
|
||||||
CFLAGS+=-DBEROEC_VERSION=1
|
CFLAGS+=-DBEROEC_VERSION=1
|
||||||
CFLAGS+=-DWITH_BEROEC
|
CFLAGS+=-DWITH_BEROEC
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CFLAGS+=-DFACILITY_DEBUG
|
|
||||||
|
|
||||||
all: chan_misdn_lib.a
|
all: chan_misdn_lib.a
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
|
@@ -1,181 +0,0 @@
|
|||||||
|
|
||||||
#include "asn1.h"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
** ASN.1 Encoding
|
|
||||||
*/
|
|
||||||
|
|
||||||
int _enc_null (__u8 *dest, int tag)
|
|
||||||
{
|
|
||||||
dest[0] = tag;
|
|
||||||
dest[1] = 0;
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _enc_bool (__u8 *dest, __u32 i, int tag)
|
|
||||||
{
|
|
||||||
dest[0] = tag;
|
|
||||||
dest[1] = 1;
|
|
||||||
dest[2] = i ? 1:0;
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _enc_int (__u8 *dest, __u32 i, int tag)
|
|
||||||
{
|
|
||||||
__u8 *p;
|
|
||||||
dest[0] = tag;
|
|
||||||
p = &dest[2];
|
|
||||||
do {
|
|
||||||
*p++ = i;
|
|
||||||
i >>= 8;
|
|
||||||
} while (i);
|
|
||||||
dest[1] = p - &dest[2];
|
|
||||||
return p - dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _enc_enum (__u8 *dest, __u32 i, int tag)
|
|
||||||
{
|
|
||||||
__u8 *p;
|
|
||||||
|
|
||||||
dest[0] = tag;
|
|
||||||
p = &dest[2];
|
|
||||||
do {
|
|
||||||
*p++ = i;
|
|
||||||
i >>= 8;
|
|
||||||
} while (i);
|
|
||||||
dest[1] = p - &dest[2];
|
|
||||||
return p - dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _enc_num_string (__u8 *dest, char *nd, __u8 len, int tag)
|
|
||||||
{
|
|
||||||
__u8 *p;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
dest[0] = tag;
|
|
||||||
p = &dest[2];
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
*p++ = *nd++;
|
|
||||||
dest[1] = p - &dest[2];
|
|
||||||
return p - dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _enc_sequence_start (__u8 *dest, __u8 **id, int tag)
|
|
||||||
{
|
|
||||||
dest[0] = tag;
|
|
||||||
*id = &dest[1];
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _enc_sequence_end (__u8 *dest, __u8 *id, int tag_dummy)
|
|
||||||
{
|
|
||||||
*id = dest - id - 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** ASN.1 Decoding
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define CHECK_P \
|
|
||||||
do { \
|
|
||||||
if (p >= end) \
|
|
||||||
return -1; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define CallASN1(ret, p, end, todo) \
|
|
||||||
do { \
|
|
||||||
ret = todo; \
|
|
||||||
if (ret < 0) { \
|
|
||||||
return -1; \
|
|
||||||
} \
|
|
||||||
p += ret; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define INIT \
|
|
||||||
int len, ret; \
|
|
||||||
__u8 *begin = p; \
|
|
||||||
if (tag) \
|
|
||||||
*tag = *p; \
|
|
||||||
p++; \
|
|
||||||
CallASN1(ret, p, end, dec_len(p, &len)); \
|
|
||||||
if (len >= 0) { \
|
|
||||||
if (p + len > end) \
|
|
||||||
return -1; \
|
|
||||||
end = p + len; \
|
|
||||||
}
|
|
||||||
|
|
||||||
int _dec_null (__u8 *p, __u8 *end, int *tag)
|
|
||||||
{
|
|
||||||
INIT;
|
|
||||||
return p - begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _dec_bool (__u8 *p, __u8 *end, int *i, int *tag)
|
|
||||||
{
|
|
||||||
INIT;
|
|
||||||
*i = 0;
|
|
||||||
while (len--) {
|
|
||||||
CHECK_P;
|
|
||||||
*i = (*i >> 8) + *p;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
return p - begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _dec_int (__u8 *p, __u8 *end, int *i, int *tag)
|
|
||||||
{
|
|
||||||
INIT;
|
|
||||||
|
|
||||||
*i = 0;
|
|
||||||
while (len--) {
|
|
||||||
CHECK_P;
|
|
||||||
*i = (*i << 8) + *p;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
return p - begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _dec_enum (__u8 *p, __u8 *end, int *i, int *tag)
|
|
||||||
{
|
|
||||||
INIT;
|
|
||||||
|
|
||||||
*i = 0;
|
|
||||||
while (len--) {
|
|
||||||
CHECK_P;
|
|
||||||
*i = (*i << 8) + *p;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
return p - begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _dec_num_string (__u8 *p, __u8 *end, char *str, int *tag)
|
|
||||||
{
|
|
||||||
INIT;
|
|
||||||
|
|
||||||
while (len--) {
|
|
||||||
CHECK_P;
|
|
||||||
*str++ = *p;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
*str = 0;
|
|
||||||
return p - begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _dec_octet_string (__u8 *p, __u8 *end, char *str, int *tag)
|
|
||||||
{
|
|
||||||
return _dec_num_string(p, end, str, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
int _dec_sequence (__u8 *p, __u8 *end, int *tag)
|
|
||||||
{
|
|
||||||
INIT;
|
|
||||||
return p - begin;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dec_len (__u8 *p, int *len)
|
|
||||||
{
|
|
||||||
*len = *p;
|
|
||||||
return 1;
|
|
||||||
}
|
|
@@ -1,72 +0,0 @@
|
|||||||
#ifndef __ASN1_H__
|
|
||||||
#define __ASN1_H__
|
|
||||||
|
|
||||||
#include <asm/types.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
** ASN.1 Tags
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define ASN1_TAG_BOOLEAN (0x01)
|
|
||||||
#define ASN1_TAG_INTEGER (0x02)
|
|
||||||
#define ASN1_TAG_BIT_STRING (0x03)
|
|
||||||
#define ASN1_TAG_OCTET_STRING (0x04)
|
|
||||||
#define ASN1_TAG_NULL (0x05)
|
|
||||||
#define ASN1_TAG_OBJECT_IDENTIFIER (0x06)
|
|
||||||
#define ASN1_TAG_ENUM (0x0a)
|
|
||||||
#define ASN1_TAG_SEQUENCE (0x30)
|
|
||||||
#define ASN1_TAG_SET (0x31)
|
|
||||||
#define ASN1_TAG_NUMERIC_STRING (0x12)
|
|
||||||
#define ASN1_TAG_PRINTABLE_STRING (0x13)
|
|
||||||
#define ASN1_TAG_IA5_STRING (0x16)
|
|
||||||
#define ASN1_TAG_UTC_TIME (0x17)
|
|
||||||
#define ASN1_TAG_CONSTRUCTED (0x20)
|
|
||||||
#define ASN1_TAG_CONTEXT_SPECIFIC (0x80)
|
|
||||||
#define ASN1_TAG_EXPLICIT (0x100)
|
|
||||||
#define ASN1_TAG_OPT (0x200)
|
|
||||||
#define ASN1_NOT_TAGGED (0x400)
|
|
||||||
|
|
||||||
/*
|
|
||||||
** ASN.1 Encoding
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define enc_null(dest) _enc_null(dest,ASN1_TAG_NULL)
|
|
||||||
#define enc_bool(dest,i) _enc_bool(dest,i,ASN1_TAG_BOOLEAN)
|
|
||||||
#define enc_int(dest,i) _enc_int(dest,i,ASN1_TAG_INTEGER)
|
|
||||||
#define enc_enum(dest,i) _enc_enum(dest,i,ASN1_TAG_ENUM)
|
|
||||||
#define enc_num_string(dest,num,len) _enc_num_string(dest,num,len,ASN1_TAG_NUMERIC_STRING)
|
|
||||||
#define enc_sequence_start(dest,id) _enc_sequence_start(dest,id,ASN1_TAG_SEQUENCE)
|
|
||||||
#define enc_sequence_end(dest,id) _enc_sequence_end(dest,id,ASN1_TAG_SEQUENCE)
|
|
||||||
|
|
||||||
int _enc_null (__u8 *dest, int tag);
|
|
||||||
int _enc_bool (__u8 *dest, __u32 i, int tag);
|
|
||||||
int _enc_int (__u8 *dest, __u32 i, int tag);
|
|
||||||
int _enc_enum (__u8 *dest, __u32 i, int tag);
|
|
||||||
int _enc_num_string (__u8 *dest, char *nd, __u8 len, int tag);
|
|
||||||
int _enc_sequence_start (__u8 *dest, __u8 **id, int tag);
|
|
||||||
int _enc_sequence_end (__u8 *dest, __u8 *id, int tag_dummy);
|
|
||||||
|
|
||||||
/*
|
|
||||||
** ASN.1 Decoding
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define dec_null(p, end) _dec_null (p, end, NULL);
|
|
||||||
#define dec_bool(p, end,i) _dec_bool (p, end, i, NULL)
|
|
||||||
#define dec_int(p, end,i) _dec_int (p, end, i, NULL)
|
|
||||||
#define dec_enum(p, end,i) _dec_enum (p, end, i, NULL)
|
|
||||||
#define dec_num_string(p, end,str) _dec_num_string (p, end, str, NULL)
|
|
||||||
#define dec_octet_string(p, end,str) _dec_octet_string (p, end, str, NULL)
|
|
||||||
#define dec_sequence(p, end) _dec_sequence (p, end, NULL)
|
|
||||||
|
|
||||||
int _dec_null (__u8 *p, __u8 *end, int *tag);
|
|
||||||
int _dec_bool (__u8 *p, __u8 *end, int *i, int *tag);
|
|
||||||
int _dec_int (__u8 *p, __u8 *end, int *i, int *tag);
|
|
||||||
int _dec_enum (__u8 *p, __u8 *end, int *i, int *tag);
|
|
||||||
int _dec_num_string (__u8 *p, __u8 *end, char *str, int *tag);
|
|
||||||
int _dec_octet_string (__u8 *p, __u8 *end, char *str, int *tag);
|
|
||||||
int _dec_sequence (__u8 *p, __u8 *end, int *tag);
|
|
||||||
|
|
||||||
int dec_len (__u8 *p, int *len);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@@ -1,267 +0,0 @@
|
|||||||
|
|
||||||
#include "fac.h"
|
|
||||||
#include "asn1.h"
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
+-------------------------------
|
|
||||||
| IE_IDENTIFIER
|
|
||||||
+-------------------------------
|
|
||||||
| {length}
|
|
||||||
+-------------------------------
|
|
||||||
| +---------------------------
|
|
||||||
| | SERVICE_DISCRIMINATOR
|
|
||||||
| +---------------------------
|
|
||||||
| | COMPONENT_TYPE_TAG
|
|
||||||
| +---------------------------
|
|
||||||
| | {length}
|
|
||||||
| +---------------------------
|
|
||||||
| | +-----------------------
|
|
||||||
| | | INVOKE_IDENTIFIER_TAG (0x2)
|
|
||||||
| | +-----------------------
|
|
||||||
| | | {length} (0x1)
|
|
||||||
| | +-----------------------
|
|
||||||
| | | {value} (odd integer 0-127)
|
|
||||||
| | +-----------------------
|
|
||||||
| | +-----------------------
|
|
||||||
| | | OPERATION_VALUE_TAG (0x2)
|
|
||||||
| | +-----------------------
|
|
||||||
| | | {length} (0x1)
|
|
||||||
| | +-----------------------
|
|
||||||
| | | {value}
|
|
||||||
| | +-----------------------
|
|
||||||
| | +-----------------------
|
|
||||||
| | | ASN.1 data
|
|
||||||
+---+---+-----------------------
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum {
|
|
||||||
SUPPLEMENTARY_SERVICE = 0x91,
|
|
||||||
} SERVICE_DISCRIMINATOR;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
INVOKE = 0xa1,
|
|
||||||
RETURN_RESULT = 0xa2,
|
|
||||||
RETURN_ERROR = 0xa3,
|
|
||||||
REJECT = 0xa4,
|
|
||||||
} COMPONENT_TYPE_TAG;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
INVOKE_IDENTIFIER = 0x02,
|
|
||||||
LINKED_IDENTIFIER = 0x80,
|
|
||||||
NULL_IDENTIFIER = 0x05,
|
|
||||||
} INVOKE_IDENTIFIER_TAG;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
OPERATION_VALUE = 0x02,
|
|
||||||
} OPERATION_VALUE_TAG;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
VALUE_QUERY = 0x8c,
|
|
||||||
SET_VALUE = 0x8d,
|
|
||||||
REQUEST_FEATURE = 0x8f,
|
|
||||||
ABORT = 0xbe,
|
|
||||||
REDIRECT_CALL = 0xce,
|
|
||||||
CALLING_PARTY_TO_HOLD = 0xcf,
|
|
||||||
CALLING_PARTY_FROM_HOLD = 0x50,
|
|
||||||
DROP_TARGET_PARTY = 0xd1,
|
|
||||||
USER_DATA_TRANSFER = 0xd3,
|
|
||||||
APP_SPECIFIC_STATUS = 0xd2,
|
|
||||||
|
|
||||||
/* not from document */
|
|
||||||
CALL_DEFLECT = 0x0d,
|
|
||||||
AOC = 0x22,
|
|
||||||
} OPERATION_CODE;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
Q931_IE_TAG = 0x40,
|
|
||||||
} ARGUMENT_TAG;
|
|
||||||
|
|
||||||
#ifdef FACILITY_DEBUG
|
|
||||||
#define FAC_DUMP(fac,len,bc) fac_dump(fac,len,bc)
|
|
||||||
#include <ctype.h>
|
|
||||||
static void fac_dump (__u8 *facility, unsigned int fac_len, struct misdn_bchannel *bc)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
cb_log(0, bc->port, " --- facility dump start. length:%d\n", fac_len);
|
|
||||||
for (i = 0; i < fac_len; ++i)
|
|
||||||
if (isprint(facility[i]))
|
|
||||||
cb_log(0, bc->port, " --- %d: %04p (char:%c)\n", i, facility[i], facility[i]);
|
|
||||||
else
|
|
||||||
cb_log(0, bc->port, " --- %d: %04p\n", i, facility[i]);
|
|
||||||
cb_log(0, bc->port, " --- facility dump end\n");
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define FAC_DUMP(fac,len,bc)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Facility Encoding
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int enc_fac_calldeflect (__u8 *dest, char *number, int pres)
|
|
||||||
{
|
|
||||||
__u8 *body_len,
|
|
||||||
*p = dest,
|
|
||||||
*seq1, *seq2;
|
|
||||||
|
|
||||||
*p++ = SUPPLEMENTARY_SERVICE;
|
|
||||||
*p++ = INVOKE;
|
|
||||||
|
|
||||||
body_len = p++;
|
|
||||||
|
|
||||||
p += _enc_int(p, 0x1 /* some odd integer in (0..127) */, INVOKE_IDENTIFIER);
|
|
||||||
p += _enc_int(p, CALL_DEFLECT, OPERATION_VALUE);
|
|
||||||
p += enc_sequence_start(p, &seq1);
|
|
||||||
p += enc_sequence_start(p, &seq2);
|
|
||||||
p += _enc_num_string(p, number, strlen(number), ASN1_TAG_CONTEXT_SPECIFIC);
|
|
||||||
p += enc_sequence_end(p, seq2);
|
|
||||||
p += enc_bool(p, pres);
|
|
||||||
p += enc_sequence_end(p, seq1);
|
|
||||||
|
|
||||||
*body_len = p - &body_len[1];
|
|
||||||
|
|
||||||
return p - dest;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void enc_ie_facility (__u8 **ntmode, msg_t *msg, __u8 *facility, int facility_len, struct misdn_bchannel *bc)
|
|
||||||
{
|
|
||||||
__u8 *ie_fac;
|
|
||||||
|
|
||||||
Q931_info_t *qi;
|
|
||||||
|
|
||||||
ie_fac = msg_put(msg, facility_len + 2);
|
|
||||||
if (bc->nt) {
|
|
||||||
*ntmode = ie_fac + 1;
|
|
||||||
} else {
|
|
||||||
qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
|
|
||||||
qi->QI_ELEMENT(facility) = ie_fac - (__u8 *)qi - sizeof(Q931_info_t);
|
|
||||||
}
|
|
||||||
|
|
||||||
ie_fac[0] = IE_FACILITY;
|
|
||||||
ie_fac[1] = facility_len;
|
|
||||||
memcpy(ie_fac + 2, facility, facility_len);
|
|
||||||
|
|
||||||
FAC_DUMP(ie_fac, facility_len + 2, bc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void fac_enc (__u8 **ntmsg, msg_t *msg, enum facility_type type, union facility fac, struct misdn_bchannel *bc)
|
|
||||||
{
|
|
||||||
__u8 facility[256];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case FACILITY_CALLDEFLECT:
|
|
||||||
len = enc_fac_calldeflect(facility, fac.calldeflect_nr, 1);
|
|
||||||
enc_ie_facility(ntmsg, msg, facility, len, bc);
|
|
||||||
break;
|
|
||||||
case FACILITY_CENTREX:
|
|
||||||
case FACILITY_NONE:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Facility Decoding
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int dec_fac_calldeflect (__u8 *p, int len, struct misdn_bchannel *bc)
|
|
||||||
{
|
|
||||||
__u8 *end = p + len;
|
|
||||||
int offset,
|
|
||||||
pres;
|
|
||||||
|
|
||||||
if ((offset = dec_sequence(p, end)) < 0)
|
|
||||||
return -1;
|
|
||||||
p += offset;
|
|
||||||
|
|
||||||
if ((offset = dec_sequence(p, end)) < 0)
|
|
||||||
return -1;
|
|
||||||
p += offset;
|
|
||||||
|
|
||||||
if ((offset = dec_num_string(p, end, bc->fac.calldeflect_nr)) < 0)
|
|
||||||
return -1;
|
|
||||||
p += offset;
|
|
||||||
|
|
||||||
if ((offset = dec_bool(p, end, &pres)) < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
cb_log(0, 0, "CALLDEFLECT: dest:%s pres:%s (not implemented yet)\n", bc->fac.calldeflect_nr, pres ? "yes" : "no");
|
|
||||||
bc->fac_type = FACILITY_CALLDEFLECT;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fac_dec (__u8 *p, Q931_info_t *qi, enum facility_type *type, union facility *fac, struct misdn_bchannel *bc)
|
|
||||||
{
|
|
||||||
int len,
|
|
||||||
offset,
|
|
||||||
inner_len,
|
|
||||||
invoke_id,
|
|
||||||
op_tag,
|
|
||||||
op_val;
|
|
||||||
__u8 *end,
|
|
||||||
*begin = p;
|
|
||||||
|
|
||||||
if (!bc->nt) {
|
|
||||||
if (qi->QI_ELEMENT(facility))
|
|
||||||
p = (__u8 *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
|
|
||||||
else
|
|
||||||
p = NULL;
|
|
||||||
}
|
|
||||||
if (!p)
|
|
||||||
return;
|
|
||||||
|
|
||||||
offset = dec_len (p, &len);
|
|
||||||
if (offset < 0) {
|
|
||||||
cb_log(0, bc->port, "Could not decode FACILITY: dec_len failed!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += offset;
|
|
||||||
end = p + len;
|
|
||||||
|
|
||||||
FAC_DUMP(p, len, bc);
|
|
||||||
|
|
||||||
if (len < 3 || p[0] != SUPPLEMENTARY_SERVICE || p[1] != INVOKE) {
|
|
||||||
cb_log(0, bc->port, "Could not decode FACILITY: invalid or not supported!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += 2;
|
|
||||||
|
|
||||||
offset = dec_len (p, &inner_len);
|
|
||||||
if (offset < 0) {
|
|
||||||
cb_log(0, bc->port, "Could not decode FACILITY: failed parsing inner length!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += offset;
|
|
||||||
|
|
||||||
offset = dec_int (p, end, &invoke_id);
|
|
||||||
if (offset < 0) {
|
|
||||||
cb_log(0, bc->port, "Could not decode FACILITY: failed parsing invoke identifier!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += offset;
|
|
||||||
|
|
||||||
offset = _dec_int (p, end, &op_val, &op_tag);
|
|
||||||
if (offset < 0) {
|
|
||||||
cb_log(0, bc->port, "Could not decode FACILITY: failed parsing operation value!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
p += offset;
|
|
||||||
|
|
||||||
if (op_tag != OPERATION_VALUE || offset != 3) {
|
|
||||||
cb_log(0, bc->port, "Could not decode FACILITY: operation value tag 0x%x unknown!\n", op_tag);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (op_val) {
|
|
||||||
case CALL_DEFLECT:
|
|
||||||
cb_log(0, bc->port, "FACILITY: Call Deflect\n");
|
|
||||||
dec_fac_calldeflect(p, len - (p - begin) + 1, bc);
|
|
||||||
break;
|
|
||||||
case AOC:
|
|
||||||
cb_log(0, bc->port, "FACILITY: AOC\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cb_log(0, bc->port, "FACILITY unknown: operation value 0x%x, ignoring ...\n", op_val);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
#ifndef __FAC_H__
|
|
||||||
#define __FAC_H__
|
|
||||||
|
|
||||||
#include "isdn_lib_intern.h"
|
|
||||||
|
|
||||||
void fac_enc (__u8 **ntmsg, msg_t *msg, enum facility_type type, union facility fac, struct misdn_bchannel *bc);
|
|
||||||
void fac_dec (__u8 *p, Q931_info_t *qi, enum facility_type *type, union facility *fac, struct misdn_bchannel *bc);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@@ -619,8 +619,8 @@ void empty_bc(struct misdn_bchannel *bc)
|
|||||||
bc->rad[0] = 0;
|
bc->rad[0] = 0;
|
||||||
bc->orig_dad[0] = 0;
|
bc->orig_dad[0] = 0;
|
||||||
|
|
||||||
bc->fac_type=FACILITY_NONE;
|
bc->fac_in.Function = FacReq_None;
|
||||||
bc->out_fac_type=FACILITY_NONE;
|
bc->fac_out.Function = FacReq_None;
|
||||||
|
|
||||||
bc->te_choose_channel = 0;
|
bc->te_choose_channel = 0;
|
||||||
|
|
||||||
@@ -1674,24 +1674,6 @@ int misdn_lib_get_port_down (int port)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int misdn_lib_send_facility(struct misdn_bchannel *bc, enum facility_type fac, void *data)
|
|
||||||
{
|
|
||||||
switch (fac) {
|
|
||||||
case FACILITY_CALLDEFLECT:
|
|
||||||
strcpy(bc->out_fac.calldeflect_nr,(char*)data);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cb_log(1,bc?bc->port:0,"We don't handle this facility yet: %d\n",fac);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bc->out_fac_type=fac;
|
|
||||||
|
|
||||||
misdn_lib_send_event(bc,EVENT_FACILITY);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int misdn_lib_port_up(int port, int check)
|
int misdn_lib_port_up(int port, int check)
|
||||||
{
|
{
|
||||||
struct misdn_stack *stack;
|
struct misdn_stack *stack;
|
||||||
@@ -3114,22 +3096,21 @@ struct misdn_bchannel* misdn_lib_get_free_bc(int port, int channel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *fac2str (enum facility_type type) {
|
char *fac2str (enum FacReqFunction func) {
|
||||||
struct arr_el {
|
struct arr_el {
|
||||||
enum facility_type p;
|
enum FacReqFunction p;
|
||||||
char *s ;
|
char *s ;
|
||||||
} arr[] = {
|
} arr[] = {
|
||||||
{ FACILITY_NONE, "FAC_NONE" },
|
{ FacReq_None, "FacReq_None" },
|
||||||
{ FACILITY_CALLDEFLECT, "FAC_CALLDEFLECT"},
|
{ FacReq_CD, "FacReq_CD"},
|
||||||
{ FACILITY_CENTREX, "FAC_CENTREX"}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i < sizeof(arr)/sizeof( struct arr_el) ; i ++)
|
for (i=0; i < sizeof(arr)/sizeof( struct arr_el) ; i ++)
|
||||||
if ( arr[i].p==type) return arr[i].s;
|
if ( arr[i].p==func) return arr[i].s;
|
||||||
|
|
||||||
return "FAC_UNKNOWN";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
void misdn_lib_log_ies(struct misdn_bchannel *bc)
|
void misdn_lib_log_ies(struct misdn_bchannel *bc)
|
||||||
@@ -3157,7 +3138,7 @@ void misdn_lib_log_ies(struct misdn_bchannel *bc)
|
|||||||
|
|
||||||
cb_log(4, stack->port, " --> addr:%x l3id:%x b_stid:%x layer_id:%x\n", bc->addr, bc->l3_id, bc->b_stid, bc->layer_id);
|
cb_log(4, stack->port, " --> addr:%x l3id:%x b_stid:%x layer_id:%x\n", bc->addr, bc->l3_id, bc->b_stid, bc->layer_id);
|
||||||
|
|
||||||
cb_log(4, stack->port, " --> facility:%s out_facility:%s\n",fac2str(bc->fac_type),fac2str(bc->out_fac_type));
|
cb_log(4, stack->port, " --> facility:%s out_facility:%s\n",fac2str(bc->fac_in.Function),fac2str(bc->fac_out.Function));
|
||||||
|
|
||||||
cb_log(5, stack->port, " --> urate:%d rate:%d mode:%d user1:%d\n", bc->urate, bc->rate, bc->mode,bc->user1);
|
cb_log(5, stack->port, " --> urate:%d rate:%d mode:%d user1:%d\n", bc->urate, bc->rate, bc->mode,bc->user1);
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
#ifndef TE_LIB
|
#ifndef TE_LIB
|
||||||
#define TE_LIB
|
#define TE_LIB
|
||||||
|
|
||||||
|
#include <mISDNuser/suppserv.h>
|
||||||
|
|
||||||
/** For initialization usage **/
|
/** For initialization usage **/
|
||||||
/* typedef int ie_nothing_t ;*/
|
/* typedef int ie_nothing_t ;*/
|
||||||
@@ -187,22 +188,6 @@ enum layer_e {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** FACILITY STUFF **/
|
|
||||||
|
|
||||||
enum facility_type {
|
|
||||||
FACILITY_NONE,
|
|
||||||
FACILITY_CALLDEFLECT=0x91,
|
|
||||||
FACILITY_CENTREX=0x88
|
|
||||||
};
|
|
||||||
|
|
||||||
union facility {
|
|
||||||
char calldeflect_nr[15];
|
|
||||||
char cnip[256];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct misdn_bchannel {
|
struct misdn_bchannel {
|
||||||
|
|
||||||
int nt;
|
int nt;
|
||||||
@@ -271,11 +256,8 @@ struct misdn_bchannel {
|
|||||||
int progress_location;
|
int progress_location;
|
||||||
int progress_indicator;
|
int progress_indicator;
|
||||||
|
|
||||||
enum facility_type fac_type;
|
struct FacReqParm fac_in;
|
||||||
union facility fac;
|
struct FacReqParm fac_out;
|
||||||
|
|
||||||
enum facility_type out_fac_type;
|
|
||||||
union facility out_fac;
|
|
||||||
|
|
||||||
enum event_e evq;
|
enum event_e evq;
|
||||||
|
|
||||||
@@ -433,9 +415,6 @@ void misdn_lib_release(struct misdn_bchannel *bc);
|
|||||||
int misdn_cap_is_speech(int cap);
|
int misdn_cap_is_speech(int cap);
|
||||||
int misdn_inband_avail(struct misdn_bchannel *bc);
|
int misdn_inband_avail(struct misdn_bchannel *bc);
|
||||||
|
|
||||||
int misdn_lib_send_facility(struct misdn_bchannel *bc, enum facility_type fac, void *data);
|
|
||||||
|
|
||||||
|
|
||||||
void manager_ec_enable(struct misdn_bchannel *bc);
|
void manager_ec_enable(struct misdn_bchannel *bc);
|
||||||
void manager_ec_disable(struct misdn_bchannel *bc);
|
void manager_ec_disable(struct misdn_bchannel *bc);
|
||||||
|
|
||||||
|
@@ -11,6 +11,12 @@
|
|||||||
|
|
||||||
#include "isdn_lib.h"
|
#include "isdn_lib.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined MISDNUSER_VERSION_CODE || (MISDNUSER_VERSION_CODE < MISDNUSER_VERSION(1, 0, 3))
|
||||||
|
#error "You need a newer version of mISDNuser ..."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define QI_ELEMENT(a) a.off
|
#define QI_ELEMENT(a) a.off
|
||||||
|
|
||||||
|
|
||||||
|
@@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
#include "ie.c"
|
#include "ie.c"
|
||||||
|
|
||||||
#include "fac.h"
|
|
||||||
|
|
||||||
|
|
||||||
void set_channel(struct misdn_bchannel *bc, int channel) {
|
void set_channel(struct misdn_bchannel *bc, int channel) {
|
||||||
|
|
||||||
@@ -879,42 +877,64 @@ msg_t *build_release_complete (struct isdn_msg msgs[], struct misdn_bchannel *bc
|
|||||||
|
|
||||||
void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
|
||||||
{
|
{
|
||||||
#ifdef FACILITY_DEBUG
|
int HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
|
||||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
FACILITY_t *facility = (FACILITY_t*)(msg->data+HEADER_LEN);
|
||||||
FACILITY_t *facility=(FACILITY_t*)((unsigned long)(msg->data+HEADER_LEN));
|
Q931_info_t *qi = (Q931_info_t*)(msg->data+HEADER_LEN);
|
||||||
Q931_info_t *qi=(Q931_info_t*)(msg->data+HEADER_LEN);
|
unsigned char *p = NULL;
|
||||||
|
int err;
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
printf("Parsing FACILITY Msg\n");
|
printf("Parsing FACILITY Msg\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fac_dec(facility->FACILITY, qi, &bc->fac_type, &bc->fac, bc);
|
if (!bc->nt) {
|
||||||
#endif
|
if (qi->QI_ELEMENT(facility))
|
||||||
|
p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
|
||||||
|
} else {
|
||||||
|
p = facility->FACILITY;
|
||||||
|
}
|
||||||
|
if (!p)
|
||||||
|
return;
|
||||||
|
|
||||||
|
err = decodeFacReq(p, &(bc->fac_in));
|
||||||
|
if (err) {
|
||||||
|
cb_log(1, bc->port, "Decoding FACILITY failed! (%d)\n", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
|
msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
|
||||||
{
|
{
|
||||||
int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
|
int len,
|
||||||
FACILITY_t *facility;
|
HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
|
||||||
|
unsigned char *ie_fac,
|
||||||
|
fac_tmp[256];
|
||||||
msg_t *msg =(msg_t*)create_l3msg(CC_FACILITY | REQUEST, MT_FACILITY, bc?bc->l3_id:-1, sizeof(FACILITY_t) ,nt);
|
msg_t *msg =(msg_t*)create_l3msg(CC_FACILITY | REQUEST, MT_FACILITY, bc?bc->l3_id:-1, sizeof(FACILITY_t) ,nt);
|
||||||
|
FACILITY_t *facility = (FACILITY_t*)(msg->data+HEADER_LEN);
|
||||||
facility=(FACILITY_t*)((msg->data+HEADER_LEN));
|
Q931_info_t *qi;
|
||||||
|
|
||||||
{
|
|
||||||
if (*bc->display) {
|
|
||||||
printf("Sending %s as Display\n", bc->display);
|
|
||||||
enc_ie_display(&facility->DISPLAY, msg, bc->display, nt,bc);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fac_enc(&facility->FACILITY, msg, bc->out_fac_type, bc->out_fac, bc);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
printf("Building FACILITY Msg\n");
|
printf("Building FACILITY Msg\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
len = encodeFacReq(fac_tmp, &(bc->fac_out));
|
||||||
|
if (len <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ie_fac = msg_put(msg, len);
|
||||||
|
if (bc->nt) {
|
||||||
|
facility->FACILITY = ie_fac + 1;
|
||||||
|
} else {
|
||||||
|
qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
|
||||||
|
qi->QI_ELEMENT(facility) = ie_fac - (unsigned char *)qi - sizeof(Q931_info_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(ie_fac, fac_tmp, len);
|
||||||
|
|
||||||
|
if (*bc->display) {
|
||||||
|
printf("Sending %s as Display\n", bc->display);
|
||||||
|
enc_ie_display(&facility->DISPLAY, msg, bc->display, nt,bc);
|
||||||
|
}
|
||||||
|
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user