aboutsummaryrefslogtreecommitdiffstats
path: root/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
diff options
context:
space:
mode:
authorErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
committerErlang/OTP <[email protected]>2009-11-20 14:54:40 +0000
commit84adefa331c4159d432d22840663c38f155cd4c1 (patch)
treebff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
downloadotp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz
otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2
otp-84adefa331c4159d432d22840663c38f155cd4c1.zip
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src')
-rw-r--r--lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src1943
1 files changed, 1943 insertions, 0 deletions
diff --git a/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src b/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
new file mode 100644
index 0000000000..b96a69415d
--- /dev/null
+++ b/lib/megaco/src/flex/megaco_flex_scanner_drv.flex.src
@@ -0,0 +1,1943 @@
+ /*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ *
+ * ----------------------------------------------------------------------
+ * Purpose : Scanner for text encoded Megaco/H.248 messages
+ * ----------------------------------------------------------------------
+ *
+ * Throughout this file the prefix mfs is used for megaco_flex_scanner.
+ * The reason is to get shorter function and variable names.
+ */
+
+%option case-insensitive
+
+ /* MEGACO_YY_LINENO_OPTION
+ * Note that this construction is intended to make it
+ * possible to generate flex files that either reports
+ * line-number or one that don't.
+ * See MEGACO_DUMMY_DECL_YY_LINENO and
+ * MEGACO_LINENO_OR_TOKENCOUNTER below.
+ */
+%MEGACO_YY_LINENO_OPTION%
+
+%MEGACO_YY_REENTRANT_OPTION%
+%option noyywrap
+%option noinput
+%option nounput
+%{
+
+#define HAVE_UIO_H
+#include "erl_driver.h"
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#define TRUE 1
+#define FALSE 0
+#define SP 0x20
+#define HTAB 0x09
+#define CR 0x0d
+#define LF 0x0a
+#define SEMI_COLON 0x3b
+#define BACKSLASH 0x5c
+#define RBRKT 0x7b
+#define NUL 0x0
+
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+ #define MEGACO_EXTENDED_MARKER ERL_DRV_EXTENDED_MARKER
+ #define MEGACO_DRIVER_FLAGS ERL_DRV_FLAG_USE_PORT_LOCKING
+ #define MEGACO_EXTENDED_MAJOR_VERSION ERL_DRV_EXTENDED_MAJOR_VERSION
+ #define MEGACO_EXTENDED_MINOR_VERSION ERL_DRV_EXTENDED_MINOR_VERSION
+#else
+ #define MEGACO_EXTENDED_MARKER 0
+ #define MEGACO_DRIVER_FLAGS 0
+ #define MEGACO_EXTENDED_MAJOR_VERSION 0
+ #define MEGACO_EXTENDED_MINOR_VERSION 0
+#endif
+
+
+#define FREE(bufP) driver_free(bufP)
+#define ALLOC(sz) driver_alloc(sz)
+#define REALLOC(bufP, sz) driver_realloc(bufP, sz)
+
+#define YY_MAIN false
+
+// #define YY_FATAL_ERROR(msg) mfs_fatal_error(msg)
+
+
+typedef struct {
+ ErlDrvPort port;
+ char* digit_map_name_ptr;
+ int digit_map_name_len;
+ char* digit_map_value_ptr;
+ int digit_map_value_len;
+ char* digit_map_start_ptr;
+ char* digit_map_short_ptr;
+ char* digit_map_long_ptr;
+ char* digit_map_duration_ptr;
+ int error;
+ char error_msg[512];
+ char* text_buf;
+ char* text_ptr;
+ ErlDrvTermData* term_spec;
+ int term_spec_size;
+ int term_spec_index;
+ int token_counter;
+} MfsErlDrvData;
+
+#if !defined(MEGACO_REENTRANT_FLEX_SCANNER)
+static MfsErlDrvData mfs_drv_data;
+#endif
+
+char flex_version[] = "%FLEX_VERSION%";
+
+static ErlDrvTermData mfs_AddToken = 0;
+static ErlDrvTermData mfs_AndAUDITSelectToken = 0; /* v3 */
+static ErlDrvTermData mfs_AuditCapToken = 0;
+static ErlDrvTermData mfs_AuditToken = 0;
+static ErlDrvTermData mfs_AuditValueToken = 0;
+static ErlDrvTermData mfs_AuthToken = 0;
+static ErlDrvTermData mfs_BothToken = 0; /* v3 */
+static ErlDrvTermData mfs_BothwayToken = 0;
+static ErlDrvTermData mfs_BriefToken = 0;
+static ErlDrvTermData mfs_BufferToken = 0;
+static ErlDrvTermData mfs_COLON = 0;
+static ErlDrvTermData mfs_COMMA = 0;
+static ErlDrvTermData mfs_ContextAttrToken = 0; /* v3 */
+static ErlDrvTermData mfs_ContextAuditToken = 0;
+static ErlDrvTermData mfs_ContextListToken = 0; /* v3 */
+static ErlDrvTermData mfs_CtxToken = 0;
+static ErlDrvTermData mfs_DelayToken = 0;
+static ErlDrvTermData mfs_DeleteToken = 0;
+static ErlDrvTermData mfs_DigitMapDescriptor = 0;
+static ErlDrvTermData mfs_DigitMapDescriptorToken = 0;
+static ErlDrvTermData mfs_DigitMapToken = 0;
+static ErlDrvTermData mfs_DigitMapValue = 0;
+static ErlDrvTermData mfs_DirectionToken = 0; /* v3 */
+static ErlDrvTermData mfs_DiscardToken = 0;
+static ErlDrvTermData mfs_DisconnectedToken = 0;
+static ErlDrvTermData mfs_DurationToken = 0;
+static ErlDrvTermData mfs_EQUAL = 0;
+static ErlDrvTermData mfs_EmbedToken = 0;
+static ErlDrvTermData mfs_EmergencyToken = 0;
+static ErlDrvTermData mfs_EmergencyOffToken = 0; /* v3 */
+static ErlDrvTermData mfs_EmergencyValueToken = 0; /* v3 */
+static ErlDrvTermData mfs_ErrorToken = 0;
+static ErlDrvTermData mfs_EventBufferToken = 0;
+static ErlDrvTermData mfs_EventsToken = 0;
+static ErlDrvTermData mfs_ExternalToken = 0; /* v3 */
+static ErlDrvTermData mfs_FailoverToken = 0;
+static ErlDrvTermData mfs_ForcedToken = 0;
+static ErlDrvTermData mfs_GREATER = 0;
+static ErlDrvTermData mfs_GracefulToken = 0;
+static ErlDrvTermData mfs_H221Token = 0;
+static ErlDrvTermData mfs_H223Token = 0;
+static ErlDrvTermData mfs_H226Token = 0;
+static ErlDrvTermData mfs_HandOffToken = 0;
+static ErlDrvTermData mfs_IEPSToken = 0; /* v3 */
+static ErlDrvTermData mfs_IllegalChar = 0;
+static ErlDrvTermData mfs_ImmAckRequiredToken = 0;
+static ErlDrvTermData mfs_InactiveToken = 0;
+static ErlDrvTermData mfs_InSvcToken = 0;
+static ErlDrvTermData mfs_IntsigDelayToken = 0; /* v3 */
+static ErlDrvTermData mfs_InternalToken = 0; /* v3 */
+static ErlDrvTermData mfs_InterruptByEventToken = 0;
+static ErlDrvTermData mfs_InterruptByNewSignalsDescrToken = 0;
+static ErlDrvTermData mfs_IsolateToken = 0;
+static ErlDrvTermData mfs_IterationToken = 0; /* v3 */
+static ErlDrvTermData mfs_KeepActiveToken = 0;
+static ErlDrvTermData mfs_LBRKT = 0;
+static ErlDrvTermData mfs_LESSER = 0;
+static ErlDrvTermData mfs_LSBRKT = 0;
+static ErlDrvTermData mfs_LocalControlToken = 0;
+static ErlDrvTermData mfs_LocalDescriptorToken = 0;
+static ErlDrvTermData mfs_LocalToken = 0;
+static ErlDrvTermData mfs_LockStepToken = 0;
+static ErlDrvTermData mfs_LoopbackToken = 0;
+static ErlDrvTermData mfs_MediaToken = 0;
+static ErlDrvTermData mfs_MegacopToken = 0;
+static ErlDrvTermData mfs_MethodToken = 0;
+static ErlDrvTermData mfs_MessageSegmentToken = 0;
+static ErlDrvTermData mfs_MgcIdToken = 0;
+static ErlDrvTermData mfs_ModeToken = 0;
+static ErlDrvTermData mfs_ModemToken = 0;
+static ErlDrvTermData mfs_ModifyToken = 0;
+static ErlDrvTermData mfs_MoveToken = 0;
+static ErlDrvTermData mfs_MtpAddressToken = 0;
+static ErlDrvTermData mfs_MuxToken = 0;
+static ErlDrvTermData mfs_NEQUAL = 0;
+static ErlDrvTermData mfs_NeverNotifyToken = 0; /* v3 */
+static ErlDrvTermData mfs_NotifyCompletionToken = 0;
+static ErlDrvTermData mfs_NotifyImmediateToken = 0; /* v3 */
+static ErlDrvTermData mfs_NotifyRegulatedToken = 0; /* v3 */
+static ErlDrvTermData mfs_NotifyToken = 0;
+static ErlDrvTermData mfs_Nx64kToken = 0;
+static ErlDrvTermData mfs_ObservedEventsToken = 0;
+static ErlDrvTermData mfs_OffToken = 0;
+static ErlDrvTermData mfs_OnOffToken = 0;
+static ErlDrvTermData mfs_OnToken = 0;
+static ErlDrvTermData mfs_OnewayToken = 0;
+static ErlDrvTermData mfs_OnewayBothToken = 0; /* v3 */
+static ErlDrvTermData mfs_OnewayExternalToken = 0; /* v3 */
+static ErlDrvTermData mfs_OrAUDITselectToken = 0; /* v3 */
+static ErlDrvTermData mfs_OtherReasonToken = 0;
+static ErlDrvTermData mfs_OutOfSvcToken = 0;
+static ErlDrvTermData mfs_PackagesToken = 0;
+static ErlDrvTermData mfs_PendingToken = 0;
+static ErlDrvTermData mfs_PriorityToken = 0;
+static ErlDrvTermData mfs_ProfileToken = 0;
+static ErlDrvTermData mfs_QuotedChars = 0;
+static ErlDrvTermData mfs_RBRKT = 0;
+static ErlDrvTermData mfs_RSBRKT = 0;
+static ErlDrvTermData mfs_ReasonToken = 0;
+static ErlDrvTermData mfs_RecvonlyToken = 0;
+static ErlDrvTermData mfs_RemoteDescriptorToken = 0;
+static ErlDrvTermData mfs_RemoteToken = 0;
+static ErlDrvTermData mfs_RequestIDToken = 0; /* v3 */
+static ErlDrvTermData mfs_ReplyToken = 0;
+static ErlDrvTermData mfs_ReservedGroupToken = 0;
+static ErlDrvTermData mfs_ReservedValueToken = 0;
+static ErlDrvTermData mfs_ResetEventsDescriptorToken = 0; /* v3 */
+static ErlDrvTermData mfs_ResponseAckToken = 0;
+static ErlDrvTermData mfs_RestartToken = 0;
+static ErlDrvTermData mfs_SEP = 0;
+static ErlDrvTermData mfs_SafeChars = 0;
+static ErlDrvTermData mfs_SegmentationCompleteToken = 0; /* v3 */
+static ErlDrvTermData mfs_SendonlyToken = 0;
+static ErlDrvTermData mfs_SendrecvToken = 0;
+static ErlDrvTermData mfs_ServiceChangeAddressToken = 0;
+static ErlDrvTermData mfs_ServiceChangeIncompleteToken = 0; /* v3 */
+static ErlDrvTermData mfs_ServiceChangeToken = 0;
+static ErlDrvTermData mfs_ServiceStatesToken = 0;
+static ErlDrvTermData mfs_ServicesToken = 0;
+static ErlDrvTermData mfs_SignalListToken = 0;
+static ErlDrvTermData mfs_SignalTypeToken = 0;
+static ErlDrvTermData mfs_SignalsToken = 0;
+static ErlDrvTermData mfs_StatsToken = 0;
+static ErlDrvTermData mfs_StreamToken = 0;
+static ErlDrvTermData mfs_SubtractToken = 0;
+static ErlDrvTermData mfs_SynchISDNToken = 0;
+static ErlDrvTermData mfs_TerminationStateToken = 0;
+static ErlDrvTermData mfs_TestToken = 0;
+static ErlDrvTermData mfs_TimeOutToken = 0;
+static ErlDrvTermData mfs_TimeStampToken = 0; /* OTP-5042 */
+static ErlDrvTermData mfs_TopologyToken = 0;
+static ErlDrvTermData mfs_TransToken = 0;
+static ErlDrvTermData mfs_V18Token = 0;
+static ErlDrvTermData mfs_V22Token = 0;
+static ErlDrvTermData mfs_V22bisToken = 0;
+static ErlDrvTermData mfs_V32Token = 0;
+static ErlDrvTermData mfs_V32bisToken = 0;
+static ErlDrvTermData mfs_V34Token = 0;
+static ErlDrvTermData mfs_V76Token = 0;
+static ErlDrvTermData mfs_V90Token = 0;
+static ErlDrvTermData mfs_V91Token = 0;
+static ErlDrvTermData mfs_VersionToken = 0;
+static ErlDrvTermData mfs_asn1_NOVALUE = 0;
+static ErlDrvTermData mfs_endOfMessage = 0;
+static ErlDrvTermData mfs_PropertyParm = 0;
+static ErlDrvTermData mfs_ErrorDescriptor = 0;
+
+/* MEGACO_DUMMY_DECL_YY_LINENO
+ * Note that this construction is intended to make it
+ * possible to generate flex files that either reports
+ * line-number or one that don't.
+ * See MEGACO_YY_LINENO_OPTION above and
+ * MEGACO_LINENO_OR_TOKENCOUNTER below.
+ */
+#if !defined(MEGACO_REENTRANT_FLEX_SCANNER)
+%MEGACO_DUMMY_DECL_YY_LINENO%
+#endif
+
+/*
+static ErlDrvPort mfs_port = 0;
+static char* mfs_digit_map_name_ptr = 0;
+static int mfs_digit_map_name_len = 0;
+static char* mfs_digit_map_value_ptr = 0;
+static int mfs_digit_map_value_len = 0;
+static char* mfs_digit_map_start_ptr = 0;
+static char* mfs_digit_map_short_ptr = 0;
+static char* mfs_digit_map_long_ptr = 0;
+static char* mfs_digit_map_duration_ptr = 0;
+static int mfs_error = FALSE;
+static char mfs_error_msg[512];
+static char* mfs_text_buf = 0;
+static char* mfs_text_ptr = 0;
+static ErlDrvTermData* mfs_term_spec = 0;
+static int mfs_term_spec_size = 0;
+static int mfs_term_spec_index = 0;
+static int mfs_token_counter = 0;
+*/
+
+
+static void mfs_alloc_failed(MfsErlDrvData* dataP, char* msg, int sz);
+static void mfs_fatal_error(MfsErlDrvData* dataP, char* msg);
+static void mfs_ensure_term_spec(MfsErlDrvData* dataP, int size);
+
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+
+static void mfs_short_load_token(ErlDrvTermData token_tag,
+ yyscan_t yyscanner);
+static void mfs_lower_load_token(ErlDrvTermData token_tag, int is_empty,
+ yyscan_t yyscanner);
+static void mfs_octet_load_token(ErlDrvTermData token_tag, int is_empty,
+ yyscan_t yyscanner);
+static void mfs_load_property_groups(MfsErlDrvData* dataP, yyscan_t yyscanner);
+static void mfs_load_map_name(yyscan_t yyscanner);
+static void mfs_load_map_value(yyscan_t yyscanner);
+static void mfs_load_map_timer(yyscan_t yyscanner);
+static void mfs_load_map_token(yyscan_t yyscanner);
+
+#else
+
+static void mfs_short_load_token(ErlDrvTermData token_tag);
+static void mfs_lower_load_token(ErlDrvTermData token_tag, int is_empty);
+static void mfs_octet_load_token(ErlDrvTermData token_tag, int is_empty);
+static void mfs_load_property_groups(MfsErlDrvData* dataP);
+static void mfs_load_map_name();
+static void mfs_load_map_value();
+static void mfs_load_map_timer();
+static void mfs_load_map_token();
+
+#endif
+
+static ErlDrvData mfs_start(ErlDrvPort port, char *buf);
+static void mfs_stop(ErlDrvData handle);
+static void mfs_command(ErlDrvData handle,
+ char *buf, int buf_len);
+static int mfs_control(ErlDrvData handle,
+ unsigned int command,
+ char *buf, int buf_len,
+ char **res_buf, int res_buf_len);
+static void mfs_finish(void);
+
+/*
+ * The driver entry
+ */
+
+static ErlDrvEntry mfs_entry = {
+ NULL, /* init, always NULL for dynamic drivers */
+ mfs_start, /* start, called when port is opened */
+ mfs_stop, /* stop, called when port is closed */
+ mfs_command, /* output, called when erlang has sent */
+ NULL, /* ready_input, called when input descriptor ready */
+ NULL, /* ready_output, called when output descriptor ready */
+ MEGACO_DRV_NAME, /* char *driver_name, the arg to open_port */
+ mfs_finish, /* finish, called when unloaded */
+ NULL, /* void * that is not used (BC) */
+ mfs_control, /* control, port_control callback */
+ NULL, /* timeout, called on timeouts */
+ NULL, /* outputv, vector output interface */
+ NULL, /* ready_async, called after an asynchronous call has completed */
+ NULL, /* flush, port is about to be closed */
+ NULL, /* call, a syncronous call into the driver */
+ NULL, /* event, event selected by driver_event() has occurred */
+ MEGACO_EXTENDED_MARKER, /* extended_marker, which we use if reentrant */
+ MEGACO_EXTENDED_MAJOR_VERSION, /* major_version, ... */
+ MEGACO_EXTENDED_MINOR_VERSION, /* minor_version, ... */
+ MEGACO_DRIVER_FLAGS, /* driver_flags, used for port lock indication */
+ NULL, /* handle2, emulator internal use */
+ NULL /* process_exit, Called when a process monitor fires */
+#if defined(MEGACO_DRV_ENTRY_HAS_STOP_SELECT)
+ ,NULL /* stop_select, Called to close an event object */
+#endif
+};
+
+
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+
+#define LOAD_TOKEN(TokenTag) mfs_lower_load_token(TokenTag, FALSE, yyscanner)
+#define LOAD_EMPTY_TOKEN(TokenTag) mfs_lower_load_token(TokenTag, TRUE, yyscanner)
+#define LOAD_SHORT_TOKEN(TokenTag) mfs_short_load_token(TokenTag, yyscanner)
+#define LOAD_OCTET_TOKEN(TokenTag) mfs_octet_load_token(TokenTag, FALSE, yyscanner)
+#define LOAD_EMPTY_OCTET_TOKEN(TokenTag) mfs_octet_load_token(TokenTag, TRUE, yyscanner)
+#define LOAD_MAP_NAME() mfs_load_map_name(yyscanner)
+#define LOAD_MAP_TIMER() mfs_load_map_timer(yyscanner)
+#define LOAD_MAP_TOKEN() mfs_load_map_token(yyscanner)
+#define LOAD_MAP_VALUE() mfs_load_map_value(yyscanner)
+#define LOAD_PROP_GRPS(dataP) mfs_load_property_groups(dataP, yyscanner)
+
+#else
+
+#define LOAD_TOKEN(TokenTag) mfs_lower_load_token(TokenTag, FALSE)
+#define LOAD_EMPTY_TOKEN(TokenTag) mfs_lower_load_token(TokenTag, TRUE)
+#define LOAD_SHORT_TOKEN(TokenTag) mfs_short_load_token(TokenTag)
+#define LOAD_OCTET_TOKEN(TokenTag) mfs_octet_load_token(TokenTag, FALSE)
+#define LOAD_EMPTY_OCTET_TOKEN(TokenTag) mfs_octet_load_token(TokenTag, TRUE)
+#define LOAD_MAP_NAME() mfs_load_map_name()
+#define LOAD_MAP_TIMER() mfs_load_map_timer()
+#define LOAD_MAP_TOKEN() mfs_load_map_token()
+#define LOAD_MAP_VALUE() mfs_load_map_value()
+#define LOAD_PROP_GRPS(dataP) mfs_load_property_groups(dataP)
+
+#endif
+
+/* OTP-4236 */
+#define ASSIGN_TERM_SPEC(dataP, what) \
+{ \
+ if (dataP->term_spec != NULL) { \
+ dataP->term_spec[dataP->term_spec_index++] = what; \
+ } \
+}
+
+%}
+
+%x SKIP_RBRKT MTP_HEXDIG LOCAL_OCTETS REMOTE_OCTETS
+%x MAP_NAME MAP_OPT_LBRKT MAP_VALUE MAP_SKIP_COMMA MAP_BODY
+%x QUOTED_CHARS SKIP_DQUOTE
+
+digit ([0-9])
+alpha ([a-zA-Z])
+hexdig ([0-9a-fA-F])
+sp (\x20)
+htab (\x09)
+cr (\x0D)
+lf (\x0A)
+slash (\/)
+dquote (\")
+colon (\:)
+dot (\.)
+wsp ({sp}|{htab})
+eol ({cr}|({cr}{lf})|{lf})
+safechar ({digit}|{alpha}|[\+\-\&\!\_\/\'\?\@\^\`\~\*\$\\\(\)\%\|\.])
+restchar ([\;\[\]\{\}\:\,\#\<\>\=])
+octet ((\\\})|[\x01-\x7C\x7E-\xFF])
+
+comment (\;({safechar}|{restchar}|{wsp}|\x22)*{eol})
+lwsp ({wsp}|{comment}|{eol})*
+
+equal ({lwsp}\={lwsp})
+nequal ({lwsp}\#{lwsp})
+lesser ({lwsp}\<{lwsp})
+greater ({lwsp}\>{lwsp})
+lbrkt ({lwsp}\{{lwsp})
+rbrkt ({lwsp}\}{lwsp})
+lsbrkt ({lwsp}\[{lwsp})
+rsbrkt ({lwsp}\]{lwsp})
+lpar ({lwsp}\({lwsp})
+rpar ({lwsp}\){lwsp})
+vbar ({lwsp}\|{lwsp})
+comma ({lwsp}\,{lwsp})
+sep (({wsp}|{eol}|{comment}){lwsp})+
+opt ((o\-)?)
+wild ((w\-)?)
+
+%%
+
+<SKIP_RBRKT>{rbrkt} BEGIN(INITIAL);
+
+{digit}{8,8}t{digit}{8,8} LOAD_TOKEN(mfs_TimeStampToken); /* OTP-5042 */
+
+(MTP){lbrkt} BEGIN(MTP_HEXDIG);
+<MTP_HEXDIG>{hexdig}{4,8} {LOAD_TOKEN(mfs_MtpAddressToken); BEGIN(SKIP_RBRKT);}
+
+((Local)|L){lbrkt} BEGIN(LOCAL_OCTETS);
+<LOCAL_OCTETS>{rbrkt} {LOAD_EMPTY_OCTET_TOKEN(mfs_LocalDescriptorToken); BEGIN(INITIAL);}
+<LOCAL_OCTETS>{octet}+ {LOAD_OCTET_TOKEN(mfs_LocalDescriptorToken); BEGIN(SKIP_RBRKT);}
+
+((Remote)|R){lbrkt} BEGIN(REMOTE_OCTETS);
+<REMOTE_OCTETS>{rbrkt} {LOAD_EMPTY_OCTET_TOKEN(mfs_RemoteDescriptorToken); BEGIN(INITIAL);}
+<REMOTE_OCTETS>{octet}+ {LOAD_OCTET_TOKEN(mfs_RemoteDescriptorToken); BEGIN(SKIP_RBRKT);}
+
+((DigitMap)|DM) LOAD_TOKEN(mfs_DigitMapToken);
+((DigitMap)|DM){equal} BEGIN(MAP_NAME);
+((DigitMap)|DM){equal}{lbrkt} BEGIN(MAP_VALUE);
+((DigitMap)|DM){lbrkt} BEGIN(MAP_VALUE);
+
+<MAP_NAME>{safechar}+ {LOAD_MAP_NAME(); BEGIN(MAP_OPT_LBRKT);}
+
+<MAP_OPT_LBRKT>{lbrkt} BEGIN(MAP_VALUE);
+<MAP_OPT_LBRKT><<EOF>> {LOAD_MAP_TOKEN(); LOAD_TOKEN(mfs_endOfMessage); BEGIN(INITIAL); yyterminate();}
+<MAP_OPT_LBRKT>.|\n {LOAD_MAP_TOKEN(); yyless(0); BEGIN(INITIAL);}
+
+<MAP_VALUE>t{colon}{digit}{1,2} {LOAD_MAP_TIMER(); BEGIN(MAP_SKIP_COMMA);}
+<MAP_VALUE>s{colon}{digit}{1,2} {LOAD_MAP_TIMER(); BEGIN(MAP_SKIP_COMMA);}
+<MAP_VALUE>l{colon}{digit}{1,2} {LOAD_MAP_TIMER(); BEGIN(MAP_SKIP_COMMA);}
+<MAP_VALUE>z{colon}{digit}{1,2} {LOAD_MAP_TIMER(); BEGIN(MAP_SKIP_COMMA);}
+<MAP_VALUE>.|\n {yyless(0); BEGIN(MAP_BODY);}
+
+<MAP_SKIP_COMMA>{comma} BEGIN(MAP_VALUE);
+
+<MAP_BODY>{octet}+ {LOAD_MAP_VALUE(); LOAD_MAP_TOKEN(); BEGIN(SKIP_RBRKT);}
+
+{equal} LOAD_SHORT_TOKEN(mfs_EQUAL);
+{colon} LOAD_SHORT_TOKEN(mfs_COLON);
+{lbrkt} LOAD_SHORT_TOKEN(mfs_LBRKT);
+{rbrkt} LOAD_SHORT_TOKEN(mfs_RBRKT);
+{lsbrkt} LOAD_SHORT_TOKEN(mfs_LSBRKT);
+{rsbrkt} LOAD_SHORT_TOKEN(mfs_RSBRKT);
+{comma} LOAD_SHORT_TOKEN(mfs_COMMA);
+{nequal} LOAD_SHORT_TOKEN(mfs_NEQUAL);
+{lesser} LOAD_SHORT_TOKEN(mfs_LESSER);
+{greater} LOAD_SHORT_TOKEN(mfs_GREATER);
+{sep} LOAD_SHORT_TOKEN(mfs_SEP);
+
+{dquote} BEGIN(QUOTED_CHARS);
+
+<QUOTED_CHARS>{dquote} {LOAD_EMPTY_TOKEN(mfs_QuotedChars); BEGIN(INITIAL);}
+<QUOTED_CHARS>({safechar}|{restchar}|{wsp})+ {LOAD_TOKEN(mfs_QuotedChars); BEGIN(SKIP_DQUOTE);}
+
+<SKIP_DQUOTE>{dquote} BEGIN(INITIAL);
+
+{opt}{wild}add LOAD_TOKEN(mfs_AddToken);
+{opt}{wild}a LOAD_TOKEN(mfs_AddToken);
+andlgc LOAD_TOKEN(mfs_AndAUDITSelectToken);
+audit LOAD_TOKEN(mfs_AuditToken);
+at LOAD_TOKEN(mfs_AuditToken);
+{opt}{wild}auditcapability LOAD_TOKEN(mfs_AuditCapToken);
+{opt}{wild}ac LOAD_TOKEN(mfs_AuditCapToken);
+{opt}{wild}auditvalue LOAD_TOKEN(mfs_AuditValueToken);
+{opt}{wild}av LOAD_TOKEN(mfs_AuditValueToken);
+authentication LOAD_TOKEN(mfs_AuthToken);
+au LOAD_TOKEN(mfs_AuthToken);
+both LOAD_TOKEN(mfs_BothToken);
+b LOAD_TOKEN(mfs_BothToken);
+bothway LOAD_TOKEN(mfs_BothwayToken);
+bw LOAD_TOKEN(mfs_BothwayToken);
+brief LOAD_TOKEN(mfs_BriefToken);
+br LOAD_TOKEN(mfs_BriefToken);
+buffer LOAD_TOKEN(mfs_BufferToken);
+bf LOAD_TOKEN(mfs_BufferToken);
+context LOAD_TOKEN(mfs_CtxToken);
+c LOAD_TOKEN(mfs_CtxToken);
+contextattr LOAD_TOKEN(mfs_ContextAttrToken);
+ct LOAD_TOKEN(mfs_ContextAttrToken);
+contextaudit LOAD_TOKEN(mfs_ContextAuditToken);
+ca LOAD_TOKEN(mfs_ContextAuditToken);
+contextlist LOAD_TOKEN(mfs_ContextListToken);
+clt LOAD_TOKEN(mfs_ContextListToken);
+spadirection LOAD_TOKEN(mfs_DirectionToken);
+direction LOAD_TOKEN(mfs_DirectionToken);
+spadi LOAD_TOKEN(mfs_DirectionToken);
+di LOAD_TOKEN(mfs_DirectionToken);
+discard LOAD_TOKEN(mfs_DiscardToken);
+ds LOAD_TOKEN(mfs_DiscardToken);
+disconnected LOAD_TOKEN(mfs_DisconnectedToken);
+dc LOAD_TOKEN(mfs_DisconnectedToken);
+delay LOAD_TOKEN(mfs_DelayToken);
+dl LOAD_TOKEN(mfs_DelayToken);
+delete LOAD_TOKEN(mfs_DeleteToken);
+de LOAD_TOKEN(mfs_DeleteToken);
+duration LOAD_TOKEN(mfs_DurationToken);
+dr LOAD_TOKEN(mfs_DurationToken);
+embed LOAD_TOKEN(mfs_EmbedToken);
+em LOAD_TOKEN(mfs_EmbedToken);
+emergency LOAD_TOKEN(mfs_EmergencyToken);
+eg LOAD_TOKEN(mfs_EmergencyToken);
+emergencyoff LOAD_TOKEN(mfs_EmergencyOffToken);
+emergencyofftoken LOAD_TOKEN(mfs_EmergencyOffToken);
+ego LOAD_TOKEN(mfs_EmergencyOffToken);
+emergencyvalue LOAD_TOKEN(mfs_EmergencyValueToken);
+egv LOAD_TOKEN(mfs_EmergencyValueToken);
+error LOAD_TOKEN(mfs_ErrorToken);
+er LOAD_TOKEN(mfs_ErrorToken);
+eventbuffer LOAD_TOKEN(mfs_EventBufferToken);
+eb LOAD_TOKEN(mfs_EventBufferToken);
+events LOAD_TOKEN(mfs_EventsToken);
+e LOAD_TOKEN(mfs_EventsToken);
+external LOAD_TOKEN(mfs_ExternalToken);
+ex LOAD_TOKEN(mfs_ExternalToken);
+failover LOAD_TOKEN(mfs_FailoverToken);
+fl LOAD_TOKEN(mfs_FailoverToken);
+forced LOAD_TOKEN(mfs_ForcedToken);
+fo LOAD_TOKEN(mfs_ForcedToken);
+graceful LOAD_TOKEN(mfs_GracefulToken);
+gr LOAD_TOKEN(mfs_GracefulToken);
+h221 LOAD_TOKEN(mfs_H221Token);
+h223 LOAD_TOKEN(mfs_H223Token);
+h226 LOAD_TOKEN(mfs_H226Token);
+handoff LOAD_TOKEN(mfs_HandOffToken);
+ho LOAD_TOKEN(mfs_HandOffToken);
+iepscall LOAD_TOKEN(mfs_IEPSToken);
+ieps LOAD_TOKEN(mfs_IEPSToken);
+inactive LOAD_TOKEN(mfs_InactiveToken);
+in LOAD_TOKEN(mfs_InactiveToken);
+immackrequired LOAD_TOKEN(mfs_ImmAckRequiredToken);
+ia LOAD_TOKEN(mfs_ImmAckRequiredToken);
+inservice LOAD_TOKEN(mfs_InSvcToken);
+iv LOAD_TOKEN(mfs_InSvcToken);
+internal LOAD_TOKEN(mfs_InternalToken);
+it LOAD_TOKEN(mfs_InternalToken);
+intersignal LOAD_TOKEN(mfs_IntsigDelayToken);
+spais LOAD_TOKEN(mfs_IntsigDelayToken);
+isolate LOAD_TOKEN(mfs_IsolateToken);
+is LOAD_TOKEN(mfs_IsolateToken);
+intbyevent LOAD_TOKEN(mfs_InterruptByEventToken);
+ibe LOAD_TOKEN(mfs_InterruptByEventToken);
+intbysigdescr LOAD_TOKEN(mfs_InterruptByNewSignalsDescrToken);
+ibs LOAD_TOKEN(mfs_InterruptByNewSignalsDescrToken);
+iteration LOAD_TOKEN(mfs_IterationToken);
+ir LOAD_TOKEN(mfs_IterationToken);
+keepactive LOAD_TOKEN(mfs_KeepActiveToken);
+ka LOAD_TOKEN(mfs_KeepActiveToken);
+local LOAD_TOKEN(mfs_LocalToken);
+l LOAD_TOKEN(mfs_LocalToken);
+localcontrol LOAD_TOKEN(mfs_LocalControlToken);
+lockstep LOAD_TOKEN(mfs_LockStepToken);
+sp LOAD_TOKEN(mfs_LockStepToken);
+o LOAD_TOKEN(mfs_LocalControlToken);
+loopback LOAD_TOKEN(mfs_LoopbackToken);
+lb LOAD_TOKEN(mfs_LoopbackToken);
+media LOAD_TOKEN(mfs_MediaToken);
+m LOAD_TOKEN(mfs_MediaToken);
+megaco LOAD_TOKEN(mfs_MegacopToken);
+! LOAD_TOKEN(mfs_MegacopToken);
+segment LOAD_TOKEN(mfs_MessageSegmentToken);
+sm LOAD_TOKEN(mfs_MessageSegmentToken);
+method LOAD_TOKEN(mfs_MethodToken);
+mt LOAD_TOKEN(mfs_MethodToken);
+mgcidtotry LOAD_TOKEN(mfs_MgcIdToken);
+mg LOAD_TOKEN(mfs_MgcIdToken);
+mode LOAD_TOKEN(mfs_ModeToken);
+mo LOAD_TOKEN(mfs_ModeToken);
+{opt}modify LOAD_TOKEN(mfs_ModifyToken);
+{opt}mf LOAD_TOKEN(mfs_ModifyToken);
+modem LOAD_TOKEN(mfs_ModemToken);
+md LOAD_TOKEN(mfs_ModemToken);
+{opt}move LOAD_TOKEN(mfs_MoveToken);
+{opt}mv LOAD_TOKEN(mfs_MoveToken);
+mux LOAD_TOKEN(mfs_MuxToken);
+mx LOAD_TOKEN(mfs_MuxToken);
+nevernotify LOAD_TOKEN(mfs_NeverNotifyToken);
+nbnn LOAD_TOKEN(mfs_NeverNotifyToken);
+{opt}{wild}notify LOAD_TOKEN(mfs_NotifyToken);
+{opt}{wild}n LOAD_TOKEN(mfs_NotifyToken);
+notifycompletion LOAD_TOKEN(mfs_NotifyCompletionToken);
+nc LOAD_TOKEN(mfs_NotifyCompletionToken);
+immediatenotify LOAD_TOKEN(mfs_NotifyImmediateToken);
+nbin LOAD_TOKEN(mfs_NotifyImmediateToken);
+regulatednotify LOAD_TOKEN(mfs_NotifyRegulatedToken);
+nbrn LOAD_TOKEN(mfs_NotifyRegulatedToken);
+nx64kservice LOAD_TOKEN(mfs_Nx64kToken);
+n64 LOAD_TOKEN(mfs_Nx64kToken);
+observedevents LOAD_TOKEN(mfs_ObservedEventsToken);
+oe LOAD_TOKEN(mfs_ObservedEventsToken);
+oneway LOAD_TOKEN(mfs_OnewayToken);
+ow LOAD_TOKEN(mfs_OnewayToken);
+onewayboth LOAD_TOKEN(mfs_OnewayBothToken);
+owb LOAD_TOKEN(mfs_OnewayBothToken);
+onewayexternal LOAD_TOKEN(mfs_OnewayExternalToken);
+owe LOAD_TOKEN(mfs_OnewayExternalToken);
+off LOAD_TOKEN(mfs_OffToken);
+on LOAD_TOKEN(mfs_OnToken);
+onoff LOAD_TOKEN(mfs_OnOffToken);
+oo LOAD_TOKEN(mfs_OnOffToken);
+orlgc LOAD_TOKEN(mfs_OrAUDITselectToken);
+otherreason LOAD_TOKEN(mfs_OtherReasonToken);
+or LOAD_TOKEN(mfs_OtherReasonToken);
+outofservice LOAD_TOKEN(mfs_OutOfSvcToken);
+os LOAD_TOKEN(mfs_OutOfSvcToken);
+packages LOAD_TOKEN(mfs_PackagesToken);
+pg LOAD_TOKEN(mfs_PackagesToken);
+pending LOAD_TOKEN(mfs_PendingToken);
+pn LOAD_TOKEN(mfs_PendingToken);
+priority LOAD_TOKEN(mfs_PriorityToken);
+pr LOAD_TOKEN(mfs_PriorityToken);
+profile LOAD_TOKEN(mfs_ProfileToken);
+pf LOAD_TOKEN(mfs_ProfileToken);
+reason LOAD_TOKEN(mfs_ReasonToken);
+re LOAD_TOKEN(mfs_ReasonToken);
+receiveonly LOAD_TOKEN(mfs_RecvonlyToken);
+rc LOAD_TOKEN(mfs_RecvonlyToken);
+reply LOAD_TOKEN(mfs_ReplyToken);
+p LOAD_TOKEN(mfs_ReplyToken);
+reseteventsdescriptor LOAD_TOKEN(mfs_ResetEventsDescriptorToken);
+rse LOAD_TOKEN(mfs_ResetEventsDescriptorToken);
+transactionresponseack LOAD_TOKEN(mfs_ResponseAckToken);
+k LOAD_TOKEN(mfs_ResponseAckToken);
+restart LOAD_TOKEN(mfs_RestartToken);
+rs LOAD_TOKEN(mfs_RestartToken);
+remote LOAD_TOKEN(mfs_RemoteToken);
+r LOAD_TOKEN(mfs_RemoteToken);
+sparequestid LOAD_TOKEN(mfs_RequestIDToken);
+requestid LOAD_TOKEN(mfs_RequestIDToken);
+sparq LOAD_TOKEN(mfs_RequestIDToken);
+rq LOAD_TOKEN(mfs_RequestIDToken);
+reservedgroup LOAD_TOKEN(mfs_ReservedGroupToken);
+rg LOAD_TOKEN(mfs_ReservedGroupToken);
+reservedvalue LOAD_TOKEN(mfs_ReservedValueToken);
+rv LOAD_TOKEN(mfs_ReservedValueToken);
+end LOAD_TOKEN(mfs_SegmentationCompleteToken);
+& LOAD_TOKEN(mfs_SegmentationCompleteToken);
+sendonly LOAD_TOKEN(mfs_SendonlyToken);
+so LOAD_TOKEN(mfs_SendonlyToken);
+sendreceive LOAD_TOKEN(mfs_SendrecvToken);
+sr LOAD_TOKEN(mfs_SendrecvToken);
+services LOAD_TOKEN(mfs_ServicesToken);
+sv LOAD_TOKEN(mfs_ServicesToken);
+servicestates LOAD_TOKEN(mfs_ServiceStatesToken);
+si LOAD_TOKEN(mfs_ServiceStatesToken);
+{opt}{wild}servicechange LOAD_TOKEN(mfs_ServiceChangeToken);
+{opt}{wild}sc LOAD_TOKEN(mfs_ServiceChangeToken);
+servicechangeaddress LOAD_TOKEN(mfs_ServiceChangeAddressToken);
+ad LOAD_TOKEN(mfs_ServiceChangeAddressToken);
+servicechangeinc LOAD_TOKEN(mfs_ServiceChangeIncompleteToken);
+sic LOAD_TOKEN(mfs_ServiceChangeIncompleteToken);
+signallist LOAD_TOKEN(mfs_SignalListToken);
+sl LOAD_TOKEN(mfs_SignalListToken);
+signals LOAD_TOKEN(mfs_SignalsToken);
+sg LOAD_TOKEN(mfs_SignalsToken);
+signaltype LOAD_TOKEN(mfs_SignalTypeToken);
+sy LOAD_TOKEN(mfs_SignalTypeToken);
+statistics LOAD_TOKEN(mfs_StatsToken);
+sa LOAD_TOKEN(mfs_StatsToken);
+stream LOAD_TOKEN(mfs_StreamToken);
+st LOAD_TOKEN(mfs_StreamToken);
+{opt}{wild}subtract LOAD_TOKEN(mfs_SubtractToken);
+{opt}{wild}s LOAD_TOKEN(mfs_SubtractToken);
+synchisdn LOAD_TOKEN(mfs_SynchISDNToken);
+sn LOAD_TOKEN(mfs_SynchISDNToken);
+terminationstate LOAD_TOKEN(mfs_TerminationStateToken);
+ts LOAD_TOKEN(mfs_TerminationStateToken);
+test LOAD_TOKEN(mfs_TestToken);
+te LOAD_TOKEN(mfs_TestToken);
+timeout LOAD_TOKEN(mfs_TimeOutToken);
+to LOAD_TOKEN(mfs_TimeOutToken);
+topology LOAD_TOKEN(mfs_TopologyToken);
+tp LOAD_TOKEN(mfs_TopologyToken);
+transaction LOAD_TOKEN(mfs_TransToken);
+t LOAD_TOKEN(mfs_TransToken);
+v18 LOAD_TOKEN(mfs_V18Token);
+v22 LOAD_TOKEN(mfs_V22Token);
+v22b LOAD_TOKEN(mfs_V22bisToken);
+v32 LOAD_TOKEN(mfs_V32Token);
+v32b LOAD_TOKEN(mfs_V32bisToken);
+v34 LOAD_TOKEN(mfs_V34Token);
+v76 LOAD_TOKEN(mfs_V76Token);
+v90 LOAD_TOKEN(mfs_V90Token);
+v91 LOAD_TOKEN(mfs_V91Token);
+version LOAD_TOKEN(mfs_VersionToken);
+v LOAD_TOKEN(mfs_VersionToken);
+({safechar})+ LOAD_TOKEN(mfs_SafeChars);
+
+<<EOF>> {LOAD_SHORT_TOKEN(mfs_endOfMessage); BEGIN(INITIAL); yyterminate();}
+<*>.|\n {LOAD_TOKEN(mfs_IllegalChar); BEGIN(INITIAL); yyterminate();}
+
+%%
+
+/* MEGACO_LINENO_OR_TOKENCOUNTER
+ * Note that this construction is intended to make it
+ * possible to generate flex files that either reports
+ * line-number or one that don't.
+ * See MEGACO_YY_LINENO_OPTION and
+ * MEGACO_DUMMY_DECL_YY_LINENO above.
+ */
+
+#if defined(MEGACO_LINENO)
+#define LINENO_OR_TOKENCNT(P) yylineno
+#else
+#define LINENO_OR_TOKENCNT(P) P->token_counter
+#endif
+
+
+/* #define MFS_DEBUG true */ /* temporary */
+#if defined(MFS_DEBUG)
+# define DBG( proto ) printf proto
+# define DBG_BUF(func, bufName, buf, bufSz) mfs_dbg_buf_print(func, bufName, buf, bufSz)
+#else
+# define DBG( proto ) ((void) 0)
+# define DBG_BUF(func, bufName, buf, bufSz) ((void) 0)
+#endif /* if defined(MFS_DEBUG) */
+
+
+#if defined(MFS_DEBUG)
+
+#define CHUNK 16
+
+static void hexdump(unsigned char *buf, int bufsz)
+{
+ int i,j;
+ int count;
+
+ /* do this in chunks of CHUNK bytes */
+ for (i=0; i<bufsz; i+=CHUNK) {
+ /* show the offset */
+ printf("0x%06x ", i);
+
+ /* max of CHUNK or remaining bytes */
+ count = ((bufsz-i) > CHUNK ? CHUNK : bufsz-i);
+
+ /* show the bytes */
+ for (j=0; j<count; j++) {
+ if (j==CHUNK/2) printf(" ");
+ printf("%02x ",buf[i+j]);
+ }
+
+ /* pad with spaces if less than CHUNK */
+ for (j=count; j<CHUNK; j++) {
+ if (j==CHUNK/2) printf(" ");
+ printf(" ");
+ }
+
+ /* divider between hex and ascii */
+ printf(" ");
+
+ for (j=0; j<count; j++)
+ printf("%c",(isprint(buf[i+j]) ? buf[i+j] : '.'));
+
+ printf("\n");
+ }
+}
+
+static void mfs_dbg_buf_print(char* func, char* bufName, char* buf, int len)
+{
+ printf("%s -> %s (%d):\n", func, bufName, len);
+ hexdump((unsigned char*) buf, len);
+}
+
+
+#endif /* if defined(MFS_DEBUG) */
+
+static void mfs_alloc_failed(MfsErlDrvData* dataP, char* msg, int sz)
+{
+ /*
+ * Make sure we are not allready in error state
+ */
+ if (!dataP->error) {
+
+ /*
+ * Make sure that there is room in the buffer:
+ * length of msg + 10 chars for the ' of %d bytes'
+ * + 10 chars for the size value...
+ * This is really overkill since the msg string is never
+ * longer then 50 chars, but sinze this function is
+ * called when we have run out of memory...
+ */
+
+ int msg_len = strlen(msg);
+ if ((10 + 10 + msg_len) < sizeof(dataP->error_msg)) {
+ if (0 >= sprintf(dataP->error_msg, "%s of %d bytes", msg, sz)) {
+ mfs_fatal_error(dataP, msg);
+ }
+ } else {
+ mfs_fatal_error(dataP, msg);
+ }
+ dataP->error = TRUE;
+ }
+}
+
+
+static void mfs_ensure_term_spec(MfsErlDrvData* dataP, int size)
+{
+ DBG( ("mfs_ensure_term_spec -> entry with"
+ "\n size: %d"
+ "\nwhen"
+ "\n spec_index: %d"
+ "\n spec_size: %d"
+ "\n", size, dataP->term_spec_index, dataP->term_spec_size) );
+
+ /* OTP-4236 - BEGIN */
+ if ((dataP->term_spec_index + size) >= dataP->term_spec_size) {
+ void *tmp;
+
+ DBG( ("mfs_ensure_term_spec -> allocate more memory when"
+ "\n term_spec_index: %d"
+ "\n term_spec_size: %d\n",
+ dataP->term_spec_index, dataP->term_spec_size) );
+
+ dataP->term_spec_size = (dataP->term_spec_size * 2) + size;
+
+ DBG( ("mfs_ensure_term_spec -> "
+ "term_spec is at 0x%X, new term_spec_size is %d\n",
+ (unsigned int) dataP->term_spec, dataP->term_spec_size) );
+
+ tmp = REALLOC(dataP->term_spec,
+ dataP->term_spec_size * sizeof(ErlDrvTermData));
+
+ if (tmp == NULL) {
+ /*
+ * Ouch, we did'nt get any new memory.
+ * Just give ut. I.e. free the memory we have (note that
+ * the assign macro tests the buffer before assigning).
+ */
+ FREE(dataP->term_spec);
+ dataP->term_spec = NULL;
+
+ mfs_alloc_failed(dataP, "failed reallocating term spec buffer",
+ dataP->term_spec_size * sizeof(ErlDrvTermData));
+
+ } else {
+ dataP->term_spec = tmp;
+ }
+
+ DBG( ("mfs_ensure_term_spec -> new term_spec is at 0x%X\n",
+ (unsigned int) dataP->term_spec) );
+ }
+ /* OTP-4236 - END */
+}
+
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+static void mfs_short_load_token(ErlDrvTermData TokenTag, yyscan_t yyscanner)
+#else
+static void mfs_short_load_token(ErlDrvTermData TokenTag)
+#endif
+{
+ /* Build a {TokenTag, LineNumber} tuple */
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ MfsErlDrvData* dataP = (MfsErlDrvData*) yyget_extra(yyscanner);
+#else
+ MfsErlDrvData* dataP = &mfs_drv_data;
+#endif
+
+ /*
+ DBG( ("mfs_short_load_token -> entry with"
+ "\n TokenTag: %ld\n", TokenTag) );
+ */
+
+ mfs_ensure_term_spec(dataP, 6);
+ dataP->token_counter++;
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_ATOM);
+ ASSIGN_TERM_SPEC(dataP, TokenTag);
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_INT);
+ ASSIGN_TERM_SPEC(dataP, LINENO_OR_TOKENCNT(dataP));
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_TUPLE);
+ ASSIGN_TERM_SPEC(dataP, 2);
+}
+
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+static void mfs_octet_load_token(ErlDrvTermData TokenTag, int is_empty,
+ yyscan_t yyscanner)
+#else
+static void mfs_octet_load_token(ErlDrvTermData TokenTag, int is_empty)
+#endif
+{
+ /* Build a {TokenTag, LineNumber, String} tuple */
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ MfsErlDrvData* dataP = (MfsErlDrvData*) yyget_extra(yyscanner);
+#else
+ MfsErlDrvData* dataP = &mfs_drv_data;
+#endif
+
+ DBG( ("mfs_octet_load_token -> entry with"
+ "\n TokenTag: %d"
+ "\n is_empty: %d"
+ "\n yyleng: %d"
+ "\n", (int) TokenTag, is_empty, yyleng) );
+
+ mfs_ensure_term_spec(dataP, 9);
+ dataP->token_counter++;
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_ATOM);
+ ASSIGN_TERM_SPEC(dataP, TokenTag);
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_INT);
+ ASSIGN_TERM_SPEC(dataP, LINENO_OR_TOKENCNT(dataP));
+
+ if (is_empty) {
+
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_NIL); // End of list
+
+ } else {
+
+ LOAD_PROP_GRPS(dataP);
+
+ }
+
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_TUPLE);
+ ASSIGN_TERM_SPEC(dataP, 3);
+}
+
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+static void mfs_lower_load_token(ErlDrvTermData TokenTag, int is_empty,
+ yyscan_t yyscanner)
+#else
+static void mfs_lower_load_token(ErlDrvTermData TokenTag, int is_empty)
+#endif
+{
+ /* Build a {TokenTag, LineNumber, LowerCaseString} tuple */
+ int i;
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ MfsErlDrvData* dataP = (MfsErlDrvData*) yyget_extra(yyscanner);
+#else
+ MfsErlDrvData* dataP = &mfs_drv_data;
+#endif
+
+ DBG( ("mfs_lower_load_token -> entry with"
+ "\n TokenTag: %ld"
+ "\n is_empty: %d"
+ "\n", TokenTag, is_empty) );
+
+ mfs_ensure_term_spec(dataP, 9);
+ dataP->token_counter++;
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_ATOM);
+ ASSIGN_TERM_SPEC(dataP, TokenTag);
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_INT);
+ ASSIGN_TERM_SPEC(dataP, LINENO_OR_TOKENCNT(dataP));
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_STRING);
+
+ if (is_empty) {
+
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData)"");
+ ASSIGN_TERM_SPEC(dataP, 0);
+
+ } else {
+ for ( i = 0; i < yyleng; ++i ) {
+ dataP->text_ptr[i] = tolower(yytext[i]);
+ }
+
+ DBG_BUF("mfs_lower_load_token", "dataP->text_ptr",
+ dataP->text_ptr, yyleng);
+
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) dataP->text_ptr);
+ dataP->text_ptr += yyleng;
+ ASSIGN_TERM_SPEC(dataP, yyleng);
+ }
+
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_TUPLE);
+ ASSIGN_TERM_SPEC(dataP, 3);
+}
+
+#define PG_ERR_PRE "bad_property_parm:"
+#define PG_ERR1 "Could not find property parm value for"
+#define PG_ERR2 "Could not find proper property parm name"
+
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+static void mfs_load_property_groups(MfsErlDrvData* dataP, yyscan_t yyscanner)
+#else
+static void mfs_load_property_groups(MfsErlDrvData* dataP)
+#endif
+{
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ // MfsErlDrvData* dataP = (MfsErlDrvData*) yyget_extra(yyscanner);
+#else
+ // MfsErlDrvData* dataP = &mfs_drv_data;
+#endif
+
+ /*
+ * Process the property groups string
+ * v= is a property group delimiter
+ */
+
+ /*
+ * For each string, look for the first '='.
+ * Everything to the left is the name and
+ * everything to the right is the value.
+ */
+
+ int i = 0; // loop counter
+ int numGroups = 0; // Number of property groups
+ int numPps = 0; // Number of property parms (in the group)
+ char* name; // Pointer to the name buffer
+ int nameStart = 0; // Start position of the property parm name
+ int nameLen; // Length of the name part
+ char* value; // Pointer to the value buffer
+ int valueStart = 0; // Start position of the property parm name
+ int valueLen = 0; // Length of the value part
+
+ DBG( ("mfs_load_property_groups -> entry\n") );
+
+ mfs_ensure_term_spec(dataP, 10); /*�Just in case... */
+
+ while (i <= yyleng) {
+
+ /* Skip white-spaces and end-of-line */
+
+ DBG( ("mfs_load_property_groups -> "
+ "skip white-spaces and end-of-line: i = %d\n", i) );
+
+ if ((yytext[i] != SP) &&
+ (yytext[i] != HTAB) &&
+ (yytext[i] != LF) &&
+ (yytext[i] != CR) &&
+ (yytext[i] != NUL)) {
+
+ DBG( ("mfs_load_property_groups -> "
+ "start looking for delimiter ('=')\n") );
+
+ /* Start looking for '=' */
+ nameStart = i;
+ nameLen = 0;
+ while (i <= yyleng) {
+
+ /* Is it a name-value delimiter? */
+ if (yytext[i] == '=') {
+
+ /*
+ * Found the name/value delimiter
+ */
+ nameLen = i-nameStart;
+
+ DBG( ("mfs_load_property_groups -> "
+ "found delimiter at %d (name length = %d)\n", i, nameLen) );
+
+ /*
+ * "v=" is the start of a new group.
+ * So, check if this maybe is the beginning of
+ * the first group or not. If not, we need to
+ * "terminate" the previous group.
+ */
+ if (0 == strncmp("v", &yytext[nameStart], nameLen)) {
+
+ DBG( ("mfs_load_property_groups -> "
+ "found a 'v' when group count is %d\n", numGroups) );
+
+ if (numGroups > 0) {
+ /*
+ * End the previous group
+ * (only if this is not the first group)
+ */
+
+ DBG( ("mfs_load_property_groups -> "
+ "start of new group - terminate previous group\n") );
+
+ mfs_ensure_term_spec(dataP, 3);
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_NIL); // End of list
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_LIST); // List
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) numPps + 1); // Length of (group) list
+ numPps = 0; /* reset for next group */
+ } // if ...
+ numGroups++;
+ } // if ...
+ numPps++;
+ i++;
+
+ /*
+ * Now, look for the end of the value string,
+ * which is an EOL = (CR [LF] / LF )
+ */
+
+ DBG( ("mfs_load_property_groups -> "
+ "start looking for end of value\n") );
+ valueStart = i;
+ valueLen = 0;
+ while (i <= yyleng) {
+ if ((yytext[i] == CR) || (yytext[i] == LF)) {
+ valueLen = i-valueStart;
+ DBG( ("mfs_load_property_groups -> "
+ "found end of value at %d\n", i) );
+ break;
+ } else {
+ i++;
+ } // if ...
+ } // while ...
+
+ /* Name */
+ name = dataP->text_ptr;
+ strncpy(name, &yytext[nameStart], nameLen);
+ name[nameLen] = 0;
+ dataP->text_ptr += (nameLen + 1); // Make room for the NULL termination
+
+ /* Check that we actually got a proper value */
+ if (valueLen == 0) {
+ /* Invalid property parm value */
+ DBG( ("mfs_load_property_groups -> "
+ "property parm value not found\n") );
+
+ /**********************************************
+ * -record('ErrorDescriptor',
+ * {
+ * errorCode,
+ * errorText = asn1_NOVALUE
+ * }).
+ */
+
+ if (0 >= sprintf(dataP->error_msg, "%s %s %s",
+ PG_ERR_PRE, PG_ERR1, name)) {
+ mfs_fatal_error(dataP, PG_ERR1);
+ }
+ dataP->error = TRUE;
+
+ DBG( ("mfs_load_property_groups -> "
+ "done after value error (%s)\n", name) );
+
+ return; // Bail out
+
+ } else {
+
+
+ /***************************************
+ * -record('PropertyParm',
+ * {
+ * name,
+ * value,
+ * extraInfo = asn1_NOVALUE
+ * }). % with extension mark
+ */
+
+ mfs_ensure_term_spec(dataP, 15); // 2 + 3 + 6 + 2 + 2
+
+ DBG( ("mfs_load_property_groups -> "
+ "insert PropertyParm record name\n") );
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_ATOM);
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) mfs_PropertyParm);
+
+ /* Name */
+ DBG( ("mfs_load_property_groups -> insert name field\n") );
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_STRING);
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) name);
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) nameLen);
+
+ /*
+ * value, which is actually a list of length 1
+ * where the "actual value" is the (only) element
+ */
+ DBG( ("mfs_load_property_groups -> "
+ "insert value field (length = %d)\n", valueLen) );
+ value = dataP->text_ptr;
+ strncpy(value, &yytext[valueStart], valueLen);
+ dataP->text_ptr += valueLen;
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_STRING);
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) value);
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) valueLen);
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_NIL); // End of value list
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_LIST);
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) 1 + 1); // Length of (group) list
+
+ /* extraInfo - never used */
+ DBG( ("mfs_load_property_groups -> "
+ "insert the extraInfo field\n") );
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_ATOM);
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) mfs_asn1_NOVALUE);
+
+ DBG( ("mfs_load_property_groups -> "
+ "terminate PropertyParm tuple\n") );
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_TUPLE);
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) 4);
+ break;
+
+ } // if (valueLen == 0) ...
+
+ } else {
+ DBG( ("mfs_load_property_groups -> "
+ "b) skipping %d [%d] (%d)\n", i, yyleng - i, yytext[i]) );
+ i++;
+ } // if (yytext[i] == '=')
+
+ } // while (i <= yyleng)
+
+ /* Check that we actually got a proper name */
+ if (nameLen == 0) {
+ /* Invalid property parm name */
+ DBG( ("mfs_load_property_groups -> "
+ "property parm name not found when "
+ "nameStart = %d\n", nameStart) );
+
+ if (0 >= sprintf(dataP->error_msg, "%s %s (name start at %d)",
+ PG_ERR_PRE, PG_ERR2, nameStart)) {
+ mfs_fatal_error(dataP, PG_ERR2);
+ }
+
+ dataP->error = TRUE;
+
+ DBG( ("mfs_load_property_groups -> done after name error\n") );
+
+ return; // Bail out
+
+ } // if (nameLen == 0) ...
+
+ } else {
+ DBG( ("mfs_load_property_groups -> "
+ "a) skipping %d [%d] (%d)\n", i, yyleng - i, yytext[i]) );
+ i++; // next
+ } // if ((yytext[i] != SP)...
+ } // while ...
+
+ mfs_ensure_term_spec(dataP, 4); // 2 + 2 just in case
+
+ /* Make sure we actually have some groups */
+
+ if (numGroups > 0) {
+
+ DBG( ("mfs_load_property_groups -> "
+ "terminate group (list of properties) list (length = %d)\n",
+ numPps) );
+
+ /* Terminate the final group */
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_NIL); // End of list
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_LIST);
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) numPps + 1); // Length of (group) list
+
+ }
+
+ DBG( ("mfs_load_property_groups -> "
+ "terminate groups (list of property groups) list (length = %d)\n",
+ numGroups) );
+
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_NIL); // End of list
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_LIST);
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) numGroups + 1); // Length of (groups) list
+
+ DBG( ("mfs_load_property_groups -> done\n") );
+}
+
+
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+static void mfs_load_map_name(yyscan_t yyscanner)
+#else
+static void mfs_load_map_name()
+#endif
+{
+ /* Copy digit map name as lower case */
+ int i;
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ MfsErlDrvData* dataP = (MfsErlDrvData*) yyget_extra(yyscanner);
+#else
+ MfsErlDrvData* dataP = &mfs_drv_data;
+#endif
+
+ for ( i = 0; i < yyleng; ++i ) {
+ dataP->text_ptr[i] = tolower(yytext[i]);
+ }
+
+ dataP->digit_map_name_ptr = dataP->text_ptr;
+ dataP->digit_map_name_len = yyleng;
+ dataP->text_ptr += yyleng;
+}
+
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+static void mfs_load_map_value(yyscan_t yyscanner)
+#else
+static void mfs_load_map_value()
+#endif
+{
+ /* Copy digit map value as lower case */
+ int i;
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ MfsErlDrvData* dataP = (MfsErlDrvData*) yyget_extra(yyscanner);
+#else
+ MfsErlDrvData* dataP = &mfs_drv_data;
+#endif
+
+ for ( i = 0; i < yyleng; ++i ) {
+ dataP->text_ptr[i] = tolower(yytext[i]);
+ }
+
+ dataP->digit_map_value_ptr = dataP->text_ptr;
+ dataP->digit_map_value_len = yyleng;
+ dataP->text_ptr += yyleng;
+}
+
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+static void mfs_load_map_timer(yyscan_t yyscanner)
+#else
+static void mfs_load_map_timer()
+#endif
+{
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ MfsErlDrvData* dataP = (MfsErlDrvData*) yyget_extra(yyscanner);
+#else
+ MfsErlDrvData* dataP = &mfs_drv_data;
+#endif
+ int timer_len = yyleng - 2;
+
+ /* The digit map timer consists of 3 or 4 characters:
+ * z and Z are actually version 2 only
+ * 0 - the kind of timer (t|T|s|S|l|L|z|Z)
+ * 1 - a colon
+ * 2 - mandatory digit
+ * 3 - optional digit
+ */
+
+ /*
+ DBG( ("mfs_load_map_timer -> entry when yyleng: %d\n", yyleng) );
+ DBG( ("mfs_load_map_timer -> yytext: 0x%x\n", yytext) );
+
+ DBG( ("mfs_load_map_timer -> yytext[0]: %u (%c)\n", yytext[0], yytext[0]) );
+ DBG( ("mfs_load_map_timer -> yytext[1]: %u (%c)\n", yytext[1], yytext[1]) );
+ DBG( ("mfs_load_map_timer -> yytext[2]: %u (%c)\n", yytext[2], yytext[2]) );
+ DBG( ("mfs_load_map_timer -> yytext[3]: %u (%c)\n", yytext[3], yytext[3]) );
+ */
+
+ /* Pad with leading zero */
+
+ if (timer_len == 1) {
+ dataP->text_ptr[0] = '0';
+ dataP->text_ptr[1] = yytext[2];
+ } else if (timer_len == 2) {
+ dataP->text_ptr[0] = yytext[2];
+ dataP->text_ptr[1] = yytext[3];
+ }
+
+ /*
+ DBG( ("mfs_load_map_timer -> dataP->text_ptr[0]: %u (%c)\n",
+ dataP->text_ptr[0], dataP->text_ptr[0]) );
+ DBG( ("mfs_load_map_timer -> dataP->text_ptr[1]: %u (%c)\n",
+ dataP->text_ptr[1], dataP->text_ptr[1]) );
+
+ DBG( ("mfs_load_map_timer -> dataP->text_ptr: 0x%x\n",
+ dataP->text_ptr) );
+ */
+
+ switch (yytext[0]) {
+ case 't':
+ case 'T':
+ dataP->digit_map_start_ptr = dataP->text_ptr;
+ break;;
+ case 's':
+ case 'S':
+ dataP->digit_map_short_ptr = dataP->text_ptr;
+ break;;
+ case 'l':
+ case 'L':
+ dataP->digit_map_long_ptr = dataP->text_ptr;
+ break;;
+ case 'z':
+ case 'Z':
+ dataP->digit_map_duration_ptr = dataP->text_ptr;
+ break;;
+ }
+
+ /* We pad when there is only one digit, so it will always be two */
+ dataP->text_ptr += 2;
+
+}
+
+static void mfs_load_timer_field(MfsErlDrvData* dataP, char* text)
+{
+ mfs_ensure_term_spec(dataP, 2); /* OTP-4236 */
+ if (text == NULL) {
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_ATOM);
+ ASSIGN_TERM_SPEC(dataP, mfs_asn1_NOVALUE);
+ } else {
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_INT);
+ ASSIGN_TERM_SPEC(dataP, ((text[0] - '0') * 10) + (text[1] - '0'));
+ }
+}
+
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+static void mfs_load_map_token(yyscan_t yyscanner)
+#else
+static void mfs_load_map_token()
+#endif
+{
+ /*
+ * Build a {'DigitMapDescriptorToken', LineNumber,
+ * {'DigitMapDescriptor', DigitMapName, DigitMapValue}} tuple
+ */
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ MfsErlDrvData* dataP = (MfsErlDrvData*) yyget_extra(yyscanner);
+#else
+ MfsErlDrvData* dataP = &mfs_drv_data;
+#endif
+
+ mfs_ensure_term_spec(dataP, 20);
+ dataP->token_counter++;
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_ATOM);
+ ASSIGN_TERM_SPEC(dataP, mfs_DigitMapDescriptorToken);
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_INT);
+ ASSIGN_TERM_SPEC(dataP, LINENO_OR_TOKENCNT(dataP));
+
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_ATOM);
+ ASSIGN_TERM_SPEC(dataP, mfs_DigitMapDescriptor);
+
+ if (dataP->digit_map_name_ptr == 0) {
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_ATOM);
+ ASSIGN_TERM_SPEC(dataP, mfs_asn1_NOVALUE);
+ } else {
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_STRING);
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) dataP->digit_map_name_ptr);
+ ASSIGN_TERM_SPEC(dataP, dataP->digit_map_name_len);
+ dataP->digit_map_name_ptr = NULL;
+ }
+
+ if (dataP->digit_map_value_ptr == NULL) {
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_ATOM);
+ ASSIGN_TERM_SPEC(dataP, mfs_asn1_NOVALUE);
+ } else {
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_ATOM);
+ ASSIGN_TERM_SPEC(dataP, mfs_DigitMapValue);
+
+ /* Take care of timer values */
+ mfs_load_timer_field(dataP, dataP->digit_map_start_ptr);
+ dataP->digit_map_start_ptr = NULL;
+
+ mfs_load_timer_field(dataP, dataP->digit_map_short_ptr);
+ dataP->digit_map_short_ptr = NULL;
+
+ mfs_load_timer_field(dataP, dataP->digit_map_long_ptr);
+ dataP->digit_map_long_ptr = NULL;
+
+ mfs_load_timer_field(dataP, dataP->digit_map_duration_ptr);
+ dataP->digit_map_duration_ptr = NULL;
+
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_STRING);
+ ASSIGN_TERM_SPEC(dataP, (ErlDrvTermData) dataP->digit_map_value_ptr);
+ ASSIGN_TERM_SPEC(dataP, dataP->digit_map_value_len);
+ dataP->digit_map_value_ptr = NULL;
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_TUPLE);
+ ASSIGN_TERM_SPEC(dataP, 6);
+ }
+
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_TUPLE);
+ ASSIGN_TERM_SPEC(dataP, 3);
+
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_TUPLE);
+ ASSIGN_TERM_SPEC(dataP, 3);
+
+}
+
+
+DRIVER_INIT(mfs_drv)
+{
+ DBG( ("DRIVER_INIT(mfs_drv) -> entry\n") );
+
+ return &mfs_entry;
+}
+
+static ErlDrvData mfs_start(ErlDrvPort port, char *buf)
+{
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+ MfsErlDrvData* dataP = ALLOC(sizeof(MfsErlDrvData));
+#else
+ MfsErlDrvData* dataP = &mfs_drv_data;
+#endif
+
+ DBG( ("mfs_start -> entry\n") );
+
+ dataP->port = port;
+ dataP->digit_map_name_ptr = NULL;
+ dataP->digit_map_name_len = 0;
+ dataP->digit_map_value_ptr = NULL;
+ dataP->digit_map_value_len = 0;
+ dataP->digit_map_start_ptr = NULL;
+ dataP->digit_map_short_ptr = NULL;
+ dataP->digit_map_long_ptr = NULL;
+ dataP->digit_map_duration_ptr = NULL;
+ dataP->error = FALSE;
+ /* dataP->error_msg[512]; */
+ dataP->text_buf = NULL;
+ dataP->text_ptr = NULL;
+ dataP->term_spec = NULL;
+ dataP->term_spec_size = 0;
+ dataP->term_spec_index = 0;
+ dataP->token_counter = 0;
+
+ mfs_AddToken = driver_mk_atom("AddToken");
+ mfs_AndAUDITSelectToken = driver_mk_atom("AndAUDITSelectToken");
+ mfs_AuditCapToken = driver_mk_atom("AuditCapToken");
+ mfs_AuditToken = driver_mk_atom("AuditToken");
+ mfs_AuditValueToken = driver_mk_atom("AuditValueToken");
+ mfs_AuthToken = driver_mk_atom("AuthToken");
+ mfs_BothToken = driver_mk_atom("BothToken");
+ mfs_BothwayToken = driver_mk_atom("BothwayToken");
+ mfs_BriefToken = driver_mk_atom("BriefToken");
+ mfs_BufferToken = driver_mk_atom("BufferToken");
+ mfs_COLON = driver_mk_atom("COLON");
+ mfs_COMMA = driver_mk_atom("COMMA");
+ mfs_ContextAttrToken = driver_mk_atom("ContextAttrToken");
+ mfs_ContextAuditToken = driver_mk_atom("ContextAuditToken");
+ mfs_ContextListToken = driver_mk_atom("ContextListToken");
+ mfs_CtxToken = driver_mk_atom("CtxToken");
+ mfs_DelayToken = driver_mk_atom("DelayToken");
+ mfs_DeleteToken = driver_mk_atom("DeleteToken");
+ mfs_DigitMapDescriptor = driver_mk_atom("DigitMapDescriptor");
+ mfs_DigitMapDescriptorToken = driver_mk_atom("DigitMapDescriptorToken");
+ mfs_DigitMapToken = driver_mk_atom("DigitMapToken");
+ mfs_DigitMapValue = driver_mk_atom("DigitMapValue");
+ mfs_DirectionToken = driver_mk_atom("DirectionToken");
+ mfs_DiscardToken = driver_mk_atom("DiscardToken");
+ mfs_DisconnectedToken = driver_mk_atom("DisconnectedToken");
+ mfs_DurationToken = driver_mk_atom("DurationToken");
+ mfs_EQUAL = driver_mk_atom("EQUAL");
+ mfs_EmbedToken = driver_mk_atom("EmbedToken");
+ mfs_EmergencyToken = driver_mk_atom("EmergencyToken");
+ mfs_EmergencyOffToken = driver_mk_atom("EmergencyOffToken");
+ mfs_EmergencyValueToken = driver_mk_atom("EmergencyValueToken");
+ mfs_ErrorToken = driver_mk_atom("ErrorToken");
+ mfs_EventBufferToken = driver_mk_atom("EventBufferToken");
+ mfs_EventsToken = driver_mk_atom("EventsToken");
+ mfs_ExternalToken = driver_mk_atom("ExternalToken");
+ mfs_FailoverToken = driver_mk_atom("FailoverToken");
+ mfs_ForcedToken = driver_mk_atom("ForcedToken");
+ mfs_GREATER = driver_mk_atom("GREATER");
+ mfs_GracefulToken = driver_mk_atom("GracefulToken");
+ mfs_H221Token = driver_mk_atom("H221Token");
+ mfs_H223Token = driver_mk_atom("H223Token");
+ mfs_H226Token = driver_mk_atom("H226Token");
+ mfs_HandOffToken = driver_mk_atom("HandOffToken");
+ mfs_IEPSToken = driver_mk_atom("IEPSToken");
+ mfs_IllegalChar = driver_mk_atom("IllegalChar");
+ mfs_ImmAckRequiredToken = driver_mk_atom("ImmAckRequiredToken");
+ mfs_InSvcToken = driver_mk_atom("InSvcToken");
+ mfs_InactiveToken = driver_mk_atom("InactiveToken");
+ mfs_InternalToken = driver_mk_atom("InternalToken");
+ mfs_InterruptByEventToken = driver_mk_atom("InterruptByEventToken");
+ mfs_InterruptByNewSignalsDescrToken = driver_mk_atom("InterruptByNewSignalsDescrToken");
+ mfs_IntsigDelayToken = driver_mk_atom("IntsigDelayToken");
+ mfs_IsolateToken = driver_mk_atom("IsolateToken");
+ mfs_IterationToken = driver_mk_atom("IterationToken");
+ mfs_KeepActiveToken = driver_mk_atom("KeepActiveToken");
+ mfs_LBRKT = driver_mk_atom("LBRKT");
+ mfs_LESSER = driver_mk_atom("LESSER");
+ mfs_LSBRKT = driver_mk_atom("LSBRKT");
+ mfs_LocalControlToken = driver_mk_atom("LocalControlToken");
+ mfs_LocalDescriptorToken = driver_mk_atom("LocalDescriptorToken");
+ mfs_LocalToken = driver_mk_atom("LocalToken");
+ mfs_LockStepToken = driver_mk_atom("LockStepToken");
+ mfs_LoopbackToken = driver_mk_atom("LoopbackToken");
+ mfs_MediaToken = driver_mk_atom("MediaToken");
+ mfs_MegacopToken = driver_mk_atom("MegacopToken");
+ mfs_MessageSegmentToken = driver_mk_atom("MessageSegmentToken");
+ mfs_MethodToken = driver_mk_atom("MethodToken");
+ mfs_MgcIdToken = driver_mk_atom("MgcIdToken");
+ mfs_ModeToken = driver_mk_atom("ModeToken");
+ mfs_ModemToken = driver_mk_atom("ModemToken");
+ mfs_ModifyToken = driver_mk_atom("ModifyToken");
+ mfs_MoveToken = driver_mk_atom("MoveToken");
+ mfs_MtpAddressToken = driver_mk_atom("MtpAddressToken");
+ mfs_MuxToken = driver_mk_atom("MuxToken");
+ mfs_NEQUAL = driver_mk_atom("NEQUAL");
+ mfs_NotifyCompletionToken = driver_mk_atom("NotifyCompletionToken");
+ mfs_NotifyImmediateToken = driver_mk_atom("NotifyImmediateToken");
+ mfs_NotifyRegulatedToken = driver_mk_atom("NotifyRegulatedToken");
+ mfs_NeverNotifyToken = driver_mk_atom("NeverNotifyToken");
+ mfs_NotifyToken = driver_mk_atom("NotifyToken");
+ mfs_Nx64kToken = driver_mk_atom("Nx64kToken");
+ mfs_ObservedEventsToken = driver_mk_atom("ObservedEventsToken");
+ mfs_OffToken = driver_mk_atom("OffToken");
+ mfs_OnOffToken = driver_mk_atom("OnOffToken");
+ mfs_OnToken = driver_mk_atom("OnToken");
+ mfs_OnewayToken = driver_mk_atom("OnewayToken");
+ mfs_OnewayBothToken = driver_mk_atom("OnewayBothToken");
+ mfs_OnewayExternalToken = driver_mk_atom("OnewayExternalToken");
+ mfs_OrAUDITselectToken = driver_mk_atom("OrAUDITselectToken");
+ mfs_OtherReasonToken = driver_mk_atom("OtherReasonToken");
+ mfs_OutOfSvcToken = driver_mk_atom("OutOfSvcToken");
+ mfs_PackagesToken = driver_mk_atom("PackagesToken");
+ mfs_PendingToken = driver_mk_atom("PendingToken");
+ mfs_PriorityToken = driver_mk_atom("PriorityToken");
+ mfs_ProfileToken = driver_mk_atom("ProfileToken");
+ mfs_QuotedChars = driver_mk_atom("QuotedChars");
+ mfs_RBRKT = driver_mk_atom("RBRKT");
+ mfs_RSBRKT = driver_mk_atom("RSBRKT");
+ mfs_ReasonToken = driver_mk_atom("ReasonToken");
+ mfs_RecvonlyToken = driver_mk_atom("RecvonlyToken");
+ mfs_RemoteDescriptorToken = driver_mk_atom("RemoteDescriptorToken");
+ mfs_RemoteToken = driver_mk_atom("RemoteToken");
+ mfs_ReplyToken = driver_mk_atom("ReplyToken");
+ mfs_RequestIDToken = driver_mk_atom("RequestIDToken");
+ mfs_ReservedGroupToken = driver_mk_atom("ReservedGroupToken");
+ mfs_ReservedValueToken = driver_mk_atom("ReservedValueToken");
+ mfs_ResetEventsDescriptorToken = driver_mk_atom("ResetEventsDescriptorToken");
+ mfs_ResponseAckToken = driver_mk_atom("ResponseAckToken");
+ mfs_RestartToken = driver_mk_atom("RestartToken");
+ mfs_SEP = driver_mk_atom("SEP");
+ mfs_SafeChars = driver_mk_atom("SafeChars");
+ mfs_SegmentationCompleteToken = driver_mk_atom("SegmentationCompleteToken");
+ mfs_SendonlyToken = driver_mk_atom("SendonlyToken");
+ mfs_SendrecvToken = driver_mk_atom("SendrecvToken");
+ mfs_ServiceChangeAddressToken = driver_mk_atom("ServiceChangeAddressToken");
+ mfs_ServiceChangeIncompleteToken = driver_mk_atom("ServiceChangeIncompleteToken");
+ mfs_ServiceChangeToken = driver_mk_atom("ServiceChangeToken");
+ mfs_ServiceStatesToken = driver_mk_atom("ServiceStatesToken");
+ mfs_ServicesToken = driver_mk_atom("ServicesToken");
+ mfs_SignalListToken = driver_mk_atom("SignalListToken");
+ mfs_SignalTypeToken = driver_mk_atom("SignalTypeToken");
+ mfs_SignalsToken = driver_mk_atom("SignalsToken");
+ mfs_StatsToken = driver_mk_atom("StatsToken");
+ mfs_StreamToken = driver_mk_atom("StreamToken");
+ mfs_SubtractToken = driver_mk_atom("SubtractToken");
+ mfs_SynchISDNToken = driver_mk_atom("SynchISDNToken");
+ mfs_TerminationStateToken = driver_mk_atom("TerminationStateToken");
+ mfs_TestToken = driver_mk_atom("TestToken");
+ mfs_TimeOutToken = driver_mk_atom("TimeOutToken");
+ mfs_TimeStampToken = driver_mk_atom("TimeStampToken"); /* OTP-5042 */
+ mfs_TopologyToken = driver_mk_atom("TopologyToken");
+ mfs_TransToken = driver_mk_atom("TransToken");
+ mfs_V18Token = driver_mk_atom("V18Token");
+ mfs_V22Token = driver_mk_atom("V22Token");
+ mfs_V22bisToken = driver_mk_atom("V22bisToken");
+ mfs_V32Token = driver_mk_atom("V32Token");
+ mfs_V32bisToken = driver_mk_atom("V32bisToken");
+ mfs_V34Token = driver_mk_atom("V34Token");
+ mfs_V76Token = driver_mk_atom("V76Token");
+ mfs_V90Token = driver_mk_atom("V90Token");
+ mfs_V91Token = driver_mk_atom("V91Token");
+ mfs_VersionToken = driver_mk_atom("VersionToken");
+ mfs_asn1_NOVALUE = driver_mk_atom("asn1_NOVALUE");
+ mfs_endOfMessage = driver_mk_atom("endOfMessage");
+ mfs_PropertyParm = driver_mk_atom("PropertyParm");
+ mfs_ErrorDescriptor = driver_mk_atom("ErrorDescriptor");
+
+ DBG( ("mfs_start -> exit\n") );
+
+ return (ErlDrvData) dataP;
+}
+
+static void mfs_stop(ErlDrvData handle)
+{
+ MfsErlDrvData* dataP = (MfsErlDrvData*) handle;
+
+ dataP->port = 0;
+
+ DBG( ("mfs_stop -> exit\n") );
+
+ return;
+}
+
+static void mfs_command(ErlDrvData handle,
+ char *buf, int buf_len)
+{
+ driver_failure_atom(((MfsErlDrvData*) handle)->port, "bad_usage");
+
+ return;
+}
+
+static int mfs_control(ErlDrvData handle,
+ unsigned int command,
+ char *buf, int buf_len,
+ char **res_buf, int res_buf_len)
+{
+ MfsErlDrvData* dataP = (MfsErlDrvData*) handle;
+ char* tmp;
+ YY_BUFFER_STATE state;
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+ yyscan_t scanner;
+ /* struct yyguts_t * yyg = (struct yyguts_t*) scanner; */
+#endif
+
+ DBG( ("mfs_control -> entry with"
+ "\n command: %d"
+ "\n buf_len: %d"
+ "\n res_buf_len: %d\n", command, buf_len, res_buf_len) );
+
+ if (NULL == (tmp = ALLOC(buf_len))) {
+ int len;
+ mfs_alloc_failed(dataP, "failed allocating text buffer", buf_len);
+
+ len = strlen(dataP->error_msg);
+
+ if (res_buf_len < len) {
+ /*
+ * Since we failed the memory allocation in the first place,
+ * there is no point in trying to get more memory for the
+ * error code...
+ */
+ len = res_buf_len;
+ }
+
+ strncpy(*res_buf, dataP->error_msg, len);
+
+ return len;
+ }
+ dataP->text_buf = tmp;
+ dataP->text_ptr = tmp;
+
+ dataP->term_spec_size = 1000 + buf_len; /* OTP-4237 */
+
+ DBG( ("mfs_control -> allocate term-spec buffer: "
+ "\n term_spec_size: %d\n", dataP->term_spec_size) );
+
+ dataP->term_spec = ALLOC(dataP->term_spec_size * sizeof(ErlDrvTermData));
+ if (NULL == dataP->term_spec) {
+ int len;
+ mfs_alloc_failed(dataP, "failed allocating term spec buffer",
+ dataP->term_spec_size * sizeof(ErlDrvTermData));
+
+ len = strlen(dataP->error_msg);
+
+ if (res_buf_len < len) {
+ /*
+ * Since we failed the memory allocation in the first place,
+ * there is no point in trying to get more memory for the
+ * error code...
+ */
+ len = res_buf_len;
+ }
+
+ strncpy(*res_buf, dataP->error_msg, len);
+
+ FREE(dataP->text_buf);
+
+ return len;
+ }
+ dataP->term_spec_index = 0;
+ dataP->token_counter = 0;
+ dataP->error = FALSE;
+
+ /* Prepare the first field in the {tokens, TokenList, LastLine} tuple */
+ DBG( ("mfs_control -> prepare the first field in the tokens tuple\n") );
+ mfs_ensure_term_spec(dataP, 2);
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_ATOM);
+ ASSIGN_TERM_SPEC(dataP, driver_mk_atom("tokens"));
+
+ /* Perform the actual scan */
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+
+ /*
+ * R e e n t r a n t s c a n n e r
+ */
+
+ DBG( ("mfs_control -> initiate scanner\n") );
+ yylex_init(&scanner);
+
+ DBG( ("mfs_control -> maybe enable flex debug\n") );
+ yyset_debug(MFS_FLEX_DEBUG, scanner);
+
+ DBG( ("mfs_control -> set my extra data (ErlDrvData)\n") );
+ yyset_extra(dataP, scanner);
+
+ DBG( ("mfs_control -> scan bytes\n") );
+ state = yy_scan_bytes(buf, buf_len, scanner);
+
+ DBG( ("mfs_control -> set initial line-no (1) when state is at 0x%x\n",
+ (unsigned int) state) );
+ yyset_lineno(1, scanner);
+
+ DBG( ("mfs_control -> do the actual scan\n") );
+ yylex(scanner);
+
+#else
+
+ /*
+ * N o n - R e e n t r a n t s c a n n e r
+ */
+
+ yylineno = 1;
+ state = yy_scan_bytes(buf, buf_len);
+ yylex();
+ yy_delete_buffer(state);
+
+#endif
+
+ DBG( ("mfs_control -> scan done - now check if ok or not (%d)\n", dataP->error) );
+ if (!dataP->error) {
+
+ /*
+ * Prepare the rest of the {tokens, TokenList, LastLine} tuple
+ * and send it as message top caller.
+ */
+
+ DBG( ("mfs_control -> ensure term spec(7)\n") );
+
+ mfs_ensure_term_spec(dataP, 7);
+ DBG( ("mfs_control -> assign nil\n") );
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_NIL);
+ DBG( ("mfs_control -> assign type list\n") );
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_LIST);
+ DBG( ("mfs_control -> assign size of list: %d\n", dataP->token_counter + 1) );
+ ASSIGN_TERM_SPEC(dataP, dataP->token_counter + 1);
+ DBG( ("mfs_control -> assign type int\n") );
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_INT);
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+ DBG( ("mfs_control -> assign lineno (or tokenno): %d\n", yyget_lineno(scanner)) );
+ // ASSIGN_TERM_SPEC(LINENO_OR_TOKENCNT);
+ ASSIGN_TERM_SPEC(dataP, yyget_lineno(scanner));
+#else
+ DBG( ("mfs_control -> assign lineno (or tokenno): %d\n", LINENO_OR_TOKENCNT(dataP)) );
+ // ASSIGN_TERM_SPEC(LINENO_OR_TOKENCNT);
+ ASSIGN_TERM_SPEC(dataP, LINENO_OR_TOKENCNT(dataP));
+#endif
+ // ASSIGN_TERM_SPEC(1);
+ DBG( ("mfs_control -> assign tuple\n") );
+ ASSIGN_TERM_SPEC(dataP, ERL_DRV_TUPLE);
+ DBG( ("mfs_control -> assign size 3\n") );
+ ASSIGN_TERM_SPEC(dataP, 3);
+
+ DBG( ("mfs_control -> send the term when"
+ "\n term_spec_index: %d"
+ "\n term_spec_size: %d\n",
+ dataP->term_spec_index, dataP->term_spec_size) );
+
+ driver_send_term(dataP->port,
+ driver_caller(dataP->port),
+ dataP->term_spec,
+ dataP->term_spec_index);
+
+ if (dataP->text_buf != NULL) FREE(dataP->text_buf);
+ if (dataP->term_spec != NULL) FREE(dataP->term_spec);
+
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+
+ /*
+ * R e e n t r a n t s c a n n e r
+ */
+
+ DBG( ("mfs_control -> delete buffer\n") );
+ yy_delete_buffer(state, scanner);
+
+ DBG( ("mfs_control -> destroy scanner\n") );
+ yylex_destroy(scanner);
+
+#endif
+
+ DBG( ("mfs_control -> done (0)\n") );
+
+ return 0;
+
+ } else {
+ /*
+ * Return the error message
+ */
+ int len = strlen(dataP->error_msg);
+
+ DBG( ("mfs_control -> return the error message: \n%s\n\n",
+ dataP->error_msg) );
+
+ /*
+ * If we fail to alloc a bigger block of memory
+ * we have to make do with what we got
+ */
+ if (res_buf_len < len) {
+ void *tmp = ALLOC(len);
+ if (tmp != NULL)
+ *res_buf = tmp;
+ else
+ len = res_buf_len;
+ }
+
+ strncpy(*res_buf, dataP->error_msg, len);
+
+ if (dataP->text_buf != NULL) FREE(dataP->text_buf);
+ if (dataP->term_spec != NULL) FREE(dataP->term_spec);
+
+#if defined(MEGACO_REENTRANT_FLEX_SCANNER)
+
+ /*
+ * R e e n t r a n t s c a n n e r
+ */
+
+ DBG( ("mfs_control -> delete buffer\n") );
+ yy_delete_buffer(state, scanner);
+
+ DBG( ("mfs_control -> destroy scanner\n") );
+ yylex_destroy(scanner);
+
+#endif
+
+ DBG( ("mfs_control -> done (%d)\n", len) );
+
+ return len;
+ }
+}
+
+static void mfs_finish(void)
+{
+ return;
+}
+
+static void mfs_fatal_error(MfsErlDrvData* dataP, char* msg)
+{
+ if (!dataP->error) {
+ int len = strlen(msg);
+
+ if (len >= sizeof(dataP->error_msg))
+ len = sizeof(dataP->error_msg) - 1;
+
+ strncpy(dataP->error_msg, msg, len);
+ dataP->error_msg[len] = '\0';
+ dataP->error = TRUE;
+ }
+}