1 /*
2 * libpri: An implementation of Primary Rate ISDN
3 *
4 * Copyright (C) 2009 Digium, Inc.
5 *
6 * Richard Mudgett <rmudgett@digium.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2 as published by the
16 * Free Software Foundation. See the LICENSE file included with
17 * this program for more details.
18 *
19 * In addition, when this program is distributed with Asterisk in
20 * any form that would qualify as a 'combined work' or as a
21 * 'derivative work' (but not mere aggregation), you can redistribute
22 * and/or modify the combination under the terms of the license
23 * provided with that copy of Asterisk, instead of the license
24 * terms granted here.
25 */
26
27 /*!
28 * \file
29 * \brief Switch type operations for: NI2, 4ESS, 5ESS, DMS-100
30 *
31 * \author Richard Mudgett <rmudgett@digium.com>
32 */
33
34
35 #include "compat.h"
36 #include "libpri.h"
37 #include "pri_internal.h"
38 #include "rose.h"
39 #include "rose_internal.h"
40 #include "asn1.h"
41
42
43 /* ------------------------------------------------------------------- */
44
45 /*!
46 * \brief Encode the DMS-100 RLT_OperationInd result facility ie arguments.
47 *
48 * \param ctrl D channel controller for diagnostic messages or global options.
49 * \param pos Starting position to encode ASN.1 component.
50 * \param end End of ASN.1 encoding data buffer.
51 * \param args Arguments to encode in the buffer.
52 *
53 * \retval Start of the next ASN.1 component to encode on success.
54 * \retval NULL on error.
55 */
rose_enc_dms100_RLT_OperationInd_RES(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_result_args * args)56 unsigned char *rose_enc_dms100_RLT_OperationInd_RES(struct pri *ctrl, unsigned char *pos,
57 unsigned char *end, const union rose_msg_result_args *args)
58 {
59 return asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0,
60 args->dms100.RLT_OperationInd.call_id);
61 }
62
63 /*!
64 * \brief Encode the DMS-100 RLT_ThirdParty invoke facility ie arguments.
65 *
66 * \param ctrl D channel controller for diagnostic messages or global options.
67 * \param pos Starting position to encode ASN.1 component.
68 * \param end End of ASN.1 encoding data buffer.
69 * \param args Arguments to encode in the buffer.
70 *
71 * \retval Start of the next ASN.1 component to encode on success.
72 * \retval NULL on error.
73 */
rose_enc_dms100_RLT_ThirdParty_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)74 unsigned char *rose_enc_dms100_RLT_ThirdParty_ARG(struct pri *ctrl, unsigned char *pos,
75 unsigned char *end, const union rose_msg_invoke_args *args)
76 {
77 const struct roseDms100RLTThirdParty_ARG *rlt_thirdparty;
78 unsigned char *seq_len;
79
80 ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
81
82 rlt_thirdparty = &args->dms100.RLT_ThirdParty;
83 ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0,
84 rlt_thirdparty->call_id));
85 ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 1,
86 rlt_thirdparty->reason));
87
88 ASN1_CONSTRUCTED_END(seq_len, pos, end);
89
90 return pos;
91 }
92
93 /*!
94 * \brief Decode the DMS-100 RLT_OperationInd result argument parameters.
95 *
96 * \param ctrl D channel controller for diagnostic messages or global options.
97 * \param tag Component tag that identified this structure.
98 * \param pos Starting position of the ASN.1 component length.
99 * \param end End of ASN.1 decoding data buffer.
100 * \param args Arguments to fill in from the decoded buffer.
101 *
102 * \retval Start of the next ASN.1 component on success.
103 * \retval NULL on error.
104 */
rose_dec_dms100_RLT_OperationInd_RES(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_result_args * args)105 const unsigned char *rose_dec_dms100_RLT_OperationInd_RES(struct pri *ctrl, unsigned tag,
106 const unsigned char *pos, const unsigned char *end, union rose_msg_result_args *args)
107 {
108 int32_t value;
109
110 ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 0);
111 ASN1_CALL(pos, asn1_dec_int(ctrl, "callId", tag, pos, end, &value));
112 args->dms100.RLT_OperationInd.call_id = value;
113
114 return pos;
115 }
116
117 /*!
118 * \brief Decode the DMS-100 RLT_ThirdParty invoke argument parameters.
119 *
120 * \param ctrl D channel controller for diagnostic messages or global options.
121 * \param tag Component tag that identified this structure.
122 * \param pos Starting position of the ASN.1 component length.
123 * \param end End of ASN.1 decoding data buffer.
124 * \param args Arguments to fill in from the decoded buffer.
125 *
126 * \retval Start of the next ASN.1 component on success.
127 * \retval NULL on error.
128 */
rose_dec_dms100_RLT_ThirdParty_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)129 const unsigned char *rose_dec_dms100_RLT_ThirdParty_ARG(struct pri *ctrl, unsigned tag,
130 const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
131 {
132 int32_t value;
133 int length;
134 int seq_offset;
135 const unsigned char *seq_end;
136 struct roseDms100RLTThirdParty_ARG *rlt_third_party;
137
138 rlt_third_party = &args->dms100.RLT_ThirdParty;
139
140 ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
141 if (ctrl->debug & PRI_DEBUG_APDU) {
142 pri_message(ctrl, " RLT_ThirdParty %s\n", asn1_tag2str(tag));
143 }
144 ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
145 ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
146
147 ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
148 ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 0);
149 ASN1_CALL(pos, asn1_dec_int(ctrl, "callId", tag, pos, seq_end, &value));
150 rlt_third_party->call_id = value;
151
152 ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
153 ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_CLASS_CONTEXT_SPECIFIC | 1);
154 ASN1_CALL(pos, asn1_dec_int(ctrl, "reason", tag, pos, seq_end, &value));
155 rlt_third_party->reason = value;
156
157 /* Fixup will skip over any OPTIONAL information */
158 ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
159
160 return pos;
161 }
162
163 /*!
164 * \brief Encode the NI2 InformationFollowing invoke facility ie arguments.
165 *
166 * \param ctrl D channel controller for diagnostic messages or global options.
167 * \param pos Starting position to encode ASN.1 component.
168 * \param end End of ASN.1 encoding data buffer.
169 * \param args Arguments to encode in the buffer.
170 *
171 * \retval Start of the next ASN.1 component to encode on success.
172 * \retval NULL on error.
173 */
rose_enc_ni2_InformationFollowing_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)174 unsigned char *rose_enc_ni2_InformationFollowing_ARG(struct pri *ctrl,
175 unsigned char *pos, unsigned char *end, const union rose_msg_invoke_args *args)
176 {
177 /* Encode the unknown enumeration value. */
178 return asn1_enc_int(pos, end, ASN1_TYPE_ENUMERATED,
179 args->ni2.InformationFollowing.value);
180 }
181
182 /*!
183 * \brief Encode the NI2 InitiateTransfer invoke facility ie arguments.
184 *
185 * \param ctrl D channel controller for diagnostic messages or global options.
186 * \param pos Starting position to encode ASN.1 component.
187 * \param end End of ASN.1 encoding data buffer.
188 * \param args Arguments to encode in the buffer.
189 *
190 * \retval Start of the next ASN.1 component to encode on success.
191 * \retval NULL on error.
192 */
rose_enc_ni2_InitiateTransfer_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)193 unsigned char *rose_enc_ni2_InitiateTransfer_ARG(struct pri *ctrl, unsigned char *pos,
194 unsigned char *end, const union rose_msg_invoke_args *args)
195 {
196 const struct roseNi2InitiateTransfer_ARG *initiate_transfer;
197 unsigned char *seq_len;
198
199 ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, ASN1_TAG_SEQUENCE);
200
201 initiate_transfer = &args->ni2.InitiateTransfer;
202 ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER,
203 initiate_transfer->call_reference));
204
205 ASN1_CONSTRUCTED_END(seq_len, pos, end);
206
207 return pos;
208 }
209
210 /*!
211 * \brief Decode the NI2 InformationFollowing invoke argument parameters.
212 *
213 * \param ctrl D channel controller for diagnostic messages or global options.
214 * \param tag Component tag that identified this structure.
215 * \param pos Starting position of the ASN.1 component length.
216 * \param end End of ASN.1 decoding data buffer.
217 * \param args Arguments to fill in from the decoded buffer.
218 *
219 * \retval Start of the next ASN.1 component on success.
220 * \retval NULL on error.
221 */
rose_dec_ni2_InformationFollowing_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)222 const unsigned char *rose_dec_ni2_InformationFollowing_ARG(struct pri *ctrl,
223 unsigned tag, const unsigned char *pos, const unsigned char *end,
224 union rose_msg_invoke_args *args)
225 {
226 int32_t value;
227
228 ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_ENUMERATED);
229 ASN1_CALL(pos, asn1_dec_int(ctrl, "unknown", tag, pos, end, &value));
230 args->ni2.InformationFollowing.value = value;
231
232 return pos;
233 }
234
235 /*!
236 * \brief Decode the NI2 InitiateTransfer invoke argument parameters.
237 *
238 * \param ctrl D channel controller for diagnostic messages or global options.
239 * \param tag Component tag that identified this structure.
240 * \param pos Starting position of the ASN.1 component length.
241 * \param end End of ASN.1 decoding data buffer.
242 * \param args Arguments to fill in from the decoded buffer.
243 *
244 * \retval Start of the next ASN.1 component on success.
245 * \retval NULL on error.
246 */
rose_dec_ni2_InitiateTransfer_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)247 const unsigned char *rose_dec_ni2_InitiateTransfer_ARG(struct pri *ctrl, unsigned tag,
248 const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
249 {
250 int32_t value;
251 int length;
252 int seq_offset;
253 const unsigned char *seq_end;
254 struct roseNi2InitiateTransfer_ARG *initiate_transfer;
255
256 initiate_transfer = &args->ni2.InitiateTransfer;
257
258 ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TAG_SEQUENCE);
259 if (ctrl->debug & PRI_DEBUG_APDU) {
260 pri_message(ctrl, " InitiateTransfer %s\n", asn1_tag2str(tag));
261 }
262 ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
263 ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
264
265 ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
266 ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
267 ASN1_CALL(pos, asn1_dec_int(ctrl, "callReference", tag, pos, seq_end, &value));
268 initiate_transfer->call_reference = value;
269
270 /* Fixup will skip over any OPTIONAL information */
271 ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
272
273 return pos;
274 }
275
276 /* ------------------------------------------------------------------- */
277 /* end rose_other.c */
278