2 This file contains all data structures and definitions associated
3 with facility message usage and the ROSE components included
6 by Matthew Fredrickson <creslin@digium.com>
7 Copyright (C) Digium, Inc. 2004-2005
11 * See http://www.asterisk.org for more information about
12 * the Asterisk project. Please do not directly contact
13 * any of the maintainers of this project for assistance;
14 * the project provides a web site, mailing lists and IRC
15 * channels for your use.
17 * This program is free software, distributed under the terms of
18 * the GNU General Public License Version 2 as published by the
19 * Free Software Foundation. See the LICENSE file included with
20 * this program for more details.
22 * In addition, when this program is distributed with Asterisk in
23 * any form that would qualify as a 'combined work' or as a
24 * 'derivative work' (but not mere aggregation), you can redistribute
25 * and/or modify the combination under the terms of the license
26 * provided with that copy of Asterisk, instead of the license
30 #ifndef _PRI_FACILITY_H
31 #define _PRI_FACILITY_H
33 /* Protocol Profile field */
34 #define Q932_PROTOCOL_ROSE 0x11 /* X.219 & X.229 */
35 #define Q932_PROTOCOL_CMIP 0x12 /* Q.941 */
36 #define Q932_PROTOCOL_ACSE 0x13 /* X.217 & X.227 */
37 #define Q932_PROTOCOL_GAT 0x16
38 #define Q932_PROTOCOL_EXTENSIONS 0x1F
41 #define ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE 0x80
42 #define ROSE_NAME_PRESENTATION_RESTRICTED_NULL 0x87
43 #define ROSE_NAME_NOT_AVAIL 0x84
46 #define COMP_TYPE_INTERPRETATION 0x8B
47 #define COMP_TYPE_NETWORK_PROTOCOL_PROFILE 0x92
48 #define COMP_TYPE_INVOKE 0xA1
49 #define COMP_TYPE_RETURN_RESULT 0xA2
50 #define COMP_TYPE_RETURN_ERROR 0xA3
51 #define COMP_TYPE_REJECT 0xA4
52 #define COMP_TYPE_NFE 0xAA
54 /* Operation ID values */
55 /* Q.952 ROSE operations (Diverting) */
56 #define ROSE_DIVERTING_LEG_INFORMATION1 18
57 #define ROSE_DIVERTING_LEG_INFORMATION2 15
58 #define ROSE_DIVERTING_LEG_INFORMATION3 19
59 /* Q.956 ROSE operations (Advice Of Charge) */
60 #define ROSE_AOC_NO_CHARGING_INFO_AVAILABLE 26
61 #define ROSE_AOC_CHARGING_REQUEST 30
62 #define ROSE_AOC_AOCS_CURRENCY 31
63 #define ROSE_AOC_AOCS_SPECIAL_ARR 32
64 #define ROSE_AOC_AOCD_CURRENCY 33
65 #define ROSE_AOC_AOCD_CHARGING_UNIT 34
66 #define ROSE_AOC_AOCE_CURRENCY 35
67 #define ROSE_AOC_AOCE_CHARGING_UNIT 36
68 #define ROSE_AOC_IDENTIFICATION_OF_CHARGE 37
69 /* Q.SIG operations */
70 #define SS_CNID_CALLINGNAME 0
71 #define SS_DIVERTING_LEG_INFORMATION2 22
72 #define SS_MWI_ACTIVATE 80
73 #define SS_MWI_DEACTIVATE 81
74 #define SS_MWI_INTERROGATE 82
76 #define ROSE_CALLDEFLECTION 0x0D
77 #define ROSE_CALLREROUTING 0x0E
78 #define ROSE_EXPLICIT_CALL_TRANSFER 0x06
79 #define ROSE_MALICIOUS_CID 0x31
81 /* ROSE definitions and data structures */
82 #define INVOKE_IDENTIFIER 0x02
83 #define INVOKE_LINKED_IDENTIFIER 0x80
84 #define INVOKE_NULL_IDENTIFIER __USE_ASN1_NULL
86 /* ASN.1 Identifier Octet - Data types */
87 #define ASN1_TYPE_MASK 0x1f
88 #define ASN1_BOOLEAN 0x01
89 #define ASN1_INTEGER 0x02
90 #define ASN1_BITSTRING 0x03
91 #define ASN1_OCTETSTRING 0x04
92 #define ASN1_NULL 0x05
93 #define ASN1_OBJECTIDENTIFIER 0x06
94 #define ASN1_OBJECTDESCRIPTOR 0x07
95 #define ASN1_EXTERN 0x08
96 #define ASN1_REAL 0x09
97 #define ASN1_ENUMERATED 0x0a
98 #define ASN1_EMBEDDEDPDV 0x0b
99 #define ASN1_UTF8STRING 0x0c
100 #define ASN1_RELATIVEOBJECTID 0x0d
101 /* 0x0e & 0x0f are reserved for future ASN.1 editions */
102 #define ASN1_SEQUENCE 0x10
103 #define ASN1_SET 0x11
104 #define ASN1_NUMERICSTRING 0x12
105 #define ASN1_PRINTABLESTRING 0x13
106 #define ASN1_TELETEXSTRING 0x14
107 #define ASN1_IA5STRING 0x16
108 #define ASN1_UTCTIME 0x17
109 #define ASN1_GENERALIZEDTIME 0x18
111 /* ASN.1 Identifier Octet - Tags */
112 #define ASN1_TAG_0 0x00
113 #define ASN1_TAG_1 0x01
114 #define ASN1_TAG_2 0x02
115 #define ASN1_TAG_3 0x03
116 #define ASN1_TAG_4 0x04
117 #define ASN1_TAG_5 0x05
118 #define ASN1_TAG_6 0x06
119 #define ASN1_TAG_7 0x07
120 #define ASN1_TAG_8 0x08
121 #define ASN1_TAG_9 0x09
123 /* ASN.1 Identifier Octet - Primitive/Constructor Bit */
124 #define ASN1_PC_MASK 0x20
125 #define ASN1_PRIMITIVE 0x00
126 #define ASN1_CONSTRUCTOR 0x20
128 /* ASN.1 Identifier Octet - Clan Bits */
129 #define ASN1_CLAN_MASK 0xc0
130 #define ASN1_UNIVERSAL 0x00
131 #define ASN1_APPLICATION 0x40
132 #define ASN1_CONTEXT_SPECIFIC 0x80
133 #define ASN1_PRIVATE 0xc0
135 /* ASN.1 Length masks */
136 #define ASN1_LEN_INDEF 0x80
139 #define INVOKE_OPERATION_INT __USE_ASN1_INTEGER
140 #define INVOKE_OBJECT_ID __USE_ASN1_OBJECTIDENTIFIER
142 /* Q.952 Divert cause */
143 #define Q952_DIVERT_REASON_UNKNOWN 0x00
144 #define Q952_DIVERT_REASON_CFU 0x01
145 #define Q952_DIVERT_REASON_CFB 0x02
146 #define Q952_DIVERT_REASON_CFNR 0x03
147 #define Q952_DIVERT_REASON_CD 0x04
148 #define Q952_DIVERT_REASON_IMMEDIATE 0x05
149 /* Q.SIG Divert cause. Listed in ECMA-174 */
150 #define QSIG_DIVERT_REASON_UNKNOWN 0x00 /* Call forward unknown reason */
151 #define QSIG_DIVERT_REASON_CFU 0x01 /* Call Forward Unconditional (other reason) */
152 #define QSIG_DIVERT_REASON_CFB 0x02 /* Call Forward Busy */
153 #define QSIG_DIVERT_REASON_CFNR 0x03 /* Call Forward No Reply */
155 /* Q.932 Type of number */
156 #define Q932_TON_UNKNOWN 0x00
157 #define Q932_TON_INTERNATIONAL 0x01
158 #define Q932_TON_NATIONAL 0x02
159 #define Q932_TON_NET_SPECIFIC 0x03
160 #define Q932_TON_SUBSCRIBER 0x04
161 #define Q932_TON_ABBREVIATED 0x06
163 /* RLT related Operations */
164 #define RLT_SERVICE_ID 0x3e
165 #define RLT_OPERATION_IND 0x01
166 #define RLT_THIRD_PARTY 0x02
168 struct rose_component
{
174 #define GET_COMPONENT(component, idx, ptr, length) \
175 if ((idx)+2 > (length)) \
177 (component) = (struct rose_component*)&((ptr)[idx]); \
178 if ((idx)+(component)->len+2 > (length)) { \
179 if ((component)->len != ASN1_LEN_INDEF) \
180 pri_message(pri, "Length (%d) of 0x%X component is too long\n", (component)->len, (component)->type); \
183 pri_message("XX Got component %d (0x%02X), length %d\n", (component)->type, (component)->type, (component)->len); \
184 if ((component)->len > 0) { \
186 pri_message("XX Data:"); \
187 for (zzz = 0; zzz < (component)->len; ++zzz) \
188 pri_message(" %02X", (component)->data[zzz]); \
193 #define NEXT_COMPONENT(component, idx) \
194 (idx) += (component)->len + 2
196 #define SUB_COMPONENT(component, idx) \
199 #define CHECK_COMPONENT(component, comptype, message) \
200 if ((component)->type && ((component)->type & ASN1_TYPE_MASK) != (comptype)) { \
201 pri_message(pri, (message), (component)->type); \
202 asn1_dump(pri, (component), (component)->len+2); \
206 #define ASN1_GET_INTEGER(component, variable) \
210 for (comp_idx = 0; comp_idx < (component)->len; ++comp_idx) \
211 (variable) = ((variable) << 8) | (component)->data[comp_idx]; \
214 #define ASN1_ADD_SIMPLE(component, comptype, ptr, idx) \
216 (component) = (struct rose_component *)&((ptr)[(idx)]); \
217 (component)->type = (comptype); \
218 (component)->len = 0; \
222 #define ASN1_ADD_BYTECOMP(component, comptype, ptr, idx, value) \
224 (component) = (struct rose_component *)&((ptr)[(idx)]); \
225 (component)->type = (comptype); \
226 (component)->len = 1; \
227 (component)->data[0] = (value); \
231 #define ASN1_ADD_WORDCOMP(component, comptype, ptr, idx, value) \
233 int __val = (value); \
235 (component) = (struct rose_component *)&((ptr)[(idx)]); \
236 (component)->type = (comptype); \
238 (component)->data[__i++] = (__val >> 24) & 0xff; \
240 (component)->data[__i++] = (__val >> 16) & 0xff; \
242 (component)->data[__i++] = (__val >> 8) & 0xff; \
243 (component)->data[__i++] = __val & 0xff; \
244 (component)->len = __i; \
248 #define ASN1_PUSH(stack, stackpointer, component) \
249 (stack)[(stackpointer)++] = (component)
251 #define ASN1_FIXUP(stack, stackpointer, data, idx) \
254 (stack)[(stackpointer)]->len = (unsigned char *)&((data)[(idx)]) - (unsigned char *)(stack)[(stackpointer)] - 2; \
257 /* Decoder for the invoke ROSE component */
258 int rose_invoke_decode(struct pri
*pri
, struct q931_call
*call
, unsigned char *data
, int len
);
260 /* Decoder for the return result ROSE component */
261 int rose_return_result_decode(struct pri
*pri
, struct q931_call
*call
, unsigned char *data
, int len
);
263 /* Decoder for the return error ROSE component */
264 int rose_return_error_decode(struct pri
*pri
, struct q931_call
*call
, unsigned char *data
, int len
);
266 /* Decoder for the reject ROSE component */
267 int rose_reject_decode(struct pri
*pri
, struct q931_call
*call
, unsigned char *data
, int len
);
269 int asn1_copy_string(char * buf
, int buflen
, struct rose_component
*comp
);
271 int asn1_string_encode(unsigned char asn1_type
, void *data
, int len
, int max_len
, void *src
, int src_len
);
273 /* Get Name types from ASN.1 */
274 int asn1_name_decode(void * data
, int len
, char *namebuf
, int buflen
);
276 int typeofnumber_from_q931(struct pri
*pri
, int ton
);
278 int redirectingreason_from_q931(struct pri
*pri
, int redirectingreason
);
280 /* Queues an MWI apdu on a the given call */
281 int mwi_message_send(struct pri
*pri
, q931_call
*call
, struct pri_sr
*req
, int activate
);
284 int eect_initiate_transfer(struct pri
*pri
, q931_call
*c1
, q931_call
*c2
);
286 int rlt_initiate_transfer(struct pri
*pri
, q931_call
*c1
, q931_call
*c2
);
288 /* Use this function to queue a facility-IE born APDU onto a call
289 * call is the call to use, messagetype is any one of the Q931 messages,
290 * apdu is the apdu data, apdu_len is the length of the apdu data */
291 int pri_call_apdu_queue(q931_call
*call
, int messagetype
, void *apdu
, int apdu_len
, void (*function
)(void *data
), void *data
);
293 /* Used by q931.c to cleanup the apdu queue upon destruction of a call */
294 int pri_call_apdu_queue_cleanup(q931_call
*call
);
296 /* Adds the "standard" APDUs to a call */
297 int pri_call_add_standard_apdus(struct pri
*pri
, q931_call
*call
);
299 int asn1_dump(struct pri
*pri
, void *comp
, int len
);
301 extern int add_call_deflection_facility_ie(struct pri
*pri
, q931_call
*c
, char *destination
);
303 extern int add_call_rerouting_facility_ie(struct pri
*pri
, q931_call
*c
, char *destination
);
305 extern int aoc_aoce_charging_unit_encode(struct pri
*pri
, q931_call
*c
, long chargedunits
, int send_facility_message
);
307 #endif /* _PRI_FACILITY_H */