1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 2003-2020. All Rights Reserved.
5%%
6%% Licensed under the Apache License, Version 2.0 (the "License");
7%% you may not use this file except in compliance with the License.
8%% You may obtain a copy of the License at
9%%
10%%     http://www.apache.org/licenses/LICENSE-2.0
11%%
12%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21%%
22%%----------------------------------------------------------------------
23%% Purpose: YECC grammar for text encoding of Megaco/H.248
24%%----------------------------------------------------------------------
25
26%%----------------------------------------------------------------------
27%% Annex B TEXT ENCODING OF THE PROTOCOL (NORMATIVE)
28%%
29%% B.1 Coding of wildcards
30%%
31%% In a text encoding of the protocol, while TerminationIDs are
32%% arbitrary, by judicious choice of names, the wildcard character, "*"
33%% may be made more useful.  When the wildcard character is encountered,
34%% it will "match" all TerminationIDs having the same previous and
35%% following characters (if appropriate).  For example, if there were
36%% TerminationIDs of R13/3/1, R13/3/2 and R13/3/3, the TerminationID
37%% R13/3/* would match all of them.  There are some circumstances where
38%% ALL Terminations must be referred to.  The TerminationID "*" suffices,
39%% and is referred to as ALL. The CHOOSE TerminationID "$" may be used to
40%% signal to the MG that it has to create an ephemeral Termination or
41%% select an idle physical Termination.
42%%
43%% B.2 ABNF specification
44%%
45%% The protocol syntax is presented in ABNF according to RFC2234.  The
46%% protocol is not case sensitive.  Identifiers are not case sensitive.
47%%----------------------------------------------------------------------
48
49%%----------------------------------------------------------------------
50%% Number of expected shift/reduce warnings
51%% This is ugly but...
52%%----------------------------------------------------------------------
53
54Expect 137.
55
56
57%%----------------------------------------------------------------------
58%% Non-terminals
59%%----------------------------------------------------------------------
60
61Nonterminals
62
63    actionReply
64    actionReplyBody
65    actionReplyList
66    actionRequest
67    actionRequestItem
68    actionRequestItems
69    actionRequestList
70    alternativeValue
71    ammParameter
72    ammParameters
73    ammRequest
74    ammRequestBody
75    ammToken
76    ammsReply
77    ammsReplyBody
78    ammsToken
79    auditDescriptor
80    auditDescriptorBody
81    auditItem
82    auditItemList
83    auditOther
84    auditReply
85    auditRequest
86    auditReturnItem
87    auditReturnParameter
88    auditReturnParameterList
89    authenticationHeader
90    commandReply
91    commandReplyList
92    commandRequest
93    contextAudit
94    contextAuditProperties
95    contextAuditProperty
96    contextID
97    contextProperty
98    contextTerminationAudit
99    daddr
100    deviceName
101    digitMapDescriptor
102    domainAddress
103    domainName
104    embedFirst
105    embedNoSig
106    embedSig
107    embedWithSig
108    errorCode
109    errorDescriptor
110    errorText
111    eventBufferControl
112    eventBufferControlState
113    eventBufferDescriptor
114    eventDM
115    eventParameter
116    eventParameterName
117    eventParameters
118    eventSpec
119    eventSpecList
120    eventStream
121    eventStreamOrOther
122    eventsDescriptor
123    extension
124    extensionParameter
125
126    %% v2 - start
127    indAudauditReturnParameter
128    indAuddigitMapDescriptor
129    indAudeventBufferDescriptor
130    indAudeventSpec
131    indAudeventSpecParameter
132    %% indAudeventSpecParameterList
133    indAudeventsDescriptor
134    indAudlocalControlDescriptor
135    indAudlocalParm
136    indAudlocalParmList
137    indAudmediaDescriptor
138    indAudmediaParm
139    %% indAudmediaParmList
140    indAudpackagesDescriptor
141    indAudrequestedEvent
142    indAudsignalsDescriptor
143    indAudsignalList
144    %% indAudsignalListParm
145    indAudsignalParm
146    %% indAudsignalRequest
147    indAudstreamDescriptor
148    indAudstreamParm
149    indAudstatisticsDescriptor
150    indAudterminationAudit
151    indAudterminationAuditList
152    indAudterminationStateDescriptor
153    indAudterminationStateParm
154    %% indAudterminationStateParmList
155    optIndAudeventSpecParameter
156    optIndAudsignalParm
157    %% v2 - end
158
159
160    localControlDescriptor
161    localParm
162    localParmList
163    mId
164    mediaDescriptor
165    mediaParm
166    mediaParmList
167    megacoMessage
168    message
169    messageBody
170    modemDescriptor   % Deprecated as of Corr 1
171    modemType         % Deprecated as of Corr 1
172    modemTypeList     % Deprecated as of Corr 1
173    mtpAddress
174    muxDescriptor
175    muxType
176    notificationReason
177    notificationReasons
178    notifyReply
179    notifyReplyBody
180    notifyRequest
181    notifyRequestBody
182    observedEvent
183    observedEventBody
184    observedEventParameter
185    observedEventParameters
186    % observedEventTimeStamp
187    observedEvents
188    observedEventsDescriptor
189    onOrOff
190    optAuditDescriptor
191    optImmAckRequired
192    optPropertyParms
193    optSep
194    packagesDescriptor
195    packagesItem
196    packagesItems
197    %% parmName
198    parmValue
199    pathName
200    pkgdName
201    portNumber
202    priority
203    propertyParm
204    propertyParms
205    requestID
206    requestedEvent
207    requestedEventBody
208    requestedEvents
209    safeToken
210    safeToken2
211    secondEventParameter
212    secondEventParameters
213    secondRequestedEvent
214    secondRequestedEventBody
215    secondRequestedEvents
216    servChgReplyParm
217    servChgReplyParms
218    serviceChangeAddress
219    serviceChangeDelay
220    serviceChangeDescriptor
221    serviceChangeMethod
222    serviceChangeMgcId
223    serviceChangeParm
224    serviceChangeParms
225    serviceChangeProfile
226    serviceChangeReason
227    serviceChangeReply
228    serviceChangeReplyBody
229    serviceChangeReplyDescriptor
230    serviceChangeRequest
231    serviceChangeVersion
232    serviceState
233    serviceStates
234    sigParameter
235    sigParameters
236    signalList
237    signalListId
238    signalListParm
239    signalListParms
240    signalName
241    signalParm
242    signalParms
243    signalRequest
244    signalsDescriptor
245    signalType
246    statisticsDescriptor
247    statisticsParameter
248    statisticsParameters
249    streamDescriptor
250    streamID
251    streamModes
252    streamParm
253    streamParmList
254    subtractRequest
255    terminationA
256    terminationAudit
257    terminationB
258    terminationID
259    terminationIDList
260    terminationIDListRepeat
261    terminationStateDescriptor
262    terminationStateParm
263    terminationStateParms
264    timeStamp
265    topologyDescriptor
266    topologyDirection
267    topologyTriple
268    topologyTripleList
269    transactionAck
270    transactionAckList
271    transactionID
272    transactionItem
273    transactionList
274    transactionPending
275    transactionReply
276    transactionReplyBody
277    transactionRequest
278    transactionResponseAck
279    value
280    valueList
281
282.
283
284%%----------------------------------------------------------------------
285%% Terminals
286%%----------------------------------------------------------------------
287
288Terminals
289
290    'AddToken'
291    'AuditCapToken'
292    'AuditToken'
293    'AuditValueToken'
294    'AuthToken'
295    'BothwayToken'
296    'BriefToken'
297    'BufferToken'
298    'COLON'
299    'COMMA'
300    %% 'ContextAttrToken'   % OTP-7138: See OTP-7534 below
301    'ContextAuditToken'
302    'CtxToken'
303    'DelayToken'
304    'DigitMapToken'
305    'DigitMapDescriptorToken'
306    'DiscardToken'
307    'DisconnectedToken'
308    'DurationToken'
309    'EQUAL'
310    'EmbedToken'
311    'EmergencyToken'
312    'EmergencyOffToken'
313    'ErrorToken'
314    'EventBufferToken'
315    'EventsToken'
316    'FailoverToken'
317    'ForcedToken'
318    'GREATER'
319    'GracefulToken'
320    'H221Token'
321    'H223Token'
322    'H226Token'
323    'HandOffToken'
324    'ImmAckRequiredToken'
325    'InSvcToken'
326    'InactiveToken'
327    %% 'IndAudTerminationAuditToken'  %% testing fix...
328    'InterruptByEventToken'
329    'InterruptByNewSignalsDescrToken'
330    'IsolateToken'
331    'KeepActiveToken'
332    'LBRKT'
333    'LESSER'
334    'LSBRKT'
335    'LocalControlToken'
336    'LocalDescriptorToken'
337    'LockStepToken'
338    'LoopbackToken'
339    'MediaToken'
340    %% 'MegacopToken'
341    'MethodToken'
342    'MgcIdToken'
343    'ModeToken'
344    'ModemToken'
345    'ModifyToken'
346    'MoveToken'
347    'MtpAddressToken'
348    'MuxToken'
349    'NEQUAL'
350    'NotifyCompletionToken'
351    'NotifyToken'
352    'Nx64kToken'  %% v2
353    'ObservedEventsToken'
354    'OffToken'
355    'OnToken'
356    'OnOffToken'
357    'OnewayToken'
358    'OtherReasonToken'
359    'OutOfSvcToken'
360    'PackagesToken'
361    'PendingToken'
362    'PriorityToken'
363    'ProfileToken'
364    'QuotedChars'
365    'RBRKT'
366    'RSBRKT'
367    'ReasonToken'
368    'RecvonlyToken'
369    'RemoteDescriptorToken'
370    'ReplyToken'
371    'ReservedGroupToken'
372    'ReservedValueToken'
373    'ResponseAckToken'
374    'RestartToken'
375    'SEP'
376    'SafeChars'
377    'SendonlyToken'
378    'SendrecvToken'
379    'ServiceChangeAddressToken'
380    'ServiceChangeToken'
381    'ServiceStatesToken'
382    'ServicesToken'
383    'SignalListToken'
384    'SignalTypeToken'
385    'SignalsToken'
386    'StatsToken'
387    'StreamToken'
388    'SubtractToken'
389    'SynchISDNToken'
390    'TerminationStateToken'
391    'TestToken'
392    'TimeOutToken'
393    'TimeStampToken'
394    'TopologyToken'
395    'TransToken'
396    'V18Token'
397    'V22Token'
398    'V22bisToken'
399    'V32Token'
400    'V32bisToken'
401    'V34Token'
402    'V76Token'
403    'V90Token'
404    'V91Token'
405    'VersionToken'
406    'AndAUDITSelectToken'            %% OTP-7534: v3-fix
407    'BothToken'                      %% OTP-7534: v3-fix
408    'ContextAttrToken'               %% OTP-7534: v3-fix
409    'ContextListToken'               %% OTP-7534: v3-fix
410    'DirectionToken'                 %% OTP-7534: v3-fix
411    %% 'EmergencyOffToken'              %% OTP-7534: v3-fix
412    'EmergencyValueToken'            %% OTP-7534: v3-fix
413    'ExternalToken'                  %% OTP-7534: v3-fix
414    'IEPSToken'                      %% OTP-7534: v3-fix
415    'IntsigDelayToken'               %% OTP-7534: v3-fix
416    'InternalToken'                  %% OTP-7534: v3-fix
417    'IterationToken'                 %% OTP-7534: v3-fix
418    'MessageSegmentToken'            %% OTP-7534: v3-fix
419    'NeverNotifyToken'               %% OTP-7534: v3-fix
420    'NotifyImmediateToken'           %% OTP-7534: v3-fix
421    'NotifyRegulatedToken'           %% OTP-7534: v3-fix
422    'OnewayBothToken'                %% OTP-7534: v3-fix
423    'OnewayExternalToken'            %% OTP-7534: v3-fix
424    'OrAUDITselectToken'             %% OTP-7534: v3-fix
425    'RequestIDToken'                 %% OTP-7534: v3-fix
426    'ResetEventsDescriptorToken'     %% OTP-7534: v3-fix
427    'SegmentationCompleteToken'      %% OTP-7534: v3-fix
428    'ServiceChangeIncompleteToken'   %% OTP-7534: v3-fix
429    endOfMessage
430
431.
432
433%%----------------------------------------------------------------------
434%% Root symbol
435%%----------------------------------------------------------------------
436
437Rootsymbol megacoMessage.
438
439%%----------------------------------------------------------------------
440%% The grammar
441%%----------------------------------------------------------------------
442
443%% megacoMessage        = LWSP [authenticationHeader SEP ] message
444%% authenticationHeader = AuthToken EQUAL SecurityParmIndex COLON
445%%                        SequenceNum COLON AuthData
446%%
447%% SecurityParmIndex    = "0x" 8(HEXDIG)
448%% SequenceNum          = "0x" 8(HEXDIG)
449%% AuthData             = "0x" 24*64(HEXDIG)
450%% message              = MegacopToken SLASH version SEP mId SEP messageBody
451%% version              = 1*2(DIGIT) .
452
453megacoMessage        -> optSep authenticationHeader message endOfMessage
454                            : #'MegacoMessage'{authHeader = '$2', mess = '$3'} .
455
456optSep               -> 'SEP'    : sep .
457optSep               -> '$empty' : no_sep .
458
459authenticationHeader -> 'AuthToken' 'EQUAL' safeToken 'COLON'
460                            safeToken 'COLON' safeToken optSep
461                            : ensure_auth_header('$3', '$5', '$7') .
462authenticationHeader -> '$empty' : asn1_NOVALUE .
463
464message              -> safeToken mId messageBody : ensure_message('$1', '$2', '$3') .
465
466messageBody          -> errorDescriptor : {messageError, '$1'} .
467messageBody          -> transactionList : {transactions, '$1'} .
468
469transactionList      -> transactionItem : ['$1'] .
470transactionList      -> transactionItem transactionList : ['$1' | '$2'] .
471
472transactionItem      -> transactionRequest      : {transactionRequest,     '$1'} .
473transactionItem      -> transactionReply        : {transactionReply,       '$1'}.
474transactionItem      -> transactionPending      : {transactionPending,     '$1'} .
475transactionItem      -> transactionResponseAck  : {transactionResponseAck, '$1'} .
476
477transactionResponseAck -> 'ResponseAckToken'
478                          'LBRKT' transactionAck transactionAckList 'RBRKT' : ['$3' | '$4'] .
479
480transactionAckList   -> 'COMMA' transactionAck transactionAckList : ['$2' | '$3'] .
481transactionAckList   -> '$empty' : [] .
482
483transactionAck       -> safeToken : ensure_transactionAck('$1') .
484
485transactionPending   -> 'PendingToken' 'EQUAL' transactionID 'LBRKT' 'RBRKT'
486                            : #'TransactionPending'{transactionId = ensure_transactionID('$3') } .
487
488%% OTP-4359: We have the first two rule's in order to be able
489%%           to handle chapter 8.1.1 in RFC3525
490transactionRequest   -> 'TransToken'
491                        'LBRKT'  actionRequest actionRequestList 'RBRKT'
492                            : #'TransactionRequest'{transactionId = asn1_NOVALUE,
493                                                    actions = ['$3' | '$4']} .
494transactionRequest   -> 'TransToken' 'EQUAL'
495                        'LBRKT'  actionRequest actionRequestList 'RBRKT'
496                            : #'TransactionRequest'{transactionId = asn1_NOVALUE,
497                                                    actions = ['$4' | '$5']} .
498transactionRequest   -> 'TransToken' 'EQUAL' transactionID
499                        'LBRKT'  actionRequest actionRequestList 'RBRKT'
500                            : #'TransactionRequest'{transactionId = ensure_transactionID('$3'),
501                                                    actions = ['$5' | '$6']} .
502
503actionRequestList    -> 'COMMA' actionRequest actionRequestList : ['$2' | '$3'] .
504actionRequestList    -> '$empty' : [] .
505
506actionRequest        -> 'CtxToken' 'EQUAL' contextID
507                        'LBRKT' actionRequestItem actionRequestItems 'RBRKT'
508                            : merge_action_requests('$3', ['$5' | '$6']) .
509
510actionRequestItems   -> 'COMMA' actionRequestItem actionRequestItems  : ['$2' | '$3'] .
511actionRequestItems   -> '$empty' : [] .
512
513actionRequestItem    -> contextProperty : '$1' .
514actionRequestItem    -> contextAudit    : '$1' .
515actionRequestItem    -> commandRequest  : '$1' .
516
517%% at-most-once
518contextProperty      -> topologyDescriptor  : {topology, '$1'}.
519contextProperty      -> priority            : {priority, '$1'}.
520contextProperty      -> 'EmergencyToken'    : {emergency, true}.
521contextProperty      -> 'EmergencyOffToken' : {emergency, false}.
522
523contextAudit         -> 'ContextAuditToken'
524                        'LBRKT' contextAuditProperty contextAuditProperties 'RBRKT'
525                        : {contextAudit, ['$3' | '$4']} .
526
527contextAuditProperties -> 'COMMA' contextAuditProperty contextAuditProperties
528                          : ['$2' | '$3'] .
529contextAuditProperties -> '$empty' : [] .
530
531%% at-most-once .
532contextAuditProperty -> 'TopologyToken'  : topologyAudit .
533contextAuditProperty -> 'EmergencyToken' : emergencyAudit .
534contextAuditProperty -> 'PriorityToken'  : priorityAudit .
535
536commandRequest       -> ammRequest             : '$1'.
537commandRequest       -> subtractRequest        : '$1'.
538commandRequest       -> auditRequest           : '$1'.
539commandRequest       -> notifyRequest          : '$1'.
540commandRequest       -> serviceChangeRequest   : '$1'.
541
542transactionReply     -> 'ReplyToken' 'EQUAL' transactionID
543			    'LBRKT'
544			        optImmAckRequired transactionReplyBody
545                            'RBRKT'
546			    : #'TransactionReply'{transactionId     = '$3',
547						  immAckRequired    = '$5',
548						  transactionResult = '$6'} .
549
550optImmAckRequired    -> 'ImmAckRequiredToken' 'COMMA' : 'NULL' .
551optImmAckRequired    -> '$empty' : asn1_NOVALUE .
552
553transactionReplyBody -> errorDescriptor              : {transactionError, '$1'} .
554transactionReplyBody -> actionReply actionReplyList  : {actionReplies, ['$1' | '$2']} .
555
556actionReplyList      -> 'COMMA' actionReply actionReplyList  : ['$2' | '$3'] .
557actionReplyList      -> '$empty' : [] .
558
559actionReply          -> 'CtxToken' 'EQUAL' contextID
560                        'LBRKT' actionReplyBody 'RBRKT' :
561                        setelement(#'ActionReply'.contextId, '$5', '$3') .
562
563actionReplyBody      -> errorDescriptor               :
564                        #'ActionReply'{errorDescriptor = '$1'} .
565actionReplyBody      -> commandReply commandReplyList :
566                        merge_action_reply(['$1' | '$2']) .
567
568commandReply         -> serviceChangeReply  : {command, '$1'} .
569commandReply         -> auditReply          : {command, '$1'} .
570commandReply         -> ammsReply           : {command, '$1'} .
571commandReply         -> notifyReply         : {command, '$1'} .
572commandReply         -> contextProperty     : {context, '$1'} .
573
574%% OTP-5085
575%% This ugly thing is to fool the parser. The errorDescriptor does not
576%% realy belong here. The merge_action_reply will remove it and put it
577%% in it's right place later.
578commandReplyList     -> 'COMMA' errorDescriptor :
579                        ['$2'] .
580commandReplyList     -> 'COMMA' commandReply commandReplyList  :
581                        ['$2' | '$3'] .
582commandReplyList     -> '$empty' : [] .
583
584%Add Move and Modify have the same request parameter
585ammRequest           -> ammToken 'EQUAL' terminationID ammRequestBody :
586                        Descs = merge_AmmRequest_descriptors('$4', []),
587                        make_commandRequest('$1',
588				            #'AmmRequest'{terminationID = ['$3'],
589						          descriptors   = Descs}) .
590
591ammToken             -> 'AddToken'     : {addReq,  '$1'} .
592ammToken             -> 'MoveToken'    : {moveReq, '$1'} .
593ammToken             -> 'ModifyToken'  : {modReq,  '$1'} .
594
595ammRequestBody       -> 'LBRKT' ammParameter ammParameters 'RBRKT'  : ['$2' | '$3'] .
596ammRequestBody       -> '$empty' : [] .
597
598ammParameters        -> 'COMMA' ammParameter ammParameters  :  ['$2' | '$3'] .
599ammParameters        -> '$empty' : [] .
600
601%at-most-once
602ammParameter         -> mediaDescriptor        : {mediaDescriptor,       '$1'}.
603ammParameter         -> modemDescriptor        : {modemDescriptor, deprecated}.
604ammParameter         -> muxDescriptor          : {muxDescriptor,         '$1'}.
605ammParameter         -> eventsDescriptor       : {eventsDescriptor,      '$1'}.
606ammParameter         -> eventBufferDescriptor  : {eventBufferDescriptor, '$1'}.
607ammParameter         -> signalsDescriptor      : {signalsDescriptor,     '$1'}.
608ammParameter         -> digitMapDescriptor     : {digitMapDescriptor,    '$1'}.
609ammParameter         -> auditDescriptor        : {auditDescriptor,       '$1'}.
610
611ammsReply            -> ammsToken 'EQUAL' terminationID ammsReplyBody
612			    :  {'$1', #'AmmsReply'{terminationID = ['$3'],
613						   terminationAudit = '$4'}} .
614
615ammsToken            -> 'AddToken'       : addReply .
616ammsToken            -> 'MoveToken'      : moveReply .
617ammsToken            -> 'ModifyToken'    : modReply .
618ammsToken            -> 'SubtractToken'  : subtractReply .
619
620ammsReplyBody        -> 'LBRKT' terminationAudit 'RBRKT' : '$2' .
621ammsReplyBody        -> '$empty' : asn1_NOVALUE .
622
623subtractRequest      -> 'SubtractToken' 'EQUAL' terminationID optAuditDescriptor
624                            : make_commandRequest({subtractReq, '$1'},
625                                                  #'SubtractRequest'{terminationID = ['$3'],
626                                                                     auditDescriptor = '$4'}) .
627
628
629optAuditDescriptor   -> 'LBRKT' auditDescriptor 'RBRKT'  : '$2'.
630optAuditDescriptor   -> '$empty'                         : asn1_NOVALUE .
631
632auditRequest -> 'AuditValueToken' 'EQUAL'
633                terminationID optAuditDescriptor :
634                make_commandRequest({auditValueRequest, '$1'},
635		                    #'AuditRequest'{terminationID   = '$3',
636				                    auditDescriptor = '$4'}) .
637auditRequest -> 'AuditCapToken' 'EQUAL'
638                terminationID optAuditDescriptor :
639                make_commandRequest({auditCapRequest, '$1'},
640				    #'AuditRequest'{terminationID   = '$3',
641						    auditDescriptor = '$4'}) .
642
643auditReply -> 'AuditValueToken' 'EQUAL' 'CtxToken' contextTerminationAudit
644		  : {auditValueReply, '$4'} .
645auditReply -> 'AuditCapToken'   'EQUAL' 'CtxToken' contextTerminationAudit
646		  : {auditCapReply,   '$4'} .
647auditReply -> 'AuditValueToken' 'EQUAL' auditOther
648		  : {auditValueReply, '$3'} .
649auditReply -> 'AuditCapToken'   'EQUAL' auditOther
650		  : {auditCapReply,   '$3'} .
651
652contextTerminationAudit -> terminationIDList               : {contextAuditResult, '$1'} .
653contextTerminationAudit -> 'LBRKT' errorDescriptor 'RBRKT' : {contextAuditResult, '$2'} .
654
655auditOther              -> terminationID :
656                           {auditResult,
657                            #'AuditResult'{terminationID          = '$1',
658					   terminationAuditResult = []}} .
659auditOther              -> terminationID 'LBRKT' terminationAudit 'RBRKT' :
660			   {auditResult,
661                            #'AuditResult'{terminationID          = '$1',
662					   terminationAuditResult = '$3'}} .
663
664
665terminationAudit     -> auditReturnParameter auditReturnParameterList :
666                        merge_terminationAudit(['$1' |'$2' ]) .
667
668auditReturnParameterList -> 'COMMA' auditReturnParameter auditReturnParameterList : ['$2' | '$3'] .
669auditReturnParameterList -> '$empty' : [] .
670
671auditReturnParameter -> mediaDescriptor           : {mediaDescriptor, '$1'} .
672auditReturnParameter -> modemDescriptor.
673auditReturnParameter -> muxDescriptor             : {muxDescriptor, '$1'} .
674auditReturnParameter -> eventsDescriptor          : {eventsDescriptor, '$1'} .
675auditReturnParameter -> signalsDescriptor         : {signalsDescriptor, '$1'} .
676auditReturnParameter -> digitMapDescriptor        : {digitMapDescriptor, '$1'} .
677auditReturnParameter -> observedEventsDescriptor  : {observedEventsDescriptor, '$1'} .
678auditReturnParameter -> eventBufferDescriptor     : {eventBufferDescriptor, '$1'} .
679auditReturnParameter -> statisticsDescriptor      : {statisticsDescriptor, '$1'} .
680auditReturnParameter -> packagesDescriptor        : {packagesDescriptor, '$1'} .
681auditReturnParameter -> errorDescriptor           : {errorDescriptor, '$1'} .
682auditReturnParameter -> auditReturnItem           : {auditReturnItem, '$1'} .
683
684auditDescriptor      -> 'AuditToken' 'LBRKT' auditDescriptorBody 'RBRKT' :
685                        merge_auditDescriptor('$3') .
686
687auditDescriptorBody  -> auditItem auditItemList : ['$1' | '$2'].
688auditDescriptorBody  -> '$empty'                : asn1_NOVALUE .
689
690auditItemList        -> 'COMMA' auditItem auditItemList : ['$2' | '$3'] .
691auditItemList        -> '$empty'                        : [] .
692
693%% IGv11 - begin
694%%
695auditReturnItem      -> 'MuxToken'             : muxToken .
696auditReturnItem      -> 'ModemToken'           : modemToken .
697auditReturnItem      -> 'MediaToken'           : mediaToken .
698auditReturnItem      -> 'DigitMapToken'        : digitMapToken .
699auditReturnItem      -> 'StatsToken'           : statsToken .
700auditReturnItem      -> 'ObservedEventsToken'  : observedEventsToken .
701auditReturnItem      -> 'PackagesToken'        : packagesToken .
702
703%% at-most-once, and DigitMapToken and PackagesToken are not allowed
704%% in AuditCapabilities command
705auditItem          -> auditReturnItem        : '$1' .
706auditItem          -> 'SignalsToken'         : signalsToken.
707auditItem          -> 'EventBufferToken'     : eventBufferToken.
708auditItem          -> 'EventsToken'          : eventsToken .
709auditItem          -> indAudterminationAudit : {terminationAudit, '$1'} . % v2
710%%
711%% IGv11 - end
712
713
714%% v2 - start
715%%
716indAudterminationAudit  -> indAudauditReturnParameter
717                           indAudterminationAuditList
718                           : ['$1' | '$2'] .
719
720% testing fix...
721% indAudterminationAudit  -> 'IndAudTerminationAuditToken'
722%                            indAudauditReturnParameter
723%                            indAudterminationAuditList
724%                            : ['$2' | '$3'] .
725
726indAudterminationAuditList -> 'COMMA' indAudauditReturnParameter
727                              indAudterminationAuditList
728                              : ['$2' | '$3'] .
729indAudterminationAuditList -> '$empty' : [] .
730
731indAudauditReturnParameter -> indAudmediaDescriptor
732                              : {indAudMediaDescriptor,       '$1'} .
733indAudauditReturnParameter -> indAudeventsDescriptor
734                              : {indAudEventsDescriptor,      '$1'} .
735indAudauditReturnParameter -> indAudsignalsDescriptor
736                              : {indAudSignalsDescriptor,     '$1'} .
737indAudauditReturnParameter -> indAuddigitMapDescriptor
738                              : {indAudDigitMapDescriptor,    '$1'} .
739indAudauditReturnParameter -> indAudeventBufferDescriptor
740                              : {indAudEventBufferDescriptor, '$1'} .
741indAudauditReturnParameter -> indAudstatisticsDescriptor
742                              : {indAudStatisticsDescriptor,  '$1'} .
743indAudauditReturnParameter -> indAudpackagesDescriptor
744                              : {indAudPackagesDescriptor,    '$1'} .
745
746
747indAudmediaDescriptor -> 'MediaToken' 'LBRKT'
748                         indAudmediaParm  'RBRKT'
749                         : merge_indAudMediaDescriptor('$3') .
750
751%% at-most-once per item
752%% and either streamParm or streamDescriptor but not both
753%% <rambling>
754%% This is solved in another way in text than in binary :(
755%% Instead of having a list of indAudmediaParm we put this
756%% stuff in the indAudterminationAuditList with several
757%% indAudmediaDescriptor's.
758%% </rambling>
759%%
760
761indAudmediaParm -> indAudstreamParm                 : {streamParm,     '$1'} .
762indAudmediaParm -> indAudstreamDescriptor           : {streamDescr,    '$1'} .
763indAudmediaParm -> indAudterminationStateDescriptor : {termStateDescr, '$1'} .
764
765%% at-most-once
766indAudstreamParm -> indAudlocalControlDescriptor
767                    : #'IndAudStreamParms'{localControlDescriptor = '$1'} .
768
769indAudstreamDescriptor -> 'StreamToken' 'EQUAL' streamID
770                          'LBRKT' indAudstreamParm 'RBRKT'
771                          : #'IndAudStreamDescriptor'{streamID    = '$3',
772                                                      streamParms = '$5'} .
773
774
775indAudlocalControlDescriptor -> 'LocalControlToken'
776                                'LBRKT' indAudlocalParm indAudlocalParmList 'RBRKT' :
777                                merge_indAudLocalControlDescriptor(['$3'| '$4']) .
778
779indAudlocalParmList -> 'COMMA' indAudlocalParm indAudlocalParmList : ['$2'| '$3'] .
780indAudlocalParmList -> '$empty' : [] .
781
782%% at-most-once per item
783%%
784indAudlocalParm -> safeToken : ensure_indAudLocalParm('$1') .
785
786indAudterminationStateDescriptor -> 'TerminationStateToken'
787                                    'LBRKT' indAudterminationStateParm 'RBRKT'
788                                    :
789                                    merge_indAudTerminationStateDescriptor('$3') .
790
791%% at-most-once per item
792%%
793
794indAudterminationStateParm  -> safeToken :
795                               ensure_indAudTerminationStateParm('$1') .
796
797indAudeventBufferDescriptor -> 'EventBufferToken'
798                               'LBRKT' indAudeventSpec 'RBRKT' : '$3' .
799
800indAudeventSpec -> pkgdName optIndAudeventSpecParameter
801                   : merge_indAudEventBufferDescriptor('$1','$2') .
802
803optIndAudeventSpecParameter -> 'LBRKT' indAudeventSpecParameter 'RBRKT'
804                               : '$2' .
805optIndAudeventSpecParameter -> '$empty' : asn1_NOVALUE .
806
807
808indAudeventSpecParameter    -> eventStream        : {streamID, '$1'} .
809indAudeventSpecParameter    -> eventParameterName : {eventParameterName, '$1'} .
810
811indAudeventsDescriptor      -> 'EventsToken' 'EQUAL' requestID
812                               'LBRKT' indAudrequestedEvent 'RBRKT'
813                               : #'IndAudEventsDescriptor'{requestID = '$3',
814                                                           pkgdName  = '$5'} .
815
816indAudrequestedEvent        -> pkgdName : '$1' .
817
818
819indAudsignalsDescriptor     -> 'SignalsToken' optIndAudsignalParm : '$2' .
820
821
822optIndAudsignalParm -> 'LBRKT' 'RBRKT' : asn1_NOVALUE .
823optIndAudsignalParm -> 'LBRKT' indAudsignalParm 'RBRKT'  : '$2' .
824
825indAudsignalParm -> indAudsignalList  : {seqSigList, '$1'} .
826indAudsignalParm -> signalRequest     : {signal, ensure_indAudSignal('$1')} .
827
828indAudsignalList -> 'SignalListToken' 'EQUAL' signalListId
829                    'LBRKT' signalListParm 'RBRKT' :
830                     #'IndAudSeqSigList'{id = ensure_uint16('$3'),
831					   signalList =
832                                           ensure_indAudSignalListParm('$5')} .
833
834
835%% The DigitMapDescriptorToken is specially treated by the scanner
836indAuddigitMapDescriptor   -> 'DigitMapDescriptorToken' :
837                              ensure_IADMD('$1') .
838
839indAudstatisticsDescriptor -> 'StatsToken' 'LBRKT' pkgdName 'RBRKT' :
840                              #'IndAudStatisticsDescriptor'{statName = '$3'} .
841
842indAudpackagesDescriptor   -> 'PackagesToken' 'LBRKT' packagesItem 'RBRKT'
843                              : merge_indAudPackagesDescriptor('$3') .
844
845eventStream                -> 'StreamToken' 'EQUAL' streamID : '$3' .
846
847
848%%
849%% v2 - end
850
851notifyRequest        -> 'NotifyToken' 'EQUAL' terminationID
852                        'LBRKT' notifyRequestBody 'RBRKT'
853                      : make_commandRequest({notifyReq, '$1'},
854					    setelement(#'NotifyRequest'.terminationID, '$5', ['$3'])) .
855
856notifyRequestBody    -> observedEventsDescriptor
857                            : #'NotifyRequest'{observedEventsDescriptor = '$1'}.
858notifyRequestBody    -> errorDescriptor
859                            : #'NotifyRequest'{errorDescriptor = '$1'}.
860
861notifyReply          -> 'NotifyToken' 'EQUAL' terminationID notifyReplyBody
862			    : {notifyReply,
863			       #'NotifyReply'{terminationID = ['$3'],
864					      errorDescriptor = '$4'}} .
865
866notifyReplyBody      -> 'LBRKT' errorDescriptor 'RBRKT' : '$2'.
867notifyReplyBody      -> '$empty' : asn1_NOVALUE .
868
869serviceChangeRequest -> 'ServiceChangeToken' 'EQUAL' terminationID
870                        'LBRKT' serviceChangeDescriptor 'RBRKT'
871                      : make_commandRequest({serviceChangeReq, '$1'},
872					    #'ServiceChangeRequest'{terminationID = ['$3'],
873								    serviceChangeParms = '$5'}) .
874
875serviceChangeReply   -> 'ServiceChangeToken' 'EQUAL' terminationID serviceChangeReplyBody
876			: {serviceChangeReply,
877	                   #'ServiceChangeReply'{terminationID = ['$3'],
878						 serviceChangeResult = '$4'}} .
879
880serviceChangeReplyBody -> 'LBRKT' errorDescriptor 'RBRKT'
881			      : {errorDescriptor, '$2'} .
882serviceChangeReplyBody -> 'LBRKT' serviceChangeReplyDescriptor 'RBRKT'
883			      : {serviceChangeResParms, '$2'} .
884serviceChangeReplyBody -> '$empty' : {serviceChangeResParms, #'ServiceChangeResParm'{}}.
885
886errorDescriptor      -> 'ErrorToken' 'EQUAL' errorCode 'LBRKT' errorText 'RBRKT'
887                            : #'ErrorDescriptor'{errorCode = '$3',
888                                                 errorText = '$5'} .
889
890errorCode            -> safeToken : ensure_uint('$1', 0, 999) .
891
892errorText            -> 'QuotedChars' : value_of('$1') .
893errorText            -> '$empty'      : asn1_NOVALUE .
894
895transactionID        -> safeToken : ensure_uint32('$1') .
896
897mId                  -> domainName               : '$1' .
898mId                  -> domainAddress            : '$1' .
899mId                  -> optSep mtpAddress optSep : '$2' .
900mId                  -> optSep deviceName optSep : '$2' .
901
902domainName           -> 'LESSER' safeToken 'GREATER' 'COLON' portNumber optSep
903                            : ensure_domainName('$2', '$5') .
904domainName           -> 'LESSER' safeToken 'GREATER'
905                            : ensure_domainName('$2', asn1_NOVALUE) .
906
907deviceName           -> pathName  : {deviceName, '$1'} .
908
909%% '-' is used for NULL context
910contextID            -> safeToken : ensure_contextID('$1') .
911
912domainAddress        -> 'LSBRKT' daddr 'RSBRKT' 'COLON' portNumber optSep
913                        : ensure_domainAddress('$2', '$5') .
914domainAddress        -> 'LSBRKT' daddr 'RSBRKT'
915                        : ensure_domainAddress('$2', asn1_NOVALUE) .
916
917daddr -> '$empty'        : [] .
918daddr -> 'COLON' daddr   : [colon| '$2'] .
919daddr -> safeToken daddr : ['$1'| '$2'] .
920
921
922portNumber           -> safeToken : ensure_uint16('$1') .
923
924mtpAddress           -> 'MtpAddressToken' : ensure_mtpAddress('$1') .
925
926%% terminationIDList    -> LBRKT terminationID *(COMMA terminationID) RBRKT .
927
928terminationIDList    -> 'LBRKT' terminationID terminationIDListRepeat 'RBRKT'
929                                 : ['$2' | '$3'] .
930
931terminationIDListRepeat -> 'COMMA' terminationID terminationIDListRepeat
932                                 : ['$2'| '$3'] .
933terminationIDListRepeat -> '$empty' : [] .
934
935
936pathName             -> safeToken : ensure_pathName('$1') .
937
938terminationID        -> safeToken : ensure_terminationID('$1') .
939
940mediaDescriptor      -> 'MediaToken' 'LBRKT' mediaParm mediaParmList 'RBRKT'
941			    : merge_mediaDescriptor(['$3' | '$4']) .
942
943mediaParmList        -> 'COMMA' mediaParm mediaParmList : ['$2' | '$3'] .
944mediaParmList        -> '$empty' : [] .
945
946
947%% at-most-once per item
948%% using either streamParms or streamDescriptors but not both
949mediaParm            -> streamParm
950			    : {streamParm, '$1'} .
951mediaParm            -> streamDescriptor
952			    : {streamDescriptor, '$1'} .
953mediaParm            -> terminationStateDescriptor
954			    : {termState, '$1'} .
955
956%% at-most-onc .
957%% Specially treated by the scanner.
958streamParm           -> 'LocalDescriptorToken' :
959                        PGs = ensure_prop_groups('$1'),
960		        {local, #'LocalRemoteDescriptor'{propGrps = PGs}} .
961streamParm           -> 'RemoteDescriptorToken' :
962                         PGs = ensure_prop_groups('$1'),
963                         {remote, #'LocalRemoteDescriptor'{propGrps = PGs}} .
964streamParm           -> localControlDescriptor  : {control, '$1'} .
965
966streamDescriptor     -> 'StreamToken' 'EQUAL' streamID
967                        'LBRKT' streamParm streamParmList 'RBRKT'
968		      : #'StreamDescriptor'{streamID    = '$3',
969					    streamParms = merge_streamParms(['$5' | '$6'])} .
970
971streamParmList       -> 'COMMA' streamParm streamParmList : ['$2' | '$3'] .
972streamParmList       -> '$empty' : [] .
973
974localControlDescriptor -> 'LocalControlToken' 'LBRKT' localParm localParmList 'RBRKT'
975                        : ['$3' | '$4'] .
976
977localParmList        -> 'COMMA' localParm localParmList : ['$2' | '$3'] .
978localParmList        -> '$empty': [] .
979
980terminationStateDescriptor -> 'TerminationStateToken'
981				  'LBRKT' terminationStateParm terminationStateParms 'RBRKT'
982		            : merge_terminationStateDescriptor(['$3' | '$4']) .
983
984terminationStateParms -> 'COMMA' terminationStateParm terminationStateParms : ['$2' | '$3'] .
985terminationStateParms -> '$empty' : [] .
986
987%% at-most-once per item except for propertyParm
988localParm            -> 'ReservedGroupToken' 'EQUAL' onOrOff : {group, '$3'} .
989localParm            -> 'ReservedValueToken' 'EQUAL' onOrOff : {value, '$3'} .
990localParm            -> 'ModeToken' 'EQUAL' streamModes      : {mode,  '$3'} .
991localParm            -> propertyParm                         : {prop,  '$1'} .
992
993onOrOff              -> 'OnToken'  : true .
994onOrOff              -> 'OffToken' : false .
995
996%% at-most-once
997streamModes          -> 'SendonlyToken' : sendOnly .
998streamModes          -> 'RecvonlyToken' : recvOnly .
999streamModes          -> 'SendrecvToken' : sendRecv .
1000streamModes          -> 'InactiveToken' : inactive .
1001streamModes          -> 'LoopbackToken' : loopBack .
1002
1003propertyParm         -> pkgdName parmValue :
1004                        setelement(#'PropertyParm'.name, '$2', '$1') .
1005
1006parmValue            -> 'EQUAL' alternativeValue :
1007                         '$2' .
1008
1009parmValue            -> 'NEQUAL'  value :
1010                        #'PropertyParm'{value = ['$2'],
1011                                        extraInfo = {relation, unequalTo}} .
1012parmValue            -> 'LESSER'  value :
1013                        #'PropertyParm'{value = ['$2'],
1014                                        extraInfo = {relation, smallerThan}} .
1015parmValue            -> 'GREATER' value :
1016                        #'PropertyParm'{value = ['$2'],
1017                                        extraInfo = {relation, greaterThan}} .
1018
1019%% OTP-4013
1020%% alternativeValue  = ( VALUE /
1021%%                       LSBRKT VALUE *(COMMA VALUE) RSBRKT  /
1022%%                       LSBRKT VALUE COLON VALUE RSBRKT ) /
1023%%                       LBRKT VALUE *(COMMA VALUE) RBRKT
1024alternativeValue     -> 'LBRKT' value valueList 'RBRKT' :
1025                            #'PropertyParm'{value     = ['$2' | '$3'],
1026					    extraInfo = {sublist, false}}. % OR
1027
1028alternativeValue     -> 'LSBRKT' value 'COLON' value 'RSBRKT' :
1029                            #'PropertyParm'{value     = ['$2', '$4'],
1030                                            extraInfo = {range, true}}.
1031
1032alternativeValue     -> 'LSBRKT' value valueList 'RSBRKT' :
1033                            #'PropertyParm'{value     = ['$2' | '$3'],
1034					    extraInfo = {sublist, true}}. % AND
1035
1036alternativeValue     -> value :
1037                        #'PropertyParm'{value = ['$1']} .
1038
1039valueList            -> 'COMMA' value valueList : ['$2' | '$3'] .
1040valueList            -> '$empty' : [] .
1041
1042
1043eventBufferDescriptor -> 'EventBufferToken' : [] .
1044eventBufferDescriptor -> 'EventBufferToken' 'LBRKT' eventSpec eventSpecList 'RBRKT'
1045			 : ['$3' | '$4'] .
1046
1047eventSpecList        -> 'COMMA' eventSpec eventSpecList : ['$2' | '$3'] .
1048eventSpecList        -> '$empty' : [] .
1049
1050eventSpec            -> observedEvent : merge_eventSpec('$1') .
1051
1052%% at-most-once per item except for propertyParm
1053terminationStateParm -> serviceStates      : {serviceState, '$1'} .
1054terminationStateParm -> eventBufferControl : {eventBufferControl, '$1'} .
1055terminationStateParm -> propertyParm       : {propertyParm, '$1'} .
1056
1057serviceStates        -> 'ServiceStatesToken' 'EQUAL' serviceState : '$3' .
1058
1059serviceState         -> 'TestToken'     : test .
1060serviceState         -> 'OutOfSvcToken' : outOfSvc .
1061serviceState         -> 'InSvcToken'    : inSvc .
1062
1063eventBufferControl   -> 'BufferToken' 'EQUAL' eventBufferControlState : '$3' .
1064
1065eventBufferControlState -> 'OffToken'      : off .
1066eventBufferControlState -> 'LockStepToken' : lockStep .
1067
1068muxDescriptor        -> 'MuxToken' 'EQUAL' muxType  terminationIDList :
1069                        #'MuxDescriptor'{muxType  = '$3',
1070					 termList = '$4'} .
1071
1072muxType              -> safeToken : ensure_muxType('$1') .
1073
1074streamID             -> safeToken : ensure_streamID('$1') .
1075
1076pkgdName             -> safeToken : ensure_pkgdName('$1') .
1077
1078eventsDescriptor     -> 'EventsToken' :
1079                        #'EventsDescriptor'{requestID = asn1_NOVALUE,
1080                                            eventList = []} .
1081eventsDescriptor     -> 'EventsToken' 'EQUAL' requestID
1082                        'LBRKT' requestedEvent requestedEvents 'RBRKT' :
1083                        #'EventsDescriptor'{requestID = '$3',
1084                                            eventList = ['$5' | '$6']} .
1085
1086requestedEvents      -> 'COMMA' requestedEvent requestedEvents : ['$2' | '$3']  .
1087requestedEvents      -> '$empty' : [] .
1088
1089requestedEvent       -> pkgdName requestedEventBody :
1090                        setelement(#'RequestedEvent'.pkgdName, '$2', '$1') .
1091
1092requestedEventBody   -> 'LBRKT' eventParameter eventParameters 'RBRKT' :
1093			 merge_eventParameters(['$2' | '$3']) .
1094requestedEventBody   -> '$empty' : #'RequestedEvent'{evParList = []} .
1095
1096eventParameters      -> 'COMMA' eventParameter eventParameters :
1097                        ['$2' | '$3'] .
1098eventParameters      -> '$empty' : [] .
1099
1100%% at-most-once each of embedOrKeepActive , eventDM or eventStream
1101eventParameter       -> 'KeepActiveToken'   : keepActive .
1102eventParameter       -> embedWithSig        : '$1'.
1103eventParameter       -> embedNoSig          : '$1'.
1104eventParameter       -> eventDM             : '$1'.
1105eventParameter       -> eventStreamOrOther  : '$1'.
1106
1107embedWithSig         -> 'EmbedToken' 'LBRKT' signalsDescriptor
1108			    'COMMA' embedFirst 'RBRKT'
1109			    : {embed, '$3', '$5'} .
1110embedWithSig         -> 'EmbedToken' 'LBRKT' signalsDescriptor 'RBRKT'
1111			    : {embed, '$3', asn1_NOVALUE} .
1112
1113embedNoSig           -> 'EmbedToken' 'LBRKT' embedFirst 'RBRKT'
1114			    : {embed, asn1_NOVALUE, '$3'} .
1115
1116embedFirst           -> 'EventsToken' :
1117                        #'SecondEventsDescriptor'{requestID = asn1_NOVALUE,
1118                                                  eventList = []} .
1119embedFirst           -> 'EventsToken' 'EQUAL' requestID
1120                        'LBRKT' secondRequestedEvent secondRequestedEvents 'RBRKT' :
1121		        #'SecondEventsDescriptor'{requestID = '$3',
1122						  eventList = ['$5' | '$6']} .
1123
1124secondRequestedEvents -> 'COMMA' secondRequestedEvent secondRequestedEvents : ['$2' | '$3'] .
1125secondRequestedEvents -> '$empty' : [] .
1126
1127%% at-most-once of each
1128secondRequestedEvent  -> pkgdName secondRequestedEventBody
1129			     : setelement(#'SecondRequestedEvent'.pkgdName, '$2', '$1') .
1130
1131secondRequestedEventBody -> 'LBRKT' secondEventParameter secondEventParameters 'RBRKT'
1132				    : merge_secondEventParameters(['$2' | '$3']) .
1133secondRequestedEventBody -> '$empty' :  #'SecondRequestedEvent'{evParList = []} .
1134
1135secondEventParameters -> 'COMMA' secondEventParameter secondEventParameters : ['$2' | '$3'] .
1136secondEventParameters -> '$empty' : [] .
1137
1138%% at-most-once each of embedOrKeepActive , eventDM or eventStream
1139secondEventParameter -> 'KeepActiveToken'    : keepActive .
1140secondEventParameter -> embedSig             : '$1' .
1141secondEventParameter -> eventDM              : '$1' .
1142secondEventParameter -> eventStreamOrOther   : '$1' .
1143
1144embedSig             -> 'EmbedToken' 'LBRKT' signalsDescriptor 'RBRKT'
1145			    : {second_embed, '$3'} .
1146
1147eventStreamOrOther   -> eventParameterName parmValue :
1148                        select_stream_or_other('$1', '$2') .
1149
1150eventParameterName   -> safeToken : ensure_NAME('$1') .
1151
1152%% The DigitMapDescriptorToken is specially treated by the scanner
1153eventDM              -> 'DigitMapDescriptorToken' :
1154                        ensure_eventDM('$1') .
1155
1156%% H248S-IG (IGv11)
1157signalsDescriptor    -> 'SignalsToken' 'LBRKT' signalParm signalParms 'RBRKT' :
1158			 ['$3' | '$4'] .
1159signalsDescriptor    -> 'SignalsToken' : [] .
1160
1161signalParms          -> 'COMMA' signalParm signalParms : [ '$2' | '$3'] .
1162signalParms          -> '$empty' : [] .
1163
1164signalParm           -> signalList    : {seqSigList, '$1'} .
1165signalParm           -> signalRequest : {signal, '$1'} .
1166
1167signalRequest        -> signalName 'LBRKT' sigParameter sigParameters 'RBRKT'
1168			    : merge_signalRequest('$1', ['$3' | '$4']).
1169signalRequest        -> signalName : merge_signalRequest('$1', []).
1170
1171sigParameters        -> 'COMMA' sigParameter sigParameters : ['$2' | '$3'] .
1172sigParameters        -> '$empty' : [] .
1173
1174%%    sigParameter    = sigStream / sigSignalType / sigDuration / sigOther
1175%% 		      / notifyCompletion / KeepActiveToken
1176%%    sigStream            = StreamToken EQUAL StreamID
1177%%    sigOther             = sigParameterName parmValue
1178%%    sigParameterName     = NAME
1179%%    sigSignalType        = SignalTypeToken EQUAL signalType
1180%%    signalType           = (OnOffToken / TimeOutToken / BriefToken)
1181%%    sigDuration          = DurationToken EQUAL UINT16
1182%%    notifyCompletion     = NotifyCompletionToken EQUAL (LBRKT
1183%% 		      notificationReason *(COMMA notificationReason) RBRKT
1184%%
1185%%    notificationReason   = ( TimeOutToken / InterruptByEventToken
1186%% 				   / InterruptByNewSignalsDescrToken
1187%% 				   / OtherReasonToken )
1188
1189sigParameter         -> 'StreamToken' 'EQUAL' streamID : {stream, '$3'}.
1190sigParameter         -> 'SignalTypeToken' 'EQUAL' signalType : {signal_type, '$3'} .
1191sigParameter         -> 'DurationToken' 'EQUAL' safeToken : {duration, ensure_uint16('$3')} .
1192sigParameter         -> safeToken parmValue : {other, ensure_NAME('$1'), '$2'}.
1193sigParameter         -> 'NotifyCompletionToken' 'EQUAL'
1194			    'LBRKT' notificationReason notificationReasons 'RBRKT'
1195			    : {notify_completion, ['$4' | '$5']} .
1196sigParameter         -> 'KeepActiveToken' : keepActive .
1197
1198signalType           -> 'OnOffToken'   : onOff.
1199signalType           -> 'TimeOutToken' : timeOut.
1200signalType           -> 'BriefToken'   : brief.
1201
1202notificationReasons  -> 'COMMA' notificationReason notificationReasons : ['$2' | '$3'] .
1203notificationReasons  -> '$empty' : [] .
1204
1205notificationReason   -> 'TimeOutToken' : onTimeOut .
1206notificationReason   -> 'InterruptByEventToken' : onInterruptByEvent .
1207notificationReason   -> 'InterruptByNewSignalsDescrToken' : onInterruptByNewSignalDescr .
1208notificationReason   -> 'OtherReasonToken' : otherReason .
1209
1210signalList           -> 'SignalListToken' 'EQUAL' signalListId
1211                        'LBRKT' signalListParm signalListParms 'RBRKT'
1212			    : #'SeqSigList'{id = ensure_uint16('$3'),
1213					    signalList = ['$5' | '$6']} .
1214
1215signalListParms      -> 'COMMA' signalListParm signalListParms :
1216                        ['$2' | '$3'] .
1217signalListParms      -> '$empty' : [] .
1218
1219signalListId         -> safeToken : ensure_uint16('$1') .
1220
1221%% exactly once signalType,
1222%% at most once duration and every signal parameter
1223signalListParm       -> signalRequest  : '$1'.
1224
1225signalName           -> pkgdName  : '$1'.
1226
1227observedEventsDescriptor -> 'ObservedEventsToken' 'EQUAL' requestID
1228                            'LBRKT' observedEvent observedEvents 'RBRKT'
1229                      : #'ObservedEventsDescriptor'{requestId        = '$3',
1230						    observedEventLst = ['$5' | '$6']} .
1231
1232observedEvents       -> 'COMMA' observedEvent observedEvents : ['$2' | '$3'] .
1233observedEvents       -> '$empty' : [] .
1234
1235%%time per event, because it might be buffered
1236
1237observedEvent        -> timeStamp optSep 'COLON' optSep pkgdName observedEventBody :
1238                        merge_observed_event('$6', '$5', '$1') .
1239observedEvent        -> optSep pkgdName observedEventBody :
1240                        merge_observed_event('$3', '$2', asn1_NOVALUE) .
1241
1242observedEventBody    -> 'LBRKT' observedEventParameter
1243                                observedEventParameters 'RBRKT'
1244			 : ['$2' | '$3'] .
1245observedEventBody    -> '$empty' : [] .
1246
1247observedEventParameters -> 'COMMA' observedEventParameter observedEventParameters : ['$2' | '$3'] .
1248observedEventParameters -> '$empty' : [] .
1249
1250%%at-most-once eventStream, every eventParameterName at most once
1251observedEventParameter -> eventStreamOrOther : '$1' .
1252
1253requestID            -> safeToken : ensure_requestID('$1') .
1254
1255%% Deprecated as of Corr 1
1256modemDescriptor      -> 'ModemToken' 'EQUAL' modemType optPropertyParms .
1257modemDescriptor      -> 'ModemToken' 'LSBRKT' modemType modemTypeList 'RSBRKT'
1258                        optPropertyParms.
1259modemTypeList 	     -> 'COMMA' modemType modemTypeList.
1260modemTypeList 	     -> '$empty'.
1261modemType            -> safeToken.
1262
1263optPropertyParms     -> 'LBRKT' propertyParm propertyParms 'RBRKT' :
1264                        ['$2' | '$3'] .
1265optPropertyParms     -> '$empty' : [] .
1266
1267propertyParms  	     -> 'COMMA' propertyParm propertyParms :  ['$2' | '$3'] .
1268propertyParms 	     -> '$empty' : [] .
1269
1270% parmName             -> safeToken : ensure_NAME('$1') .
1271
1272%% The DigitMapDescriptorToken is specially treated by the scanner
1273digitMapDescriptor   -> 'DigitMapDescriptorToken' :
1274                        ensure_DMD('$1') .
1275
1276%% each parameter at-most-once, except auditItem
1277%% at most one of either serviceChangeAddress or serviceChangeMgcId but
1278%% not both. serviceChangeMethod and serviceChangeReason are REQUIRED
1279serviceChangeDescriptor -> 'ServicesToken'
1280                           'LBRKT' serviceChangeParm
1281                                   serviceChangeParms 'RBRKT' :
1282                            merge_ServiceChangeParm(['$3' | '$4']) .
1283
1284serviceChangeParms   -> 'COMMA' serviceChangeParm serviceChangeParms :
1285                        ['$2' | '$3'] .
1286serviceChangeParms   -> '$empty' : [] .
1287
1288serviceChangeParm    -> serviceChangeMethod  : {method,     '$1'} .
1289serviceChangeParm    -> serviceChangeReason  : {reason,     '$1'} .
1290serviceChangeParm    -> serviceChangeDelay   : {delay,      '$1'} .
1291serviceChangeParm    -> serviceChangeAddress : {address,    '$1'} .
1292serviceChangeParm    -> serviceChangeProfile : {profile,    '$1'} .
1293serviceChangeParm    -> extension            : {extension,  '$1'} .
1294serviceChangeParm    -> timeStamp            : {time_stamp, '$1'} .
1295serviceChangeParm    -> serviceChangeMgcId   : {mgc_id,     '$1'} .
1296serviceChangeParm    -> serviceChangeVersion : {version,    '$1'} .
1297serviceChangeParm    -> auditItem            : {audit_item, '$1'} . % v2
1298
1299serviceChangeMethod  -> 'MethodToken' 'EQUAL' safeToken : ensure_serviceChangeMethod('$3') .
1300
1301serviceChangeReason  -> 'ReasonToken' 'EQUAL' value : ['$3'] .
1302
1303serviceChangeDelay   -> 'DelayToken'  'EQUAL' safeToken : ensure_uint32('$3').
1304
1305serviceChangeAddress -> 'ServiceChangeAddressToken' 'EQUAL' mId : '$3' .
1306serviceChangeAddress -> 'ServiceChangeAddressToken' 'EQUAL' portNumber :
1307                        {portNumber, '$3'} .
1308
1309serviceChangeMgcId   -> 'MgcIdToken'   'EQUAL' mId       : '$3' .
1310
1311serviceChangeProfile -> 'ProfileToken' 'EQUAL' safeToken : ensure_profile('$3').
1312
1313serviceChangeVersion -> 'VersionToken' 'EQUAL' safeToken : ensure_version('$3') .
1314
1315extension            ->  extensionParameter parmValue
1316			     : setelement(#'PropertyParm'.name, '$2', '$1') .
1317
1318%% at most once. Version is REQUIRED on first ServiceChange response
1319%% at most of either serviceChangeAddress or serviceChangeMgcId but not both
1320serviceChangeReplyDescriptor -> 'ServicesToken'
1321                                'LBRKT' servChgReplyParm
1322                                        servChgReplyParms 'RBRKT' :
1323                                merge_ServiceChangeResParm(['$3' | '$4']) .
1324
1325servChgReplyParms    -> 'COMMA' servChgReplyParm servChgReplyParms :
1326                        ['$2' | '$3'] .
1327servChgReplyParms    -> '$empty' :  [] .
1328
1329servChgReplyParm     -> serviceChangeAddress : {address,   '$1'} .
1330servChgReplyParm     -> serviceChangeMgcId   : {mgc_id,    '$1'} .
1331servChgReplyParm     -> serviceChangeProfile : {profile,   '$1'} .
1332servChgReplyParm     -> serviceChangeVersion : {version,   '$1'} .
1333servChgReplyParm     -> timeStamp            : {time_stamp,'$1'} .
1334
1335packagesDescriptor   -> 'PackagesToken' 'LBRKT' packagesItem packagesItems 'RBRKT'
1336                            : ['$3' | '$4'] .
1337
1338packagesItems        -> 'COMMA' packagesItem packagesItems  : ['$2' | '$3'] .
1339packagesItems        -> '$empty' : [] .
1340
1341packagesItem         -> safeToken : ensure_packagesItem('$1') .
1342
1343timeStamp            -> TimeStampToken : ensure_timeStamp('$1') .
1344
1345statisticsDescriptor -> 'StatsToken'
1346                        'LBRKT' statisticsParameter statisticsParameters 'RBRKT'
1347                            :  ['$3' | '$4'] .
1348
1349statisticsParameters -> 'COMMA' statisticsParameter statisticsParameters  : ['$2' | '$3'] .
1350statisticsParameters -> '$empty' : [] .
1351
1352%%at-most-once per item
1353statisticsParameter  -> pkgdName
1354                            : #'StatisticsParameter'{statName  = '$1',
1355                                                     statValue = asn1_NOVALUE} .
1356statisticsParameter  -> pkgdName 'EQUAL' value
1357                            : #'StatisticsParameter'{statName  = '$1',
1358                                                     statValue = ['$3']} .
1359
1360topologyDescriptor   -> 'TopologyToken' 'LBRKT' topologyTriple
1361                        topologyTripleList 'RBRKT' : ['$3' | '$4'] .
1362
1363terminationA         -> terminationID  : '$1' .
1364
1365terminationB         -> terminationID  : '$1' .
1366
1367topologyTriple       -> terminationA 'COMMA' terminationB 'COMMA'
1368                        topologyDirection 'COMMA' eventStream :
1369                          #'TopologyRequest'{terminationFrom   = '$1',
1370                                             terminationTo     = '$3',
1371                                             topologyDirection = '$5',
1372                                             streamID          = '$7'} .
1373topologyTriple       -> terminationA 'COMMA' terminationB 'COMMA'
1374                        topologyDirection :
1375                          #'TopologyRequest'{terminationFrom   = '$1',
1376                                             terminationTo     = '$3',
1377                                             topologyDirection = '$5'} .
1378
1379topologyTripleList   -> '$empty' : [] .
1380topologyTripleList   -> 'COMMA' topologyTriple topologyTripleList :
1381                          ['$2' | '$3'] .
1382
1383topologyDirection    -> 'BothwayToken' : bothway .
1384topologyDirection    -> 'IsolateToken' : isolate .
1385topologyDirection    -> 'OnewayToken'  : oneway .
1386
1387priority             -> 'PriorityToken' 'EQUAL' safeToken : ensure_uint16('$3') .
1388
1389extensionParameter   -> safeToken : ensure_extensionParameter('$1') .
1390
1391value                -> 'QuotedChars' :
1392                        ensure_value('$1') .
1393value                -> safeToken     :
1394                        ensure_value('$1').
1395
1396safeToken            -> safeToken2              : make_safe_token('$1') .
1397
1398safeToken2           -> 'SafeChars'             : '$1' .
1399safeToken2           -> 'AddToken'              : '$1' .
1400safeToken2           -> 'AuditToken'            : '$1' .
1401safeToken2           -> 'AuditCapToken'         : '$1' .
1402safeToken2           -> 'AuditValueToken'       : '$1' .
1403safeToken2           -> 'AuthToken'             : '$1' .
1404safeToken2           -> 'BothwayToken'          : '$1' .
1405safeToken2           -> 'BriefToken'            : '$1' .
1406safeToken2           -> 'BufferToken'           : '$1' .
1407safeToken2           -> 'CtxToken'              : '$1' .
1408%% safeToken2           -> 'ContextAttrToken'      : '$1' .
1409safeToken2           -> 'ContextAuditToken'     : '$1' .
1410%% v2-safeToken2           -> 'DigitMapToken'         : '$1' .
1411%% safeToken2        -> 'DigitMapDescriptorToken' : '$1' .
1412safeToken2           -> 'DiscardToken'          : '$1' .
1413safeToken2           -> 'DisconnectedToken'     : '$1' .
1414safeToken2           -> 'DelayToken'            : '$1' .
1415safeToken2           -> 'DurationToken'         : '$1' .
1416safeToken2           -> 'EmbedToken'            : '$1' .
1417safeToken2           -> 'EmergencyToken'        : '$1' .
1418safeToken2           -> 'EmergencyOffToken'     : '$1' .
1419safeToken2           -> 'ErrorToken'            : '$1' .
1420%% v2-safeToken2           -> 'EventBufferToken'      : '$1' .
1421safeToken2           -> 'EventsToken'           : '$1' .
1422safeToken2           -> 'FailoverToken'         : '$1' .
1423safeToken2           -> 'ForcedToken'           : '$1' .
1424safeToken2           -> 'GracefulToken'         : '$1' .
1425safeToken2           -> 'H221Token'             : '$1' .
1426safeToken2           -> 'H223Token'             : '$1' .
1427safeToken2           -> 'H226Token'             : '$1' .
1428safeToken2           -> 'HandOffToken'          : '$1' .
1429safeToken2           -> 'ImmAckRequiredToken'   : '$1' .
1430safeToken2           -> 'InactiveToken'         : '$1' .
1431safeToken2           -> 'InterruptByEventToken' : '$1' .
1432safeToken2           -> 'InterruptByNewSignalsDescrToken' : '$1' .
1433safeToken2           -> 'IsolateToken'          : '$1' .
1434safeToken2           -> 'InSvcToken'            : '$1' .
1435safeToken2           -> 'KeepActiveToken'       : '$1' .
1436%% safeToken2        -> 'LocalToken'            : '$1' .
1437%% safeToken2        -> 'LocalDescriptorToken'  : '$1' .
1438safeToken2           -> 'LocalControlToken'     : '$1' .
1439safeToken2           -> 'LoopbackToken'         : '$1' .
1440safeToken2           -> 'LockStepToken'         : '$1' .
1441%% v2-safeToken2           -> 'MediaToken'            : '$1' .
1442%% safeToken2        -> 'MegacopToken'          : '$1' .
1443safeToken2           -> 'MethodToken'           : '$1' .
1444safeToken2           -> 'MgcIdToken'            : '$1' .
1445safeToken2           -> 'ModeToken'             : '$1' .
1446safeToken2           -> 'ModifyToken'           : '$1' .
1447%% v2-safeToken2           -> 'ModemToken'            : '$1' .
1448safeToken2           -> 'MoveToken'             : '$1' .
1449%% safeToken2        -> 'MtpToken'              : '$1' .
1450%% safeToken2        -> 'MtpAddressToken'       : '$1' .
1451%% v2-safeToken2           -> 'MuxToken'              : '$1' .
1452safeToken2           -> 'NotifyToken'           : '$1' .
1453safeToken2           -> 'NotifyCompletionToken' : '$1' .
1454safeToken2           -> 'Nx64kToken'            : '$1' .
1455%% v2-safeToken2           -> 'ObservedEventsToken'   : '$1' .
1456safeToken2           -> 'OnewayToken'           : '$1' .
1457safeToken2           -> 'OffToken'              : '$1' .
1458safeToken2           -> 'OnToken'               : '$1' .
1459safeToken2           -> 'OnOffToken'            : '$1' .
1460safeToken2           -> 'OutOfSvcToken'         : '$1' .
1461safeToken2           -> 'OtherReasonToken'      : '$1' .
1462%% v2-safeToken2           -> 'PackagesToken'         : '$1' .
1463safeToken2           -> 'PendingToken'          : '$1' .
1464safeToken2           -> 'PriorityToken'         : '$1' .
1465safeToken2           -> 'ProfileToken'          : '$1' .
1466safeToken2           -> 'ReasonToken'           : '$1' .
1467safeToken2           -> 'RecvonlyToken'         : '$1' .
1468safeToken2           -> 'ReplyToken'            : '$1' .
1469safeToken2           -> 'ResponseAckToken'      : '$1' .
1470safeToken2           -> 'RestartToken'          : '$1' .
1471%% safeToken2        -> 'RemoteToken'           : '$1' .
1472%% safeToken2        -> 'RemoteDescriptorToken' : '$1' .
1473safeToken2           -> 'ReservedGroupToken'    : '$1' .
1474safeToken2           -> 'ReservedValueToken'    : '$1' .
1475safeToken2           -> 'SendonlyToken'         : '$1' .
1476safeToken2           -> 'SendrecvToken'         : '$1' .
1477safeToken2           -> 'ServicesToken'         : '$1' .
1478safeToken2           -> 'ServiceStatesToken'    : '$1' .
1479safeToken2           -> 'ServiceChangeToken'    : '$1' .
1480safeToken2           -> 'ServiceChangeAddressToken' : '$1' .
1481safeToken2           -> 'SignalListToken'       : '$1' .
1482%% v2-safeToken2           -> 'SignalsToken'          : '$1' .
1483safeToken2           -> 'SignalTypeToken'       : '$1' .
1484%% v2-safeToken2           -> 'StatsToken'            : '$1' .
1485safeToken2           -> 'StreamToken'           : '$1' .
1486safeToken2           -> 'SubtractToken'         : '$1' .
1487safeToken2           -> 'SynchISDNToken'        : '$1' .
1488safeToken2           -> 'TerminationStateToken' : '$1' .
1489safeToken2           -> 'TestToken'             : '$1' .
1490safeToken2           -> 'TimeOutToken'          : '$1' .
1491safeToken2           -> 'TimeStampToken'        : '$1' .
1492safeToken2           -> 'TopologyToken'         : '$1' .
1493safeToken2           -> 'TransToken'            : '$1' .
1494safeToken2           -> 'V18Token'              : '$1' .
1495safeToken2           -> 'V22Token'              : '$1' .
1496safeToken2           -> 'V22bisToken'           : '$1' .
1497safeToken2           -> 'V32Token'              : '$1' .
1498safeToken2           -> 'V32bisToken'           : '$1' .
1499safeToken2           -> 'V34Token'              : '$1' .
1500safeToken2           -> 'V76Token'              : '$1' .
1501safeToken2           -> 'V90Token'              : '$1' .
1502safeToken2           -> 'V91Token'              : '$1' .
1503safeToken2           -> 'VersionToken'          : '$1' .
1504%% <OTP-7534>
1505safeToken2           -> 'AndAUDITSelectToken'   : '$1' .
1506safeToken2           -> 'BothToken'             : '$1' .
1507safeToken2           -> 'ContextAttrToken'      : '$1' .
1508safeToken2           -> 'ContextListToken'      : '$1' .
1509safeToken2           -> 'DirectionToken'        : '$1' .
1510%% safeToken2           -> 'EmergencyOffToken'     : '$1' .
1511safeToken2           -> 'EmergencyValueToken'   : '$1' .
1512safeToken2           -> 'ExternalToken'         : '$1' .
1513safeToken2           -> 'IEPSToken'             : '$1' .
1514safeToken2           -> 'InternalToken'         : '$1' .
1515safeToken2           -> 'IntsigDelayToken'      : '$1' .
1516safeToken2           -> 'IterationToken'        : '$1' .
1517safeToken2           -> 'MessageSegmentToken'   : '$1' .
1518safeToken2           -> 'NeverNotifyToken'      : '$1' .
1519safeToken2           -> 'NotifyImmediateToken'  : '$1' .
1520safeToken2           -> 'NotifyRegulatedToken'  : '$1' .
1521safeToken2           -> 'OnewayBothToken'       : '$1' .
1522safeToken2           -> 'OnewayExternalToken'   : '$1' .
1523safeToken2           -> 'OrAUDITselectToken'    : '$1' .
1524safeToken2           -> 'RequestIDToken'        : '$1' .
1525safeToken2           -> 'ResetEventsDescriptorToken'    : '$1' .
1526safeToken2           -> 'SegmentationCompleteToken'     : '$1' .
1527safeToken2           -> 'ServiceChangeIncompleteToken'  : '$1' .
1528%% </OTP-7534>
1529
1530
1531Erlang code.
1532
1533-include("megaco_text_parser_v2.hrl").
1534
1535
1536