📄 q931.c
字号:
return -1;}static FUNC_DUMP(dump_channel_id){ int pos=0; int x; int res = 0; static const char* msg_chan_sel[] = { "No channel selected", "B1 channel", "B2 channel","Any channel selected", "No channel selected", "As indicated in following octets", "Reserved","Any channel selected" }; pri_message(pri, "%c Channel ID (len=%2d) [ Ext: %d IntID: %s %s Spare: %d %s Dchan: %d\n", prefix, len, (ie->data[0] & 0x80) ? 1 : 0, (ie->data[0] & 0x40) ? "Explicit" : "Implicit", (ie->data[0] & 0x20) ? "PRI" : "Other", (ie->data[0] & 0x10) ? 1 : 0, (ie->data[0] & 0x08) ? "Exclusive" : "Preferred", (ie->data[0] & 0x04) ? 1 : 0); pri_message(pri, "%c ChanSel: %s\n", prefix, msg_chan_sel[(ie->data[0] & 0x3) + ((ie->data[0]>>3) & 0x4)]); pos++; len--; if (ie->data[0] & 0x40) { /* Explicitly defined DS1 */ pri_message(pri, "%c Ext: %d DS1 Identifier: %d \n", prefix, (ie->data[pos] & 0x80) >> 7, ie->data[pos] & 0x7f); pos++; } else { /* Implicitly defined DS1 */ } if (pos+2 < len) { /* Still more information here */ pri_message(pri, "%c Ext: %d Coding: %d %s Specified Channel Type: %d\n", prefix, (ie->data[pos] & 0x80) >> 7, (ie->data[pos] & 60) >> 5, (ie->data[pos] & 0x10) ? "Slot Map" : "Number", ie->data[pos] & 0x0f); if (!(ie->data[pos] & 0x10)) { /* Number specified */ pos++; pri_message(pri, "%c Ext: %d Channel: %d ]\n", prefix, (ie->data[pos] & 0x80) >> 7, (ie->data[pos]) & 0x7f); } else { pos++; /* Map specified */ for (x=0;x<3;x++) { res <<= 8; res |= ie->data[pos++]; } pri_message(pri, "%c Map: %s ]\n", prefix, binary(res, 24)); } } else pri_message(pri, " ]\n"); }static char *ri2str(int ri){ static struct msgtype ris[] = { { 0, "Indicated Channel" }, { 6, "Single DS1 Facility" }, { 7, "All DS1 Facilities" }, }; return code2str(ri, ris, sizeof(ris) / sizeof(ris[0]));}static FUNC_DUMP(dump_restart_indicator){ pri_message(pri, "%c Restart Indentifier (len=%2d) [ Ext: %d Spare: %d Resetting %s (%d) ]\n", prefix, len, (ie->data[0] & 0x80) >> 7, (ie->data[0] & 0x78) >> 3, ri2str(ie->data[0] & 0x7), ie->data[0] & 0x7);}static FUNC_RECV(receive_restart_indicator){ /* Pretty simple */ call->ri = ie->data[0] & 0x7; return 0;}static FUNC_SEND(transmit_restart_indicator){ /* Pretty simple */ switch(call->ri) { case 0: case 6: case 7: ie->data[0] = 0x80 | (call->ri & 0x7); break; case 5: /* Switch compatibility */ ie->data[0] = 0xA0 | (call->ri & 0x7); break; default: pri_error(pri, "!! Invalid restart indicator value %d\n", call->ri); return-1; } return 3;}static char *redirection_reason2str(int mode){ static struct msgtype modes[] = { { PRI_REDIR_UNKNOWN, "Unknown" }, { PRI_REDIR_FORWARD_ON_BUSY, "Forwarded on busy" }, { PRI_REDIR_FORWARD_ON_NO_REPLY, "Forwarded on no reply" }, { PRI_REDIR_DEFLECTION, "Call deflected" }, { PRI_REDIR_DTE_OUT_OF_ORDER, "Called DTE out of order" }, { PRI_REDIR_FORWARDED_BY_DTE, "Forwarded by called DTE" }, { PRI_REDIR_UNCONDITIONAL, "Forwarded unconditionally" }, }; return code2str(mode, modes, sizeof(modes) / sizeof(modes[0]));}static char *cap2str(int mode){ static struct msgtype modes[] = { { PRI_TRANS_CAP_SPEECH, "Speech" }, { PRI_TRANS_CAP_DIGITAL, "Unrestricted digital information" }, { PRI_TRANS_CAP_RESTRICTED_DIGITAL, "Restricted digital information" }, { PRI_TRANS_CAP_3_1K_AUDIO, "3.1kHz audio" }, { PRI_TRANS_CAP_DIGITAL_W_TONES, "Unrestricted digital information with tones/announcements" }, { PRI_TRANS_CAP_VIDEO, "Video" }, { PRI_TRANS_CAP_AUDIO_4ESS, "3.1khz audio (4ESS)" }, }; return code2str(mode, modes, sizeof(modes) / sizeof(modes[0]));}static char *mode2str(int mode){ static struct msgtype modes[] = { { TRANS_MODE_64_CIRCUIT, "64kbps, circuit-mode" }, { TRANS_MODE_2x64_CIRCUIT, "2x64kbps, circuit-mode" }, { TRANS_MODE_384_CIRCUIT, "384kbps, circuit-mode" }, { TRANS_MODE_1536_CIRCUIT, "1536kbps, circuit-mode" }, { TRANS_MODE_1920_CIRCUIT, "1920kbps, circuit-mode" }, { TRANS_MODE_MULTIRATE, "Multirate (Nx64kbps)" }, { TRANS_MODE_PACKET, "Packet Mode" }, }; return code2str(mode, modes, sizeof(modes) / sizeof(modes[0]));}static char *l12str(int proto){ static struct msgtype protos[] = { { PRI_LAYER_1_ITU_RATE_ADAPT, "V.110 Rate Adaption" }, { PRI_LAYER_1_ULAW, "u-Law" }, { PRI_LAYER_1_ALAW, "A-Law" }, { PRI_LAYER_1_G721, "G.721 ADPCM" }, { PRI_LAYER_1_G722_G725, "G.722/G.725 7kHz Audio" }, { PRI_LAYER_1_H223_H245, "H.223/H.245 Multimedia" }, { PRI_LAYER_1_NON_ITU_ADAPT, "Non-ITU Rate Adaption" }, { PRI_LAYER_1_V120_RATE_ADAPT, "V.120 Rate Adaption" }, { PRI_LAYER_1_X31_RATE_ADAPT, "X.31 Rate Adaption" }, }; return code2str(proto, protos, sizeof(protos) / sizeof(protos[0]));}static char *ra2str(int proto){ static struct msgtype protos[] = { { PRI_RATE_ADAPT_9K6, "9.6 kbit/s" }, }; return code2str(proto, protos, sizeof(protos) / sizeof(protos[0]));}static char *l22str(int proto){ static struct msgtype protos[] = { { LAYER_2_LAPB, "LAPB" }, }; return code2str(proto, protos, sizeof(protos) / sizeof(protos[0]));}static char *l32str(int proto){ static struct msgtype protos[] = { { LAYER_3_X25, "X.25" }, }; return code2str(proto, protos, sizeof(protos) / sizeof(protos[0]));}static char *int_rate2str(int proto){ static struct msgtype protos[] = { { PRI_INT_RATE_8K, "8 kbit/s" }, { PRI_INT_RATE_16K, "16 kbit/s" }, { PRI_INT_RATE_32K, "32 kbit/s" }, }; return code2str(proto, protos, sizeof(protos) / sizeof(protos[0]));}static FUNC_DUMP(dump_bearer_capability){ int pos=2; pri_message(pri, "%c Bearer Capability (len=%2d) [ Ext: %d Q.931 Std: %d Info transfer capability: %s (%d)\n", prefix, len, (ie->data[0] & 0x80 ) >> 7, (ie->data[0] & 0x60) >> 5, cap2str(ie->data[0] & 0x1f), (ie->data[0] & 0x1f)); pri_message(pri, "%c Ext: %d Trans mode/rate: %s (%d)\n", prefix, (ie->data[1] & 0x80) >> 7, mode2str(ie->data[1] & 0x7f), ie->data[1] & 0x7f); /* octet 4.1 exists iff mode/rate is multirate */ if ((ie->data[1] & 0x7f) == 0x18) { pri_message(pri, "%c Ext: %d Transfer rate multiplier: %d x 64\n", prefix, (ie->data[2] & 0x80) >> 7, ie->data[2] & 0x7f); pos++; } /* don't count the IE num and length as part of the data */ len -= 2; /* Look for octet 5; this is identified by bits 5,6 == 01 */ if (pos < len && (ie->data[pos] & 0x60) == 0x20) { /* although the layer1 is only the bottom 5 bits of the byte, previous versions of this library passed bits 5&6 through too, so we have to do the same for binary compatability */ u_int8_t layer1 = ie->data[pos] & 0x7f; pri_message(pri, "%c User information layer 1: %s (%d)\n", prefix, l12str(layer1), layer1); pos++; /* octet 5a? */ if (pos < len && !(ie->data[pos-1] & 0x80)) { int ra = ie->data[pos] & 0x7f; pri_message(pri, "%c Async: %d, Negotiation: %d, " "User rate: %s (%#x)\n", prefix, ra & PRI_RATE_ADAPT_ASYNC ? 1 : 0, ra & PRI_RATE_ADAPT_NEGOTIATION_POSS ? 1 : 0, ra2str(ra & PRI_RATE_USER_RATE_MASK), ra & PRI_RATE_USER_RATE_MASK); pos++; } /* octet 5b? */ if (pos < len && !(ie->data[pos-1] & 0x80)) { u_int8_t data = ie->data[pos]; if (layer1 == PRI_LAYER_1_ITU_RATE_ADAPT) { pri_message(pri, "%c Intermediate rate: %s (%d), " "NIC on Tx: %d, NIC on Rx: %d, " "Flow control on Tx: %d, " "Flow control on Rx: %d\n", prefix, int_rate2str((data & 0x60)>>5), (data & 0x60)>>5, (data & 0x10)?1:0, (data & 0x08)?1:0, (data & 0x04)?1:0, (data & 0x02)?1:0); } else if (layer1 == PRI_LAYER_1_V120_RATE_ADAPT) { pri_message(pri, "%c Hdr: %d, Multiframe: %d, Mode: %d, " "LLI negot: %d, Assignor: %d, " "In-band neg: %d\n", prefix, (data & 0x40)?1:0, (data & 0x20)?1:0, (data & 0x10)?1:0, (data & 0x08)?1:0, (data & 0x04)?1:0, (data & 0x02)?1:0); } else { pri_message(pri, "%c Unknown octet 5b: 0x%x\n", data ); } pos++; } /* octet 5c? */ if (pos < len && !(ie->data[pos-1] & 0x80)) { u_int8_t data = ie->data[pos]; const char *stop_bits[] = {"?","1","1.5","2"}; const char *data_bits[] = {"?","5","7","8"}; const char *parity[] = {"Odd","?","Even","None", "zero","one","?","?"}; pri_message(pri, "%c Stop bits: %s, data bits: %s, " "parity: %s\n", prefix, stop_bits[(data & 0x60) >> 5], data_bits[(data & 0x18) >> 3], parity[(data & 0x7)]); pos++; } /* octet 5d? */ if (pos < len && !(ie->data[pos-1] & 0x80)) { u_int8_t data = ie->data[pos]; pri_message(pri, "%c Duplex mode: %d, modem type: %d\n", prefix, (data & 0x40) ? 1 : 0,data & 0x3F); pos++; } } /* Look for octet 6; this is identified by bits 5,6 == 10 */ if (pos < len && (ie->data[pos] & 0x60) == 0x40) { pri_message(pri, "%c User information layer 2: %s (%d)\n", prefix, l22str(ie->data[pos] & 0x1f), ie->data[pos] & 0x1f); pos++; } /* Look for octet 7; this is identified by bits 5,6 == 11 */ if (pos < len && (ie->data[pos] & 0x60) == 0x60) { pri_message(pri, "%c User information layer 3: %s (%d)\n", prefix, l32str(ie->data[pos] & 0x1f), ie->data[pos] & 0x1f); pos++; /* octets 7a and 7b? */ if (pos + 1 < len && !(ie->data[pos-1] & 0x80) && !(ie->data[pos] & 0x80)) { unsigned int proto; proto = ((ie->data[pos] & 0xF) << 4 ) | (ie->data[pos+1] & 0xF); pri_message(pri, "%c Network layer: 0x%x\n", prefix, proto ); pos += 2; } }}static FUNC_RECV(receive_bearer_capability){ int pos=2; if (ie->data[0] & 0x60) { pri_error(pri, "!! non-standard Q.931 standard field\n"); return -1; } call->transcapability = ie->data[0] & 0x1f; call->transmoderate = ie->data[1] & 0x7f; /* octet 4.1 exists iff mode/rate is multirate */ if (call->transmoderate == TRANS_MODE_MULTIRATE) { call->transmultiple = ie->data[pos++] & 0x7f; } /* Look for octet 5; this is identified by bits 5,6 == 01 */ if (pos < len && (ie->data[pos] & 0x60) == 0x20 ) { /* although the layer1 is only the bottom 5 bits of the byte, previous versions of this library passed bits 5&6 through too, so we have to do the same for binary compatability */ call->userl1 = ie->data[pos] & 0x7f; pos++; /* octet 5a? */ if (pos < len && !(ie->data[pos-1] & 0x80)) { call->rateadaption = ie->data[pos] & 0x7f; pos++; } /* octets 5b through 5d? */ while (pos < len && !(ie->data[pos-1] & 0x80)) { pos++; } } /* Look for octet 6; this is identified by bits 5,6 == 10 */ if (pos < len && (ie->data[pos] & 0x60) == 0x40) { call->userl2 = ie->data[pos++] & 0x1f; } /* Look for octet 7; this is identified by bits 5,6 == 11 */ if (pos < len && (ie->data[pos] & 0x60) == 0x60) { call->userl3 = ie->data[pos++] & 0x1f; } return 0;}static FUNC_SEND(transmit_bearer_capability){ int tc; int pos; /* We are ready to transmit single IE only */ if(order > 1) return 0; tc = call->transcapability; if (pri->subchannel && !pri->bri) { /* Bearer capability is *hard coded* in GR-303 */ ie->data[0] = 0x88; ie->data[1] = 0x90; return 4; } if (call->justsignalling) { ie->data[0] = 0xa8; ie->data[1] = 0x80; return 4; } ie->data[0] = 0x80 | tc; ie->data[1] = call->transmoderate | 0x80; pos = 2; /* octet 4.1 exists iff mode/rate is multirate */ if (call->transmoderate == TRANS_MODE_MULTIRATE ) { ie->data[pos++] = call->transmultiple | 0x80; } if ((tc & PRI_TRANS_CAP_DIGITAL) && (pri->switchtype == PRI_SWITCH_EUROISDN_E1) && (call->transmoderate == TRANS_MODE_PACKET)) { /* Apparently EuroISDN switches don't seem to like user layer 2/3 */ return 4; } if (call->transmoderate != TRANS_MODE_PACKET) { /* If you have an AT&T 4ESS, you don't send any more info */ if ((pri->switchtype != PRI_SWITCH_ATT4ESS) && (call->userl1 > -1)) { ie->data[pos++] = call->userl1 | 0x80; /* XXX Ext bit? XXX */ if (call->userl1 == PRI_LAYER_1_ITU_RATE_ADAPT) { ie->data[pos++] = call->rateadaption | 0x80; } return pos + 2; } ie->data[pos++] = 0xa0 | (call->userl1 & 0x1f); if (call->userl1 == PRI_LAYER_1_ITU_RATE_ADAPT) { ie->data[pos-1] &= ~0x80; /* clear EXT bit in octet 5 */ ie->data[pos++] = call->rateadaption | 0x80; } } if (call->userl2 != -1) ie->data[pos++] = 0xc0 | (call->userl2 & 0x1f);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -