From: Paul B. S. <pa...@us...> - 2001-09-03 18:41:09
|
Update of /cvsroot/linux-atm/linux-atm/src/qgen In directory usw-pr-cvs1:/tmp/cvs-serv10656/qgen Added Files: Tag: V2_4_0 TODO op.h qtest.c uni.h first.c third.c mknl.pl common.c common.h file.c file.h Makefile.am msg.fmt second.c qgen.c qgen.h ql_l.l ql_y.y qlib.c qlib.h incl.pl Log Message: --- NEW FILE: TODO --- - handle repeated IEs - q_assign should remove old value (i.e. zero destination) - bit numbering is wrong; should be <size@high> - should be library (well, need at least more flexible name selection) - copies of adjacent fields should be merged - copies of partial bytes should be byte-wide if rest is only zeroes - should be able to have multiple selectors in one byte - case/default needs better compile-time check - parser shouldn't copy unnamed fields - optimize - code needs a lot of cleaning Restrictions ------------ - there's only very limited error checking - no support for arrays (repeated IEs) - copy operations are not optimized --- NEW FILE: op.h --- /* op.h - message processor opcodes */ /* Written 1995,1996 by Werner Almesberger, EPFL-LRC */ #ifndef OP_H #define OP_H /* construction */ #define OP_INVALID 0 /* crash here */ #define OP_COPY 1 /* copy <jump>,<src>,<size> */ #define OP_COPYVAR 2 /* copy <index>,<src>,<maxsize(bytes)> */ #define OP_BEGIN_LEN 3 /* begin_length <jump>,<src>,<size> */ #define OP_END_LEN 4 /* end_length */ #if 0 #define OP_CASE 4 /* case <groups>, { <group>,<offset>,... { <op>,..., jump }, ... } */ #endif #define OP_JUMP 5 /* jump <addr> */ #define OP_END 6 /* end */ #define OP_IFGROUP 7 /* ifgroup <group>,<jump> */ /* parsing */ #define OP_MULTI 8 /* multi <size>,case,... */ #define OP_CASE 9 /* case <jump>,<src>,<size>,<groups>, { <pattern>, <group>,<offset>,... { <op>,...,jump }, ... } */ #define OP_IFEND 10 /* ifend <addr> */ #define OP_DUMP 11 /* dump <index>; dumper only */ #define OP_BEGIN_REC 12 /* begin_recovery <id>,<group>,<addr> */ #define OP_END_REC 13 /* end_recovery */ #define OP_ABORT 14 /* abort <id> */ #endif --- NEW FILE: qtest.c --- #if HAVE_CONFIG_H #include <config.h> #endif #include <stdio.h> #include <string.h> int main(void) { int error,i,j,u; error = 0; for (i = 0; fields[i]; i++) for (j = i+1; fields[j]; j++) if (!strcmp(fields[i],fields[j])) { fprintf(stderr,"collision: field \"%s\"\n",fields[i]); error = 1; } for (i = 0; groups[i]; i++) for (j = i+1; groups[j]; j++) if (!strcmp(groups[i],groups[j])) { fprintf(stderr,"collision: group \"%s\"\n",groups[i]); error = 1; } for (u = 0; unique[u]; u++) for (i = 0; unique[u][i] != -1; i++) for (j = i+1; unique[u][j] != -1; j++) if (unique[u][i] == unique[u][j]) { fprintf(stderr,"collision: value %d in collection %d\n", unique[u][i],u); error = 1; } return error; } --- NEW FILE: uni.h --- /* uni.h - Various Q.2931/Q.2971/Q.2963.1/UNI 3.x/UNI 4.0 constants */ /* Written 1995-1998 by Werner Almesberger, EPFL-LRC/ICA */ /* * Note: some values don't appear in UNI 3.0 or 3.1 but are taken from Q.2931 * and related ITU documents. */ #ifndef UNI_H #define UNI_H /* Maximum message size */ #define MAX_Q_MSG 1000 /* Protocol discriminator */ #define Q2931_PROTO_DSC 9 /* Q.2931 user-network call/connection control message */ /* Coding Standards */ #define Q2931_CS_ITU 0 /* ITU-T standardized */ #define Q2931_CS_NET 3 /* Standard defined for the network */ /* Message types */ #define ATM_MSG_NATIONAL 0x00 /* National specific message escape */ #define ATM_MSG_SETUP 0x05 /* SETUP */ #define ATM_MSG_ALERTING 0x01 /* ALERTING */ #define ATM_MSG_CALL_PROC 0x02 /* CALL PROCEEDING */ #define ATM_MSG_CONNECT 0x07 /* CONNECT */ #define ATM_MSG_CONN_ACK 0x0f /* CONNECT ACKNOWLEDGE */ #define ATM_MSG_RESTART 0x46 /* RESTART */ #define ATM_MSG_RELEASE 0x4d /* RELEASE */ #define ATM_MSG_REST_ACK 0x4e /* RESTART ACKNOWLEDGE */ #define ATM_MSG_REL_COMP 0x5a /* RELEASE COMPLETE */ #define ATM_MSG_NOTIFY 0x6e /* NOTIFY */ #define ATM_MSG_STATUS_ENQ 0x75 /* STATUS ENQUIRY */ #define ATM_MSG_STATUS 0x7d /* STATUS */ #define ATM_MSG_ADD_PARTY 0x80 /* ADD PARTY */ #define ATM_MSG_ADD_PARTY_ACK 0x81 /* ADD PARTY ACKNOWLEDGE */ #define ATM_MSG_ADD_PARTY_REJ 0x82 /* ADD PART REJECT */ #define ATM_MSG_PARTY_ALERT 0x85 /* PARTY ALERTING */ #define ATM_MSG_DROP_PARTY 0x83 /* DROP PARTY */ #define ATM_MSG_DROP_PARTY_ACK 0x84 /* DROP PARTY ACKNOWLEDGE */ #define ATM_MSG_MODIFY_REQ 0x88 /* MODIFY REQUEST */ #define ATM_MSG_MODIFY_ACK 0x89 /* MODIFY ACKNOWLEDGE */ #define ATM_MSG_MODIFY_REJ 0x8a /* MODIFY REJECT */ #define ATM_MSG_CONN_AVAIL 0x8b /* CONNECTION AVAILABLE */ #define ATM_MSG_LEAF_FAILURE 0x90 /* LEAF SETUP FAILURE */ #define ATM_MSG_LEAF_REQUEST 0x91 /* LEAF SETUP REQUEST */ #define ATM_MSG_RESERVED 0xff /* reserved for EVEN MORE msg types */ /* Information element identifiers */ #define ATM_IE_CAUSE 0x08 /* Cause */ #define ATM_IE_CALL_STATE 0x14 /* Call state */ #define ATM_IE_NOTIFY 0x27 /* Notification indicator */ #define ATM_IE_E2E_TDL 0x42 /* End-to-end transit delay */ #define ATM_IE_EPR 0x54 /* Endpoint reference */ #define ATM_IE_EP_STATE 0x55 /* Endpoint state */ #define ATM_IE_AAL 0x58 /* ATM adaption layer parameters */ #define ATM_IE_TD 0x59 /* ATM traffic descriptor */ #define ATM_IE_CONN_ID 0x5a /* Connection identifier */ #define ATM_IE_OAM_TD 0x5b /* OAM traffic descriptor */ #define ATM_IE_QOS 0x5c /* Quality of service parameter */ #define ATM_IE_BHLI 0x5d /* Broadband high layer information */ #define ATM_IE_BBCAP 0x5e /* Broadband bearer capability */ #define ATM_IE_BLLI 0x5f /* Broadband low-layer information */ #define ATM_IE_BBS_COMP 0x62 /* Broadband sending complete */ #define ATM_IE_BBREP 0x63 /* Broadband repeat indicator */ #define ATM_IE_CGPN 0x6c /* Calling party number */ #define ATM_IE_CGPS 0x6d /* Calling party subaddress */ #define ATM_IE_CDPN 0x70 /* Called party number */ #define ATM_IE_CDPS 0x71 /* Called party subaddress */ #define ATM_IE_TNS 0x78 /* Transit network selection */ #define ATM_IE_RESTART 0x79 /* Restart indicator */ #define ATM_IE_GIT 0x7f /* Generic identifier transport */ #define ATM_IE_ALT_TD 0x81 /* Alternate ATM traffic descriptor */ #define ATM_IE_MIN_TD 0x80 /* Minimum acceptable ATM traffic desc. */ #define ATM_IE_ABR_SET_PRM 0x84 /* ABR setup parameters */ #define ATM_IE_BBRT 0x89 /* Broadband report type */ #define ATM_IE_ABR_ADD_PRM 0xe4 /* ABR additional parameters */ #define ATM_IE_LIJ_ID 0xe8 /* Leaf initiated join call identifer */ #define ATM_IE_LIJ_PRM 0xe9 /* Leaf initiated join parameters */ #define ATM_IE_LEAF_SN 0xea /* Leaf sequence number */ #define ATM_IE_SCOPE_SEL 0xeb /* Connection Scope Selection */ #define ATM_IE_EQOS 0xec /* Extended QOS parameters */ /* Cause: Location */ #define ATM_LOC_USER 0 /* user */ #define ATM_LOC_PRV_LOC 1 /* private network serving the local user */ #define ATM_LOC_PUB_LOC 2 /* public network serving the local user */ #define ATM_LOC_TRANS_NET 3 /* transit network */ #define ATM_LOC_PRV_RMT 4 /* public network serving the remote user */ #define ATM_LOC_PUB_RMT 5 /* private network serving the remote user */ #define ATM_LOC_INT_NET 7 /* international network */ #define ATM_LOC_BEYOND_IWP 10 /* network beyond interworking point */ /* Cause: Cause values */ /* ----------------------------------- normal event */ #define ATM_CV_UNALLOC 1 /* unallocated (unassigned) number */ #define ATM_CV_NO_ROUTE_TNS 2 /* no route to specified transit network */ #define ATM_CV_NO_ROUTE_DEST 3 /* no route to destination */ #if defined(UNI30) || defined(DYNAMIC_UNI) #define ATM_CV_CI_UNACC 10 /* VPCI/VCI unacceptable */ #endif #if defined(UNI31) || defined(UNI40) || defined(DYNAMIC_UNI) #define ATM_CV_NORMAL_CLEAR 16 /* normal call clearing */ #endif #define ATM_CV_USER_BUSY 17 /* user busy */ #define ATM_CV_NO_USER_RESP 18 /* no user responding */ #define ATM_CV_CALL_REJ 21 /* call rejected */ #define ATM_CV_NUM_CHANGED 22 /* number changed */ #define ATM_CV_REJ_CLIR 23 /* user rejects all calls with calling line identification restriction (CLIR)*/ #define ATM_CV_DEST_OOO 27 /* destination out of order */ #define ATM_CV_INV_NUM_FMT 28 /* invalid number format (address incomplete) */ #define ATM_CV_RESP_STAT_ENQ 30 /* response to STATUS ENQUIRY */ #define ATM_CV_NORMAL_UNSPEC 31 /* normal, unspecified */ /* ----------------------------------- resource unavailable */ #define ATM_CV_CI_UNAVAIL 35 /* requested VPCI/VCI unavailable */ #if defined(UNI31) || defined(UNI40) || defined(DYNAMIC_UNI) #define ATM_CV_CI_FAIL 36 /* VPCI/VCI assignment failure */ #define ATM_CV_UCR_UNAVAIL_NEW 37 /* user cell rate not available (>3.0)*/ #endif #define ATM_CV_NET_OOO 38 /* network out of order - unused */ #define ATM_CV_TEMP_FAIL 41 /* temporary failure */ #define ATM_CV_ACC_INF_DISC 43 /* access information discarded */ #define ATM_CV_NO_CI 45 /* no VPCI/VCI available */ #define ATM_CV_RES_UNAVAIL 47 /* resource unavailable, unspecified */ /* ----------------------------------- service or option not available */ #define ATM_CV_QOS_UNAVAIL 49 /* Quality of Service unavailable */ #if defined(UNI30) || defined(ALLOW_UNI30) || defined(DYNAMIC_UNI) #define ATM_CV_UCR_UNAVAIL_OLD 51 /* user cell rate not available (3.0) */ #endif #define ATM_CV_BBCAP_NOT_AUTH 57 /* bearer capability not authorized */ #define ATM_CV_BBCAP_UNAVAIL 58 /* bearer capability not presently available */ #define ATM_CV_UNAVAILABLE 63 /* service or option not available, unspecified */ /* ----------------------------------- service or option not implemented */ #define ATM_CV_BBCAP_NOT_IMPL 65 /* bearer capability not implemented */ #define ATM_CV_UNSUPP_TRAF_PRM 73 /* unsupported combination of traffic parameters */ #if defined(UNI31) || defined(UNI40) || defined(DYNAMIC_UNI) #define ATM_CV_AAL_UNSUPP_NEW 78 /* AAL param. cannot be supported (>3.0) */ #endif /* ----------------------------------- invalid message */ #define ATM_CV_INV_CR 81 /* invalid call reference value */ #define ATM_CV_NO_SUCH_CHAN 82 /* identified channel does not exist */ #define ATM_CV_INCOMP_DEST 88 /* incompatible destination */ #define ATM_CV_INV_EPR 89 /* invalid endpoint reference */ #define ATM_CV_INV_TNS 91 /* invalid transit network selection */ #define ATM_CV_TOO_MANY_APR 92 /* too many pending add party requests */ #if defined(UNI30) || defined(DYNAMIC_UNI) #define ATM_CV_AAL_UNSUPP_OLD 93 /* AAL param. cannot be supported (3.0) */ #endif /* ----------------------------------- protocol error */ #define ATM_CV_MAND_IE_MISSING 96 /* mandatory information element is missing */ #define ATM_CV_UNKNOWN_MSG_TYPE 97 /* message type non-existent or not implemented */ #define ATM_CV_UNKNOWN_IE 99 /* information element non-existent or not implemented */ #define ATM_CV_INVALID_IE 100 /* invalid information element contents */ #define ATM_CV_INCOMP_MSG 101 /* message not compatible with call state*/ #define ATM_CV_TIMER_EXP 102 /* recovery on timer expiry */ #define ATM_CV_BAD_MSG_LEN 104 /* incorrect message length */ #define ATM_CV_PROTOCOL_ERROR 111 /* protocol error, unspecified */ /* Cause: P-U values */ #define ATM_PU_PROVIDER 0 /* Network service - Provider */ #define ATM_PU_USER 1 /* Network service - User */ /* Cause: N-A values */ #define ATM_NA_NORMAL 0 /* Normal */ #define ATM_NA_ABNORMAL 1 /* Abnormal */ /* Cause: Condition */ #define ATM_COND_UNKNOWN 0 /* Unknown */ #define ATM_COND_PERMANENT 1 /* Permanent */ #define ATM_COND_TRANSIENT 2 /* Transient */ /* Cause: Reject reason */ #define ATM_RSN_USER 0 /* User specific */ #define ATM_RSN_IE_MISS 1 /* Information element missing */ #define ATM_RSN_IE_INSUFF 2 /* Information element contents are not sufficient */ /* Restart Indicator class values */ #define ATM_RST_IND_VC 0 /* Indicated virtual channel */ #define ATM_RST_ALL_VC 2 /* All virtual channels controlled by the Layer 3 entity which sends the RESTART message */ /* Action Indicator for messages */ #define ATM_AI_MSG_CLEAR 0 /* clear call */ #define ATM_AI_MSG_DSC_IGN 1 /* discard and ignore */ #define ATM_AI_MSG_DSC_STAT 2 /* discard and report status */ #define ATM_AI_MSG_RSV 3 /* reserved */ /* Action Indicator for IEs */ #define ATM_AI_IE_CLEAR 0 /* clear call */ #define ATM_AI_IE_DSCIE_PRC 1 /* discard IE and proceed */ #define ATM_AI_IE_DSCIE_STAT 2 /* discard IE, procees, and report status */ #define ATM_AI_IE_DSCMSG_IGN 5 /* discard message, and ignore */ #define ATM_AI_IE_DSCMSG_STAT 6 /* discard message, and report status */ /* Type of number */ #define ATM_TON_UNKNOWN 0 /* unknown */ #define ATM_TON_INTRNTNL 1 /* international number */ #define ATM_TON_NATIONAL 2 /* national number */ #define ATM_TON_NETWORK 3 /* network specific number */ #define ATM_TON_SUBSCRIBER 4 /* subscriber number */ #define ATM_TON_ABBRV 6 /* abbreviated number */ /* Numbering/addressing plan */ #define ATM_NP_UNKNOWN 0 /* unknown */ #define ATM_NP_E164 1 /* ISDN numbering plan (E.164) */ #define ATM_NP_AEA 2 /* ATM endsystem address */ #define ATM_NP_PRIVATE 9 /* private numbering plan */ /* Type of sub-address */ #define ATM_SAT_NSAP 0 /* NSAP (Rec. X.213 ISO/IEC 8348) */ #define ATM_SAT_AEA 1 /* ATM endsystem address */ #define ATM_SAT_USER 2 /* user-specified */ /* Presentation indicator */ #define ATM_PRS_ALLOW 0 /* presentation allowed */ #define ATM_PRS_RESTRICT 1 /* presentation restricted */ #define ATM_PRS_NOTAVL 2 /* number not available */ /* Screening indicator */ #define ATM_SCRN_UP_NS 0 /* user-provided, not screened */ #define ATM_SCRN_UP_VP 1 /* user-provided, verified and passed */ #define ATM_SCRN_UP_VF 2 /* user-provided, verified and failed */ #define ATM_SCRN_NP 3 /* network provided */ /* VP-associated signalling */ #define ATM_VPA_VPA 0 /* VP-associated signalling */ #define ATM_VPA_EXPL 1 /* explicit indication of VPCI */ /* Preferred/exclusive */ #define ATM_POE_EXC_EXC 0 /* exclusive VPCI; exclusive VCI */ #define ATM_POE_EXC_ANY 1 /* exclusive VPCI; any VCI */ #if defined(UNI40) || defined(DYNAMIC_UNI) #define ATM_POE_EXC_NO 2 /* exclusive VPCI; no VCI (used for VPCs) */ #endif /* Traffic descriptor tags */ #define ATM_TD_FW_PCR_0 0x82 /* Forward peak cell rate (CLP=0) */ #define ATM_TD_BW_PCR_0 0x83 /* Backward peak cell rate (CLP=0) */ #define ATM_TD_FW_PCR_01 0x84 /* Forward peak cell rate (CLP=0+1) */ #define ATM_TD_BW_PCR_01 0x85 /* Backward peak cell rate (CLP=0+1) */ #define ATM_TD_FW_SCR_0 0x88 /* Forward sustained cell rate (CLP=0) */ #define ATM_TD_BW_SCR_0 0x89 /* Backward sustained cell rate (CLP=0) */ #define ATM_TD_FW_SCR_01 0x90 /* Forward sustained cell rate (CLP=0+1) */ #define ATM_TD_BW_SCR_01 0x91 /* Backward sustained cell rate (CLP=0+1)*/ #define ATM_TD_FW_MCR_01 0x92 /* Forward ABR min. cell rate (CLP=0+1) */ #define ATM_TD_BW_MCR_01 0x93 /* Backward ABR min. cell rate (CLP=0+1) */ #define ATM_TD_FW_MBS_0 0xa0 /* Forward maximum burst size (CLP=0) */ #define ATM_TD_BW_MBS_0 0xa1 /* Backward maximum burst size (CLP=0) */ #define ATM_TD_FW_MBS_01 0xb0 /* Forward maximum burst size (CLP=0+1) */ #define ATM_TD_BW_MBS_01 0xb1 /* Backward maximum burst size (CLP=0+1) */ #define ATM_TD_BEST_EFFORT 0xbe /* Best effort indicator */ #define ATM_TD_TM_OPT 0xbf /* Traffic management options */ /* Frame discard forward/backward */ #define ATM_FD_NO 0 /* No Frame discard allowed */ #define ATM_FD_YES 1 /* Frame discard allowed */ /* Tagging forward/backward */ #define ATM_TAG_NO 0 /* Tagging not requested */ #define ATM_TAG_YES 1 /* Tagging requested */ /* Bearer class */ #define ATM_BC_BCOB_A 1 /* BCOB-A */ #define ATM_BC_BCOB_C 3 /* BCOB-C */ #define ATM_BC_BCOB_X 16 /* BCOB-X */ #define ATM_BC_TVP 24 /* Transparent VP service */ /* ATM Transfer Capability */ #define ATM_TC_CBR 0x05 /* CBR */ #define ATM_TC_CBR_CLR 0x07 /* CBR with CLR commitment on CLP=0+1 */ #define ATM_TC_VBR_RT 0x09 /* Real time VBR */ #define ATM_TC_VBR_RT_CLR 0x13 /* Real time VBR w/ CLR comm. on CLP=0+1 */ #define ATM_TC_VBR_NRT 0x0a /* Non-real time VBR */ #define ATM_TC_VBR_NRT_CLR 0x0b /* Non-real time VBR w/ CLR com. CLP=0+1 */ #define ATM_TC_ABR 0x0c /* ABR */ #define ATM_TC_VBR_NRT_R00 0x00 /* Non-real time VBR (reception only) */ #define ATM_TC_VBR_RT_R01 0x01 /* Real time VBR (reception only) */ #define ATM_TC_VBR_NRT_R02 0x02 /* Non-real time VBR (reception only) */ #define ATM_TC_CBR_R04 0x04 /* CBR (reception only) */ #define ATM_TC_CBR_R06 0x06 /* CBR (reception only) */ #define ATM_TC_VBR_NRT_R08 0x08 /* Non-real time VBR (reception only) */ #define ATM_TC_RSV_20 0x20 /* Reserved for backward compatibility */ #define ATM_TC_RSV_21 0x21 /* Reserved for backward compatibility */ #define ATM_TC_RSV_22 0x22 /* Reserved for backward compatibility */ #define ATM_TC_RSV_24 0x24 /* Reserved for backward compatibility */ #define ATM_TC_RSV_25 0x25 /* Reserved for backward compatibility */ #define ATM_TC_RSV_26 0x26 /* Reserved for backward compatibility */ #define ATM_TC_RSV_28 0x28 /* Reserved for backward compatibility */ #define ATM_TC_RSV_29 0x29 /* Reserved for backward compatibility */ #define ATM_TC_RSV_2A 0x2a /* Reserved for backward compatibility */ #define ATM_TC_RSV_40 0x40 /* Reserved for backward compatibility */ #define ATM_TC_RSV_41 0x41 /* Reserved for backward compatibility */ #define ATM_TC_RSV_42 0x42 /* Reserved for backward compatibility */ #define ATM_TC_RSV_44 0x44 /* Reserved for backward compatibility */ #define ATM_TC_RSV_45 0x45 /* Reserved for backward compatibility */ #define ATM_TC_RSV_46 0x46 /* Reserved for backward compatibility */ #define ATM_TC_RSV_48 0x48 /* Reserved for backward compatibility */ #define ATM_TC_RSV_49 0x49 /* Reserved for backward compatibility */ #define ATM_TC_RSV_4A 0x4a /* Reserved for backward compatibility */ #define ATM_TC_RSV_60 0x60 /* Reserved for backward compatibility */ #define ATM_TC_RSV_61 0x61 /* Reserved for backward compatibility */ #define ATM_TC_RSV_62 0x62 /* Reserved for backward compatibility */ #define ATM_TC_RSV_64 0x64 /* Reserved for backward compatibility */ #define ATM_TC_RSV_65 0x65 /* Reserved for backward compatibility */ #define ATM_TC_RSV_66 0x66 /* Reserved for backward compatibility */ #define ATM_TC_RSV_68 0x68 /* Reserved for backward compatibility */ #define ATM_TC_RSV_69 0x69 /* Reserved for backward compatibility */ #define ATM_TC_RSV_6A 0x6a /* Reserved for backward compatibility */ #ifdef OBSOLETE_DEFINITIONS_FOLLOW /* Traffic type */ ATM_TT_NO_IND 0 /* no indication */ ATM_TT_CBR 1 /* constant bit rate */ ATM_TT_VBR 2 /* variable bit rate */ /* Timing requirements */ ATM_TR_NO_IND 0 /* no indication */ ATM_TR_E2E_REQ 1 /* end-to-end timing required */ ATM_TR_E2E_NRQ 2 /* end-to-end timing not required */ #endif /* Susceptibility to clipping */ #define ATM_STC_NO 0 /* not susceptible to clipping */ #define ATM_STC_YES 1 /* susceptible to clipping */ /* User-plane connection configuration */ #define ATM_UPCC_P2P 0 /* point-to-point */ #define ATM_UPCC_P2M 1 /* point-to-multipoint */ /* Instruction field flags */ #define ATM_FLAG_NO 0 /* instruction field not significant */ #define ATM_FLAG_YES 1 /* follow explicit instructions */ /* AAL parameter tags */ #define ATM_AALP_FW_MAX_SDU 0x8c /* Forward maximum CPCS-SDU size */ #define ATM_AALP_BW_MAX_SDU 0x81 /* Backward maximum CPCS-SDU size */ #define ATM_AALP_AAL_MODE 0x83 /* AAL mode (UNI 3.0 only) */ #define ATM_AALP_SSCS 0x84 /* SSCS type */ /* Transit delay identifiers */ #define ATM_TDL_CUM 0x01 /* Cumulative transit delay value */ #define ATM_TDL_E2EMAX 0x03 /* Maximum end-to-end transit delay value*/ #define ATM_TDL_NGI 0x06 /* Network generated indicator */ /* Transit network identification */ #define ATM_TNI_USER 0x00 /* User-specified */ #define ATM_TNI_NNI 0x02 /* National network identification */ #define ATM_TNI_INI 0x04 /* International network identification */ /* Network identification plan */ #define ATM_NIP_UNKNOWN 0x00 /* Unknown */ #define ATM_NIP_CARRIER 0x01 /* Carrier identification code */ #define ATM_NIP_DATA 0x03 /* Data network id. code (X.121) */ /* Shaping indicator */ #define ATM_SHI_NONE 0x00 /* No user specified requirement */ #define ATM_SHI_NOAGG 0x01 /* Aggr. shaping of user & OAM not all. */ /* Compliance indicator */ #define ATM_OCI_OPT 0x00 /* Use of e2e OAM F5 flow is optional */ #define ATM_OCI_MAND 0x01 /* Use of e2e OAM F5 flow is mandatory */ /* User-network fault management indicator */ #define ATM_UNFM_NONE 0x00 /* No user-orig. fault mg. indications */ #define ATM_UNFM_1CPS 0x01 /* Use of u-o fm. ind. w/ rate 1 cps */ /* End-to-end OAM F5 flow indicator */ #define ATM_OFI_0_0 0x00 /* 0% of cell rate (CLP=0+1) in ATM TD */ #define ATM_OFI_0_1 0x01 /* 0.1% of cell rate (CLP=0+1) in ATM TD */ #define ATM_OFI_1_0 0x04 /* 1% of cell rate (CLP=0+1) in ATM TD */ /* Identifier related standard/application */ #define ATM_IRS_DSMCC 0x01 /* DSM-CC ISO/IEC 13818-6 */ #define ATM_IRS_H245 0x02 /* Recommendation H.245 */ /* Identifier type */ #define ATM_IT_SESSION 0x01 /* Session */ #define ATM_IT_RESOURCE 0x02 /* Resource */ /* Leaf call identifier type */ #define ATM_LIT_ROOT 0x00 /* Root assigned */ /* (LIJ) screening indication */ #define ATM_LSI_NJ_NR 0x00 /* Network Join Without Root Notif. */ /* Type of connection scope */ #define ATM_TCS_ORGANIZATIONAL 0x00 /* Organizational */ /* Connection scope selection */ #define ATM_CSS_RSV_00 0x00 /* Reserved */ #define ATM_CSS_LOCAL 0x01 /* Local network */ #define ATM_CSS_LOCAL_P1 0x02 /* Local network plus one */ #define ATM_CSS_LOCAL_P2 0x03 /* Local network plus two */ #define ATM_CSS_SITE_M1 0x04 /* Site minus one */ #define ATM_CSS_SITE 0x05 /* Intra-site */ #define ATM_CSS_SITE_P1 0x06 /* Site plus one */ #define ATM_CSS_ORG_M1 0x07 /* Organization minus one */ #define ATM_CSS_ORG 0x08 /* Intra-organization */ #define ATM_CSS_ORG_P1 0x09 /* Organization plus one */ #define ATM_CSS_COM_M1 0x0a /* Community minus one */ #define ATM_CSS_COM 0x0b /* Intra-community */ #define ATM_CSS_COM_P1 0x0c /* Community plus one */ #define ATM_CSS_REG 0x0d /* Regional */ #define ATM_CSS_INTER 0x0e /* Inter-regional */ #define ATM_CSS_GLOBAL 0x0f /* Global */ /* Origin (of extended QOS) */ #define ATM_EQO_USER 0x00 /* Originating user */ #define ATM_EQO_NET 0x01 /* Intermediate network */ /* Extended QOS parameters */ #define ATM_EQP_ACC_FW_CDV 0x94 /* Acceptable fwd peak-to-peak CDV */ #define ATM_EQP_ACC_BW_CDV 0x95 /* Acceptable bwd peak-to-peak CDV */ #define ATM_EQP_CUM_FW_CDV 0x96 /* Cumulative fwd peak-to-peak CDV */ #define ATM_EQP_CUM_BW_CDV 0x97 /* Cumulative bwd peak-to-peak CDV */ #define ATM_EQP_ACC_FW_CLR 0xa2 /* Acceptable fwd cell loss ratio */ #define ATM_EQP_ACC_BW_CLR 0xa3 /* Acceptable bwd cell loss ratio */ /* ABR additional parameters */ #define ATM_AAP_FW_REC 0xc2 /* Forward additional parameters record */ #define ATM_AAP_BW_REC 0xc3 /* Backward additional parameters record */ /* ABR setup parameters */ #define ATM_ASP_FW_ICR 0xc2 /* Forward ABR initial cell rate, CLP01 */ #define ATM_ASP_BW_ICR 0xc3 /* Backward ABR initial cell rate, CLP01 */ #define ATM_ASP_FW_TBE 0xc4 /* Fwd ABR transient buffer exposure */ #define ATM_ASP_BW_TBE 0xc5 /* Bwd ABR transient buffer exposure */ #define ATM_ASP_CRF_RTT 0xc6 /* Cumulative RM fixed round trip time */ #define ATM_ASP_FW_RIF 0xc8 /* Forward rate increase factor */ #define ATM_ASP_BW_RIF 0xc9 /* Backward rate increase factor */ #define ATM_ASP_FW_RDF 0xca /* Forward rate decrease factor */ #define ATM_ASP_BW_RDF 0xcb /* Backward rate decrease factor */ /* Type of report (Q.2963.1) */ #define ATM_TOR_MOD_CONF 0x01 /* Modification confirmation */ /* The following constants tag message parser errors. */ #define RECOV_IND_IE 1 /* IE problem */ /* The following constants tag application-specific errors. */ #define RECOV_ASE_UNKNOWN_IE 1 /* unknown IE */ #endif --- NEW FILE: first.c --- /* first.c - Phase I, input data preprocessing */ /* Written 1995-1997 by Werner Almesberger, EPFL-LRC */ #if HAVE_CONFIG_H #include <config.h> #endif #include <stdlib.h> #include <stdio.h> #include "common.h" #include "qgen.h" #include "file.h" int field = 0; int group = 0; int offset = 0; int varlen_fields = 0; static unsigned char mask = 0; static int seq = 0; #define ALLOC(field) ({ \ if (mask & beg_mask) \ die("bit collision (%s: 0x%02X+0x%02X)",walk->id,mask,beg_mask); \ field->pos += offset; \ if (next <= 8) { \ mask |= end_mask; \ walk->jump = 0; \ } \ else { \ mask = end_mask; \ walk->jump = (next-1) >> 3; \ } \ if (walk->flush && walk->size) { \ if (!mask) die("nothing to flush (%s)",walk->id); \ walk->jump++; \ mask = 0; \ } }) static void process(FIELD *start,int defines) { FIELD *walk; TAG *scan; unsigned char beg_mask,end_mask,orig_mask; int tmp,shift,next; for (walk = start; walk; walk = walk->next) { walk->field = field; /* record it even if this isn't a real field (we need to know the first field number later in second.c and this way we don't have to search for it) */ if (walk->structure) { int start_field,start_group; start_field = field; start_group = group; process(walk->my_block,walk->structure->instances > 0); if (walk->structure->instances > 1) { walk->structure->instances = -1; walk->structure->first_field = start_field; walk->structure->fields = field-start_field; walk->structure->groups = group-start_group; } continue; } walk->seq = seq++; /* number of fields, always increases */ if (*walk->id != '_') { if (defines) to_h("#define QF_%s %d\n",walk->id,field); to_test(" \"%s\",\n",walk->id); field++; } if (mask && walk->brk) die("mask 0x%02x at break (%s)\n",mask,walk->id); /* compute position and adjust masks */ tmp = walk->size > 7 ? 0xff : (1 << walk->size)-1; beg_mask = tmp << walk->pos; tmp = 0xff & ~((1 << (8-(walk->size & 7)))-1); if (walk->size && !tmp) tmp = 0xff; next = walk->pos+walk->size; shift = 8-(next & 7); if (shift == 8) shift = 0; end_mask = tmp >> shift; if (debug) printf("mask 0x%02X, beg 0x%02X, end 0x%02X, offset %d, flush %d, " "%s\n",mask,beg_mask,end_mask,offset,walk->flush,walk->id); /* handle values */ if (!walk->value) { if (walk->var_len == -2) walk->var_len = varlen_fields++; ALLOC(walk); offset += walk->jump*8; } else switch (walk->value->type) { case vt_id: ALLOC(walk); to_c(" q_put(q_initial,%d,%d,%s); /* %s */\n",walk->pos, walk->size,walk->value->id,walk->id); offset += walk->jump*8; break; case vt_case: if (*walk->id != '_') { ALLOC(walk); offset += walk->jump*8; #if 0 /* bad idea */ for (scan = walk->value->tags; scan; scan = scan->next) if (scan->deflt) { to_c(" q_put(q_initial,%d,%d,%s); " "/* %s */\n",walk->pos,walk->size, scan->value,walk->id); } #endif } /* fall through */ #if 0 if (*walk->id != '_') { ALLOC(walk); offset += walk->jump*8; orig_mask = mask; for (scan = walk->value->tags; scan; scan = scan->next) { if (scan->id && defines) to_h("#define QG_%s %d\n",scan->id,-group-1); scan->group = group++; scan->pos = walk->pos; mask = orig_mask; to_c(" q_put(q_initial,%d,%d,%s); /* %s */\n", walk->pos,walk->size,scan->value,walk->id); process(scan->block,defines); if (mask) offset += 8; } break; } #endif /* fall through */ case vt_multi: orig_mask = mask; for (scan = walk->value->tags; scan; scan = scan->next) { if (scan->id && defines) to_h("#define QG_%s %d\n",scan->id,-group-1); scan->group = group++; scan->pos = walk->pos; if (debug) printf("| %s/%s (walk->flush = %d)\n",walk->id, scan->value,walk->flush); if (*walk->id != '_') mask = orig_mask; else { ALLOC(scan); if (debug) printf("| jump = %d (mask 0x%02x)\n", walk->jump,mask); offset += walk->jump*8; to_c(" q_put(q_initial,%d,%d,%s); /* %s */\n", scan->pos,walk->size,scan->value,walk->id); } process(scan->block,defines); if (*walk->id != '_' && mask) die("EF129"); } break; case vt_length: ALLOC(walk); offset += walk->jump*8; process(walk->value->block,defines); break; default: abort(); } } } void first(FIELD *def) { def->group = group++; to_h("/*\n * Identifiers to access numbers of fields and of named\n"); to_h(" * groups (unnamed groups don't need that). Field numbers are\n"); to_h(" * zero-based. Group numbers are negative and -1-based.\n */\n\n"); to_c("static unsigned char q_initial[Q_DATA_BYTES];\n\n"); to_c("/*\n * Initialization of constant data. Could also do this in\n"); to_c(" * the translator and output the resulting byte stream.\n */\n\n"); to_c("static void q_init_global(void)\n{\n"); to_c(" memset(q_initial,0,sizeof(q_initial));\n"); to_test("static const char *fields[] = {\n"); process(def,1); to_test(" NULL\n};\n\n"); to_c("}\n\n"); if (mask) offset += 8; to_h("\n/*\n * Sizes of various tables which are allocated at run-time.\n"); to_h(" */\n"); to_h("\n#define Q_DATA_BYTES %d\n",offset/8); to_h("#define Q_GROUPS %d\n",group); to_h("#define Q_FIELDS %d\n",field); to_h("#define Q_VARLEN_FIELDS %d\n\n",varlen_fields); } --- NEW FILE: third.c --- /* third.c - Phase III, code generation */ /* Written 1995-1997 by Werner Almesberger, EPFL-LRC */ #if HAVE_CONFIG_H #include <config.h> #endif #include <stdlib.h> #include <stdio.h> #include "common.h" #include "qgen.h" #include "file.h" typedef struct _break { int pc; struct _break *next; } BREAK; int constr_size,parser_size; static BREAK *brks = NULL; static void construct(FIELD *start) { FIELD *walk; TAG *scan; int patch_here; patch_here = 0; /* for gcc */ for (walk = start; walk; walk = walk->next) { if (walk->structure) { construct(walk->my_block); continue; } if (!walk->value) if (walk->var_len == -1) code("%s%d%d%d/* %s */\n","OP_COPY",walk->jump,walk->pos, walk->size,walk->id); else code("%s%d%d%d/* %s */\n","OP_COPYVAR",walk->var_len, walk->pos,walk->size/8,walk->id); else switch (walk->value->type) { case vt_id: code("%s%d%d%d/* %s */\n","OP_COPY",walk->jump,walk->pos, walk->size,walk->id); break; case vt_case: if (*walk->id != '_') code("%s%d%d%d/* %s */\n","OP_COPY",walk->jump, walk->pos,walk->size,walk->id); for (scan = walk->value->tags; scan; scan = scan->next) { if (debug) printf("C %s/%s(%d): %d\n",walk->id,scan->value, scan->group,scan->deflt); if (!scan->deflt) { code("%s%d%s\n","OP_IFGROUP",scan->group,"?"); patch_here = pc-1; } if (*walk->id == '_') code("%s%d%d%d/* %s */\n","OP_COPY",walk->jump, scan->pos,walk->size,scan->value); construct(scan->block); if (scan->next) { code("%s%s\n","OP_JUMP","?"); scan->patch = pc-1; } if (!scan->deflt) patch(patch_here,pc-patch_here-1); } for (scan = walk->value->tags; scan && scan->next; scan = scan->next) patch(scan->patch,pc-scan->patch-1); break; case vt_multi: for (scan = walk->value->tags; scan; scan = scan->next) { if (debug) printf("M %s/%s(%d)\n",walk->id,scan->value, scan->group); code("%s%d%s\n","OP_IFGROUP",scan->group,"?"); scan->patch = pc-1; code("%s%d%d%d/* %s */\n","OP_COPY",walk->jump, scan->pos,walk->size,scan->value); construct(scan->block); patch(scan->patch,pc-scan->patch-1); } break; case vt_length: code("%s%d%d%d/* %s */\n","OP_BEGIN_LEN",walk->jump, walk->pos,walk->size,walk->id); construct(walk->value->block); code("%s\n","OP_END_LEN"); break; default: abort(); } } } static void parser(FIELD *start,int level,int group) { FIELD *walk; TAG *scan; VALUE_LIST *tag; int count,patch_here; BREAK *brk,*tmp_brks,*next; patch_here = 0; /* for gcc */ for (walk = start; walk; walk = walk->next) { if (walk->structure) { parser(walk->my_block,level,group); continue; } if (walk->brk) { code("%s%s\n","OP_IFEND","?"); brk = alloc_t(BREAK); brk->pc = pc-1; brk->next = brks; brks = brk; } if (dump) { if ((!walk->value || walk->value->type != vt_multi) && walk->size) code("%s%d\n","OP_DUMP",walk->seq); if (walk->value || walk->name_list) to_dump(" { %d, dump_sym_%d, \"%s\" },\n",level, walk->name_list ? walk->name_list->id : walk->seq,walk->id); else to_dump(" { %d, NULL, \"%s\" },\n",level,walk->id); } if (!walk->value) { if (walk->var_len != -1) code("%s%d%d%d/* %s */\n","OP_COPYVAR",walk->var_len,walk->pos, walk->size/8,walk->id); else if (*walk->id != '_' || walk->jump || dump) code("%s%d%d%d/* %s */\n","OP_COPY",walk->jump,walk->pos, walk->size,walk->id); } else switch (walk->value->type) { case vt_id: if (*walk->id != '_' || walk->jump || dump) code("%s%d%d%d/* %s */\n","OP_COPY",walk->jump, walk->pos,walk->size,walk->id); break; case vt_multi: code("%s%s/* %s */\n","OP_IFEND","?",walk->id); walk->patch = pc-1; if (dump) code("%s%d\n","OP_DUMP",walk->seq); /* fall through */ case vt_case: if (*walk->id != '_' || dump) code("%s%d%d%d/* %s */\n","OP_COPY",0,walk->pos, walk->size,walk->id); /* don't move */ count = 0; for (scan = walk->value->tags; scan; scan = scan->next) { count++; for (tag = scan->more; tag; tag = tag->next) count++; } code("%s%d%d%d%d/* %s */\n","OP_CASE",walk->jump, walk->pos,walk->size,count,walk->id); for (scan = walk->value->tags; scan; scan = scan->next) { code("%s%d%s\n",scan->deflt ? "-1" : scan->value, scan->group,"?"); scan->patch = pc-1; for (tag = scan->more; tag; tag = tag->next) { code("%s%d%s\n",tag->value,scan->group,"?"); tag->patch = pc-1; } } for (scan = walk->value->tags; scan; scan = scan->next) { patch(scan->patch,pc-scan->patch-1); for (tag = scan->more; tag; tag = tag->next) patch(tag->patch,pc-tag->patch-1); if (!scan->block && scan->abort_id) code("%s%s\n","OP_ABORT",scan->abort_id); parser(scan->block,level+1,scan->group); if (scan->next) { code("%s%s\n","OP_JUMP","?"); scan->patch = pc-1; } } for (scan = walk->value->tags; scan && scan->next; scan = scan->next) patch(scan->patch,pc-scan->patch-1); if (walk->value->type == vt_multi) { code("%s%d\n","OP_JUMP",walk->patch-pc-3); patch(walk->patch,pc-walk->patch-1); } break; case vt_length: code("%s%d%d%d/* %s */\n","OP_BEGIN_LEN",walk->jump, walk->pos,walk->size,walk->id); if (walk->value->recovery) { code("%s%s%d%d\n","OP_BEGIN_REC",walk->value->recovery, group,"?"); patch_here = pc-1; } tmp_brks = brks; if (!walk->value->block && walk->value->abort_id) code("%s%s\n","OP_ABORT",walk->value->abort_id); parser(walk->value->block,level+1,group); if (walk->value->recovery) { code("%s\n","OP_END_REC"); patch(patch_here,pc); } for (brk = brks; brk; brk = next) { next = brk->next; patch(brk->pc,pc-brk->pc-1); free(brk); } brks = tmp_brks; code("%s /* %s */\n","OP_END_LEN",walk->id); break; default: abort(); } } } void third(FIELD *def) { if (dump) constr_size = 0; else { to_c("\n/*\n"); to_c(" * \"Microcode\" used to construct messages. It copies all\n"); to_c(" * fields from the construction area to the resulting message."); to_c("\n */\n\n"); to_c("static int construct[] = {\n"); begin_code(); construct(def); constr_size = end_code()+1; to_c(" OP_END\n};\n\n"); } to_c("\n/*\n * \"Microcode\" used to parse messages. It detects the\n"); to_c(" * presence of fields and copies them from the message to the\n"); to_c(" * construction area.\n */\n\n"); to_c("static int parse[] = {\n"); if (dump) { to_dump("typedef struct {\n int level;\n const SYM_NAME *sym;\n"); to_dump(" const char *name;\n"); to_dump("} DUMP_FIELD;\n\n"); to_dump("static DUMP_FIELD dump_fields[] = {\n"); } begin_code(); parser(def,0,0); parser_size = end_code()+1; to_c(" OP_END\n};\n\n"); if (dump) to_dump("};\n\n"); } --- NEW FILE: mknl.pl --- #!/usr/bin/perl print "# THIS IS A MACHINE-GENERATED FILE. DO NOT EDIT !\n" || die "write: $!"; while ($line = <STDIN>) { chop($line); next unless $line =~ /^#define\s/; while ($line =~ m|/\*| && $line !~ m|\*/|) { $line .= <STDIN>; } $line =~ s/\s+/ /g; if (!defined($curr) || $line !~ /^#define ${curr}_/) { undef $curr; for (@ARGV) { ($tmp = $_) =~ tr/a-z/A-Z/; next unless $line =~ /^#define ${tmp}_/; $curr = $tmp; print "\n:$_\n" || die "write: $!"; last; } } next unless defined $curr; next unless $line =~ m|^#define (\S+) (\S+)( (/\*\s*(.*\S)\s*\*/))?|; # if (defined $3) { # print "$2=$1 $4\n" || die "write: $!"; # } if (defined $3) { print "$2=$2 \\\"$5\\\"\n" || die "write: $!"; } else { print "$2=$1\n" || die "write: $!"; } } --- NEW FILE: common.c --- /* common.c - Common functions */ /* Written 1995 by Werner Almesberger, EPFL-LRC */ #if HAVE_CONFIG_H #include <config.h> #endif #include <stdlib.h> #include <stdarg.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include "common.h" void *alloc(size_t size) { void *n; n = malloc(size); if (n) return n; perror("malloc"); exit(1); } char *stralloc(const char *str) { char *n; n = strdup(str); if (n) return n; perror("malloc"); exit(1); } void die(const char *fmt,...) { va_list ap; fflush(stdout); va_start(ap,fmt); vfprintf(stderr,fmt,ap); va_end(ap); fputc('\n',stderr); exit(1); } --- NEW FILE: common.h --- /* common.h - Common definitions */ /* Written 1995,1996 by Werner Almesberger, EPFL-LRC */ #ifndef COMMON_H #define COMMON_H #include <sys/types.h> #define alloc_t(t) ((t *) alloc(sizeof(t))) extern int debug; extern int dump; void *alloc(size_t size); char *stralloc(const char *str); void die(const char *fmt,...); #endif --- NEW FILE: file.c --- /* file.c - (source) file IO */ /* Written 1995,1996 by Werner Almesberger, EPFL-LRC */ #if HAVE_CONFIG_H #include <config.h> #endif #include <stdlib.h> #include <stdarg.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include "common.h" #include "file.h" #define DEFAULT_BUF_SIZE 256 typedef struct { const char *data; const char *extra; } CODE_ITEM; int pc; static FILE *h_file,*c_file,*test_file,*dump_file; static CODE_ITEM *buf; static int buf_size; void to_h(const char *fmt,...) { va_list ap; va_start(ap,fmt); if (vfprintf(h_file,fmt,ap) == EOF) { perror("write"); exit(1); } va_end(ap); } void to_c(const char *fmt,...) { va_list ap; va_start(ap,fmt); if (vfprintf(c_file,fmt,ap) == EOF) { perror("write"); exit(1); } va_end(ap); } void to_test(const char *fmt,...) { va_list ap; va_start(ap,fmt); if (vfprintf(test_file,fmt,ap) == EOF) { perror("write"); exit(1); } va_end(ap); } void to_dump(const char *fmt,...) { va_list ap; va_start(ap,fmt); if (vfprintf(dump_file,fmt,ap) == EOF) { perror("write"); exit(1); } va_end(ap); } void open_files(const char *prefix) { char name[100]; /* maximum name */ sprintf(name,"%s.out.h",prefix); h_file = fopen(name,"w"); if (!h_file) { perror("creat"); exit(1); } sprintf(name,"%s.out.c",prefix); c_file = fopen(name,"w"); if (!c_file) { perror("creat"); exit(1); } sprintf(name,"%s.test.c",prefix); test_file = fopen(name,"w"); if (!test_file) { perror("creat"); exit(1); } if (dump) { sprintf(name,"%s.dump.c",prefix); dump_file = fopen(name,"w"); if (!dump_file) { perror("creat"); exit(1); } } } void close_files(void) { if (fclose(h_file) == EOF) { perror("fclose"); exit(1); } if (fclose(c_file) == EOF) { perror("fclose"); exit(1); } if (fclose(test_file) == EOF) { perror("fclose"); exit(1); } if (dump) if (fclose(dump_file) == EOF) { perror("fclose"); exit(1); } } void begin_code(void) { pc = 0; buf_size = DEFAULT_BUF_SIZE; buf = alloc(sizeof(CODE_ITEM)*buf_size); } static void put_item(const char *item) { if (pc >= buf_size) { buf_size *= 2; buf = realloc(buf,sizeof(CODE_ITEM)*buf_size); if (!buf) die("out of memory"); } buf[pc].data = item; buf[pc++].extra = NULL; } static void append_last(const char *str) { buf[pc-1].extra = str; } static char *itos(int val) { char buffer[21]; /* enough for 64 bits ... */ sprintf(buffer,"%d",val); return stralloc(buffer); } void code(const char *fmt,...) { va_list ap; va_start(ap,fmt); while (*fmt) if (*fmt++ == '%') { switch (*fmt++) { case 'd': put_item(itos(va_arg(ap,int))); break; case 's': put_item(va_arg(ap,const char *)); break; default: die("invalid format character %c",fmt[-1]); } } else { const char *here; here = strchr(--fmt,'%'); if (!here) append_last(fmt); else { char buffer[200]; /* ugly */ if (here[1] != 's') die("bad format in extension"); strncpy(buffer,fmt,(size_t) (here-fmt)); strcpy(buffer+(here-fmt),va_arg(ap,const char *)); strcat(buffer,here+2); append_last(stralloc(buffer)); } break; } va_end(ap); } int end_code(void) { int indent,i; indent = 1; for (i = 0; i < pc; i++) { if (indent) { to_c(" "); indent = 0; } to_c(buf[i].data); if (buf[i].extra && *buf[i].extra == '\n') to_c(","); else to_c(", "); if (buf[i].extra) { to_c(buf[i].extra); indent = !!strchr(buf[i].extra,'\n'); if (indent) to_c("/*%4d*/",i+1); } } return pc; } void patch(int old_pc,int value) { /* may leak memory */ buf[old_pc].data = itos(value); } --- NEW FILE: file.h --- /* file.h - (source) file IO */ /* Written 1995,1996 by Werner Almesberger, EPFL-LRC */ #ifndef FILE_H #define FILE_H extern int pc; void open_files(const char *prefix); void to_h(const char *fmt,...); void to_c(const char *fmt,...); void to_test(const char *fmt,...); void to_dump(const char *fmt,...); void close_files(void); void begin_code(void); void code(const char *fmt,...); int end_code(void); void patch(int old_pc,int value); #endif --- NEW FILE: Makefile.am --- noinst_PROGRAMS = qgen q.dump # q40.out.o check_PROGRAMS = q.test qgen_SOURCES = common.c common.h file.c file.h first.c ql_y.y ql_l.l qgen.c \ qgen.h second.c third.c qgen_LDADD = -lfl q_dump_SOURCES = common.c q_dump_LDADD = qd.dump.standalone.o # FIXME: paulsch: We don't really depend on qd.dump.o or q.out.o here, but this # trick will get it built with only a minor glitch in the dependency checking # for q.dump. q_dump_DEPENDENCIES = $(q_dump_LDADD) qd.dump.o q.out.o EXTRA_q_dump_SOURCES = op.h uni.h qlib.c qlib.h q_test_SOURCES = qtest.c uni.h q_test_DEPENDENCIES = q.test.c #TESTS = $(check_PROGRAMS) EXTRA_DIST = ql_y.h incl.pl mknl.pl msg.fmt TODO CLEANFILES = q.out.h q.out.c q.test.c qd.out.h qd.out.c qd.dump.c qd.test.c \ default.nl # q40.out.h q40.out.c q40.test.c NLS = atm_ai_msg atm_ai_ie atm_loc atm_cv atm_pu atm_na atm_cond atm_ie \ atm_msg atm_np atm_ton atm_sat atm_prs atm_scrn atm_vpa atm_poe \ q2931_cs atm_td atm_bc atm_tc atm_stc atm_upcc q2931_proto atm_flag \ atm_aalp atm_fd atm_tag atm_l2 atm_l3 atm_tt atm_mc atm_hl atm_imd \ atm_tdl atm_tni atm_nip atm_shi atm_oci atm_unfm atm_ofi atm_irs \ atm_it atm_lit atm_lsi atm_tcs atm_css atm_eqo atm_eqp atm_aap \ atm_asp atm_tor SYMFILES = uni.h $(shell @PERL@ incl.pl $(CFLAGS) linux/atmsap.h) default.nl: mknl.pl $(SYMFILES) cat $(SYMFILES) | @PERL@ mknl.pl $(NLS) >default.nl || \ { rm -f default.nl; echo 1; } q.out.h q.out.c q.test.c: qgen msg.fmt default.nl $(CPP) $(DEFS) - <msg.fmt | ./qgen #q40.out.h q40.out.c q40.test.c: qgen uni40 default.nl # $(CPP) $(DEFS) - <uni40 | PREFIX=q40 ./qgen qd.out.h qd.out.c qd.dump.c: qgen msg.fmt default.nl $(CPP) $(DEFS) - <msg.fmt | ./qgen -D q.out.o: q.out.c q.out.h qlib.c qlib.h $(CC) $(DEFS) $(CFLAGS) -c q.out.c #q40.out.o: q40.out.c q40.out.h qlib.c qlib.h # $(CC) -DUNI40 $(CFLAGS) -c q40.out.c qd.dump.o: qd.dump.c qd.out.c qlib.c qlib.h $(CC) $(DEFS) $(CFLAGS) -c qd.dump.c qd.dump.standalone.o: qd.dump.c qd.out.c qlib.c qlib.h $(CC) $(DEFS) -DSTANDALONE $(CFLAGS) -c qd.dump.c \ -o qd.dump.standalone.o --- NEW FILE: msg.fmt --- /* msg.fmt - Signaling message format decription for UNI 3.0, 3.1, and 4.0 */ /* Written 1995-1998 by Werner Almesberger, EPFL-LRC/ICA */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #undef linux /* grr ... */ include "atmsap.h" include "uni.h" #define VAR_STD_HDR(name,defl) \ _ext <1@8,more> = 1 \ name##_cs "q2931_cs" <2@6,more> = defl \ _flag "atm_flag" <1@5,more> = ATM_FLAG_NO \ _action_ind "atm_ai_ie" <3@1> = 0 /* only 2 bits in UNI 3.0 */ \ _ie_len <16> = recover RECOV_IND_IE length #define ITU_STD_HDR VAR_STD_HDR(,Q2931_CS_ITU) #define NET_STD_HDR VAR_STD_HDR(,Q2931_CS_NET) def ie_aal = { ITU_STD_HDR { aal_type <8> = case { 5 { _id "atm_aalp" <8> = multi { ATM_AALP_FW_MAX_SDU { fw_max_sdu <16> } ATM_AALP_BW_MAX_SDU { bw_max_sdu <16> } #if defined(UNI30) || defined(ALLOW_UNI30) || defined(DYNAMIC_UNI) ATM_AALP_AAL_MODE { aal_mode <8> # UNI 3.0 only } #endif ATM_AALP_SSCS { sscs_type <8> } } } } } } #define TRAFFIC_DESCRIPTOR_PCR(p) \ ATM_TD_FW_PCR_0 { p##fw_pcr_0 <24> } \ ATM_TD_BW_PCR_0 { p##bw_pcr_0 <24> } \ ATM_TD_FW_PCR_01 { p##fw_pcr_01 <24> } \ ATM_TD_BW_PCR_01 { p##bw_pcr_01 <24> } \ #define TRAFFIC_DESCRIPTOR_VBR(p) \ ATM_TD_FW_SCR_0 { p##fw_scr_0 <24> } \ ATM_TD_BW_SCR_0 { p##bw_scr_0 <24> } \ ATM_TD_FW_SCR_01 { p##fw_scr_01 <24> } \ ATM_TD_BW_SCR_01 { p##bw_scr_01 <24> } \ ATM_TD_FW_MBS_0 { p##fw_mbs_0 <24> } \ ATM_TD_BW_MBS_0 { p##bw_mbs_0 <24> } \ ATM_TD_FW_MBS_01 { p##fw_mbs_01 <24> } \ ATM_TD_BW_MBS_01 { p##bw_mbs_01 <24> } \ #define TRAFFIC_DESCRIPTOR_BE(p) \ ATM_TD_BEST_EFFORT { p##best_effort <0> } \ #if defined(UNI40) || defined(DYNAMIC_UNI) #define TRAFFIC_DESCRIPTOR_ABR(p) \ ATM_TD_FW_MCR_01 { p##fw_mcr_01 <24> } \ ATM_TD_BW_MCR_01 { p##bw_mcr_01 <24> } \ #else #define TRAFFIC_DESCRIPTOR_ABR(p) /* not yet */ #endif #define TRAFFIC_DESCRIPTOR(p) \ TRAFFIC_DESCRIPTOR_PCR(p) \ TRAFFIC_DESCRIPTOR_VBR(p) \ TRAFFIC_DESCRIPTOR_BE(p) #ifdef NOT_YET TRAFFIC_DESCRIPTOR_ABR(p) #endif def ie_td = { # UNI 3.0 calls this "User Cell Rate" ITU_STD_HDR { _id "atm_td" <8> = multi { TRAFFIC_DESCRIPTOR(_dummy <0> = length {}) /* * Confused ? ;-) Here, we want no prefix at all, but cpp * insists in getting an argument. So we give it that funny * construct. This yields something like * ... { _dummy <0> = length {}field <24> } * with the rather useless "dummy" field. "= length {}" is * necessary to avoid the restriction that unnamed fields must * have values (which would then get concatenated with the name * of the field we're actually interested in). */ ATM_TD_TM_OPT { # @@@ should this also go into the TD macro ? #if defined(UNI40) || defined(DYNAMIC_UNI) fw_fdisc "atm_fd" <1@8,more> = ATM_FD_NO bw_fdisc "atm_fd" <1@7,more> = ATM_FD_NO #endif bw_tag "atm_tag" <1@2,more> = ATM_TAG_NO fw_tag "atm_tag" <1@1> = ATM_TAG_NO } } } } def ie_bbcap = { ITU_STD_HDR { bearer_class "atm_bc" <5@1,more> _ext <1@8> = case { 0 { _ext <1@8,more> = 1 trans_cap "atm_tc" <7@1> } default 1 {} } _ext <1@8,more> = 1 susc_clip "atm_stc" <2@6,more> = ATM_STC_NO upcc "atm_upcc" <2@1> = ATM_UPCC_P2P } } def ie_bhli = { ITU_STD_HDR { _ext <1@8,more> = 1 hli_type <7@1> = case { # Note: cannot use ATM_HL_* here, because those values are incremented by one # to keep zero available for ATM_HL_NONE 0 { # ISO iso_hli <-64> } 1 { # User Specific user_hli <-64> } #if defined(UNI30) || defined(ALLOW_UNI30) || defined(DYNAMIC_UNI) 2 { # High layer profile - UNI 3.0 only hlp <32> } #endif 3 { # Vendor-Specific Application identifier hli_oui <24> app_id <32> } #if defined(UNI40) || defined(DYNAMIC_UNI) 4 { # Reference to ITU-T SG 1 B-ISDN Teleservice Recommendation tobedefined <8> } #endif } } } def ie_blli = { ITU_STD_HDR { _lid <2@6,more> = multi { 1 { _ext <1@8,more> = 1 uil1_proto <5@1> } 2 { uil2_proto "atm_l2" <5@1,more> = case { ATM_L2_X25_LL,ATM_L2_X25_ML,ATM_L2_HDLC_ARM, ATM_L2_HDLC_NRM,ATM_L2_HDLC_ABM,ATM_L2_Q922, ATM_L2_ISO7776 { # CCITT encoding _ext <1@8> = case { 0 { l2_mode "atm_imd" <2@6,more> = ATM_IMD_NORMAL q933 <2@1,more> = 0 _ext <1@8> = case { 0 { window_size <7@1,more> _ext <1@8> = 1 } default 1 {} } } default 1 {} } } ATM_L2_USER { # User specified _ext <1@8> = 0 user_l2 <7@1,more> _ext <1@8> = 1 } default ATM_L2_ISO1745,ATM_L2_Q291,ATM_L2_LAPB, ATM_L2_ISO8802,ATM_L2_X75 { # No additional data _ext <1@8> = 1 } } } 3 { uil3_proto "atm_l3" <5@1,more> = case { ATM_L3_X25,ATM_L3_ISO8208,ATM_L3_X223 { # CCITT coding _ext <1@8> = case { 0 { l3_mode "atm_imd" <2@6,more> = ATM_IMD_NORMAL _ext <1@8> = case { 0 { def_pck_size <4@1,more> _ext <1@8> = case { 0 { _ext <1@8> = 1 pck_win_size <7@1> } default 1 {} } } default 1 {} } } default 1 {} } } #if defined(UNI40) || defined(DYNAMIC_UNI) ATM_L3_H310 { # ITU-T Rec. H.310 _ext <1@8> = case { 0 { term_type "atm_tt" <4@1,more> = ATM_TT_RXTX _ext <1@8> = case { 0 { _ext <1@8,more> = 1 fw_mpx_cap "atm_mc" <3@4,more> = ATM_MC_NONE bw_mpx_cap "atm_mc" <3@1> = ATM_MC_NONE } default 1 {} } } default 1 {} } } #endif ATM_L3_TR9577 { # ISO/IEC TR9577 _ext <1@8> = case { 0 { _ext <1@8,more> = 0 ipi_high <7@1> = case { 0x40 { # SNAP hack _ext <1@8,more> = 1 _ipi_low <1@7> = case { # ugly 0 { _ext <1@8,more> = 1 _snap_id <2@6> = 0 oui <24> pid <16> } default 1 {} } } default 0x0 { # ugly _ext <1@8,more> = 1 ipi_low <1@7> } } } default 1 {} } } ATM_L3_USER { # User specified _ext <1@8> = 0 user_l3 <7@1,more> _ext <1@8> = 1 } } } } } } def ie_call_state = { ITU_STD_HDR { call_state <6@1> } } def ie_cdpn = { ITU_STD_HDR { _ext <1@8,more> = 1 _plan "atm_np" <4@1,more> = case { ATM_NP_E164 { _type "atm_ton" <3@5> = ATM_TON_INTRNTNL cdpn_e164 <-96> } ATM_NP_AEA { # ATM Endsystem Address _type "atm_ton" <3@5> = ATM_TON_UNKNOWN cdpn_esa <-160> } } } } def ie_cdps = { ITU_STD_HDR { _ext <1@8,more> = 1 #ifdef UNI30 _type "atm_sat" <3@5,more> = ATM_SAT_AEA #endif #if defined(UNI31) || defined(DYNAMIC_UNI) cdps_type "atm_sat" <3@5,more> = ATM_SAT_AEA #endif _oddeven <1@4> = 0 cdps <-160> } } def ie_cgpn = { # @@@ extend language to allow same trick as for cdpn ITU_STD_HDR { cgpn_plan "atm_np" <4@1,more> cgpn_type "atm_ton" <3@5,more> _ext <1@8> = case { 0 { _ext <1@8,more> = 1 pres_ind "atm_prs" <2@6,more> = ATM_PRS_ALLOW scr_ind "atm_scrn" <2@1> = ATM_SCRN_UP_NS } default 1 {} } cgpn <-160> } } def ie_cgps = { ITU_STD_HDR { _ext <1@8,more> = 1 #ifdef UNI30 _type "atm_sat" <3@5,more> = ATM_SAT_AEA #endif #if defined(UNI31) || defined(DYNAMIC_UNI) cgps_type "atm_sat" <3@5,more> = ATM_SAT_AEA #endif _oddeven <1@4> = 0 cgps <-160> } } def ie_cause = { VAR_STD_HDR(cause,Q2931_CS_ITU) { _ext <1@8,more> = 1 location "atm_loc" <4@1> = ATM_LOC_USER _ext <1@8,more> = 1 cause "atm_cv" <7@1> = case { ATM_CV_UNALLOC,ATM_CV_NO_ROUTE_DEST,ATM_CV_QOS_UNAVAIL { # Note 2 break _ext <1@8,more> = 1 pu "atm_pu" <1@4,more> = ATM_PU_USER na "atm_na" <1@3,more> = ATM_NA_NORMAL cond2 "atm_cond" <2@1> = ATM_COND_UNKNOWN } ATM_CV_CALL_REJ { # Note 3 break _ext <1@8,more> = 1 cond3 "atm_cond" <2@1,more> = ATM_COND_UNKNOWN reason <5@3> = case { ATM_RSN_USER { user_diag <-216> } ATM_RSN_IE_MISS,ATM_RSN_IE_INSUFF { ie_id3 "atm_ie" <8> } } } ATM_CV_NUM_CHANGED { # Note 4 break new_dest <-224> # good luck ... } ATM_CV_REJ_CLIR { # Note 5 break invalid <8> # not supported } ATM_CV_ACC_INF_DISC,ATM_CV_INCOMP_DEST,ATM_CV_MAND_IE_MISSING, ATM_CV_UNKNOWN_IE,ATM_CV_INVALID_IE { # Note 6 break ie_id6 <-224> } #if defined(DYNAMIC_UNI) || defined(ALLOW_UNI30) ATM_CV_UCR_UNAVAIL_OLD,ATM_CV_UCR_UNAVAIL_NEW { # Note 8 #else #ifdef UNI30 ATM_CV_UCR_UNAVAIL_OLD { # Note 8 #else ATM_CV_UCR_UNAVAIL_NEW { # Note 8 #endif #endif break ucr_id <-224> } ATM_CV_NO_SUCH_CHAN { # Note 9 break unav_vpci <16> unav_vci <16> } ATM_CV_UNKNOWN_MSG_TYPE,ATM_CV_INCOMP_MSG { # Note 10 break bad_msg_type "atm_msg" <8> } ATM_CV_TIMER_EXP { # Note 11 break timer <24> } default 0 {} } } } def ie_conn_id = { ITU_STD_HDR { _ext <1@8,more> = 1 _vp_ass "atm_vpa" <2@4,more> = ATM_VPA_EXPL /* explicit */ _pref_exc "atm_poe" <3@1> = 0 vpi <16> vci <16> } } #if defined(UNI40) || defined(DYNAMIC_UNI) def ie_e2e_tdl = { ITU_STD_HDR { _id "atm_tdl" <8> = multi { ATM_TDL_CUM { cum_delay <16> } ATM_TDL_E2EMAX { max_delay <16> } ATM_TDL_NGI {} } } } #endif def ie_qos = { #if defined(UNI30) && !defined(DYNAMIC_UNI) NET_STD_HDR { #else /* * Depending on what values are put into qos_fw and qos_bw, this may * still be invalid. But at least the defaults should be okay. Note * that defining UNI30 and UNI31 together yields only the UNI30 * behaviour. We assume that everybody who implements UNI 3.1 today * has a similar kludge in their networking code, so we should get * away with that. */ VAR_STD_HDR(qos,Q2931_CS_NET) { #endif qos_fw <8> = 0 qos_bw <8> = 0 } } def ie_bbrep = { ITU_STD_HDR { _ext <1@8,more> = 1 rep_ind <4@1> = 2 } } def ie_restart = { ITU_STD_HDR { _ext <1@8,more> = 1 rst_class <3@1> } } def ie_bbs_comp = { ITU_STD_HDR { _ext <1@8,more> = 1 bbsc_ind <7@1> = 0x21 } } def ie_tns = { ITU_STD_HDR { _ext <1@8,more> = 1 _net_type "atm_tni" <3@5,more> = ATM_TNI_NNI /* @@@ default ? */ _carrier_id "atm_nip" <4@1> = ATM_NIP_CARRIER /* @@@ default ? */ net_id <-32> } } #if defined(UNI40) || defined(DYNAMIC_UNI) def ie_notify = { ITU_STD_HDR { notification <-32> # @@@ how many actually ? } } def ie_oam_td = { ITU_STD_HDR { _ext <1@8,more> = 1 shaping "atm_shi" <2@6,more> = ATM_SHI_NONE compliance "atm_oci" <1@5,more> = ATM_OCI_OPT fault "atm_unfm" <3@1> = ATM_UNFM_NONE _ext <1@8,more> = 1 fwd_ofi "atm_ofi" <3@5,more> = ATM_OFI_0_0 bwd_ofi "atm_ofi" <3@1> = ATM_OFI_0_0 } } def ie_git = { NET_STD_HDR { # @@@ UNI 4.0 does not specify the coding _dummy <1@8> = 0 # bit is "spare", although not indicated in spec id_std_app "atm_irs" <7@1> = case { ATM_IRS_DSMCC,ATM_IRS_H245 { _type "atm_it" <8> = ATM_IT_SESSION _length <8> = length { session_id <-160> } _type "atm_it" <8> = ATM_IT_RESOURCE _length <8> = length { resource_id <-32> } } default 0 { unrecognized_git_identifiers <-224> # 33-5 bytes } } } } def ie_lij_id = { NET_STD_HDR { # @@@ UNI 4.0 does not specify the coding _ext <1@8,more> = 1 lij_id_type "atm_lit" <7@1> = ATM_LIT_ROOT lij_id <32> } } def ie_lij_prm = { NET_STD_HDR { # @@@ UNI 4.0 does not specify the coding _ext <1@8,more> = 1 lij_scr_ind "atm_lsi" <2@1> } } def ie_leaf_sn = { NET_STD_HDR { # @@@ UNI 4.0 does not specify the coding leaf_sn <32> } } def ie_scope_sel = { NET_STD_HDR { # @@@ UNI 4.0 does not specify the coding _ext <1@8,more> = 1 scope_type "atm_tcs" <4@1> = ATM_TCS_ORGANIZATIONAL scope_sel "atm_css" <8> } } def ie_alt_td = { ITU_STD_HDR { _id "atm_td" <8> = multi { TRAFFIC_DESCRIPTOR(alt) } } } def ie_min_td = { NET_STD_HDR { # @@@ UNI 4.0 does not specify the coding _id "atm_td" <8> = multi { TRAFFIC_DESCRIPTOR_PCR(min) TRAFFIC_DESCRIPTOR_ABR(min) } } } def ie_eqos = { NET_STD_HDR { eqos_origin "atm_eqo" <8> _id "atm_eqp" <8> = multi { ATM_EQP_ACC_FW_CDV { acc_fw_cdv <24> } ATM_EQP_ACC_BW_CDV { acc_bw_cdv <24> } ATM_EQP_CUM_FW_CDV { cum_fw_cdv <24> } ATM_EQP_CUM_BW_CDV { cum_bw_cdv <24> } ATM_EQP_ACC_FW_CLR { acc_fw_clr <8> } ATM_EQP_ACC_BW_CLR { acc_bw_clr <8> } } } } def ie_abr_add_prm = { NET_STD_HDR { _id "atm_aap" <8> = multi { ATM_AAP_FW_REC { abr_fw_add_rec <32> } ATM_AAP_BW_REC { abr_bw_add_rec <32> } } } } def ie_abr_set_prm = { NET_STD_HDR { # @@@ UNI 4.0 does not specify the coding _id "atm_asp" <8> = multi { ATM_ASP_FW_ICR { abr_fw_icr <24> } ATM_ASP_BW_ICR { abr_bw_icr <24> } ATM_ASP_FW_TBE { abr_fw_tbe <24> } ATM_ASP_BW_TBE { abr_bw_tbe <24> } ATM_ASP_CRF_RTT { atm_crf_rtt <24> } ATM_ASP_FW_RIF { atm_fw_rif <8> } ATM_ASP_BW_RIF { atm_bw_rif <8> } ATM_ASP_FW_RDF { atm_fw_rdf <8> } ATM_ASP_BW_RDF { atm_bw_rdf <8> } } } } #endif def ie_ep_ref = { ITU_STD_HDR { _ep_type <8> = 0 ep_ref <16> } } def ie_ep_state = { ITU_STD_HDR { ep_state <6@1> } } #if defined(Q2963_1) || defined(DYNAMIC_UNI) def ie_bbrt = { ITU_STD_HDR { type_of_report "atm_tor" <8> } } #endif { _pdsc "q2931_proto" <8> = Q2931_PROTO_DSC _cr_len <8> = 3 call_ref <24> msg_type "atm_msg" <8> _ext <1@8,more> = 1 _flag "atm_flag" <1@5,more> = ATM_FLAG_NO _action_ind "atm_ai_msg" <2@1> = 0 msg_len <16> = length { _ie_id "atm_ie" <8> = multi { aal: ATM_IE_AAL ie_aal td: ATM_IE_TD ie_td bbcap: ATM_IE_BBCAP ie_bbcap bhli: ATM_IE_BHLI ie_bhli blli1: ATM_IE_BLLI ie_blli blli2: ATM_IE_BLLI ie_blli blli3: ATM_IE_BLLI ie_blli call_state: ATM_IE_CALL_STATE ie_call_state cdpn: ATM_IE_CDPN ie_cdpn cdps: ATM_IE_CDPS ie_cdps cgpn: ATM_IE_CGPN ie_cgpn cgps: ATM_IE_CGPS ie_cgps cause: ATM_IE_CAUSE ie_cause cause2: ATM_IE_CAUSE ie_cause conn_id: ATM_IE_CONN_ID ie_conn_id #if defined(UNI40) || defined(DYNAMIC_UNI) e2e_tdl: ATM_IE_E2E_TDL ie_e2e_tdl #endif qos: ATM_IE_QOS ie_qos bbrep: ATM_IE_BBREP ie_bbrep restart: ATM_IE_RESTART ie_restart bbs_comp: ATM_IE_BBS_COMP ie_bbs_comp tns: ATM_IE_TNS ie_tns #if defined(UNI40) || defined(DYNAMIC_UNI) notify: ATM_IE_NOTIFY ie_notify oam_td: AT... [truncated message content] |