Ignore files generated in the dependency checks.
[libpri-bristuff.git] / pri_facility.c
blob3fd08016b4d45695248195cb70a099fe2ab1a60f
1 /*
2 <<<<<<< HEAD:pri_facility.c
3 * libpri: An implementation of Primary Rate ISDN
5 * Written by Matthew Fredrickson <creslin@digium.com>
7 * Copyright (C) 2004-2005, Digium, Inc.
8 * All Rights Reserved.
10 * Copyright (C) 2005-2006 Junghanns.NET GmbH
11 * Klaus-Peter Junghanns <kpj@junghanns.net>
15 * See http://www.asterisk.org for more information about
16 * the Asterisk project. Please do not directly contact
17 * any of the maintainers of this project for assistance;
18 * the project provides a web site, mailing lists and IRC
19 * channels for your use.
21 * This program is free software, distributed under the terms of
22 * the GNU General Public License Version 2 as published by the
23 * Free Software Foundation. See the LICENSE file included with
24 * this program for more details.
27 #include "compat.h"
28 #include "libpri.h"
29 #include "pri_internal.h"
30 #include "pri_q921.h"
31 #include "pri_q931.h"
32 #include "pri_facility.h"
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <limits.h>
39 static char *asn1id2text(int id)
41 static char data[32];
42 static char *strings[] = {
43 "none",
44 "Boolean",
45 "Integer",
46 "Bit String",
47 "Octet String",
48 "NULL",
49 "Object Identifier",
50 "Object Descriptor",
51 "External Reference",
52 "Real Number",
53 "Enumerated",
54 "Embedded PDV",
55 "UTF-8 String",
56 "Relative Object ID",
57 "Reserved (0e)",
58 "Reserved (0f)",
59 "Sequence",
60 "Set",
61 "Numeric String",
62 "Printable String",
63 "Tele-Text String",
64 "IA-5 String",
65 "UTC Time",
66 "Generalized Time",
68 if (id > 0 && id <= 0x18) {
69 return strings[id];
70 } else {
71 sprintf(data, "Unknown (%02x)", id);
72 return data;
76 static int asn1_dumprecursive(struct pri *pri, void *comp_ptr, int len, int level)
78 unsigned char *vdata = (unsigned char *)comp_ptr;
79 struct rose_component *comp;
80 int i = 0;
81 int j, k, l;
82 int clen = 0;
84 while (len > 0) {
85 GET_COMPONENT(comp, i, vdata, len);
86 pri_message(pri, "%*s%02X %04X", 2 * level, "", comp->type, comp->len);
87 if ((comp->type == 0) && (comp->len == 0))
88 return clen + 2;
89 if ((comp->type & ASN1_PC_MASK) == ASN1_PRIMITIVE) {
90 for (j = 0; j < comp->len; ++j)
91 pri_message(pri, " %02X", comp->data[j]);
93 if ((comp->type & ASN1_CLAN_MASK) == ASN1_UNIVERSAL) {
94 switch (comp->type & ASN1_TYPE_MASK) {
95 case 0:
96 pri_message(pri, " (none)");
97 break;
98 case ASN1_BOOLEAN:
99 pri_message(pri, " (BOOLEAN: %d)", comp->data[0]);
100 break;
101 case ASN1_INTEGER:
102 for (k = l = 0; k < comp->len; ++k)
103 l = (l << 8) | comp->data[k];
104 pri_message(pri, " (INTEGER: %d)", l);
105 break;
106 case ASN1_BITSTRING:
107 pri_message(pri, " (BITSTRING:");
108 for (k = 0; k < comp->len; ++k)
109 pri_message(pri, " %02x", comp->data[k]);
110 pri_message(pri, ")");
111 break;
112 case ASN1_OCTETSTRING:
113 pri_message(pri, " (OCTETSTRING:");
114 for (k = 0; k < comp->len; ++k)
115 pri_message(pri, " %02x", comp->data[k]);
116 pri_message(pri, ")");
117 break;
118 case ASN1_NULL:
119 pri_message(pri, " (NULL)");
120 break;
121 case ASN1_OBJECTIDENTIFIER:
122 pri_message(pri, " (OBJECTIDENTIFIER:");
123 for (k = 0; k < comp->len; ++k)
124 pri_message(pri, " %02x", comp->data[k]);
125 pri_message(pri, ")");
126 break;
127 case ASN1_ENUMERATED:
128 for (k = l = 0; k < comp->len; ++k)
129 l = (l << 8) | comp->data[k];
130 pri_message(pri, " (ENUMERATED: %d)", l);
131 break;
132 case ASN1_SEQUENCE:
133 pri_message(pri, " (SEQUENCE)");
134 break;
135 default:
136 pri_message(pri, " (component %02x - %s)", comp->type, asn1id2text(comp->type & ASN1_TYPE_MASK));
137 break;
140 else if ((comp->type & ASN1_CLAN_MASK) == ASN1_CONTEXT_SPECIFIC) {
141 pri_message(pri, " (CONTEXT SPECIFIC [%d])", comp->type & ASN1_TYPE_MASK);
143 else {
144 pri_message(pri, " (component %02x)", comp->type);
146 pri_message(pri, "\n");
147 if ((comp->type & ASN1_PC_MASK) == ASN1_CONSTRUCTOR)
148 j = asn1_dumprecursive(pri, comp->data, (comp->len ? comp->len : INT_MAX), level+1);
149 else
150 j = comp->len;
151 j += 2;
152 len -= j;
153 vdata += j;
154 clen += j;
156 return clen;
159 int asn1_dump(struct pri *pri, void *comp, int len)
161 return asn1_dumprecursive(pri, comp, len, 0);
164 static unsigned char get_invokeid(struct pri *pri)
166 return ++pri->last_invoke;
169 struct addressingdataelements_presentednumberunscreened {
170 char partyaddress[21];
171 char partysubaddress[21];
172 int npi;
173 int ton;
174 int pres;
177 #define PRI_CHECKOVERFLOW(size) \
178 if (msgptr - message + (size) >= sizeof(message)) { \
179 *msgptr = '\0'; \
180 pri_message(pri, "%s", message); \
181 msgptr = message; \
184 static void dump_apdu(struct pri *pri, unsigned char *c, int len)
186 #define MAX_APDU_LENGTH 255
187 static char hexs[16] = "0123456789ABCDEF";
188 int i;
189 char message[(2 + MAX_APDU_LENGTH * 3 + 6 + MAX_APDU_LENGTH + 3)] = ""; /* please adjust here, if you make changes below! */
190 char *msgptr;
192 msgptr = message;
193 *msgptr++ = ' ';
194 *msgptr++ = '[';
195 for (i=0; i<len; i++) {
196 PRI_CHECKOVERFLOW(3);
197 *msgptr++ = ' ';
198 *msgptr++ = hexs[(c[i] >> 4) & 0x0f];
199 *msgptr++ = hexs[(c[i]) & 0x0f];
201 PRI_CHECKOVERFLOW(6);
202 strcpy(msgptr, " ] - [");
203 msgptr += strlen(msgptr);
204 for (i=0; i<len; i++) {
205 PRI_CHECKOVERFLOW(1);
206 *msgptr++ = ((c[i] < ' ') || (c[i] > '~')) ? '.' : c[i];
208 PRI_CHECKOVERFLOW(2);
209 *msgptr++ = ']';
210 *msgptr++ = '\n';
211 *msgptr = '\0';
212 pri_message(pri, "%s", message);
214 #undef PRI_CHECKOVERFLOW
216 int redirectingreason_from_q931(struct pri *pri, int redirectingreason)
218 switch(pri->switchtype) {
219 case PRI_SWITCH_QSIG:
220 switch(redirectingreason) {
221 case PRI_REDIR_UNKNOWN:
222 return QSIG_DIVERT_REASON_UNKNOWN;
223 case PRI_REDIR_FORWARD_ON_BUSY:
224 return QSIG_DIVERT_REASON_CFB;
225 case PRI_REDIR_FORWARD_ON_NO_REPLY:
226 return QSIG_DIVERT_REASON_CFNR;
227 case PRI_REDIR_UNCONDITIONAL:
228 return QSIG_DIVERT_REASON_CFU;
229 case PRI_REDIR_DEFLECTION:
230 case PRI_REDIR_DTE_OUT_OF_ORDER:
231 case PRI_REDIR_FORWARDED_BY_DTE:
232 pri_message(pri, "!! Don't know how to convert Q.931 redirection reason %d to Q.SIG\n", redirectingreason);
233 /* Fall through */
234 default:
235 return QSIG_DIVERT_REASON_UNKNOWN;
237 default:
238 switch(redirectingreason) {
239 case PRI_REDIR_UNKNOWN:
240 return Q952_DIVERT_REASON_UNKNOWN;
241 case PRI_REDIR_FORWARD_ON_BUSY:
242 return Q952_DIVERT_REASON_CFB;
243 case PRI_REDIR_FORWARD_ON_NO_REPLY:
244 return Q952_DIVERT_REASON_CFNR;
245 case PRI_REDIR_DEFLECTION:
246 return Q952_DIVERT_REASON_CD;
247 case PRI_REDIR_UNCONDITIONAL:
248 return Q952_DIVERT_REASON_CFU;
249 case PRI_REDIR_DTE_OUT_OF_ORDER:
250 case PRI_REDIR_FORWARDED_BY_DTE:
251 pri_message(pri, "!! Don't know how to convert Q.931 redirection reason %d to Q.952\n", redirectingreason);
252 /* Fall through */
253 default:
254 return Q952_DIVERT_REASON_UNKNOWN;
259 static int redirectingreason_for_q931(struct pri *pri, int redirectingreason)
261 switch(pri->switchtype) {
262 case PRI_SWITCH_QSIG:
263 switch(redirectingreason) {
264 case QSIG_DIVERT_REASON_UNKNOWN:
265 return PRI_REDIR_UNKNOWN;
266 case QSIG_DIVERT_REASON_CFU:
267 return PRI_REDIR_UNCONDITIONAL;
268 case QSIG_DIVERT_REASON_CFB:
269 return PRI_REDIR_FORWARD_ON_BUSY;
270 case QSIG_DIVERT_REASON_CFNR:
271 return PRI_REDIR_FORWARD_ON_NO_REPLY;
272 default:
273 pri_message(pri, "!! Unknown Q.SIG diversion reason %d\n", redirectingreason);
274 return PRI_REDIR_UNKNOWN;
276 default:
277 switch(redirectingreason) {
278 case Q952_DIVERT_REASON_UNKNOWN:
279 return PRI_REDIR_UNKNOWN;
280 case Q952_DIVERT_REASON_CFU:
281 return PRI_REDIR_UNCONDITIONAL;
282 case Q952_DIVERT_REASON_CFB:
283 return PRI_REDIR_FORWARD_ON_BUSY;
284 case Q952_DIVERT_REASON_CFNR:
285 return PRI_REDIR_FORWARD_ON_NO_REPLY;
286 case Q952_DIVERT_REASON_CD:
287 return PRI_REDIR_DEFLECTION;
288 case Q952_DIVERT_REASON_IMMEDIATE:
289 pri_message(pri, "!! Dont' know how to convert Q.952 diversion reason IMMEDIATE to PRI analog\n");
290 return PRI_REDIR_UNKNOWN; /* ??? */
291 default:
292 pri_message(pri, "!! Unknown Q.952 diversion reason %d\n", redirectingreason);
293 return PRI_REDIR_UNKNOWN;
298 int typeofnumber_from_q931(struct pri *pri, int ton)
300 switch(ton) {
301 case PRI_TON_INTERNATIONAL:
302 return Q932_TON_INTERNATIONAL;
303 case PRI_TON_NATIONAL:
304 return Q932_TON_NATIONAL;
305 case PRI_TON_NET_SPECIFIC:
306 return Q932_TON_NET_SPECIFIC;
307 case PRI_TON_SUBSCRIBER:
308 return Q932_TON_SUBSCRIBER;
309 case PRI_TON_ABBREVIATED:
310 return Q932_TON_ABBREVIATED;
311 case PRI_TON_RESERVED:
312 default:
313 pri_message(pri, "!! Unsupported Q.931 TypeOfNumber value (%d)\n", ton);
314 /* fall through */
315 case PRI_TON_UNKNOWN:
316 return Q932_TON_UNKNOWN;
320 static int typeofnumber_for_q931(struct pri *pri, int ton)
322 switch (ton) {
323 case Q932_TON_UNKNOWN:
324 return PRI_TON_UNKNOWN;
325 case Q932_TON_INTERNATIONAL:
326 return PRI_TON_INTERNATIONAL;
327 case Q932_TON_NATIONAL:
328 return PRI_TON_NATIONAL;
329 case Q932_TON_NET_SPECIFIC:
330 return PRI_TON_NET_SPECIFIC;
331 case Q932_TON_SUBSCRIBER:
332 return PRI_TON_SUBSCRIBER;
333 case Q932_TON_ABBREVIATED:
334 return PRI_TON_ABBREVIATED;
335 default:
336 pri_message(pri, "!! Invalid Q.932 TypeOfNumber %d\n", ton);
337 return PRI_TON_UNKNOWN;
341 int asn1_name_decode(void * data, int len, char *namebuf, int buflen)
343 struct rose_component *comp = (struct rose_component*)data;
344 int datalen = 0, res = 0;
346 if (comp->len == ASN1_LEN_INDEF) {
347 datalen = strlen((char *)comp->data);
348 res = datalen + 2;
349 } else
350 datalen = res = comp->len;
352 if (datalen > buflen) {
353 /* Truncate */
354 datalen = buflen;
355 memcpy(namebuf, comp->data, datalen);
357 return res;
360 int asn1_string_encode(unsigned char asn1_type, void *data, int len, int max_len, void *src, int src_len)
362 struct rose_component *comp = NULL;
364 if (len < 2 + src_len)
365 return -1;
367 if (max_len && (src_len > max_len))
368 src_len = max_len;
370 comp = (struct rose_component *)data;
371 comp->type = asn1_type;
372 comp->len = src_len;
373 memcpy(comp->data, src, src_len);
375 return 2 + src_len;
378 int asn1_copy_string(char * buf, int buflen, struct rose_component *comp)
380 int res;
381 int datalen;
383 if ((comp->len > buflen) && (comp->len != ASN1_LEN_INDEF))
384 return -1;
386 if (comp->len == ASN1_LEN_INDEF) {
387 datalen = strlen((char*)comp->data);
388 res = datalen + 2;
389 } else
390 res = datalen = comp->len;
392 memcpy(buf, comp->data, datalen);
393 buf[datalen] = 0;
395 return res;
398 static int rose_number_digits_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
400 int i = 0;
401 struct rose_component *comp = NULL;
402 unsigned char *vdata = data;
403 int datalen = 0;
404 int res = 0;
406 do {
407 GET_COMPONENT(comp, i, vdata, len);
408 CHECK_COMPONENT(comp, ASN1_NUMERICSTRING, "Don't know what to do with PublicPartyNumber ROSE component type 0x%x\n");
409 if(comp->len > 20 && comp->len != ASN1_LEN_INDEF) {
410 pri_message(pri, "!! Oversized NumberDigits component (%d)\n", comp->len);
411 return -1;
413 if (comp->len == ASN1_LEN_INDEF) {
414 datalen = strlen((char *)comp->data);
415 res = datalen + 2;
416 } else
417 res = datalen = comp->len;
419 memcpy(value->partyaddress, comp->data, datalen);
420 value->partyaddress[datalen] = '\0';
422 return res + 2;
424 while(0);
426 return -1;
429 static int rose_public_party_number_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
431 int i = 0;
432 struct rose_component *comp = NULL;
433 unsigned char *vdata = data;
434 int ton;
435 int res = 0;
437 if (len < 2)
438 return -1;
440 do {
441 GET_COMPONENT(comp, i, vdata, len);
442 CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Don't know what to do with PublicPartyNumber ROSE component type 0x%x\n");
443 ASN1_GET_INTEGER(comp, ton);
444 NEXT_COMPONENT(comp, i);
445 ton = typeofnumber_for_q931(pri, ton);
447 res = rose_number_digits_decode(pri, call, &vdata[i], len-i, value);
448 if (res < 0)
449 return -1;
450 value->ton = ton;
452 return res + 2;
454 } while(0);
455 return -1;
458 static int rose_cd_destination_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
460 unsigned char *vdata = data;
461 struct rose_component *comp1 = NULL, *comp2 = NULL;
462 int pos1 = 0, pos2, sublen2;
464 if (pri->debug & PRI_DEBUG_AOC)
465 dump_apdu (pri, data, len);
467 do {
468 GET_COMPONENT(comp1, pos1, vdata, len);
469 CHECK_COMPONENT(comp1, ASN1_SEQUENCE, "!! Invalid CD destination argument. Expected Sequence (0x30) but Received 0x%02X\n");
470 SUB_COMPONENT(comp1, pos1);
471 GET_COMPONENT(comp1, pos1, vdata, len);
472 switch (comp1->type) {
473 case (ASN1_SEQUENCE | ASN1_CONSTRUCTOR):
474 sublen2 = comp1->len;
475 pos2 = pos1;
476 comp2 = comp1;
477 SUB_COMPONENT(comp2, pos2);
478 do {
479 GET_COMPONENT(comp2, pos2, vdata, len);
480 switch (comp2->type) {
481 case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0):
482 memcpy(call->redirectingnum, comp2->data, comp2->len);
483 call->redirectingnum[comp2->len] = '\0';
484 return 0;
485 break;
486 default:
487 pri_message(pri, "!! Don't know how to handle 0x%02X in CD destination argument\n", comp2->type);
489 NEXT_COMPONENT(comp2, pos2);
490 } while (pos2 < sublen2);
491 break;
492 default:
493 pri_message(pri, "!! Invalid CD destination argument. Expected Sequence (0x30) or Object Identifier (0x81/0x01) but received 0x%02X\n", comp1->type);
495 NEXT_COMPONENT(comp1, pos1);
496 } while (pos1 < len);
498 return 0;
501 static int rose_address_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
503 int i = 0;
504 struct rose_component *comp = NULL;
505 unsigned char *vdata = data;
506 int res = 0;
508 do {
509 GET_COMPONENT(comp, i, vdata, len);
511 switch(comp->type) {
512 case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0): /* [0] unknownPartyNumber */
513 res = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
514 if (res < 0)
515 return -1;
516 value->npi = PRI_NPI_UNKNOWN;
517 value->ton = PRI_TON_UNKNOWN;
518 break;
519 case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0): /* [0] unknownPartyNumber */
520 res = asn1_copy_string(value->partyaddress, sizeof(value->partyaddress), comp);
521 if (res < 0)
522 return -1;
523 value->npi = PRI_NPI_UNKNOWN;
524 value->ton = PRI_TON_UNKNOWN;
525 break;
526 case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1): /* [1] publicPartyNumber */
527 res = rose_public_party_number_decode(pri, call, comp->data, comp->len, value);
528 if (res < 0)
529 return -1;
530 value->npi = PRI_NPI_E163_E164;
531 break;
532 case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_2): /* [2] nsapEncodedNumber */
533 pri_message(pri, "!! NsapEncodedNumber isn't handled\n");
534 return -1;
535 case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3): /* [3] dataPartyNumber */
536 if(rose_number_digits_decode(pri, call, comp->data, comp->len, value))
537 return -1;
538 value->npi = PRI_NPI_X121 /* ??? */;
539 value->ton = PRI_TON_UNKNOWN /* ??? */;
540 pri_message(pri, "!! dataPartyNumber isn't handled\n");
541 return -1;
542 case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_4): /* [4] telexPartyNumber */
543 res = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
544 if (res < 0)
545 return -1;
546 value->npi = PRI_NPI_F69 /* ??? */;
547 value->ton = PRI_TON_UNKNOWN /* ??? */;
548 pri_message(pri, "!! telexPartyNumber isn't handled\n");
549 return -1;
550 case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_5): /* [5] priavePartyNumber */
551 pri_message(pri, "!! privatePartyNumber isn't handled\n");
552 value->npi = PRI_NPI_PRIVATE;
553 return -1;
554 case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_8): /* [8] nationalStandardPartyNumber */
555 res = rose_number_digits_decode(pri, call, comp->data, comp->len, value);
556 if (res < 0)
557 return -1;
558 value->npi = PRI_NPI_NATIONAL;
559 value->ton = PRI_TON_NATIONAL;
560 break;
561 default:
562 pri_message(pri, "!! Unknown Party number component received 0x%X\n", comp->type);
563 return -1;
565 NEXT_COMPONENT(comp, i);
566 if(i < len)
567 pri_message(pri, "!! not all information is handled from Address component\n");
568 return res;
570 while (0);
572 return -1;
575 static int rose_presented_number_unscreened_decode(struct pri *pri, q931_call *call, unsigned char *data, int len, struct addressingdataelements_presentednumberunscreened *value)
577 int i = 0;
578 struct rose_component *comp = NULL;
579 unsigned char *vdata = data;
581 /* Fill in default values */
582 value->ton = PRI_TON_UNKNOWN;
583 value->npi = PRI_NPI_E163_E164;
584 value->pres = -1; /* Data is not available */
586 do {
587 GET_COMPONENT(comp, i, vdata, len);
589 switch(comp->type) {
590 case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0): /* [0] presentationAllowedNumber */
591 value->pres = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
592 return rose_address_decode(pri, call, comp->data, comp->len, value) + 2;
593 case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1): /* [1] IMPLICIT presentationRestricted */
594 if (comp->len != 0) { /* must be NULL */
595 pri_error(pri, "!! Invalid PresentationRestricted component received (len != 0)\n");
596 return -1;
598 value->pres = PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
599 return 2;
600 case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2): /* [2] IMPLICIT numberNotAvailableDueToInterworking */
601 if (comp->len != 0) { /* must be NULL */
602 pri_error(pri, "!! Invalid NumberNotAvailableDueToInterworking component received (len != 0)\n");
603 return -1;
605 value->pres = PRES_NUMBER_NOT_AVAILABLE;
606 return 2;
607 case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_3): /* [3] presentationRestrictedNumber */
608 value->pres = PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
609 return rose_address_decode(pri, call, comp->data, comp->len, value) + 2;
610 default:
611 pri_message(pri, "Invalid PresentedNumberUnscreened component 0x%X\n", comp->type);
613 return -1;
615 while (0);
617 return -1;
620 static int rose_diverting_leg_information2_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
622 int i = 0;
623 int diversion_counter;
624 int diversion_reason;
625 char origcalledname[50] = "", redirectingname[50] = "";
626 struct addressingdataelements_presentednumberunscreened divertingnr;
627 struct addressingdataelements_presentednumberunscreened originalcallednr;
628 struct rose_component *comp = NULL;
629 unsigned char *vdata = data;
630 int res = 0;
632 do {
633 /* diversionCounter stuff */
634 GET_COMPONENT(comp, i, vdata, len);
635 CHECK_COMPONENT(comp, ASN1_INTEGER, "Don't know what to do it diversionCounter is of type 0x%x\n");
636 ASN1_GET_INTEGER(comp, diversion_counter);
637 NEXT_COMPONENT(comp, i);
639 /* diversionReason stuff */
640 GET_COMPONENT(comp, i, vdata, len);
641 CHECK_COMPONENT(comp, ASN1_ENUMERATED, "Invalid diversionReason type 0x%X of ROSE divertingLegInformation2 component received\n");
642 ASN1_GET_INTEGER(comp, diversion_reason);
643 NEXT_COMPONENT(comp, i);
645 diversion_reason = redirectingreason_for_q931(pri, diversion_reason);
647 if(pri->debug & PRI_DEBUG_APDU)
648 pri_message(pri, " Redirection reason: %d, total diversions: %d\n", diversion_reason, diversion_counter);
650 for(; i < len; NEXT_COMPONENT(comp, i)) {
651 GET_COMPONENT(comp, i, vdata, len);
652 switch(comp->type & ASN1_TYPE_MASK) {
653 case ASN1_TAG_0:
654 call->origredirectingreason = redirectingreason_for_q931(pri, comp->data[0]);
655 if (pri->debug & PRI_DEBUG_APDU)
656 pri_message(pri, " Received reason for original redirection %d\n", call->origredirectingreason);
657 break;
658 case ASN1_TAG_1: /* divertingnr: presentednumberunscreened */
659 res = rose_presented_number_unscreened_decode(pri, call, comp->data, comp->len, &divertingnr);
660 /* TODO: Fix indefinite length form hacks */
661 comp->len = res;
662 if (res < 0)
663 return -1;
664 if (pri->debug & PRI_DEBUG_APDU) {
665 pri_message(pri, " Received divertingNr '%s'\n", divertingnr.partyaddress);
666 pri_message(pri, " ton = %d, pres = %d, npi = %d\n", divertingnr.ton, divertingnr.pres, divertingnr.npi);
668 break;
669 case ASN1_TAG_2: /* originalCalledNr: PresentedNumberUnscreened */
670 res = rose_presented_number_unscreened_decode(pri, call, comp->data, comp->len, &originalcallednr);
671 if (res < 0)
672 return -1;
673 comp->len = res;
674 if (pri->debug & PRI_DEBUG_APDU) {
675 pri_message(pri, " Received originalcallednr '%s'\n", originalcallednr.partyaddress);
676 pri_message(pri, " ton = %d, pres = %d, npi = %d\n", originalcallednr.ton, originalcallednr.pres, originalcallednr.npi);
678 break;
679 case ASN1_TAG_3:
680 comp->len = asn1_name_decode(comp->data, comp->len, redirectingname, sizeof(redirectingname));
681 if (pri->debug & PRI_DEBUG_APDU)
682 pri_message(pri, " Received RedirectingName '%s'\n", redirectingname);
683 break;
684 case ASN1_TAG_4:
685 comp->len = asn1_name_decode(comp->data, comp->len, origcalledname, sizeof(origcalledname));
686 if (pri->debug & PRI_DEBUG_APDU)
687 pri_message(pri, " Received Originally Called Name '%s'\n", origcalledname);
688 break;
689 default:
690 pri_message(pri, "!! Invalid DivertingLegInformation2 component received 0x%X\n", comp->type);
691 return -1;
694 if (i < len)
695 return -1; /* Aborted before */
697 if (divertingnr.pres >= 0) {
698 call->redirectingplan = divertingnr.npi;
699 call->redirectingpres = divertingnr.pres;
700 call->redirectingreason = diversion_reason;
701 libpri_copy_string(call->redirectingnum, divertingnr.partyaddress, sizeof(call->redirectingnum));
703 if (originalcallednr.pres >= 0) {
704 call->origcalledplan = originalcallednr.npi;
705 call->origcalledpres = originalcallednr.pres;
706 libpri_copy_string(call->origcallednum, originalcallednr.partyaddress, sizeof(call->origcallednum));
708 if (strlen(redirectingname) > 0) {
709 libpri_copy_string(call->redirectingname, redirectingname, sizeof(call->redirectingname));
711 if (strlen(origcalledname) > 0) {
712 libpri_copy_string(call->origcalledname, origcalledname, sizeof(call->origcalledname));
714 return 0;
716 while (0);
718 return -1;
721 static int rose_diverting_leg_information2_encode(struct pri *pri, q931_call *call)
723 int i = 0, j, compsp = 0;
724 struct rose_component *comp, *compstk[10];
725 unsigned char buffer[256];
726 int len = 253;
728 #if 0 /* This is not required by specifications */
729 if (!strlen(call->callername)) {
730 return -1;
732 #endif
734 buffer[i] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS);
735 i++;
736 /* Interpretation component */
737 ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer, i, 0x00 /* Discard unrecognized invokes */);
739 ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
741 ASN1_PUSH(compstk, compsp, comp);
742 /* Invoke component contents */
743 /* Invoke ID */
744 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));
745 /* Operation Tag */
747 /* ROSE operationId component */
748 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, ROSE_DIVERTING_LEG_INFORMATION2);
750 /* ROSE ARGUMENT component */
751 ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
752 ASN1_PUSH(compstk, compsp, comp);
753 /* ROSE DivertingLegInformation2.diversionCounter component */
754 /* Always is 1 because other isn't available in the current design */
755 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, 1);
757 /* ROSE DivertingLegInformation2.diversionReason component */
758 ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, redirectingreason_from_q931(pri, call->redirectingreason));
760 /* ROSE DivertingLegInformation2.divertingNr component */
761 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
763 ASN1_PUSH(compstk, compsp, comp);
764 /* Redirecting information always not screened */
766 switch(call->redirectingpres) {
767 case PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
768 case PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
769 if (call->redirectingnum && strlen(call->redirectingnum)) {
770 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0), buffer, i);
771 ASN1_PUSH(compstk, compsp, comp);
772 /* NPI of redirected number is not supported in the current design */
773 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
774 ASN1_PUSH(compstk, compsp, comp);
775 ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, typeofnumber_from_q931(pri, call->redirectingplan >> 4));
776 j = asn1_string_encode(ASN1_NUMERICSTRING, &buffer[i], len - i, 20, call->redirectingnum, strlen(call->redirectingnum));
777 if (j < 0)
778 return -1;
780 i += j;
781 ASN1_FIXUP(compstk, compsp, buffer, i);
782 ASN1_FIXUP(compstk, compsp, buffer, i);
783 break;
785 /* fall through */
786 case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
787 case PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
788 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1), buffer, i);
789 break;
790 /* Don't know how to handle this */
791 case PRES_ALLOWED_NETWORK_NUMBER:
792 case PRES_PROHIB_NETWORK_NUMBER:
793 case PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
794 case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
795 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1), buffer, i);
796 break;
797 default:
798 pri_message(pri, "!! Undefined presentation value for redirecting number: %d\n", call->redirectingpres);
799 case PRES_NUMBER_NOT_AVAILABLE:
800 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i);
801 break;
803 ASN1_FIXUP(compstk, compsp, buffer, i);
805 /* ROSE DivertingLegInformation2.originalCalledNr component */
806 /* This information isn't supported by current design - duplicate divertingNr */
807 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_2), buffer, i);
808 ASN1_PUSH(compstk, compsp, comp);
809 /* Redirecting information always not screened */
810 switch(call->redirectingpres) {
811 case PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
812 case PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
813 if (call->redirectingnum && strlen(call->redirectingnum)) {
814 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0), buffer, i);
815 ASN1_PUSH(compstk, compsp, comp);
816 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
817 ASN1_PUSH(compstk, compsp, comp);
818 ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, typeofnumber_from_q931(pri, call->redirectingplan >> 4));
820 j = asn1_string_encode(ASN1_NUMERICSTRING, &buffer[i], len - i, 20, call->redirectingnum, strlen(call->redirectingnum));
821 if (j < 0)
822 return -1;
824 i += j;
825 ASN1_FIXUP(compstk, compsp, buffer, i);
826 ASN1_FIXUP(compstk, compsp, buffer, i);
827 break;
829 /* fall through */
830 case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
831 case PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
832 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1), buffer, i);
833 break;
834 /* Don't know how to handle this */
835 case PRES_ALLOWED_NETWORK_NUMBER:
836 case PRES_PROHIB_NETWORK_NUMBER:
837 case PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
838 case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
839 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1), buffer, i);
840 break;
841 default:
842 pri_message(pri, "!! Undefined presentation value for redirecting number: %d\n", call->redirectingpres);
843 case PRES_NUMBER_NOT_AVAILABLE:
844 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i);
845 break;
847 ASN1_FIXUP(compstk, compsp, buffer, i);
849 /* Fix length of stacked components */
850 while(compsp > 0) {
851 ASN1_FIXUP(compstk, compsp, buffer, i);
854 if (pri_call_apdu_queue(call, Q931_SETUP, buffer, i, NULL, NULL))
855 return -1;
857 return 0;
860 /* Send the rltThirdParty: Invoke */
861 int rlt_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2)
863 int i = 0;
864 unsigned char buffer[256];
865 struct rose_component *comp = NULL, *compstk[10];
866 const unsigned char rlt_3rd_pty = RLT_THIRD_PARTY;
867 q931_call *callwithid = NULL, *apdubearer = NULL;
868 int compsp = 0;
870 if (c2->transferable) {
871 apdubearer = c1;
872 callwithid = c2;
873 } else if (c1->transferable) {
874 apdubearer = c2;
875 callwithid = c1;
876 } else
877 return -1;
879 buffer[i++] = (Q932_PROTOCOL_ROSE);
880 buffer[i++] = (0x80 | RLT_SERVICE_ID); /* Service Identifier octet */
882 ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
883 ASN1_PUSH(compstk, compsp, comp);
885 /* Invoke ID is set to the operation ID */
886 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, rlt_3rd_pty);
888 /* Operation Tag */
889 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, rlt_3rd_pty);
891 /* Additional RLT invoke info - Octet 12 */
892 ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
893 ASN1_PUSH(compstk, compsp, comp);
895 ASN1_ADD_WORDCOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), buffer, i, callwithid->rlt_call_id & 0xFFFFFF); /* Length is 3 octets */
896 /* Reason for redirect - unused, set to 129 */
897 ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1), buffer, i, 0);
898 ASN1_FIXUP(compstk, compsp, buffer, i);
899 ASN1_FIXUP(compstk, compsp, buffer, i);
901 if (pri_call_apdu_queue(apdubearer, Q931_FACILITY, buffer, i, NULL, NULL))
902 return -1;
904 if (q931_facility(apdubearer->pri, apdubearer)) {
905 pri_message(pri, "Could not schedule facility message for call %d\n", apdubearer->cr);
906 return -1;
908 return 0;
911 static int add_dms100_transfer_ability_apdu(struct pri *pri, q931_call *c)
913 int i = 0;
914 unsigned char buffer[256];
915 struct rose_component *comp = NULL, *compstk[10];
916 const unsigned char rlt_op_ind = RLT_OPERATION_IND;
917 int compsp = 0;
919 buffer[i++] = (Q932_PROTOCOL_ROSE); /* Note to self: DON'T set the EXT bit */
920 buffer[i++] = (0x80 | RLT_SERVICE_ID); /* Service Identifier octet */
922 ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
923 ASN1_PUSH(compstk, compsp, comp);
925 /* Invoke ID is set to the operation ID */
926 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, rlt_op_ind);
928 /* Operation Tag - basically the same as the invoke ID tag */
929 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, rlt_op_ind);
930 ASN1_FIXUP(compstk, compsp, buffer, i);
932 if (pri_call_apdu_queue(c, Q931_SETUP, buffer, i, NULL, NULL))
933 return -1;
934 else
935 return 0;
938 /* Call deflection */
939 int add_call_deflection_facility_ie(struct pri *pri, q931_call *c, char *destination) {
940 int i = 0, j, compsp = 0;
941 struct rose_component *comp, *compstk[10];
942 unsigned char buffer[256];
944 buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_ROSE);
945 /* invoke */
946 ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
947 ASN1_PUSH(compstk, compsp, comp);
949 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));
950 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, ROSE_CALLDEFLECTION);
952 /* Argument sequence */
953 ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
954 ASN1_PUSH(compstk, compsp, comp);
956 /* arg.Address */
957 ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
958 ASN1_PUSH(compstk, compsp, comp);
960 #ifndef CD_UNLIKE_IN_CAPI
961 /* arg.address.PartyNumber */
964 j = asn1_string_encode((ASN1_CONTEXT_SPECIFIC|ASN1_TAG_0), &buffer[i], sizeof(buffer)-i, 20, destination, strlen(destination));
965 if (j<0) return -1;
966 i += j;
967 #else
968 /* using PublicPartyNumber instead */
969 ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE | ASN1_CONTEXT_SPECIFIC| ASN1_TAG_1), buffer, i);
970 ASN1_PUSH(compstk, compsp, comp);
971 /* ToN: unknown */
972 ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 0);
973 j = asn1_string_encode(0x80, &buffer[i], sizeof(buffer)-i, 20, destination, strlen(destination));
974 if(j<0) return -1;
975 i += j;
976 /* close PublicPartyNumber */
977 ASN1_FIXUP(compstk, compsp, buffer, i);
978 #endif
980 /* close Address */
981 ASN1_FIXUP(compstk, compsp, buffer, i);
983 /* add boolean */
984 ASN1_ADD_BYTECOMP(comp, ASN1_BOOLEAN, buffer, i, 0);
986 /* Fix length of stacked components */
987 while(compsp > 0) {
988 ASN1_FIXUP(compstk, compsp, buffer, i);
990 if (pri_call_apdu_queue(c, Q931_FACILITY, buffer, i, NULL, NULL))
991 return -1;
993 return 0;
996 /* Call rerouting */
997 int add_call_rerouting_facility_ie(struct pri *pri, q931_call *c, char *destination) {
998 int i = 0, j, compsp = 0;
999 struct rose_component *comp, *compstk[10];
1000 unsigned char buffer[256];
1001 unsigned char bcie[5] = { 0x04, 0x03, 0x90, 0x90, 0xA3 };
1003 buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_ROSE);
1004 /* invoke */
1005 ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
1006 ASN1_PUSH(compstk, compsp, comp);
1008 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));
1009 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, ROSE_CALLREROUTING);
1011 /* Argument sequence */
1012 ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
1013 ASN1_PUSH(compstk, compsp, comp);
1015 /* DIVERSION REASON (CFU) */
1016 ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 1);
1018 /* arg.Address */
1019 ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
1020 ASN1_PUSH(compstk, compsp, comp);
1022 j = asn1_string_encode(0x80, &buffer[i], sizeof(buffer)-i, 20, destination, strlen(destination));
1023 if(j<0) return -1;
1024 i += j;
1026 /* close Address */
1027 ASN1_FIXUP(compstk, compsp, buffer, i);
1029 /* add rerouting counter tag */
1030 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, 1);
1033 /* IE tag */
1034 j = asn1_string_encode(ASN1_APPLICATION, &buffer[i], sizeof(buffer)-i, 5, bcie, 5);
1035 if(j<0) return -1;
1036 i += j;
1038 /* last rerouting number */
1039 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
1040 ASN1_PUSH(compstk, compsp, comp);
1042 /* presented number unscreened */
1043 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0), buffer, i);
1044 ASN1_PUSH(compstk, compsp, comp);
1046 j = asn1_string_encode(0x80, &buffer[i], sizeof(buffer)-i, 20, c->callednum, strlen(c->callednum));
1047 if(j<0) return -1;
1048 i += j;
1050 /* close Address */
1051 ASN1_FIXUP(compstk, compsp, buffer, i);
1053 /* Fix length of stacked components */
1054 while(compsp > 0) {
1055 ASN1_FIXUP(compstk, compsp, buffer, i);
1057 if (pri_call_apdu_queue(c, Q931_FACILITY, buffer, i, NULL, NULL))
1058 return -1;
1060 return 0;
1063 /* Sending callername information functions */
1064 static int add_callername_facility_ies(struct pri *pri, q931_call *c, int cpe)
1066 int res = 0;
1067 int i = 0;
1068 unsigned char buffer[256];
1069 unsigned char namelen = 0;
1070 struct rose_component *comp = NULL, *compstk[10];
1071 int compsp = 0;
1072 int mymessage = 0;
1073 static unsigned char op_tag[] = {
1074 0x2a, /* informationFollowing 42 */
1075 0x86,
1076 0x48,
1077 0xce,
1078 0x15,
1079 0x00,
1080 0x04
1083 if (!strlen(c->callername)) {
1084 return -1;
1087 buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS);
1088 /* Interpretation component */
1090 if (pri->switchtype == PRI_SWITCH_QSIG) {
1091 ASN1_ADD_SIMPLE(comp, COMP_TYPE_NFE, buffer, i);
1092 ASN1_PUSH(compstk, compsp, comp);
1093 ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), buffer, i, 0);
1094 ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i, 0);
1095 ASN1_FIXUP(compstk, compsp, buffer, i);
1098 ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer, i, 0);
1100 ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
1101 ASN1_PUSH(compstk, compsp, comp);
1102 /* Invoke ID */
1103 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));
1105 /* Operation Tag */
1106 res = asn1_string_encode(ASN1_OBJECTIDENTIFIER, &buffer[i], sizeof(buffer)-i, sizeof(op_tag), op_tag, sizeof(op_tag));
1107 if (res < 0)
1108 return -1;
1109 i += res;
1111 ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 0);
1112 ASN1_FIXUP(compstk, compsp, buffer, i);
1114 if (!cpe) {
1115 if (pri_call_apdu_queue(c, Q931_SETUP, buffer, i, NULL, NULL))
1116 return -1;
1120 /* Now the APDU that contains the information that needs sent.
1121 * We can reuse the buffer since the queue function doesn't
1122 * need it. */
1124 i = 0;
1125 namelen = strlen(c->callername);
1126 if (namelen > 50) {
1127 namelen = 50; /* truncate the name */
1130 buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS);
1131 /* Interpretation component */
1133 if (pri->switchtype == PRI_SWITCH_QSIG) {
1134 ASN1_ADD_SIMPLE(comp, COMP_TYPE_NFE, buffer, i);
1135 ASN1_PUSH(compstk, compsp, comp);
1136 ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), buffer, i, 0);
1137 ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i, 0);
1138 ASN1_FIXUP(compstk, compsp, buffer, i);
1141 ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer, i, 0);
1143 ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
1144 ASN1_PUSH(compstk, compsp, comp);
1146 /* Invoke ID */
1147 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));
1149 /* Operation ID: Calling name */
1150 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, SS_CNID_CALLINGNAME);
1152 res = asn1_string_encode((ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), &buffer[i], sizeof(buffer)-i, 50, c->callername, namelen);
1153 if (res < 0)
1154 return -1;
1155 i += res;
1156 ASN1_FIXUP(compstk, compsp, buffer, i);
1158 if (cpe)
1159 mymessage = Q931_SETUP;
1160 else
1161 mymessage = Q931_FACILITY;
1163 if (pri_call_apdu_queue(c, mymessage, buffer, i, NULL, NULL))
1164 return -1;
1166 return 0;
1168 /* End Callername */
1170 /* MWI related encode and decode functions */
1171 static void mwi_activate_encode_cb(void *data)
1173 return;
1176 int mwi_message_send(struct pri* pri, q931_call *call, struct pri_sr *req, int activate)
1178 int i = 0;
1179 unsigned char buffer[255] = "";
1180 int destlen = strlen(req->called);
1181 struct rose_component *comp = NULL, *compstk[10];
1182 int compsp = 0;
1183 int res;
1185 if (destlen <= 0) {
1186 return -1;
1187 } else if (destlen > 20)
1188 destlen = 20; /* Destination number cannot be greater then 20 digits */
1190 buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_EXTENSIONS);
1191 /* Interpretation component */
1193 ASN1_ADD_SIMPLE(comp, COMP_TYPE_NFE, buffer, i);
1194 ASN1_PUSH(compstk, compsp, comp);
1195 ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), buffer, i, 0);
1196 ASN1_ADD_BYTECOMP(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_2), buffer, i, 0);
1197 ASN1_FIXUP(compstk, compsp, buffer, i);
1199 ASN1_ADD_BYTECOMP(comp, COMP_TYPE_INTERPRETATION, buffer, i, 0);
1201 ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
1202 ASN1_PUSH(compstk, compsp, comp);
1204 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));
1206 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, (activate) ? SS_MWI_ACTIVATE : SS_MWI_DEACTIVATE);
1207 ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
1208 ASN1_PUSH(compstk, compsp, comp);
1209 /* PartyNumber */
1210 res = asn1_string_encode((ASN1_CONTEXT_SPECIFIC | ASN1_TAG_0), &buffer[i], sizeof(buffer)-i, destlen, req->called, destlen);
1212 if (res < 0)
1213 return -1;
1214 i += res;
1216 /* Enumeration: basicService */
1217 ASN1_ADD_BYTECOMP(comp, ASN1_ENUMERATED, buffer, i, 1 /* contents: Voice */);
1218 ASN1_FIXUP(compstk, compsp, buffer, i);
1219 ASN1_FIXUP(compstk, compsp, buffer, i);
1221 return pri_call_apdu_queue(call, Q931_SETUP, buffer, i, mwi_activate_encode_cb, NULL);
1223 /* End MWI */
1225 /* EECT functions */
1226 int eect_initiate_transfer(struct pri *pri, q931_call *c1, q931_call *c2)
1228 int i = 0;
1229 int res = 0;
1230 unsigned char buffer[255] = "";
1231 short call_reference = c2->cr ^ 0x8000; /* Let's do the trickery to make sure the flag is correct */
1232 struct rose_component *comp = NULL, *compstk[10];
1233 int compsp = 0;
1234 static unsigned char op_tag[] = {
1235 0x2A,
1236 0x86,
1237 0x48,
1238 0xCE,
1239 0x15,
1240 0x00,
1241 0x08,
1244 buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_ROSE);
1246 ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
1247 ASN1_PUSH(compstk, compsp, comp);
1249 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, get_invokeid(pri));
1251 res = asn1_string_encode(ASN1_OBJECTIDENTIFIER, &buffer[i], sizeof(buffer)-i, sizeof(op_tag), op_tag, sizeof(op_tag));
1252 if (res < 0)
1253 return -1;
1254 i += res;
1256 ASN1_ADD_SIMPLE(comp, (ASN1_SEQUENCE | ASN1_CONSTRUCTOR), buffer, i);
1257 ASN1_PUSH(compstk, compsp, comp);
1258 ASN1_ADD_WORDCOMP(comp, ASN1_INTEGER, buffer, i, call_reference);
1259 ASN1_FIXUP(compstk, compsp, buffer, i);
1260 ASN1_FIXUP(compstk, compsp, buffer, i);
1262 res = pri_call_apdu_queue(c1, Q931_FACILITY, buffer, i, NULL, NULL);
1263 if (res) {
1264 pri_message(pri, "Could not queue APDU in facility message\n");
1265 return -1;
1268 /* Remember that if we queue a facility IE for a facility message we
1269 * have to explicitly send the facility message ourselves */
1271 res = q931_facility(c1->pri, c1);
1272 if (res) {
1273 pri_message(pri, "Could not schedule facility message for call %d\n", c1->cr);
1274 return -1;
1277 return 0;
1279 /* End EECT */
1281 /* AOC */
1282 static int aoc_aoce_charging_request_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
1284 int chargingcase = -1;
1285 unsigned char *vdata = data;
1286 struct rose_component *comp = NULL;
1287 int pos1 = 0;
1289 if (pri->debug & PRI_DEBUG_AOC)
1290 dump_apdu (pri, data, len);
1292 do {
1293 GET_COMPONENT(comp, pos1, vdata, len);
1294 CHECK_COMPONENT(comp, ASN1_ENUMERATED, "!! Invalid AOC Charging Request argument. Expected Enumerated (0x0A) but Received 0x%02X\n");
1295 ASN1_GET_INTEGER(comp, chargingcase);
1296 if (chargingcase >= 0 && chargingcase <= 2) {
1297 // if (pri->debug & PRI_DEBUG_APDU)
1298 pri_message(pri, "Channel %d/%d, Call %d - received AOC charging request - charging case: %i\n",
1299 call->ds1no, call->channelno, call->cr, chargingcase);
1300 } else {
1301 pri_message(pri, "!! unkown AOC ChargingCase: 0x%02X", chargingcase);
1302 chargingcase = -1;
1304 NEXT_COMPONENT(comp, pos1);
1305 } while (pos1 < len);
1306 if (pos1 < len) {
1307 pri_message(pri, "!! Only reached position %i in %i bytes long AOC-E structure:", pos1, len );
1308 dump_apdu (pri, data, len);
1309 return -1; /* Aborted before */
1311 return 0;
1315 static int aoc_aoce_charging_unit_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
1317 long chargingunits = 0, chargetype = -1, temp, chargeIdentifier = -1;
1318 unsigned char *vdata = data;
1319 struct rose_component *comp1 = NULL, *comp2 = NULL, *comp3 = NULL;
1320 int pos1 = 0, pos2, pos3, sublen2, sublen3;
1321 struct addressingdataelements_presentednumberunscreened chargednr;
1323 if (pri->debug & PRI_DEBUG_AOC)
1324 dump_apdu (pri, data, len);
1326 do {
1327 GET_COMPONENT(comp1, pos1, vdata, len); /* AOCEChargingUnitInfo */
1328 CHECK_COMPONENT(comp1, ASN1_SEQUENCE, "!! Invalid AOC-E Charging Unit argument. Expected Sequence (0x30) but Received 0x%02X\n");
1329 SUB_COMPONENT(comp1, pos1);
1330 GET_COMPONENT(comp1, pos1, vdata, len);
1331 switch (comp1->type) {
1332 case (ASN1_SEQUENCE | ASN1_CONSTRUCTOR): /* specificChargingUnits */
1333 sublen2 = comp1->len;
1334 pos2 = pos1;
1335 comp2 = comp1;
1336 SUB_COMPONENT(comp2, pos2);
1337 do {
1338 GET_COMPONENT(comp2, pos2, vdata, len);
1339 switch (comp2->type) {
1340 case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1): /* RecordedUnitsList (0xA1) */
1341 SUB_COMPONENT(comp2, pos2);
1342 GET_COMPONENT(comp2, pos2, vdata, len);
1343 CHECK_COMPONENT(comp2, ASN1_SEQUENCE, "!! Invalid AOC-E Charging Unit argument. Expected Sequence (0x30) but received 0x02%X\n"); /* RecordedUnits */
1344 sublen3 = pos2 + comp2->len;
1345 pos3 = pos2;
1346 comp3 = comp2;
1347 SUB_COMPONENT(comp3, pos3);
1348 do {
1349 GET_COMPONENT(comp3, pos3, vdata, len);
1350 switch (comp3->type) {
1351 case ASN1_INTEGER: /* numberOfUnits */
1352 ASN1_GET_INTEGER(comp3, temp);
1353 chargingunits += temp;
1354 case ASN1_NULL: /* notAvailable */
1355 break;
1356 default:
1357 pri_message(pri, "!! Don't know how to handle 0x%02X in AOC-E RecordedUnits\n", comp3->type);
1359 NEXT_COMPONENT(comp3, pos3);
1360 } while (pos3 < sublen3);
1361 if (pri->debug & PRI_DEBUG_AOC)
1362 pri_message(pri, "Channel %d/%d, Call %d - received AOC-E charging: %i unit%s\n",
1363 call->ds1no, call->channelno, call->cr, chargingunits, (chargingunits == 1) ? "" : "s");
1364 break;
1365 case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_2): /* AOCEBillingID (0xA2) */
1366 SUB_COMPONENT(comp2, pos2);
1367 GET_COMPONENT(comp2, pos2, vdata, len);
1368 ASN1_GET_INTEGER(comp2, chargetype);
1369 pri_message(pri, "!! not handled: Channel %d/%d, Call %d - received AOC-E billing ID: %i\n",
1370 call->ds1no, call->channelno, call->cr, chargetype);
1371 break;
1372 default:
1373 pri_message(pri, "!! Don't know how to handle 0x%02X in AOC-E RecordedUnitsList\n", comp2->type);
1375 NEXT_COMPONENT(comp2, pos2);
1376 } while (pos2 < sublen2);
1377 break;
1378 case (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1): /* freeOfCharge (0x81) */
1379 if (pri->debug & PRI_DEBUG_AOC)
1380 pri_message(pri, "Channel %d/%d, Call %d - received AOC-E free of charge\n", call->ds1no, call->channelno, call->cr);
1381 chargingunits = 0;
1382 break;
1383 default:
1384 pri_message(pri, "!! Invalid AOC-E specificChargingUnits. Expected Sequence (0x30) or Object Identifier (0x81/0x01) but received 0x%02X\n", comp1->type);
1386 NEXT_COMPONENT(comp1, pos1);
1387 GET_COMPONENT(comp1, pos1, vdata, len); /* get optional chargingAssociation. will 'break' when reached end of structure */
1388 switch (comp1->type) {
1389 /* TODO: charged number is untested - please report! */
1390 case (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_0): /* chargedNumber (0xA0) */
1391 if(rose_presented_number_unscreened_decode(pri, call, comp1->data, comp1->len, &chargednr) != 0)
1392 return -1;
1393 pri_message(pri, "!! not handled: Received ChargedNr '%s' \n", chargednr.partyaddress);
1394 pri_message(pri, " ton = %d, pres = %d, npi = %d\n", chargednr.ton, chargednr.pres, chargednr.npi);
1395 break;
1396 case ASN1_INTEGER:
1397 ASN1_GET_INTEGER(comp1, chargeIdentifier);
1398 break;
1399 default:
1400 pri_message(pri, "!! Invalid AOC-E chargingAssociation. Expected Object Identifier (0xA0) or Integer (0x02) but received 0x%02X\n", comp1->type);
1402 NEXT_COMPONENT(comp1, pos1);
1403 } while (pos1 < len);
1405 if (pos1 < len) {
1406 pri_message(pri, "!! Only reached position %i in %i bytes long AOC-E structure:", pos1, len );
1407 dump_apdu (pri, data, len);
1408 return -1; /* oops - aborted before */
1410 call->aoc_units = chargingunits;
1412 return 0;
1415 int aoc_aoce_charging_unit_encode(struct pri *pri, q931_call *c, long chargedunits, int msgtype)
1417 /* sample data: [ 91 a1 12 02 02 3a 78 02 01 24 30 09 30 07 a1 05 30 03 02 01 01 ] */
1418 int i = 0, res = 0, compsp = 0;
1419 unsigned char buffer[255] = "";
1420 struct rose_component *comp = NULL, *compstk[10];
1422 /* ROSE protocol (0x91)*/
1423 buffer[i++] = (ASN1_CONTEXT_SPECIFIC | Q932_PROTOCOL_ROSE);
1425 /* ROSE Component (0xA1,len)*/
1426 ASN1_ADD_SIMPLE(comp, COMP_TYPE_INVOKE, buffer, i);
1427 ASN1_PUSH(compstk, compsp, comp);
1429 /* ROSE invokeId component (0x02,len,id)*/
1430 ASN1_ADD_WORDCOMP(comp, INVOKE_IDENTIFIER, buffer, i, ++pri->last_invoke);
1432 /* ROSE operationId component (0x02,0x01,0x24)*/
1433 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, ROSE_AOC_AOCE_CHARGING_UNIT);
1435 /* AOCEChargingUnitInfo (0x30,len) */
1436 ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
1437 ASN1_PUSH(compstk, compsp, comp);
1439 if (chargedunits > 0) {
1440 /* SpecificChargingUnits (0x30,len) */
1441 ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
1442 ASN1_PUSH(compstk, compsp, comp);
1444 /* RecordedUnitsList (0xA1,len) */
1445 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTOR | ASN1_TAG_1), buffer, i);
1446 ASN1_PUSH(compstk, compsp, comp);
1448 /* RecordedUnits (0x30,len) */
1449 ASN1_ADD_SIMPLE(comp, (ASN1_CONSTRUCTOR | ASN1_SEQUENCE), buffer, i);
1450 ASN1_PUSH(compstk, compsp, comp);
1452 /* NumberOfUnits (0x02,len,charge) */
1453 ASN1_ADD_BYTECOMP(comp, ASN1_INTEGER, buffer, i, chargedunits);
1455 ASN1_FIXUP(compstk, compsp, buffer, i);
1456 ASN1_FIXUP(compstk, compsp, buffer, i);
1457 ASN1_FIXUP(compstk, compsp, buffer, i);
1458 } else {
1459 /* freeOfCharge (0x81,0) */
1460 ASN1_ADD_SIMPLE(comp, (ASN1_CONTEXT_SPECIFIC | ASN1_TAG_1), buffer, i);
1462 ASN1_FIXUP(compstk, compsp, buffer, i);
1463 ASN1_FIXUP(compstk, compsp, buffer, i);
1465 if (pri->debug & PRI_DEBUG_AOC)
1466 dump_apdu (pri, buffer, i);
1468 /* code below is untested */
1469 res = pri_call_apdu_queue(c, msgtype, buffer, i, NULL, NULL);
1470 if (res) {
1471 pri_message(pri, "Could not queue APDU in facility message\n");
1472 return -1;
1475 if (msgtype == Q931_FACILITY) {
1476 /* Remember that if we queue a facility IE for a facility message we
1477 * have to explicitly send the facility message ourselves */
1478 res = q931_facility(c->pri, c);
1479 if (res) {
1480 pri_message(pri, "Could not schedule facility message for call %d\n", c->cr);
1481 return -1;
1484 return 0;
1486 /* End AOC */
1488 int rose_reject_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
1490 int i = 0;
1491 int problemtag = -1;
1492 int problem = -1;
1493 int invokeidvalue = -1;
1494 unsigned char *vdata = data;
1495 struct rose_component *comp = NULL;
1496 char *problemtagstr, *problemstr;
1498 do {
1499 /* Invoke ID stuff */
1500 GET_COMPONENT(comp, i, vdata, len);
1501 CHECK_COMPONENT(comp, INVOKE_IDENTIFIER, "Don't know what to do if first ROSE component is of type 0x%x\n");
1502 ASN1_GET_INTEGER(comp, invokeidvalue);
1503 NEXT_COMPONENT(comp, i);
1505 GET_COMPONENT(comp, i, vdata, len);
1506 problemtag = comp->type;
1507 problem = comp->data[0];
1509 if (pri->switchtype == PRI_SWITCH_DMS100) {
1510 switch (problemtag) {
1511 case 0x80:
1512 problemtagstr = "General problem";
1513 break;
1514 case 0x81:
1515 problemtagstr = "Invoke problem";
1516 break;
1517 case 0x82:
1518 problemtagstr = "Return result problem";
1519 break;
1520 case 0x83:
1521 problemtagstr = "Return error problem";
1522 break;
1523 default:
1524 problemtagstr = "Unknown";
1527 switch (problem) {
1528 case 0x00:
1529 problemstr = "Unrecognized component";
1530 break;
1531 case 0x01:
1532 problemstr = "Mistyped component";
1533 break;
1534 case 0x02:
1535 problemstr = "Badly structured component";
1536 break;
1537 default:
1538 problemstr = "Unknown";
1541 pri_error(pri, "ROSE REJECT:\n");
1542 pri_error(pri, "\tINVOKE ID: 0x%X\n", invokeidvalue);
1543 pri_error(pri, "\tPROBLEM TYPE: %s (0x%x)\n", problemtagstr, problemtag);
1544 pri_error(pri, "\tPROBLEM: %s (0x%x)\n", problemstr, problem);
1546 return 0;
1547 } else {
1548 pri_message(pri, "Unable to handle return result on switchtype %d!\n", pri->switchtype);
1549 return -1;
1552 } while(0);
1554 return -1;
1556 int rose_return_error_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
1558 int i = 0;
1559 int errorvalue = -1;
1560 int invokeidvalue = -1;
1561 unsigned char *vdata = data;
1562 struct rose_component *comp = NULL;
1563 char *invokeidstr, *errorstr;
1565 do {
1566 /* Invoke ID stuff */
1567 GET_COMPONENT(comp, i, vdata, len);
1568 CHECK_COMPONENT(comp, INVOKE_IDENTIFIER, "Don't know what to do if first ROSE component is of type 0x%x\n");
1569 ASN1_GET_INTEGER(comp, invokeidvalue);
1570 NEXT_COMPONENT(comp, i);
1572 GET_COMPONENT(comp, i, vdata, len);
1573 CHECK_COMPONENT(comp, ASN1_INTEGER, "Don't know what to do if second component in return error is 0x%x\n");
1574 ASN1_GET_INTEGER(comp, errorvalue);
1576 if (pri->switchtype == PRI_SWITCH_DMS100) {
1577 switch (invokeidvalue) {
1578 case RLT_OPERATION_IND:
1579 invokeidstr = "RLT_OPERATION_IND";
1580 break;
1581 case RLT_THIRD_PARTY:
1582 invokeidstr = "RLT_THIRD_PARTY";
1583 break;
1584 default:
1585 invokeidstr = "Unknown";
1588 switch (errorvalue) {
1589 case 0x10:
1590 errorstr = "RLT Bridge Fail";
1591 break;
1592 case 0x11:
1593 errorstr = "RLT Call ID Not Found";
1594 break;
1595 case 0x12:
1596 errorstr = "RLT Not Allowed";
1597 break;
1598 case 0x13:
1599 errorstr = "RLT Switch Equip Congs";
1600 break;
1601 default:
1602 errorstr = "Unknown";
1605 pri_error(pri, "ROSE RETURN ERROR:\n");
1606 pri_error(pri, "\tOPERATION: %s\n", invokeidstr);
1607 pri_error(pri, "\tERROR: %s\n", errorstr);
1609 return 0;
1610 } else {
1611 pri_message(pri, "Unable to handle return result on switchtype %d!\n", pri->switchtype);
1612 return -1;
1615 } while(0);
1617 return -1;
1620 int rose_return_result_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
1622 int i = 0;
1623 int operationidvalue = -1;
1624 int invokeidvalue = -1;
1625 unsigned char *vdata = data;
1626 struct rose_component *comp = NULL;
1628 do {
1629 /* Invoke ID stuff */
1630 GET_COMPONENT(comp, i, vdata, len);
1631 CHECK_COMPONENT(comp, INVOKE_IDENTIFIER, "Don't know what to do if first ROSE component is of type 0x%x\n");
1632 ASN1_GET_INTEGER(comp, invokeidvalue);
1633 NEXT_COMPONENT(comp, i);
1635 if (pri->switchtype == PRI_SWITCH_DMS100) {
1636 switch (invokeidvalue) {
1637 case RLT_THIRD_PARTY:
1638 if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, "Successfully completed RLT transfer!\n");
1639 return 0;
1640 case RLT_OPERATION_IND:
1641 if (pri->debug & PRI_DEBUG_APDU) pri_message(pri, "Received RLT_OPERATION_IND\n");
1642 /* Have to take out the rlt_call_id */
1643 GET_COMPONENT(comp, i, vdata, len);
1644 CHECK_COMPONENT(comp, ASN1_SEQUENCE, "Protocol error detected in parsing RLT_OPERATION_IND return result!\n");
1646 /* Traverse the contents of this sequence */
1647 /* First is the Operation Value */
1648 SUB_COMPONENT(comp, i);
1649 GET_COMPONENT(comp, i, vdata, len);
1650 CHECK_COMPONENT(comp, ASN1_INTEGER, "RLT_OPERATION_IND should be of type ASN1_INTEGER!\n");
1651 ASN1_GET_INTEGER(comp, operationidvalue);
1653 if (operationidvalue != RLT_OPERATION_IND) {
1654 pri_message(pri, "Invalid Operation ID value (0x%x) in return result!\n", operationidvalue);
1655 return -1;
1658 /* Next is the Call ID */
1659 NEXT_COMPONENT(comp, i);
1660 GET_COMPONENT(comp, i, vdata, len);
1661 CHECK_COMPONENT(comp, ASN1_TAG_0, "Error check failed on Call ID!\n");
1662 ASN1_GET_INTEGER(comp, call->rlt_call_id);
1663 /* We have enough data to transfer the call */
1664 call->transferable = 1;
1666 return 0;
1668 default:
1669 pri_message(pri, "Could not parse invoke of type 0x%x!\n", invokeidvalue);
1670 return -1;
1672 } else {
1673 pri_message(pri, "Unable to handle return result on switchtype %d!\n", pri->switchtype);
1674 return -1;
1677 } while(0);
1679 return -1;
1682 int rose_invoke_decode(struct pri *pri, q931_call *call, unsigned char *data, int len)
1684 int i = 0;
1685 int operation_tag;
1686 unsigned char *vdata = data;
1687 struct rose_component *comp = NULL, *invokeid = NULL, *operationid = NULL;
1689 do {
1690 /* Invoke ID stuff */
1691 GET_COMPONENT(comp, i, vdata, len);
1692 #if 0
1693 CHECK_COMPONENT(comp, INVOKE_IDENTIFIER, "Don't know what to do if first ROSE component is of type 0x%x\n");
1694 #endif
1695 invokeid = comp;
1696 NEXT_COMPONENT(comp, i);
1698 /* Operation Tag */
1699 GET_COMPONENT(comp, i, vdata, len);
1700 #if 0
1701 CHECK_COMPONENT(comp, ASN1_INTEGER, "Don't know what to do if second ROSE component is of type 0x%x\n");
1702 #endif
1703 operationid = comp;
1704 ASN1_GET_INTEGER(comp, operation_tag);
1705 NEXT_COMPONENT(comp, i);
1707 /* No argument - return with error */
1708 if ((i >= len) && (operation_tag != ROSE_EXPLICIT_CALL_TRANSFER))
1709 return -1;
1711 if (operation_tag != ROSE_EXPLICIT_CALL_TRANSFER) {
1712 /* Arguement Tag */
1713 GET_COMPONENT(comp, i, vdata, len);
1714 if (!comp->type)
1715 return -1;
1718 if (pri->debug & PRI_DEBUG_APDU)
1719 pri_message(pri, " [ Handling operation %d ]\n", operation_tag);
1720 switch (operation_tag) {
1721 case SS_CNID_CALLINGNAME:
1722 if (pri->debug & PRI_DEBUG_APDU)
1723 pri_message(pri, " Handle Name display operation\n");
1724 switch (comp->type) {
1725 case ROSE_NAME_PRESENTATION_ALLOWED_SIMPLE:
1726 memcpy(call->callername, comp->data, comp->len);
1727 call->callername[comp->len] = 0;
1728 if (pri->debug & PRI_DEBUG_APDU)
1729 pri_message(pri, " Received caller name '%s'\n", call->callername);
1730 return 0;
1731 default:
1732 if (pri->debug & PRI_DEBUG_APDU)
1733 pri_message(pri, "Do not handle argument of type 0x%X\n", comp->type);
1734 return -1;
1736 break;
1737 case ROSE_DIVERTING_LEG_INFORMATION2:
1738 if (pri->debug & PRI_DEBUG_APDU)
1739 pri_message(pri, " Handle DivertingLegInformation2\n");
1740 if (comp->type != (ASN1_CONSTRUCTOR | ASN1_SEQUENCE)) { /* Constructed Sequence */
1741 pri_message(pri, "Invalid DivertingLegInformation2Type argument\n");
1742 return -1;
1744 return rose_diverting_leg_information2_decode(pri, call, comp->data, comp->len);
1745 case ROSE_AOC_NO_CHARGING_INFO_AVAILABLE:
1746 if (pri->debug & PRI_DEBUG_APDU) {
1747 pri_message(pri, "ROSE %i: AOC No Charging Info Available - not handled!", operation_tag);
1748 dump_apdu (pri, comp->data, comp->len);
1750 return -1;
1751 case ROSE_AOC_CHARGING_REQUEST:
1752 return aoc_aoce_charging_request_decode(pri, call, (u_int8_t *)comp, comp->len + 2);
1753 case ROSE_AOC_AOCS_CURRENCY:
1754 if (pri->debug & PRI_DEBUG_APDU) {
1755 pri_message(pri, "ROSE %i: AOC-S Currency - not handled!", operation_tag);
1756 dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
1758 return -1;
1759 case ROSE_AOC_AOCS_SPECIAL_ARR:
1760 if (pri->debug & PRI_DEBUG_APDU) {
1761 pri_message(pri, "ROSE %i: AOC-S Special Array - not handled!", operation_tag);
1762 dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
1764 return -1;
1765 case ROSE_AOC_AOCD_CURRENCY:
1766 if (pri->debug & PRI_DEBUG_APDU) {
1767 pri_message(pri, "ROSE %i: AOC-D Currency - not handled!", operation_tag);
1768 dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
1770 return -1;
1771 case ROSE_AOC_AOCD_CHARGING_UNIT:
1772 // return aoc_aoce_charging_unit_decode(pri, call, (u_int8_t *)comp, comp->len + 2);
1773 if (pri->debug & PRI_DEBUG_APDU) {
1774 pri_message(pri, "ROSE %i: AOC-D Charging Unit - not handled!", operation_tag);
1775 dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
1777 return -1;
1778 case ROSE_AOC_AOCE_CURRENCY:
1779 if (pri->debug & PRI_DEBUG_APDU) {
1780 pri_message(pri, "ROSE %i: AOC-E Currency - not handled!", operation_tag);
1781 dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
1783 return -1;
1784 case ROSE_AOC_AOCE_CHARGING_UNIT:
1785 return aoc_aoce_charging_unit_decode(pri, call, (u_int8_t *)comp, comp->len + 2);
1786 if (0) { /* the following function is currently not used - just to make the compiler happy */
1787 aoc_aoce_charging_unit_encode(pri, call, call->aoc_units, 1); /* use this function to forward the aoc-e on a bridged channel */
1788 return 0;
1790 case ROSE_AOC_IDENTIFICATION_OF_CHARGE:
1791 if (pri->debug & PRI_DEBUG_APDU) {
1792 pri_message(pri, "ROSE %i: AOC Identification Of Charge - not handled!", operation_tag);
1793 dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
1795 return -1;
1796 case ROSE_CALLDEFLECTION:
1797 call->facility = operation_tag;
1798 return rose_cd_destination_decode(pri, call, (u_int8_t *)comp, comp->len + 2);
1799 return -1;
1800 case ROSE_EXPLICIT_CALL_TRANSFER:
1801 call->facility = operation_tag;
1802 if (pri->debug & PRI_DEBUG_APDU) {
1803 pri_message(pri, "ROSE %i: received ECT execute!", operation_tag);
1805 return 0;
1806 case ROSE_MALICIOUS_CID:
1807 // call->facility = operation_tag;
1808 // if (pri->debug & PRI_DEBUG_APDU) {
1809 pri_message(pri, "ROSE %i: received MALICIOUS CID!", operation_tag);
1810 // }
1811 return 0;
1812 default:
1813 if (pri->debug & PRI_DEBUG_APDU) {
1814 pri_message(pri, "!! Unable to handle ROSE operation %d", operation_tag);
1815 dump_apdu (pri, (u_int8_t *)comp, comp->len + 2);
1817 return -1;
1819 } while(0);
1821 return -1;
1824 int pri_call_apdu_queue(q931_call *call, int messagetype, void *apdu, int apdu_len, void (*function)(void *data), void *data)
1826 struct apdu_event *cur = NULL;
1827 struct apdu_event *new_event = NULL;
1829 if (!call || !messagetype || !apdu || (apdu_len < 1) || (apdu_len > 255))
1830 return -1;
1832 new_event = malloc(sizeof(struct apdu_event));
1834 if (new_event) {
1835 memset(new_event, 0, sizeof(struct apdu_event));
1836 new_event->message = messagetype;
1837 new_event->callback = function;
1838 new_event->data = data;
1839 memcpy(new_event->apdu, apdu, apdu_len);
1840 new_event->apdu_len = apdu_len;
1841 } else {
1842 pri_error(call->pri, "!! Malloc failed!\n");
1843 return -1;
1846 if (call->apdus) {
1847 cur = call->apdus;
1848 while (cur->next) {
1849 cur = cur->next;
1851 cur->next = new_event;
1852 } else
1853 call->apdus = new_event;
1855 return 0;
1858 int pri_call_apdu_queue_cleanup(q931_call *call)
1860 struct apdu_event *cur_event = NULL, *free_event = NULL;
1862 if (call && call->apdus) {
1863 cur_event = call->apdus;
1864 while (cur_event) {
1865 /* TODO: callbacks, some way of giving return res on status of apdu */
1866 free_event = cur_event;
1867 cur_event = cur_event->next;
1868 free(free_event);
1870 call->apdus = NULL;
1873 return 0;
1876 int pri_call_add_standard_apdus(struct pri *pri, q931_call *call)
1878 if (!pri->sendfacility)
1879 return 0;
1881 if (pri->switchtype == PRI_SWITCH_QSIG) { /* For Q.SIG it does network and cpe operations */
1882 if (call->redirectingnum[0])
1883 rose_diverting_leg_information2_encode(pri, call);
1884 add_callername_facility_ies(pri, call, 1);
1885 return 0;
1888 #if 0
1889 if (pri->localtype == PRI_NETWORK) {
1890 switch (pri->switchtype) {
1891 case PRI_SWITCH_NI2:
1892 add_callername_facility_ies(pri, call, 0);
1893 break;
1894 default:
1895 break;
1897 return 0;
1898 } else if (pri->localtype == PRI_CPE) {
1899 switch (pri->switchtype) {
1900 case PRI_SWITCH_NI2:
1901 add_callername_facility_ies(pri, call, 1);
1902 break;
1903 default:
1904 break;
1906 return 0;
1908 #else
1909 if (pri->switchtype == PRI_SWITCH_NI2)
1910 add_callername_facility_ies(pri, call, (pri->localtype == PRI_CPE));
1911 #endif
1913 if ((pri->switchtype == PRI_SWITCH_DMS100) && (pri->localtype == PRI_CPE)) {
1914 add_dms100_transfer_ability_apdu(pri, call);
1919 return 0;