~ubuntu-branches/debian/squeeze/asterisk-chan-capi/squeeze

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
/*
 *  (QSIG)
 *
 *  Implementation of QSIG extensions for chan_capi
 *  
 *  Copyright 2006-2007 (c) Mario Goegel
 *
 *  Mario Goegel <m.goegel@gmx.de>
 *
 * This program is free software and may be modified and
 * distributed under the terms of the GNU Public License.
 */

#ifndef PBX_QSIG_H
#define PBX_QSIG_H

int capiqsigdebug;

#define QSIG_DISABLED		0x00
#define QSIG_ENABLED		0x01		/* shouldn't be used anymore */

#define QSIG_TYPE_ALCATEL_ECMA	0x01		/* use additional Alcatel ECMA */
#define QSIG_TYPE_HICOM_ECMAV2	0x02		/* use additional Hicom ECMA V2 */

#define CAPI_QSIG_WAITEVENT_PRPROPOSE 0x01000000


#define Q932_PROTOCOL_ROSE			0x11	/* X.219 & X.229 */
#define Q932_PROTOCOL_CMIP			0x12	/* Q.941 */
#define Q932_PROTOCOL_ACSE			0x13	/* X.217 & X.227 */
#define Q932_PROTOCOL_GAT			0x16
#define Q932_PROTOCOL_EXTENSIONS	0x1F

#define COMP_TYPE_INVOKE	0xa1		/* Invoke component */
#define COMP_TYPE_DISCR_SS	0x91		/* Supplementary service descriptor - ROSE PROTOCOL */
#define COMP_TYPE_NFE		0xaa		/* Network Facility Extensions (ECMA-165) */
#define COMP_TYPE_APDU_INTERP	0x8b		/* APDU Interpration Type (0 DISCARD, 1 CLEARCALL-IF-UNKNOWN, 2 REJECT-APDU) */
#define COMP_TYPE_RETURN_RESULT	0xA2
#define COMP_TYPE_RETURN_ERROR	0xA3
#define COMP_TYPE_REJECT	0xA4
		
#define APDUINTERPRETATION_IGNORE	0x00
#define APDUINTERPRETATION_CLEARCALL	0x01
#define APDUINTERPRETATION_REJECT	0x02

/* const char* APDU_STR[] = { "IGNORE APDU", "CLEARCALL-IF-UNKNOWN", "REJECT APDU" }; */


		/* ASN.1 Identifier Octet - Data types */
#define ASN1_TYPE_MASK			0x1f
#define ASN1_BOOLEAN			0x01
#define ASN1_INTEGER			0x02
#define ASN1_BITSTRING			0x03
#define ASN1_OCTETSTRING		0x04
#define ASN1_NULL				0x05
#define ASN1_OBJECTIDENTIFIER	0x06
#define ASN1_OBJECTDESCRIPTOR	0x07
#define ASN1_EXTERN				0x08
#define ASN1_REAL				0x09
#define ASN1_ENUMERATED			0x0a
#define ASN1_EMBEDDEDPDV		0x0b
#define ASN1_UTF8STRING			0x0c
#define ASN1_RELATIVEOBJECTID	0x0d
		/* 0x0e & 0x0f are reserved for future ASN.1 editions */
#define ASN1_SEQUENCE			0x10
#define ASN1_SET				0x11
#define ASN1_NUMERICSTRING		0x12
#define ASN1_PRINTABLESTRING	0x13
#define ASN1_TELETEXSTRING		0x14
#define ASN1_IA5STRING			0x16
#define ASN1_UTCTIME			0x17
#define ASN1_GENERALIZEDTIME	0x18

/* ASN.1 Type/Tag Class (bits 7 & 6 of Tag octet) */
#define ASN1_TC_UNIVERSAL	0x00
#define ASN1_TC_APPLICATION	0x40
#define ASN1_TC_CONTEXTSPEC	0x80
#define ASN1_TC_PRIVATE		0xC0

/* ASN.1 Type/Tag Form (bit 5 of Tag octet) */
#define	ASN1_TF_PRIMITVE	0x00
#define ASN1_TF_CONSTRUCTED	0x20		/* field may be a type of sequence or set */

#define CNIP_CALLINGNAME	0x00		/* Name-Types defined in ECMA-164 */
#define CNIP_CALLEDNAME		0x01
#define CNIP_CONNECTEDNAME	0x02
#define CNIP_BUSYNAME		0x03


#define CNIP_NAMEPRESALLOW	0x80
#define CNIP_NAMEPRESRESTR	0xA0
#define CNIP_NAMEPRESUNAVAIL	0xC0

#define CNIP_NAMEUSERPROVIDED	0x00		/* Name is User-provided, unvalidated */
#define CNIP_NAMEUSERPROVIDEDV	0x01		/* Name is User-provided and validated */
		
/* QSIG Operations += 1000 */
#define CCQSIG__ECMA__NAMEPRES	1000		/* Setting an own constant for ECMA Operation/Namepresentation, others will follow */
#define CCQSIG__ECMA__PRPROPOSE	1004		/* Path Replacement Propose */
#define CCQSIG__ECMA__CTCOMPLETE 1012		/* Call Transfer Complete */
#define CCQSIG__ECMA__LEGINFO2	1021		/* LEG INFORMATION2 */
#define CCQSIG__ECMA__LEGINFO3	1022		/* LEG INFORMATION3 */


#define CCQSIG_TIMER_WAIT_PRPROPOSE 1		/* Wait x seconds */

struct rose_component {
	u_int8_t type;
	u_int8_t len;
	u_int8_t data[0];
};

#define GET_COMPONENT(component, idx, ptr, length) \
	if ((idx)+2 > (length)) \
		break; \
	(component) = (struct rose_component*)&((ptr)[idx]); \
	if ((idx)+(component)->len+2 > (length)) { \
		if ((component)->len != ASN1_LEN_INDEF) \
			pri_message(pri, "Length (%d) of 0x%X component is too long\n", (component)->len, (component)->type); \
}

#define NEXT_COMPONENT(component, idx) \
	(idx) += (component)->len + 2

#define SUB_COMPONENT(component, idx) \
	(idx) += 2

#define CHECK_COMPONENT(component, comptype, message) \
	if ((component)->type && ((component)->type & ASN1_TYPE_MASK) != (comptype)) { \
		pri_message(pri, (message), (component)->type); \
		asn1_dump(pri, (component), (component)->len+2); \
		break; \
}
	
#define ASN1_GET_INTEGER(component, variable) \
	do { \
		int comp_idx; \
		(variable) = 0; \
		for (comp_idx = 0; comp_idx < (component)->len; ++comp_idx) \
			(variable) = ((variable) << 8) | (component)->data[comp_idx]; \
} while (0)

#define ASN1_FIXUP_LEN(component, size) \
	do { \
		if ((component)->len == ASN1_LEN_INDEF) \
			size += 2; \
} while (0)

#define ASN1_ADD_SIMPLE(component, comptype, ptr, idx) \
	do { \
		(component) = (struct rose_component *)&((ptr)[(idx)]); \
		(component)->type = (comptype); \
		(component)->len = 0; \
		(idx) += 2; \
} while (0)

#define ASN1_ADD_BYTECOMP(component, comptype, ptr, idx, value) \
	do { \
		(component) = (struct rose_component *)&((ptr)[(idx)]); \
		(component)->type = (comptype); \
		(component)->len = 1; \
		(component)->data[0] = (value); \
		(idx) += 3; \
} while (0)

#define ASN1_ADD_WORDCOMP(component, comptype, ptr, idx, value) \
	do { \
		int __val = (value); \
		int __i = 0; \
		(component) = (struct rose_component *)&((ptr)[(idx)]); \
		(component)->type = (comptype); \
		if ((__val >> 24)) \
			(component)->data[__i++] = (__val >> 24) & 0xff; \
		if ((__val >> 16)) \
			(component)->data[__i++] = (__val >> 16) & 0xff; \
		if ((__val >> 8)) \
			(component)->data[__i++] = (__val >> 8) & 0xff; \
		(component)->data[__i++] = __val & 0xff; \
		(component)->len = __i; \
		(idx) += 2 + __i; \
} while (0)

#define ASN1_PUSH(stack, stackpointer, component) \
	(stack)[(stackpointer)++] = (component)

#define ASN1_FIXUP(stack, stackpointer, data, idx) \
	do { \
		--(stackpointer); \
		(stack)[(stackpointer)]->len = (unsigned char *)&((data)[(idx)]) - (unsigned char *)(stack)[(stackpointer)] - 2; \
} while (0)


#define free_null(x)	{ free(x); x = NULL; }

/* Common QSIG structs */

/*
 * INVOKE Data struct, contains data for further operations
 */
struct cc_qsig_invokedata {
	int len;		/* invoke length */
	int offset;		/* where does the invoke start in facility array */
	int id;			/* id from sent Invoke Number */
	int apdu_interpr;	/* What To Do with unknown Operation? */
	int descr_type;		/* component descriptor is of ASN.1 Datatype (0x02 Integer, 0x06 Object Identifier) */
	int type;		/* when component is Integer */
	int oid_len;
	unsigned char oid_bin[20];	/* when component is Object Identifier then save here the binary oid */
	int datalen;			/* invoke struct len */
	unsigned char data[255];	/* invoke */
};

/*
 * NFE Entity Address - contains destination informations for following INVOKE's
 */
struct cc_qsig_entityaddr {	/* In case of AnyPINX */
	int partynum;		/* private,public,etc a5=private */
	int ton;		/* Type of Number */
	unsigned char *num;		/* EntityNumber */
};
	
/*
 * Network Facility Extensions struct - to which pbx does the INVOKE belong to
 */
struct cc_qsig_nfe {
	int src_entity;		/* Call is coming from PBX (End|Any) */
	int dst_entity;		/* Call destination is */
	struct cc_qsig_entityaddr src_addr;	/* additional infos (PBX identifier) */
	struct cc_qsig_entityaddr dst_addr;	/* same here for destination */
};


/*
 * prototypes
 */

/*
 ***  QSIG Core Functions 
 */
extern void cc_qsig_verbose(int c_d, char *text, ...);

extern int cc_qsig_build_facility_struct(unsigned char * buf, unsigned int *idx, int protocolvar, int apdu_interpr, struct cc_qsig_nfe *nfe);
extern int cc_qsig_add_invoke(unsigned char * buf, unsigned int *idx, struct cc_qsig_invokedata *invoke, struct capi_pvt *i);

extern unsigned int cc_qsig_asn1_get_string(unsigned char *buf, int buflen, unsigned char *data);
extern unsigned int cc_qsig_asn1_get_integer(unsigned char *data, int *idx);
extern unsigned char *cc_qsig_asn1_oid2str(unsigned char *data, int size);
extern int cc_qsig_asn1_add_string2(unsigned char asn1_type, void *data, int len, int max_len, void *src, int src_len);
extern unsigned int cc_qsig_asn1_add_string(unsigned char *buf, int *idx, char *data, int datalen);
extern unsigned int cc_qsig_asn1_add_integer(unsigned char *buf, int *idx, int value);

extern signed int cc_qsig_asn1_check_ecma_isdn_oid(unsigned char *data, int len);
extern unsigned int cc_qsig_check_facility(unsigned char *data, int *idx, int *apduval, int protocol);
extern signed int cc_qsig_check_invoke(unsigned char *data, int *idx);
extern signed int cc_qsig_get_invokeid(unsigned char *data, int *idx, struct cc_qsig_invokedata *invoke);
extern signed int cc_qsig_fill_invokestruct(unsigned char *data, int *idx, struct cc_qsig_invokedata *invoke, int apduval);
extern unsigned int cc_qsig_handle_capiind(unsigned char *data, struct capi_pvt *i);
extern unsigned int cc_qsig_handle_capi_facilityind(unsigned char *data, struct capi_pvt *i);
extern unsigned int cc_qsig_add_call_setup_data(unsigned char *data, struct capi_pvt *i, struct  ast_channel *c);
extern unsigned int cc_qsig_add_call_answer_data(unsigned char *data, struct capi_pvt *i, struct  ast_channel *c);
extern unsigned int cc_qsig_add_call_alert_data(unsigned char *data, struct capi_pvt *i, struct  ast_channel *c);
extern unsigned int cc_qsig_add_call_facility_data(unsigned char *data, struct capi_pvt *i, int facility);

extern signed int cc_qsig_identifyinvoke(struct cc_qsig_invokedata *invoke, int protocol);
extern unsigned int cc_qsig_handle_invokeoperation(int invokeident, struct cc_qsig_invokedata *invoke, struct capi_pvt *i);

extern unsigned int cc_qsig_do_facility(unsigned char *fac, struct  ast_channel *c, char *param, unsigned int factype, int info1);

extern int pbx_capi_qsig_getplci(struct ast_channel *c, char *param);
extern int pbx_capi_qsig_ssct(struct ast_channel *c, char *param);
extern int pbx_capi_qsig_ct(struct ast_channel *c, char *param);
extern int pbx_capi_qsig_callmark(struct ast_channel *c, char *param);
extern int pbx_capi_qsig_bridge(struct capi_pvt *i0, struct capi_pvt *i1);
extern int pbx_capi_qsig_sendtext(struct ast_channel *c, const char *text);


extern void cc_qsig_interface_init(struct cc_capi_conf *conf, struct capi_pvt *tmp);
extern void cc_pbx_qsig_conf_interface_value(struct cc_capi_conf *conf, struct ast_variable *v);
extern void interface_cleanup_qsig(struct capi_pvt *i);
extern void pbx_capi_qsig_unload_module(struct capi_pvt *i);
extern void pbx_capi_qsig_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i);


#endif