OpenSS7 SS7 for the Common Man |
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |
||||||||||||||||||||||||||
Home | Overview | Status | News | Documentation | Resources | About | |||||||||||||||||||||
File /code/strss7/test/zurich01/test-call2.c#ident "@(#) $RCSfile: test-call2.c,v $ $Name: $($Revision: 0.8.2.1 $) $Date: 2003/02/14 13:04:37 $" static char const ident[] = "$RCSfile: test-call2.c,v $ $Name: $($Revision: 0.8.2.1 $) $Date: 2003/02/14 13:04:37 $"; #include <stropts.h> #include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <signal.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/poll.h> #include <sys/time.h> #include <sys/ioctl.h> #include <sys/stat.h> #include <fcntl.h> #include <getopt.h> #include <string.h> #include <time.h> #include <ss7/lmi.h> #include <ss7/sdli.h> #include <ss7/sdli_ioctl.h> #include <ss7/sdti.h> #include <ss7/sli.h> static int state = 0; static unsigned char called[64] = "491755915022"; static unsigned char calling[64] = "6677111222"; static uint my_cic = 1; static uint my_dpc = 0x11ae; static uint my_opc = 0x11d8; unsigned char newmail[32000] = { 0, }; static int offset = 0; static int writeit = 0; static int loopback = 0; static int swap_bits = 0; static void usage(int argc, char **argv) { fprintf(stderr, "\n\ Usage: %s [options]\n\ -h, --help\n\ prints this usage information and exits\n\ -d, --called number (max 64 digits) (default: %s)\n\ number specifies the called party number\n\ -g, --calling number (max 64 digits) (default: %s)\n\ number specifies the calling party number\n\ -c, --cic cic (default: %d)\n\ cic specified the circuit identification code to use\n\ -n, --nocall\n\ don't generate a call\n\ -t, --t1\n\ use t1 parameters instead of e1\n\ -s, --swap\n\ swap bits\n\ \n", argv[0], called, calling, my_cic); }; static void help(int argc, char **argv) { usage(argc, argv); fprintf(stderr, "\ This program opens the MTP mini-mux and initiates a telephone call to the\n\ designated cic using the called and calling party numbers supplied.\n\ \n"); }; int fd; int cfd; #define BUFSIZE 300 static char cbuf[BUFSIZE]; static char dbuf[BUFSIZE]; struct strioctl ctl; struct strbuf ctrl = { sizeof(*cbuf), 0, cbuf }; struct strbuf data = { sizeof(*dbuf), 0, dbuf }; union LMI_primitives *m = (union LMI_primitives *) cbuf; union SL_primitives *p = (union SL_primitives *) cbuf; union SDL_primitives *d = (union SDL_primitives *) cbuf; typedef unsigned short ppa_t; ppa_t ppa; sdl_config_t sdl_conf = { ifflags:0, iftype:SDL_TYPE_DS0, ifrate:64000, ifgtype:SDL_GTYPE_NONE, ifgrate:2048000, ifmode:SDL_MODE_PEER, ifgmode:SDL_GMODE_NONE, ifgcrc:SDL_GCRC_CRC5, /* E1 only */ ifclock:SDL_CLOCK_SLAVE, ifcoding:SDL_CODING_HDB3, /* E1 only */ ifframing:SDL_FRAMING_CCS, /* E1 only */ ifleads:0, ifalarms:0, ifrxlevel:0, iftxlevel:0, ifsync:0, ifsyncsrc:{1, 2, 0, 0} }; static int timer_timeout = 0; static void timer_handler(int signum) { if (signum == SIGALRM) timer_timeout = 1; return; } static int timer_sethandler(void) { sigset_t mask; struct sigaction act; act.sa_handler = timer_handler; act.sa_flags = SA_RESTART | SA_ONESHOT; act.sa_restorer = NULL; sigemptyset(&act.sa_mask); if (sigaction(SIGALRM, &act, NULL)) return -1; sigemptyset(&mask); sigaddset(&mask, SIGALRM); sigprocmask(SIG_UNBLOCK, &mask, NULL); return 0; } /* * Start an interval timer as the overall test timer. */ static inline int start_timer(long duration) { struct itimerval setting = { {0, 0}, {duration / 1000, (duration % 1000) * 1000} }; if (timer_sethandler()) return -1; if (setitimer(ITIMER_REAL, &setting, NULL)) return -1; timer_timeout = 0; return 0; } static int stop_timer(void) { sigset_t mask; struct sigaction act; act.sa_handler = SIG_DFL; act.sa_flags = 0; act.sa_restorer = NULL; sigemptyset(&act.sa_mask); if (sigaction(SIGALRM, &act, NULL)) return -1; timer_timeout = 0; sigemptyset(&mask); sigaddset(&mask, SIGALRM); sigprocmask(SIG_BLOCK, &mask, NULL); return 0; } #define TIMEOUT (-2) static int decode_msg(void) { if (ctrl.len >= sizeof(ulong)) return *(ulong *) cbuf; return -1; } static int decode_data(void) { if (data.len > 0) return SL_PDU_IND; return -1; } static int wait_event(int wait) { while (1) { struct pollfd pfd[] = { {fd, POLLIN | POLLPRI, 0}, {cfd, POLLIN | POLLPRI | (writeit ? POLLOUT : 0), 0} }; if (timer_timeout) { timer_timeout = 0; return TIMEOUT; } switch (poll(pfd, 2, wait)) { case -1: if (errno == EAGAIN || errno == EINTR || errno == ERESTART) continue; perror(__FUNCTION__); exit(1); case 0: return (0); case 1: case 2: if (pfd[0].revents & (POLLIN | POLLPRI)) { int ret, flags = 0; ctrl.maxlen = BUFSIZE; ctrl.len = 0; ctrl.buf = cbuf; data.maxlen = BUFSIZE; data.len = 0; data.buf = dbuf; if (getmsg(fd, &ctrl, &data, &flags) < 0) { perror(__FUNCTION__); exit(1); } if (ctrl.len > 0 && (ret = decode_msg()) != -1) return ret; if (data.len > 0 && (ret = decode_data()) != -1) return ret; } if (pfd[1].revents & (POLLIN | POLLPRI)) { int ret, flags = 0; ctrl.maxlen = BUFSIZE; ctrl.len = 0; ctrl.buf = cbuf; data.maxlen = BUFSIZE; data.len = 0; data.buf = dbuf; if (getmsg(cfd, &ctrl, &data, &flags) < 0) { perror(__FUNCTION__); exit(1); } if (ctrl.len > 0 && (ret = decode_msg()) != -1) return ret; if (data.len > 0 && loopback) { if (putmsg(cfd, NULL, &data, 0) < 0) { perror(__FUNCTION__); } } } if ((pfd[1].revents & POLLOUT) && writeit) { data.maxlen = BUFSIZE; data.len = 64; data.buf = newmail + offset; if ((offset += 64) >= 32000) { printf("Wrote pattern once.\n"); offset = 0; } if (putmsg(cfd, NULL, &data, 0) < 0) { perror(__FUNCTION__); } } default: break; } } } static int get_event(void) { return wait_event(-1); } static void show_time(void) { time_t t; time(&t); printf("\n%s", ctime(&t)); } #define ISUP_MT_IAM 1 /* 0x01 - 0b00000001 - Initial address */ #define ISUP_MT_SAM 2 /* 0x02 - 0b00000010 - Subsequent address */ #define ISUP_MT_INR 3 /* 0x03 - 0b00000011 - Information request */ #define ISUP_MT_INF 4 /* 0x04 - 0b00000100 - Information */ #define ISUP_MT_COT 5 /* 0x05 - 0b00000101 - Continuity */ #define ISUP_MT_ACM 6 /* 0x06 - 0b00000110 - Address complete */ #define ISUP_MT_CON 7 /* 0x07 - 0b00000111 - Connect (not old ANSI) */ #define ISUP_MT_FOT 8 /* 0x08 - 0b00001000 - Forward transfer */ #define ISUP_MT_ANM 9 /* 0x09 - 0b00001001 - Answer */ #define ISUP_MT_REL 12 /* 0x0c - 0b00001100 - Release */ #define ISUP_MT_SUS 13 /* 0x0d - 0b00001101 - Suspend */ #define ISUP_MT_RES 14 /* 0x0e - 0b00001110 - Resume */ #define ISUP_MT_RLC 16 /* 0x10 - 0b00010000 - Release complete */ #define ISUP_MT_CCR 17 /* 0x11 - 0b00010001 - Continuity check request */ #define ISUP_MT_RSC 18 /* 0x12 - 0b00010010 - Reset circuit */ #define ISUP_MT_BLO 19 /* 0x13 - 0b00010011 - Blocking */ #define ISUP_MT_UBL 20 /* 0x14 - 0b00010100 - Unblcoking */ #define ISUP_MT_BLA 21 /* 0x15 - 0b00010101 - Blocking acknowledgement */ #define ISUP_MT_UBA 22 /* 0x16 - 0b00010110 - Unblocking acknowledgement */ #define ISUP_MT_GRS 23 /* 0x17 - 0b00010111 - Circuit group reset */ #define ISUP_MT_CGB 24 /* 0x18 - 0b00011000 - Circuit group blocking */ #define ISUP_MT_CGU 25 /* 0x19 - 0b00011001 - Circuit group unblocking */ #define ISUP_MT_CGBA 26 /* 0x1a - 0b00011010 - Circuit group blocking acknowledgement */ #define ISUP_MT_CGUA 27 /* 0x1b - 0b00011011 - Circuit group unblocking acknowledgement */ #define ISUP_MT_CMR 28 /* 0x1c - 0b00011100 - Call Modification Request (not old ANSI) */ #define ISUP_MT_CMC 29 /* 0x1d - 0b00011101 - Call Modification Completed (not old ANSI) */ #define ISUP_MT_CMRJ 30 /* 0x1e - 0b00011110 - Call Modification Reject (not old ANSI) */ #define ISUP_MT_FAR 31 /* 0x1f - 0b00011111 - Facility request */ #define ISUP_MT_FAA 32 /* 0x20 - 0b00100000 - Facility accepted */ #define ISUP_MT_FRJ 33 /* 0x21 - 0b00100001 - Facility reject */ #define ISUP_MT_FAD 34 /* 0x22 - 0b00100010 - Facility Deactivated (old Bellcore only) */ #define ISUP_MT_FAI 35 /* 0x23 - 0b00100011 - Facility Information (old Bellcore only) */ #define ISUP_MT_LPA 36 /* 0x24 - 0b00100100 - Loop back acknowledgement */ #define ISUP_MT_DRS 39 /* 0x27 - 0b00100111 - Delayed release (not old ANSI) */ #define ISUP_MT_PAM 40 /* 0x28 - 0b00101000 - Pass along */ #define ISUP_MT_GRA 41 /* 0x29 - 0b00101001 - Circuit group reset acknowledgement */ #define ISUP_MT_CQM 42 /* 0x2a - 0b00101010 - Circuit group query */ #define ISUP_MT_CQR 43 /* 0x2b - 0b00101011 - Circuit group query response */ #define ISUP_MT_CPG 44 /* 0x2c - 0b00101100 - Call progress */ #define ISUP_MT_USR 45 /* 0x2d - 0b00101101 - User-to-user information */ #define ISUP_MT_UCIC 46 /* 0x2e - 0b00101110 - Unequipped circuit identification code */ #define ISUP_MT_CFN 47 /* 0x2f - 0b00101111 - Confusion */ #define ISUP_MT_OLM 48 /* 0x30 - 0b00110000 - Overload */ #define ISUP_MT_CRG 49 /* 0x31 - 0b00110001 - Charge information */ #define ISUP_MT_NRM 50 /* 0x32 - 0b00110010 - Network resource management */ #define ISUP_MT_FAC 51 /* 0x33 - 0b00110011 - Facility */ #define ISUP_MT_UPT 52 /* 0x34 - 0b00110100 - User part test */ #define ISUP_MT_UPA 53 /* 0x35 - 0b00110101 - User part available */ #define ISUP_MT_IDR 54 /* 0x36 - 0b00110110 - Identification request */ #define ISUP_MT_IRS 55 /* 0x37 - 0b00110111 - Identification response */ #define ISUP_MT_SGM 56 /* 0x38 - 0b00111000 - Segmentation */ static void send_msg(void) { /* data portion already ready */ ctrl.maxlen = BUFSIZE; ctrl.len = sizeof(p->pdu_req); ctrl.buf = cbuf; p->pdu_req.sl_primitive = SL_PDU_REQ; p->pdu_req.sl_mp = 0x0; if (putmsg(fd, &ctrl, &data, 0) < 0) perror(__FUNCTION__); return; } static void show_msg(const char *label) { int i; printf("%s", label); for (i = 0; i < data.len; i++) printf("%02x ", data.buf[i] & 0x0ff); printf("\n"); fflush(stdout); } static void send_iam(void) { unsigned char *h = data.buf; uint dsig_len = strlen(called) + 1; uint gsig_len = strlen(calling); int i; *h++ = 0x05; /* ISUP */ *h++ = (my_opc & 0x0ff); *h++ = ((my_opc >> 8) & 0x3f) | ((my_dpc & 0x3) << 6); *h++ = ((my_dpc >> 2) & 0x0ff); *h++ = ((my_dpc >> 10) & 0x0f) | ((my_cic & 0x0f) << 4); *h++ = (my_cic & 0x0ff); *h++ = ((my_cic >> 8) & 0x0f); *h++ = ISUP_MT_IAM; /* F nci */ *h++ = 0x00; /* F fci */ *h++ = 0x21; *h++ = 0x01; /* F cpc */ *h++ = 0x0a; /* 0x0a ordinary calling subscriber; 0x0d test call */ /* F tmr */ *h++ = 0x00; /* speech */ /* V cdpn */ *h++ = 0x02; /* pointer to cdpn */ *h++ = 4 + ((dsig_len + 1) >> 1); /* pointer to optional parms */ *h++ = 2 + ((dsig_len + 1) >> 1); /* CDPN length */ *h++ = 0x04 | ((dsig_len & 0x1) ? 0x80 : 0); /* 0x01 subscriber number 0x03 national 0x04 international */ *h++ = 0x10; /* inn allowed, E.164 */ for (i = 0; i < dsig_len; i += 2) *h++ = (called[i] & 0x0f) | ((called[i + 1] & 0x0f) << 4); if (dsig_len & 0x1) h[-1] |= 0xff; /* add ST and filler */ else h[-1] |= 0xf0; /* just add ST */ /* O cgpn */ *h++ = 0x0a; /* ISUP_PT_CGPN */ *h++ = 2 + ((gsig_len + 1) >> 1); /* CGPN length */ *h++ = 0x04 | ((gsig_len & 0x1) ? 0x80 : 0); /* subscriber number 0x03 national 0x04 international */ *h++ = 0x13; /* E.164, presentation allowed, user prov verified */ for (i = 0; i < gsig_len; i += 2) *h++ = (calling[i] & 0x0f) | ((calling[i + 1] & 0x0f) << 4); if (gsig_len & 0x1) h[-1] |= 0xf0; /* end of optional */ *h++ = 0x00; data.len = ((char *) h - data.buf); show_msg("-> IAM: "); send_msg(); return; } static void send_rel(void) { unsigned char *h = data.buf; *h++ = 0x05; /* ISUP */ *h++ = (my_opc & 0x0ff); *h++ = ((my_opc >> 8) & 0x3f) | ((my_dpc & 0x3) << 6); *h++ = ((my_dpc >> 2) & 0x0ff); *h++ = ((my_dpc >> 10) & 0x0f) | ((my_cic & 0x0f) << 4); *h++ = (my_cic & 0x0ff); *h++ = ((my_cic >> 8) & 0x0f); *h++ = ISUP_MT_REL; *h++ = 2; /* offset */ *h++ = 0x00; /* end of optional */ *h++ = 2; /* length */ *h++ = 0x80; /* Q.763 = User */ *h++ = 0x90; /* Normal call clearing */ data.len = ((char *) h - data.buf); show_msg("-> REL: "); send_msg(); return; } static void send_rsc(void) { unsigned char *h = data.buf; *h++ = 0x05; /* ISUP */ *h++ = (my_opc & 0x0ff); *h++ = ((my_opc >> 8) & 0x3f) | ((my_dpc & 0x3) << 6); *h++ = ((my_dpc >> 2) & 0x0ff); *h++ = ((my_dpc >> 10) & 0x0f) | ((my_cic & 0x0f) << 4); *h++ = (my_cic & 0x0ff); *h++ = ((my_cic >> 8) & 0x0f); *h++ = ISUP_MT_RSC; data.len = ((char *) h - data.buf); show_msg("-> RSC: "); send_msg(); return; } static void send_anm(void) { unsigned char *h = data.buf; *h++ = 0x05; /* ISUP */ *h++ = (my_opc & 0x0ff); *h++ = ((my_opc >> 8) & 0x3f) | ((my_dpc & 0x3) << 6); *h++ = ((my_dpc >> 2) & 0x0ff); *h++ = ((my_dpc >> 10) & 0x0f) | ((my_cic & 0x0f) << 4); *h++ = (my_cic & 0x0ff); *h++ = ((my_cic >> 8) & 0x0f); *h++ = ISUP_MT_ANM; *h++ = 0x00; /* end of optional */ data.len = ((char *) h - data.buf); show_msg("-> ANM: "); send_msg(); return; } static void handle_message(void) { unsigned char *h, *d; uint si, dpc, opc, sls, cic, mt, b; d = data.buf; si = *d++; if ((si & 0x0f) != 0x05) { printf("SI is %02x\n", si & 0x0f); return; } b = *d++ & 0x00ff; dpc = ((b << 0) & 0xff); b = *d++ & 0x00ff; dpc |= ((b << 8) & 0x3f00); opc = ((b >> 6) & 0x03); b = *d++ & 0x00ff; opc |= ((b << 2) & 0x3fc); b = *d++ & 0x00ff; opc |= ((b << 10) & 0x3c00); sls = (b >> 4) & 0x0f; b = *d++ & 0x00ff; cic = ((b << 0) & 0xff); b = *d++ & 0x00ff; cic |= ((b << 8) & 0x0f00); mt = (*d++ & 0x0ff); if (cic != my_cic) printf("CIC is %04x\n", cic & 0x0fff); printf("dpc = %04x, opc = %04x, sls = %02x, cic = %04x\n", dpc, opc, sls, cic); switch (mt) { case ISUP_MT_ACM: /* 0x06 - 0b00000110 - Address complete */ show_msg("<- ACM: "); if (state == 1) { /* wait for ACN/CON */ start_timer(120000); /* timer t9 2 minutes */ state = 2; break; } goto unexpected; case ISUP_MT_USR: /* 0x2d - 0b00101101 - User-to-user information */ show_msg("<- USR: "); goto unexpected; case ISUP_MT_CPG: /* 0x2c - 0b00101100 - Call progress */ show_msg("<- CPG: "); if (state == 2) { /* wait for ANM */ start_timer(120000); /* timer t9 2 minutes */ state = 2; } goto unexpected; case ISUP_MT_CON: /* 0x07 - 0b00000111 - Connect (not old ANSI) */ writeit = 1; show_msg("<- CON: "); if (state == 1) { /* wait for ACN/CON */ start_timer(15000); state = 5; /* connected */ break; } goto unexpected; case ISUP_MT_ANM: /* 0x09 - 0b00001001 - Answer */ writeit = 1; show_msg("<- ANM: "); if (state == 2) { /* wait for ANM */ start_timer(15000); state = 5; /* connected */ break; } goto unexpected; case ISUP_MT_REL: /* 0x0c - 0b00001100 - Release */ writeit = 0; loopback = 0; show_msg("<- REL: "); /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_RLC; *h++ = 0x00; data.len = ((char *) h - data.buf); show_msg("-> RLC: "); send_msg(); start_timer(100); state = 6; return; case ISUP_MT_BLO: /* 0x13 - 0b00010011 - Blocking */ show_msg("<- BLO: "); /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_BLA; show_msg("-> BLA: "); send_msg(); if (state == 0 || state == 1) { start_timer(100); state = 6; } return; case ISUP_MT_UBL: /* 0x14 - 0b00010100 - Unblcoking */ show_msg("<- UBL: "); /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_UBA; show_msg("-> UBA: "); send_msg(); return; case ISUP_MT_UPT: /* 0x34 - 0b00110100 - User part test */ show_msg("<- UPT: "); /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_UPA; show_msg("-> UPA: "); send_msg(); break; /* ignore */ case ISUP_MT_RLC: /* 0x10 - 0b00010000 - Release complete */ writeit = 0; loopback = 0; show_msg("<- RLC: "); start_timer(100); state = 6; return; case ISUP_MT_RSC: /* 0x12 - 0b00010010 - Reset circuit */ writeit = 0; loopback = 0; show_msg("<- RSC: "); /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_RLC; *h++ = 0x00; data.len = ((char *) h - data.buf); show_msg("-> RLC: "); send_msg(); start_timer(100); state = 6; return; case ISUP_MT_UCIC: /* 0x2e - 0b00101110 - Unequipped circuit identification code */ show_msg("<- UCIC: "); start_timer(100); state = 6; return; case ISUP_MT_UPA: /* 0x35 - 0b00110101 - User part available */ show_msg("<- UPA: "); return; case ISUP_MT_IAM: /* 0x01 - 0b00000001 - Initial address */ show_msg("<- IAM: "); my_cic = cic; if (((*d >> 2) & 0x03) != 0x01) { /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_ACM; *h++ = 0x00; /* no indication */ *h++ = 0x00; /* no indication */ *h++ = 0x00; data.len = ((char *) h - data.buf); show_msg("-> ACM: "); send_msg(); state = 8; start_timer(3000); return; } state = 7; start_timer(10000); /* t8 = 10 seconds */ break; case ISUP_MT_SAM: /* 0x02 - 0b00000010 - Subsequent address */ show_msg("<- SAM: "); if (state == 7) { start_timer(10000); /* t8 = 10 seconds */ return; } goto unexpected; case ISUP_MT_INR: /* 0x03 - 0b00000011 - Information request */ show_msg("<- INR: "); goto unexpected; case ISUP_MT_INF: /* 0x04 - 0b00000100 - Information */ show_msg("<- INF: "); goto unexpected; case ISUP_MT_COT: /* 0x05 - 0b00000101 - Continuity */ loopback = 0; show_msg("<- COT: "); if (*d & 0x1 && state == 7) { /* success */ /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_ACM; *h++ = 0x00; /* no indication */ *h++ = 0x00; /* no indication */ *h++ = 0x00; data.len = ((char *) h - data.buf); show_msg("-> ACM: "); send_msg(); state = 8; start_timer(3000); return; } start_timer(100); state = 6; return; case ISUP_MT_FOT: /* 0x08 - 0b00001000 - Forward transfer */ show_msg("<- FOT: "); goto unexpected; case ISUP_MT_SUS: /* 0x0d - 0b00001101 - Suspend */ show_msg("<- SUS: "); if (state == 5) { start_timer(15000); return; } goto unexpected; case ISUP_MT_RES: /* 0x0e - 0b00001110 - Resume */ show_msg("<- RES: "); if (state == 5) { start_timer(15000); return; } goto unexpected; case ISUP_MT_CCR: /* 0x11 - 0b00010001 - Continuity check request */ writeit = 0; loopback = 1; show_msg("<- CCR: "); if (0) { /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_LPA; data.len = ((char *) h - data.buf); show_msg("-> LPA: "); send_msg(); } start_timer(100); state = 6; break; case ISUP_MT_BLA: /* 0x15 - 0b00010101 - Blocking acknowledgement */ show_msg("<- BLA: "); return; case ISUP_MT_UBA: /* 0x16 - 0b00010110 - Unblocking acknowledgement */ show_msg("<- UBA: "); return; case ISUP_MT_CMR: /* 0x1c - 0b00011100 - Call Modification Request (not old ANSI) */ show_msg("<- CMR: "); goto unexpected; case ISUP_MT_CMC: /* 0x1d - 0b00011101 - Call Modification Completed (not old ANSI) */ show_msg("<- CMC: "); goto unexpected; case ISUP_MT_CMRJ: /* 0x1e - 0b00011110 - Call Modification Reject (not old ANSI) */ show_msg("<- CMRJ: "); goto unexpected; case ISUP_MT_FAR: /* 0x1f - 0b00011111 - Facility request */ show_msg("<- FAR: "); goto unexpected; case ISUP_MT_FAA: /* 0x20 - 0b00100000 - Facility accepted */ show_msg("<- FAA: "); goto unexpected; case ISUP_MT_FRJ: /* 0x21 - 0b00100001 - Facility reject */ show_msg("<- FRJ: "); goto unexpected; case ISUP_MT_FAD: /* 0x22 - 0b00100010 - Facility Deactivated (old Bellcore only) */ show_msg("<- FAD: "); goto unexpected; case ISUP_MT_FAI: /* 0x23 - 0b00100011 - Facility Information (old Bellcore only) */ show_msg("<- FAI: "); goto unexpected; case ISUP_MT_LPA: /* 0x24 - 0b00100100 - Loop back acknowledgement */ show_msg("<- LPA: "); /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_COT; *h++ = 0x01; /* success */ data.len = ((char *) h - data.buf); sleep(1); show_msg("-> COT: "); send_msg(); start_timer(100); state = 6; break; case ISUP_MT_DRS: /* 0x27 - 0b00100111 - Delayed release (not old ANSI) */ show_msg("<- DRS: "); goto unexpected; case ISUP_MT_PAM: /* 0x28 - 0b00101000 - Pass along */ show_msg("<- PAM: "); goto unexpected; case ISUP_MT_CFN: /* 0x2f - 0b00101111 - Confusion */ show_msg("<- CFN: "); goto unexpected; case ISUP_MT_OLM: /* 0x30 - 0b00110000 - Overload */ show_msg("<- OLM: "); goto unexpected; case ISUP_MT_CRG: /* 0x31 - 0b00110001 - Charge information */ show_msg("<- CRG: "); goto unexpected; case ISUP_MT_NRM: /* 0x32 - 0b00110010 - Network resource management */ show_msg("<- NRM: "); goto unexpected; case ISUP_MT_FAC: /* 0x33 - 0b00110011 - Facility */ show_msg("<- FAC: "); goto unexpected; case ISUP_MT_IDR: /* 0x36 - 0b00110110 - Identification request */ show_msg("<- IDR: "); goto unexpected; case ISUP_MT_IRS: /* 0x37 - 0b00110111 - Identification response */ show_msg("<- IRS: "); goto unexpected; case ISUP_MT_SGM: /* 0x38 - 0b00111000 - Segmentation */ show_msg("<- SGM: "); return; case ISUP_MT_GRS: /* 0x17 - 0b00010111 - Circuit group reset */ show_msg("<- GRS: "); /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_GRA; show_msg("-> GRA: "); send_msg(); return; case ISUP_MT_CGB: /* 0x18 - 0b00011000 - Circuit group blocking */ show_msg("<- CGB: "); /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_CGBA; show_msg("-> CGBA: "); send_msg(); if (state == 0 || state == 1) { start_timer(100); state = 6; } return; case ISUP_MT_CGU: /* 0x19 - 0b00011001 - Circuit group unblocking */ show_msg("<- CGU: "); /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_CGUA; show_msg("-> CGUA: "); send_msg(); return; case ISUP_MT_CGBA: /* 0x1a - 0b00011010 - Circuit group blocking acknowledgement */ show_msg("<- CGBA: "); return; case ISUP_MT_CGUA: /* 0x1b - 0b00011011 - Circuit group unblocking acknowledgement */ show_msg("<- CGUA: "); return; case ISUP_MT_GRA: /* 0x29 - 0b00101001 - Circuit group reset acknowledgement */ show_msg("<- GRA: "); return; case ISUP_MT_CQM: /* 0x2a - 0b00101010 - Circuit group query */ show_msg("<- CQM: "); goto unexpected; case ISUP_MT_CQR: /* 0x2b - 0b00101011 - Circuit group query response */ show_msg("<- CQR: "); return; default: show_msg("???: "); break; } return; goto release; release: /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_REL; *h++ = 2; /* offset */ *h++ = 0x00; /* end of optional */ *h++ = 2; /* length */ *h++ = 0x00; /* Q.763 = User */ *h++ = 0x10; /* Normal call clearing */ data.len = ((char *) h - data.buf); show_msg("-> REL: "); send_msg(); return; unexpected: if (state == 1) { state = 6; return; } if (state != 0 && state != 6) return; /* rewrite the header swap the point codes */ h = data.buf; *h++ = si; *h++ = (opc & 0x0ff); *h++ = ((opc >> 8) & 0x03f) | ((dpc & 0x03) << 6); *h++ = ((dpc >> 2) & 0x0ff); *h++ = ((dpc >> 10) & 0x0f) | ((sls & 0x0f) << 4); *h++ = (cic & 0x0ff); *h++ = ((cic >> 8) & 0x0f); *h++ = ISUP_MT_RSC; data.len = ((char *) h - data.buf); show_msg("-> RSC: "); send_msg(); return; } static int release_attempts = 0; static int board = 1; static int span = 1; static int channel = 1; static int mymain(int argc, char **argv) { int ret; int size = 16000; printf("Opening sound file.\n"); fflush(stdout); if ((fd = open("NewMail.raw", O_RDONLY)) < 0) { perror(argv[0]); exit(1); } printf("Reading newmail.\n"); fflush(stdout); size = 16000; do { if ((ret = read(fd, newmail + 16000 - size, size)) < 0) { perror(argv[0]); exit(1); } printf("size = %d, ret = %d\n", size, ret); size -= ret; } while (size > 8000); close(fd); printf("Opening sound file.\n"); fflush(stdout); if ((fd = open("NoMail.raw", O_RDONLY)) < 0) { perror(argv[0]); exit(1); } printf("Reading nomail.\n"); fflush(stdout); size = 16000; do { if ((ret = read(fd, newmail + 32000 - size, size)) < 0) { perror(argv[0]); exit(1); } size -= ret; } while (size > 8000); close(fd); if (swap_bits) { int i, j; uint c, d; for (i = 0; i < 32000; i++) { c = newmail[i]; d = 0; for (j = 0; j < 8; j++) { d |= (c & 0x1); c >>= 1; d <<= 1; } newmail[i] = d; } } printf("Opening channel.\n"); fflush(stdout); if ((cfd = open("/dev/x400p-sl", O_NONBLOCK | O_RDWR)) < 0) { perror(argv[0]); exit(1); } printf("Ioctl on channel.\n"); fflush(stdout); if (ioctl(cfd, I_SRDOPT, RMSGD) < 0) { perror(argv[0]); exit(1); } channel = (my_cic > 31) ? my_cic - 32 : my_cic; ppa = ((board - 1) << 12) | ((span - 1) << 8) | (channel << 0); ctrl.maxlen = BUFSIZE; ctrl.len = sizeof(m->attach_req) + sizeof(ppa_t); ctrl.buf = cbuf; m->attach_req.lmi_primitive = LMI_ATTACH_REQ; bcopy(&ppa, m->attach_req.lmi_ppa, sizeof(ppa_t)); printf("Attaching device.\n"); fflush(stdout); if (putmsg(cfd, &ctrl, NULL, 0) < 0) { perror(argv[0]); exit(1); } switch ((ret = get_event())) { case LMI_OK_ACK: break; default: fprintf(stderr, "%s: failed with event %d\n", argv[0], ret); exit(1); } printf("Configuring SDL.\n"); fflush(stdout); ctl.ic_cmd = SDL_IOCSCONFIG; ctl.ic_timout = 0; ctl.ic_len = sizeof(sdl_conf); ctl.ic_dp = (char *) &sdl_conf; if (ioctl(cfd, I_STR, &ctl) < 0) { perror(argv[0]); exit(1); } printf("Enabling channel.\n"); fflush(stdout); ctrl.maxlen = BUFSIZE; ctrl.len = sizeof(m->enable_req); ctrl.buf = cbuf; m->enable_req.lmi_primitive = LMI_ENABLE_REQ; ctrl.len = sizeof(m->enable_req); if (putmsg(cfd, &ctrl, NULL, 0) < 0) { perror(argv[0]); exit(1); } switch ((ret = get_event())) { case LMI_ENABLE_CON: break; default: fprintf(stderr, "%s: failed with event %d\n", argv[0], ret); exit(1); } printf("Connecting channel for transmit.\n"); fflush(stdout); ctrl.maxlen = BUFSIZE; ctrl.len = sizeof(d->connect_req); ctrl.buf = cbuf; d->sdl_primitive = SDL_CONNECT_REQ; d->connect_req.sdl_flags = SDL_TX_DIRECTION|SDL_RX_DIRECTION; if (putmsg(cfd, &ctrl, NULL, 0) < 0) { perror(argv[0]); exit(1); } printf("Opening mux.\n"); fflush(stdout); if ((fd = open("/dev/sl-mux", O_NONBLOCK | O_RDWR)) < 0) { perror(argv[0]); exit(1); } printf("Ioctl on mux.\n"); fflush(stdout); if (ioctl(fd, I_SRDOPT, RMSGD) < 0) { perror(argv[0]); exit(1); } if (state != 6) start_timer(100); /* wait a bit */ for (;;) { switch (state) { case 0: { switch ((ret = get_event())) { case SL_PDU_IND: handle_message(); break; case TIMEOUT: start_timer(20000); /* timer t7 = 20 seconds */ send_iam(); state = 1; break; default: break; } break; } case 1: /* waiting for ACM/CON */ { switch ((ret = get_event())) { case SL_PDU_IND: handle_message(); break; case TIMEOUT: release_attempts = 0; send_rel(); start_timer(60000); /* timer t1 = 60 seconds */ state = 3; break; default: break; } break; } case 2: /* waiting for ANM */ { switch ((ret = get_event())) { case SL_PDU_IND: handle_message(); break; case TIMEOUT: send_rel(); start_timer(60000); /* timer t1 = 60 seconds */ state = 3; break; default: break; } break; } case 3: /* wait for RLC */ { switch ((ret = get_event())) { case SL_PDU_IND: handle_message(); break; case TIMEOUT: if (++release_attempts > 4) { send_rsc(); start_timer(300000); /* timer t17 */ state = 4; } else { send_rel(); start_timer(60000); /* timer t1 = 60 seconds */ state = 3; } break; default: break; } break; } case 4: /* wait for RLC */ { switch ((ret = get_event())) { case SL_PDU_IND: handle_message(); break; case TIMEOUT: send_rsc(); start_timer(300000); /* timer t17 */ state = 4; break; default: break; } break; } case 5: /* connected */ { switch ((ret = get_event())) { case SL_PDU_IND: handle_message(); break; case TIMEOUT: send_rel(); start_timer(60000); /* timer t1 = 60 seconds */ state = 3; break; } break; } case 6: /* got RLC done, exit */ { switch ((ret = get_event())) { case SL_PDU_IND: handle_message(); break; case TIMEOUT: break; } break; } case 7: /* got IAM, wait COT t8 = 10 seconds */ { switch ((ret = get_event())) { case SL_PDU_IND: handle_message(); break; case TIMEOUT: send_rel(); start_timer(60000); /* timer t1 = 60 seconds */ state = 3; break; } break; } case 8: /* send ACM, waiting to send ANM */ { switch ((ret = get_event())) { case SL_PDU_IND: handle_message(); break; case TIMEOUT: send_anm(); start_timer(15000); state = 5; /* connected */ break; } break; } default: fprintf(stderr, "Software error.\n"); exit(1); } } close(fd); exit(0); return (0); } int main(int argc, char **argv) { int c; while (1) { int option_index = 0; static struct option long_options[] = { {"help", 0, 0, 'h'}, {"called", 1, 0, 'd'}, {"calling", 1, 0, 'g'}, {"cic", 1, 0, 'c'}, {"nocall", 0, 0, 'n'}, {"swap", 0, 0, 's'}, {"t1", 0, 0, 't'} }; c = getopt_long(argc, argv, "hd:g:c:nst", long_options, &option_index); if (c == -1) break; switch (c) { case 0: switch (option_index) { case 0: /* -h */ help(argc, argv); exit(0); case 1: /* -d called */ strncpy(called, optarg, sizeof(called) - 1); break; case 2: /* -g calling */ strncpy(calling, optarg, sizeof(calling) - 1); break; case 3: /* -c cic */ my_cic = atoi(optarg); break; case 4: /* -n */ state = 6; break; case 5: /* -s */ swap_bits = 1; break; case 6: /* -t */ sdl_conf.ifgrate = 1544000; sdl_conf.ifgcrc = SDL_GCRC_CRC6; sdl_conf.ifcoding = SDL_CODING_B8ZS; sdl_conf.ifframing = SDL_FRAMING_SF; break; default: usage(argc, argv); exit(1); } case 'h': help(argc, argv); exit(0); case 'd': strncpy(called, optarg, sizeof(called) - 1); break; case 'g': strncpy(calling, optarg, sizeof(calling) - 1); break; case 'c': my_cic = atoi(optarg); break; case 'n': state = 6; break; case 's': swap_bits = 1; break; case 't': sdl_conf.ifgrate = 1544000; sdl_conf.ifgcrc = SDL_GCRC_CRC6; sdl_conf.ifcoding = SDL_CODING_B8ZS; sdl_conf.ifframing = SDL_FRAMING_SF; break; default: usage(argc, argv); exit(1); } } if (optind < argc) { fprintf(stderr, "%s: illegal syntax -- ", argv[0]); for (; optind < argc; optind++) fprintf(stderr, "%s ", argv[optind]); fprintf(stderr, "\n"); usage(argc, argv); exit(1); } return mymain(argc, argv); }
|
|||||||||||||||||||||||||||
OpenSS7 SS7 for the Common Man |
Home | Overview | Status | News | Documentation | Resources | About | ||||||||||||||||||||
© Copyright 1997-2004,OpenSS7 Corporation, All Rights Reserved. |