summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuis Machado <luis.machado@linaro.org>2019-01-10 14:09:43 -0200
committerLuis Machado <luis.machado@linaro.org>2019-01-10 14:09:43 -0200
commit50944d206915491a66a2ca9bc5d2be823c58740e (patch)
tree5fa4818b9421b5649c4a6aa13569e0e9c16e873a
downloadlibadsprpc-master.tar.gz
Initial importHEADmaster
Signed-off-by: Luis Machado <luis.machado@linaro.org>
-rw-r--r--LICENSE28
-rw-r--r--Makefile64
-rw-r--r--inc/AEEBufBound.h568
-rw-r--r--inc/AEEQList.h857
-rw-r--r--inc/AEEStdDef.h1149
-rw-r--r--inc/AEEStdErr.h225
-rw-r--r--inc/AEEVaList.h115
-rw-r--r--inc/AEEatomic.h197
-rw-r--r--inc/AEEstd.h2609
-rw-r--r--inc/adsp_current_process.h76
-rw-r--r--inc/adsp_default_listener.h63
-rw-r--r--inc/adsp_listener.h79
-rw-r--r--inc/apps_mem.h67
-rw-r--r--inc/apps_remotectl.h75
-rw-r--r--inc/apps_std.h170
-rw-r--r--inc/fastrpc_apps_user.h38
-rw-r--r--inc/fastrpc_internal.h312
-rw-r--r--inc/listener.h50
-rw-r--r--inc/listener_buf.h143
-rw-r--r--inc/mod_table_imp.h500
-rw-r--r--inc/pthread_rw_mutex.h60
-rw-r--r--inc/qtest_stdlib.h123
-rw-r--r--inc/remote.h186
-rw-r--r--inc/remote64.h83
-rw-r--r--inc/remotectl.h77
-rw-r--r--inc/rpcmem.h138
-rw-r--r--inc/sbuf.h158
-rw-r--r--inc/shared.h77
-rw-r--r--inc/uthash.h915
-rw-r--r--inc/verify.h131
-rw-r--r--inc/version.h129
-rw-r--r--src/AEEsmath.h12
-rw-r--r--src/BufBound.c228
-rw-r--r--src/adsp_current_process_stub.c727
-rw-r--r--src/adsp_default_listener_stub.c564
-rw-r--r--src/adsp_default_listener_stub.d8
-rw-r--r--src/adsp_default_listener_stub.obin0 -> 16200 bytes
-rw-r--r--src/adsp_listener_stub.c861
-rw-r--r--src/adsp_listener_stub.d10
-rw-r--r--src/adsp_listener_stub.obin0 -> 58392 bytes
-rw-r--r--src/apps_mem_imp.c172
-rw-r--r--src/apps_mem_skel.c556
-rw-r--r--src/apps_remotectl_skel.c528
-rw-r--r--src/apps_std_imp.c583
-rw-r--r--src/apps_std_skel.c1093
-rw-r--r--src/atomic.c81
-rw-r--r--src/cae.c72
-rw-r--r--src/fastrpc_apps_user.c938
-rw-r--r--src/listener.c425
-rw-r--r--src/remotectl_stub.c639
-rw-r--r--src/rpcmem.c175
-rw-r--r--src/smath.c56
-rw-r--r--src/std.c481
-rw-r--r--src/std_SwapBytes.c214
-rw-r--r--src/std_dtoa.c496
-rw-r--r--src/std_dtoa.h113
-rw-r--r--src/std_mem.c51
-rw-r--r--src/std_path.c167
-rw-r--r--src/std_strlprintf.c45
59 files changed, 18757 insertions, 0 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..1ea9552
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2017, The Linux Foundation. All rights reserved.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors
+may be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..3ff7d32
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,64 @@
+# ---------------------------------------------------------------------------------
+# Common definitons
+# ---------------------------------------------------------------------------------
+.PHONY: all clean
+
+CFLAGS? = -g
+# Local CFLAGS for the build.
+FLAGS = -O3 -Iinc -fPIC -fno-short-enums -D_DEBUG -DARM_ARCH_7 -DUSE_SYSLOG
+# Local LDFLAGS for the build.
+LD_LOCAL_FLAGS = -ldl -lpthread -lm -shared
+TARGET := libadsprpc.so
+# Default location to install things to.
+prefix := /lib
+
+# ---------------------------------------------------------------------------------
+# Make the shared library (libadsprpc)
+# ---------------------------------------------------------------------------------
+
+SOURCES = \
+ src/fastrpc_apps_user.c \
+ src/remotectl_stub.c \
+ src/listener.c \
+ src/adsp_current_process_stub.c \
+ src/apps_std_skel.c \
+ src/apps_std_imp.c \
+ src/apps_mem_imp.c \
+ src/apps_mem_skel.c \
+ src/rpcmem.c \
+ src/apps_remotectl_skel.c \
+ src/std.c \
+ src/std_mem.c \
+ src/std_path.c \
+ src/std_dtoa.c \
+ src/std_strlprintf.c \
+ src/BufBound.c \
+ src/std_SwapBytes.c \
+ src/smath.c \
+ src/atomic.c \
+ src/cae.c
+
+OBJFILES := $(patsubst %.c,%.o,$(SOURCES))
+DEPFILES := $(patsubst %.o,%.d,$(OBJFILES))
+
+include $(dep)
+
+all: $(TARGET)
+
+$(TARGET): $(OBJFILES)
+ $(CC) ${LDFLAGS} $(LD_LOCAL_FLAGS) -o $@ $^
+
+%.d: %.c
+ @$(CC) $(CFLAGS) $(FLAGS) $< -MM -MT $(@:.d=.o) >$@
+
+.c.o:
+ @echo "(CC) $@"
+ @$(CC) $(CFLAGS) $(FLAGS) -MMD -MP -c $< -o $@
+
+clean:
+ rm -rf $(OBJFILES) $(DEPFILES) $(TARGET)
+
+install: all
+ @echo "Installing to $(DESTDIR)$(prefix)"
+ @mkdir $(DESTDIR)$(prefix) -p
+ @cp libadsprpc.so $(DESTDIR)$(prefix)
diff --git a/inc/AEEBufBound.h b/inc/AEEBufBound.h
new file mode 100644
index 0000000..4146ba6
--- /dev/null
+++ b/inc/AEEBufBound.h
@@ -0,0 +1,568 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef AEEBUFBOUND_H
+#define AEEBUFBOUND_H
+/*==============================================================================
+
+FILE: AEEBufBound.h
+
+SERVICES:
+ BufBound APIs
+
+GENERAL DESCRIPTION:
+ BufBound provides a "bounded buffer" API that facilitates
+ measuring strings or character output. It's design accomodates
+ the implementation of functions that can have the same exact logic
+ for measuring and outputting char buffer content.
+
+REVISION HISTORY:
+ Fri Aug 08 17:38:29 2003: Created
+
+==============================================================================*/
+
+typedef struct BufBound
+{
+ char *pcBuf; /* original buffer */
+ char *pcWrite; /* write pointer */
+ char *pcEnd; /* first illegal write pointer */
+} BufBound;
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* #ifdef __cplusplus */
+
+extern void BufBound_Init(BufBound *me, char *pBuf, int nLen);
+extern void BufBound_Write(BufBound *me, const char *pc, int nLen);
+extern void BufBound_Putc(BufBound *me, char c);
+extern void BufBound_Putnc(BufBound *me, char c, int nCount);
+extern void BufBound_ForceNullTerm(BufBound *me);
+extern void BufBound_Puts(BufBound *me, const char *cpsz);
+extern void BufBound_Advance(BufBound *me, int nLen);
+extern void BufBound_WriteLE(BufBound *me,
+ const void *pvSrc, int nSrcSize,
+ const char *pszFields);
+extern void BufBound_WriteBE(BufBound *me,
+ const void *pvSrc, int nSrcSize,
+ const char *pszFields);
+extern int BufBound_BufSize(BufBound *me);
+extern int BufBound_Left(BufBound *me);
+extern int BufBound_ReallyWrote(BufBound *me);
+extern int BufBound_Wrote(BufBound *me);
+
+static __inline int BufBound_IsFull(BufBound *me)
+{
+ return (BufBound_Left(me) <= 0);
+}
+
+// Deprecated:
+static __inline int BufBound_IsCounter(BufBound *me)
+{
+ return BufBound_BufSize(me) == 0;
+}
+
+#ifdef __cplusplus
+}
+#endif /* #ifdef __cplusplus */
+
+
+/*=====================================================================
+=======================================================================
+DATA STRUCTURE DOCUMENTATION
+=======================================================================
+
+BufBound
+
+Description:
+ An BufBound keeps track of whether appending to a bounded buffer
+ has overflowed.
+
+Definition:
+ typedef struct BufBound
+ {
+ char* pcBuf;
+ char* pcWrite;
+ char* pcEnd;
+ } BufBound;
+
+Members:
+ pcBuf: original start pointer
+ pcWrite: current write location
+ pcEnd: first illegal write position
+
+See Also:
+ BufBound Interface
+
+=======================================================================
+INTERFACE DOCUMENTATION
+=======================================================================
+BufBound Interface
+
+ BufBound is a statically-linked interface.
+
+ BufBound provides functions for safely appending to a character buffer. On
+ initialization, the buffer start address and size are provided. Subsequent
+ write operations are checked against the buffer bounds.
+
+ Once the buffer bounds are exceeded, no bytes will be written but the
+ BufBound will continue to increment its internal "write pointer" to reflect
+ the number of bytes that would have been written (had the bounds not been
+ exceeded).
+
+ When initialized with a buffer size of zero, a BufBound simply counts the
+ number of bytes that would be required to contain the result. This design
+ accommodates implementations that use the same logic for generating output
+ and measuring the space required for generated output.
+
+ BufBound protects clients from numerical overflow by limiting the write
+ pointer to a maximum offset of INT_MAX from the start of the buffer.
+ Functions that write data into the buffer safely ignore negative size inputs
+ (Write and Putnc).
+
+=======================================================================
+BufBound_Init()
+
+Description:
+ initialize a BufBound for appending to a buffer
+
+Prototype:
+
+ void BufBound_Init(BufBound *me, char *pBuf, int nLen);
+
+Parameters:
+ me: the BufBound
+ pBuf: the bounded buffer
+ nLen: size of pBuf, in bytes
+
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+
+BufBound_Write()
+
+Description:
+ Appends some number of bytes to a BufBound, if possible.
+
+ When a negative size is passed, it is safely treated as zero.
+
+Prototype:
+
+ void BufBound_Write(BufBound *me, const char *pc, int nLen);
+
+Parameters:
+ me: the BufBound
+ pc: pointer to bytes to append
+ int nLen: number of bytes to write
+
+Return Value:
+ None
+
+Comments:
+ If the BufBound has overflowed, no bytes are written, but pcWrite is
+ *always* advanced by nLen.
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+
+BufBound_Advance()
+
+Description:
+
+ Moves the write pointer. Advance is like a relative seek operation. It
+ does not change the contents of the buffer, so when using a forward seek
+ (positive advance) be careful of advancing over uninitialized data.
+
+ Negative numbers will decrease the write pointer down to 0 (the start of
+ the buffer) and not below. Positive numbers will increase the write
+ pointer up to offset INT_MAX and not beyond.
+
+Prototype:
+
+ void BufBound_Advance(BufBound *me, int nDelta);
+
+Parameters:
+ me: the BufBound
+ int nLen: number of bytes to advance
+
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+
+BufBound_Putc()
+
+Description:
+ Appends one byte to a BufBound, if possible.
+
+Prototype:
+
+ void BufBound_Putc(BufBound *me, char c);
+
+Parameters:
+ me: the BufBound
+ c: the byte
+
+Return Value:
+ None
+
+Comments:
+ If the BufBound has overflowed, no byte is written, but pcWrite is
+ *always* advanced by 1.
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+
+=======================================================================
+
+BufBound_Putnc()
+
+Description:
+ Appends a byte to a BufBound repeatedly.
+
+ When a negative size is passed, it is safely treated as zero.
+
+Prototype:
+
+ void BufBound_Putnc(BufBound *me, char c, int nCount);
+
+Parameters:
+ me: the BufBound
+ c: the byte
+ nCount: number of times to append c
+
+Return Value:
+ None
+
+Comments:
+ If the BufBound has overflowed, no byte is written, but pcWrite is
+ *always* advanced by nCount.
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+
+=======================================================================
+
+BufBound_ForceNullTerm()
+
+Description:
+ Appends a null terminating character to a BufBound, if possible.
+ If the BufBound has overflowed, the last legal location is
+ set to '\0'.
+
+Prototype:
+ void BufBound_ForceNullTerm(BufBound *me);
+
+Parameters:
+ me: the BufBound
+
+Return Value:
+ None
+
+Comments:
+ pcWrite is *always* advanced by 1.
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+
+=======================================================================
+
+BufBound_Puts()
+
+Description:
+ Appends a null-terminated string to a BufBound, if possible
+
+Prototype:
+
+ void BufBound_Puts(BufBound *me, const char* cpsz);
+
+Parameters:
+ me: the BufBound
+ cpsz: the string to append
+
+Return Value:
+
+Comments:
+ If the BufBound has overflowed, no bytes are written, but pcWrite is
+ *always* advanced by strlen(cpsz).
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+
+=======================================================================
+
+BufBound_BufSize()
+
+Description:
+ Returns the size of the buffer owned by the BufBound. This is
+ the same as the number passed to BufBound_Init (MAXed with zero).
+
+Prototype:
+
+ int BufBound_IsCounter(BufBound* me);
+
+Parameters:
+ me: the BufBound
+
+Return Value:
+ 1 if the BufBound is a counter, 0 otherwise
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+
+=======================================================================
+
+BufBound_Left()
+
+Description:
+ Returns the number of bytes the BufBound can still accomodate,
+ without overflowing. If overflow has occurred, it will return
+ a negative number.
+
+Prototype:
+
+ int BufBound_Left(BufBound* me);
+
+Parameters:
+ me: the BufBound
+
+Return Value:
+ The number of bytes the BufBound can still accomodate,
+ without overflowing.
+
+Comments:
+ The return value may be negative, if overflow has already occurred.
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+
+=======================================================================
+
+BufBound_ReallyWrote()
+
+Description:
+ Returns the number of bytes actually written to the BufBound,
+ not including any overflow.
+
+Prototype:
+
+ int BufBound_ReallyWrote(BufBound* me);
+
+Parameters:
+ me: the BufBound
+
+Return Value:
+ The number of bytes actually written to the BufBound,
+ not including any overflow.
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+
+=======================================================================
+
+BufBound_Wrote()
+
+Description:
+
+ Returns the number of bytes written to the BufBound, including any
+ overflow, up to INT_MAX.
+
+Prototype:
+
+ int BufBound_Wrote(BufBound* me);
+
+Parameters:
+ me: the BufBound
+
+Return Value:
+
+ The number of bytes written to the BufBound, including any overflow.
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+
+=======================================================================
+
+BufBound_IsFull()
+
+Description:
+ Tests whether an AEEBuffBound has overflowed.
+
+Prototype:
+
+ int BufBound_IsFull(BufBound* me);
+
+Parameters:
+ me: the BufBound
+
+Return Value:
+ 1 if the BufBound has overflowed, 0 otherwise
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+
+BufBound_WriteLE()
+
+Description:
+
+ Writes data while translating numeric values between host byte ordering and
+ "little endian" byte ordering.
+
+ The input buffer is treated as an array of structures. The 'abySizes'
+ parameter describes the sizes of fields in the structure.
+
+ When the host byte ordering matches the target byte ordering (little
+ endian) this operation is equivalent to BufBound_Write().
+
+Prototype:
+
+ void BufBound_WriteLE(BufBound* me,
+ const void *pvSrc, int nSrcSize,
+ const unsigned char *pszFields);
+
+Parameters:
+ me: the BufBound
+ pvSrc: the source buffer
+ nSrcSize: number of bytes to copy from the source buffer
+ pszFields: Description of the fields that comprise the source data,
+ as defined in std_CopyLE.
+
+Return Value:
+ None
+
+See Also:
+ BufBound_WriteBE, std_CopyLE
+
+=======================================================================
+
+BufBound_WriteBE()
+
+Description:
+
+ BufBounf_WriteBE() has the same semantics as BufBound_WriteLE() except it
+ copies between host byte ordering and big-endian ("network") byte order.
+
+ See BufBound_WriteLE() for more details.
+
+
+Prototype:
+
+ void BufBound_WriteBE(BufBound* me,
+ const void *pvSrc, int nSrcSize,
+ const unsigned char *pszFields);
+
+Parameters:
+ me: the BufBound
+ pvSrc: the source buffer
+ nSrcSize: number of bytes to copy from the source buffer
+ pszFields: Description of the fields that comprise the source data,
+ as defined in std_CopyLE.
+
+Return Value:
+ None
+
+See Also:
+ BufBound_WriteLE, std_CopyBE
+
+======================================================================= */
+#endif /* #ifndef AEEBUFBOUND_H */
+
diff --git a/inc/AEEQList.h b/inc/AEEQList.h
new file mode 100644
index 0000000..f3346e0
--- /dev/null
+++ b/inc/AEEQList.h
@@ -0,0 +1,857 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+/*===========================================================================
+
+FILE: AEEQList.h
+
+GENERAL DESCRIPTION: Doubly-linked circular list implementation
+
+===========================================================================*/
+#ifndef _AEEQLIST_H_
+#define _AEEQLIST_H_
+
+
+typedef struct QNode QNode;
+struct QNode
+{
+ QNode *pNext;
+ QNode *pPrev;
+};
+
+#define QLIST_DEFINE_INIT(f) QList f = { { &f.n, &f.n } }
+
+typedef struct QList QList;
+struct QList
+{
+ QNode n;
+};
+
+
+
+static __inline void QNode_InsPrev(QNode *me, QNode *pn)
+{
+ QNode *pPrev = me->pPrev;
+
+ pn->pNext = me;
+ pn->pPrev = pPrev;
+ pPrev->pNext = pn;
+ me->pPrev = pn;
+}
+
+
+static __inline void QNode_InsNext(QNode *me, QNode *pn)
+{
+ QNode *pNext = me->pNext;
+
+ pn->pPrev = me;
+ pn->pNext = pNext;
+ pNext->pPrev = pn;
+ me->pNext = pn;
+}
+
+
+
+static __inline void QNode_Dequeue(QNode *me)
+{
+ QNode *pNext = me->pNext;
+ QNode *pPrev = me->pPrev;
+
+ pPrev->pNext = pNext;
+ pNext->pPrev = pPrev;
+}
+
+static __inline void QNode_CtorZ(QNode *me)
+{
+ me->pNext = me->pPrev = 0;
+}
+
+static __inline int QNode_IsQueuedZ(QNode *me)
+{
+ return (0 != me->pNext);
+}
+
+static __inline void QNode_DequeueZ(QNode *me)
+{
+ if (QNode_IsQueuedZ(me))
+ {
+ QNode_Dequeue(me);
+ me->pNext = me->pPrev = 0;
+ }
+}
+
+//--------------------------------------------------------------------
+//-- QList functions ----------------------------------------------
+//--------------------------------------------------------------------
+
+
+static __inline void QList_Zero(QList *me)
+{
+ me->n.pNext = me->n.pPrev = &me->n;
+}
+
+
+static __inline void QList_Ctor(QList *me)
+{
+ QList_Zero(me);
+}
+
+
+static __inline int QList_IsEmpty(QList *me)
+{
+ return me->n.pNext == &me->n;
+}
+
+static __inline int QList_IsNull(QList *me)
+{
+ return ((0 == me->n.pNext) && (0 == me->n.pPrev));
+}
+
+
+static __inline void QList_AppendNode(QList *me, QNode *pn)
+{
+ QNode_InsPrev(&me->n, pn);
+}
+
+
+static __inline void QList_PrependNode(QList *me, QNode *pn)
+{
+ QNode_InsNext(&me->n, pn);
+}
+
+
+static __inline void QList_CtorFrom(QList *me, QList *psrc)
+{
+ QNode *s = &psrc->n;
+ QNode *d = &me->n;
+
+ s->pNext->pPrev = d;
+ d->pPrev = s->pPrev;
+ d->pNext = s->pNext;
+ s->pPrev->pNext = d;
+
+ QList_Zero(psrc);
+}
+
+
+
+static __inline void QList_AppendList(QList *me, QList *psrc)
+{
+ QNode *s = &psrc->n;
+ QNode *d = &me->n;
+ QNode *dp = d->pPrev;
+ QNode *sn = s->pNext;
+ QNode *sp;
+
+ sn->pPrev = dp;
+ dp->pNext = sn;
+ d->pPrev = (sp = s->pPrev);
+ sp->pNext = d;
+
+ QList_Zero(psrc);
+}
+
+
+#define QLIST_FOR_ALL(pList, pNode) \
+ for ((pNode) = (pList)->n.pNext; \
+ (pNode) != &(pList)->n; \
+ (pNode) = (pNode)->pNext)
+
+#define QLIST_FOR_REST(pList, pNode) \
+ for (; \
+ (pNode) != &(pList)->n; \
+ (pNode) = (pNode)->pNext)
+
+#define QLIST_REV_FOR_ALL(pList, pNode) \
+ for ((pNode) = (pList)->n.pPrev; \
+ (pNode) != &(pList)->n; \
+ (pNode) = (pNode)->pPrev)
+
+#define QLIST_REV_FOR_REST(pList, pNode) \
+ for (; \
+ (pNode) != &(pList)->n; \
+ (pNode) = (pNode)->pPrev)
+
+/* Allows dequeing QNodes during iteration */
+#define QLIST_NEXTSAFE_FOR_ALL(pList, pNode, pNodeNext) \
+ for ((pNode) = (pList)->n.pNext, (pNodeNext) = (pNode)->pNext; \
+ (pNode) != &(pList)->n; \
+ (pNode) = (pNodeNext), (pNodeNext) = (pNode)->pNext)
+
+static __inline QNode *QList_GetFirst(QList *me)
+{
+ QNode *pn = me->n.pNext;
+
+ return (pn == &me->n ? 0 : pn);
+}
+
+static __inline QNode *QList_GetLast(QList *me)
+{
+ QNode *pn = me->n.pPrev;
+
+ return (pn == &me->n ? 0 : pn);
+}
+
+static __inline QNode *QList_Pop(QList *me)
+{
+ QNode *pn = me->n.pNext;
+ QNode *pnn = pn->pNext;
+
+ me->n.pNext = pnn;
+ pnn->pPrev = &me->n;
+
+ return (pn == &me->n ? 0 : pn);
+}
+
+static __inline QNode *QList_PopZ(QList *me)
+{
+ QNode *pn = QList_Pop(me);
+ if (0 != pn)
+ {
+ QNode_CtorZ(pn);
+ }
+ return pn;
+}
+
+static __inline QNode *QList_PopLast(QList *me)
+{
+ QNode *pp = me->n.pPrev;
+ QNode *ppp = pp->pPrev;
+
+ me->n.pPrev = ppp;
+ ppp->pNext = &me->n;
+
+ return (pp == &me->n ? 0 : pp);
+}
+
+static __inline QNode *QList_PopLastZ(QList *me)
+{
+ QNode *pn = QList_PopLast(me);
+ if (0 != pn)
+ {
+ QNode_CtorZ(pn);
+ }
+ return pn;
+}
+
+/*=====================================================================
+=======================================================================
+DATA STRUCTURE DOCUMENTATION
+=======================================================================
+
+QNode
+
+Description:
+ Qnode is the structure that is queued. One or more Qnodes may be
+ embedded in other structures. An object can contain multiple QNodes if
+ it needs to be in different lists at the same time.
+
+Definition:
+
+ typedef struct QNode QNode;
+ struct QNode {
+ QNode *pNext;
+ QNode *pPrev;
+ };
+
+Members:
+
+See Also:
+
+=======================================================================
+
+QList
+
+Description:
+ QList keeps a doubly-linked list of QNode structures.
+ Each queue is represented by a 'head' node, not a head pointer,
+ simplifying and streamlining many operations.
+ Because it is doubly-linked it permits constant-time insertion or removal
+ of items or of entire queues.
+ Because it is circular it permits constant-time operations at both the
+ tail and the head of the queue. Circularity also streamlines some
+ operations by eliminating conditional branches.
+
+ General rules:
+ QLists are always in a defined state; they should be constructed
+ before use, using one of the supplied Ctor...() functions.
+ QNodes do not track queued vs. unqueued state. The client should
+ never dequeue an un-queued node or queue an already-queued node.
+ When not queued, QNode internal state is undefined. A client may
+ implement marking and assertion externally.
+
+Definition:
+
+ typedef struct QList QList;
+ struct QList {
+ QNode n;
+ };
+
+Members:
+
+See Also:
+
+=======================================================================
+INTERFACE DOCUMENTATION
+=======================================================================
+QNode Interface
+
+ QNode is a statically-linked interface.
+
+=======================================================================
+QNode_CtorZ()
+
+Description:
+ Zero initialize a QNode.
+
+Prototype:
+
+ void QNode_CtorZ(QNode *me);
+
+Parameters:
+ me: the QNode
+
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ QNode_IsQueued(), QNode_DequeueZ(), QList_PopZ()
+
+=======================================================================
+QNode_IsQueuedZ()
+
+Description:
+ Whether a QNode belongs in a Queue.
+
+Prototype:
+
+ int QNode_IsQueuedZ(QNode *me);
+
+Parameters:
+ me: the QNode
+
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ Does not work if a node needs to live at address 0x0.
+
+See Also:
+ QNode_CtorZ(), QNode_DequeueZ(), QList_PopZ()
+
+=======================================================================
+QNode_DequeueZ()
+
+Description:
+ Dequeue a QNode if it is in a queue. Idempotent operation.
+
+Prototype:
+
+ void QNode_DequeueZ(QNode *me);
+
+Parameters:
+ me: the QNode
+
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ QNode_CtorZ(), QNode_IsQueued(), QList_PopZ()
+
+=======================================================================
+
+QNode_InsPrev()
+
+Description:
+ insert a node before this one.
+
+Prototype:
+ static __inline void QNode_InsPrev(QNode *me, QNode *pn)
+
+Parameters:
+ me: the QNode
+ pn: the node to be inserted.
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+
+QNode_InsNext()
+
+Description:
+ insert a node after this one.
+
+Prototype:
+ static __inline void QNode_InsNext(QNode *me, QNode *pn)
+
+Parameters:
+ me: the QNode
+ pn: the node to be inserted.
+
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+QNode_Dequeue()
+
+Description:
+ dequeue this node.
+
+Prototype:
+ static __inline void QNode_Dequeue(QNode *me)
+
+Parameters:
+ me: the QNode to be dequeued
+
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+QList Interface
+
+ QList is a statically-linked interface. It provides a Queue of
+ doubly linked nodes.
+
+=======================================================================
+QList_Zero()
+
+Description:
+ discard all queued nodes.
+
+Prototype:
+
+ void QList_Zero(QList *me)
+
+Parameters:
+ me: the QList
+
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+QList_Ctor()
+
+Description:
+ Initialize a queue to an empty state
+
+Prototype:
+
+ void QList_Ctor(QList *me)
+
+Parameters:
+ me: the QList
+
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+QList_IsEmpty()
+
+Description:
+ Check whether queue is empty.
+
+Prototype:
+
+ int QList_IsEmpty(QList *me)
+
+Parameters:
+ me: the QList
+
+Return Value:
+ TRUE if queue is empty.
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+QList_AppendNode()
+
+Description:
+ Append the node to the queue. Make it the last 'next' (and the
+ first 'prev')
+
+Prototype:
+
+ void QList_AppendNode(QList *me, QNode *pn)
+
+Parameters:
+ me: the QList
+ pn: the node to append.
+
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+QList_PrependNode()
+
+Description:
+ Prepend a node to the queue. Make it the first 'next' (and the
+ last 'prev').
+
+Prototype:
+
+ void QList_PrependNode(QList *me, QNode *pn)
+
+Parameters:
+ me: the QList
+ pn: the node to prepend.
+
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+QList_CtorFrom()
+
+Description:
+ Move nodes from one queue to a newly constructed queue.
+ Weird aliasing voodoo allows this to work without conditional branches, even
+ when psrc is empty. In that case, "s->pNext->pPrev = d" overwrites s->pPrev with d,
+ so that "s->pPrev->pNext = d" will later overwrite d->pNext with d.
+
+Prototype:
+
+ void QList_CtorFrom(QList *me, QList *psrc)
+
+Parameters:
+ me: the QList
+ psrc: the Qlist from
+
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+QList_AppendList()
+
+Description:
+ Move all nodes from a source queue to the end of this queue.
+ Note that weird aliasing voodoo allows this to work without conditional
+ branches when psrc is empty. A summary:
+
+ SNP = DP => SP = DP, because SNP aliases SP
+ DPN = SN => DPN = S
+ DP = SP => DP = DP, because SP was overwritten with DP
+ SPN = D => DPN = D
+
+Prototype:
+
+ void QList_AppendList(QList *me, QList *psrc)
+
+Parameters:
+ me: the QList
+ psrc: the source Qlist.
+
+Return Value:
+ None
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+QList_GetFirst()
+
+Description:
+ Get the first item on the queue
+
+Prototype:
+
+ QNode *QList_GetFirst(QList *me)
+
+Parameters:
+ me: the QList
+
+Return Value:
+ pointer to QNode or 0 if queue is empty.
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ QList_GetLast
+
+=======================================================================
+QList_GetLast()
+
+Description:
+ Get the last item on the queue
+
+Prototype:
+
+ QNode *QList_GetLast(QList *me)
+
+Parameters:
+ me: the QList
+
+Return Value:
+ pointer to QNode or 0 if queue is empty.
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ QList_GetFirst
+
+=======================================================================
+QList_Pop()
+
+Description:
+ Remove and return the first item on the queue (FIFO).
+
+Prototype:
+
+ QNode *QList_Pop(QList *me)
+
+Parameters:
+ me: the QList
+
+Return Value:
+ pointer to QNode or 0 if queue is empty
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ QNode_PopZ, QNode_PopLast(), QNode_PopLastZ, QNode_CtorZ(), QNode_IsQueued(),
+ QNode_DequeueZ()
+
+=======================================================================
+QList_PopZ()
+
+Description:
+ Remove and return the first item on the queue (FIFO). Same as QList_Pop(),
+ except the node retured is zero-initialized.
+
+Prototype:
+
+ QNode *QList_PopZ(QList *me)
+
+Parameters:
+ me: the QList
+
+Return Value:
+ pointer to QNode or 0 if queue is empty
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ QNode_Pop, QNode_PopLast(), QNode_PopLastZ, QNode_CtorZ(), QNode_IsQueued(),
+ QNode_DequeueZ()
+
+=======================================================================
+QList_PopLast()
+
+Description:
+ Remove and return the first item on the queue (FILO).
+
+Prototype:
+
+ QNode *QList_PopLast(QList *me)
+
+Parameters:
+ me: the QList
+
+Return Value:
+ pointer to QNode or 0 if queue is empty
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ QNode_PopLastZ, QNode_Pop(), QNode_PopZ, QNode_CtorZ(), QNode_IsQueued(),
+ QNode_DequeueZ()
+
+=======================================================================
+
+QList_IsNull()
+
+Description:
+Checks if the QList is null or not.
+
+Prototype:
+static __inline int QList_IsNull(QList *me)
+
+Parameters:
+ me: the QList
+
+Return Value:
+ True or False.
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+
+QList_PopLastZ()
+
+Description:
+ Remove and return the first item on the queue (FILO).
+ Same as QList_PopLast(), except the node retured is zero-initialized.
+
+Prototype:
+
+ QNode *QList_PopLastZ(QList *me)
+
+Parameters:
+ me: the QList
+
+Return Value:
+ pointer to QNode or 0 if queue is empty
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ QNode_Pop(), QNode_PopZ, QNode_CtorZ(), QNode_IsQueued(), QNode_DequeueZ()
+
+=====================================================================*/
+#endif // _AEEQLIST_H_
diff --git a/inc/AEEStdDef.h b/inc/AEEStdDef.h
new file mode 100644
index 0000000..1baefd2
--- /dev/null
+++ b/inc/AEEStdDef.h
@@ -0,0 +1,1149 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef AEESTDDEF_H
+#define AEESTDDEF_H
+/*
+=======================================================================
+
+FILE: AEEStdDef.h
+
+DESCRIPTION: definition of basic types, constants,
+ preprocessor macros
+
+=======================================================================
+*/
+
+#include <stdint.h>
+
+#if defined(COMDEF_H) /* guards against a known re-definer */
+#define _BOOLEAN_DEFINED
+#define _UINT32_DEFINED
+#define _UINT16_DEFINED
+#define _UINT8_DEFINED
+#define _INT32_DEFINED
+#define _INT16_DEFINED
+#define _INT8_DEFINED
+#define _UINT64_DEFINED
+#define _INT64_DEFINED
+#define _BYTE_DEFINED
+#endif /* #if !defined(COMDEF_H) */
+
+/* -----------------------------------------------------------------------
+** Standard Types
+** ----------------------------------------------------------------------- */
+
+/* The following definitions are the same accross platforms. This first
+** group are the sanctioned types.
+*/
+#ifndef _BOOLEAN_DEFINED
+typedef unsigned char boolean; /* Boolean value type. */
+#define _BOOLEAN_DEFINED
+#endif
+
+#ifndef _UINT32_DEFINED
+typedef uint32_t uint32; /* Unsigned 32 bit value */
+#define _UINT32_DEFINED
+#endif
+
+#ifndef _UINT16_DEFINED
+typedef unsigned short uint16; /* Unsigned 16 bit value */
+#define _UINT16_DEFINED
+#endif
+
+#ifndef _UINT8_DEFINED
+typedef unsigned char uint8; /* Unsigned 8 bit value */
+#define _UINT8_DEFINED
+#endif
+
+#ifndef _INT32_DEFINED
+typedef int32_t int32; /* Signed 32 bit value */
+#define _INT32_DEFINED
+#endif
+
+#ifndef _INT16_DEFINED
+typedef signed short int16; /* Signed 16 bit value */
+#define _INT16_DEFINED
+#endif
+
+#ifndef _INT8_DEFINED
+typedef signed char int8; /* Signed 8 bit value */
+#define _INT8_DEFINED
+#endif
+
+#if defined(__GNUC__)
+#define __int64 long long
+#endif
+
+#ifndef _UINT64_DEFINED
+typedef unsigned __int64 uint64; /* Unsigned 64 bit value */
+#define _UINT64_DEFINED
+#endif
+
+#ifndef _INT64_DEFINED
+typedef __int64 int64; /* Signed 64 bit value */
+#define _INT64_DEFINED
+#endif
+
+#ifndef _BYTE_DEFINED
+typedef unsigned char byte; /* byte type */
+#define _BYTE_DEFINED
+#endif
+
+
+#ifndef _AEEUID_DEFINED
+typedef uint32 AEEUID;
+#define _AEEUID_DEFINED
+#endif
+
+#ifndef _AEEIID_DEFINED
+typedef uint32 AEEIID;
+#define _AEEIID_DEFINED
+#endif
+
+#ifndef _AEECLSID_DEFINED
+typedef uint32 AEECLSID;
+#define _AEECLSID_DEFINED
+#endif
+
+#ifndef _AEEPRIVID_DEFINED
+typedef uint32 AEEPRIVID;
+#define _AEEPRIVID_DEFINED
+#endif
+
+#ifndef _AECHAR_DEFINED
+typedef uint16 AECHAR;
+#define _AECHAR_DEFINED
+#endif
+
+#ifndef _AEERESULT_DEFINED
+typedef int AEEResult;
+#define _AEERESULT_DEFINED
+#endif
+
+/* -----------------------------------------------------------------------
+** Function Calling Conventions
+** ----------------------------------------------------------------------- */
+
+#ifndef CDECL
+#ifdef _MSC_VER
+#define CDECL __cdecl
+#else
+#define CDECL
+#endif /* _MSC_VER */
+#endif /* CDECL */
+
+/* -----------------------------------------------------------------------
+** Constants
+** ----------------------------------------------------------------------- */
+
+#ifndef TRUE
+#define TRUE 1 /* Boolean true value. */
+#endif
+
+#ifndef FALSE
+#define FALSE 0 /* Boolean false value. */
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef MIN_INT8
+#define MIN_INT8 -128
+#endif
+#ifndef MIN_INT16
+#define MIN_INT16 -32768
+#endif
+#ifndef MIN_INT32
+#define MIN_INT32 (~0x7fffffff) /* -2147483648 is unsigned */
+#endif
+#ifndef MIN_INT64
+#define MIN_INT64 (~0x7fffffffffffffffLL) /* -9223372036854775808 is unsigned */
+#endif
+
+#ifndef MAX_INT8
+#define MAX_INT8 127
+#endif
+#ifndef MAX_INT16
+#define MAX_INT16 32767
+#endif
+#ifndef MAX_INT32
+#define MAX_INT32 2147483647
+#endif
+#ifndef MAX_INT64
+#define MAX_INT64 9223372036854775807LL
+#endif
+
+#ifndef MAX_UINT8
+#define MAX_UINT8 255
+#endif
+#ifndef MAX_UINT16
+#define MAX_UINT16 65535
+#endif
+#ifndef MAX_UINT32
+#define MAX_UINT32 4294967295u
+#endif
+#ifndef MAX_UINT64
+#define MAX_UINT64 18446744073709551615uLL
+#endif
+
+#ifndef MIN_AECHAR
+#define MIN_AECHAR 0
+#endif
+#ifndef MAX_AECHAR
+#define MAX_AECHAR 65535
+#endif
+
+
+/* -----------------------------------------------------------------------
+** Preprocessor helpers
+** ----------------------------------------------------------------------- */
+#define __STR__(x) #x
+#define __TOSTR__(x) __STR__(x)
+#define __FILE_LINE__ __FILE__ ":" __TOSTR__(__LINE__)
+
+/* -----------------------------------------------------------------------
+** Types for code generated from IDL
+** ----------------------------------------------------------------------- */
+
+#ifndef __QIDL_WCHAR_T_DEFINED__
+#define __QIDL_WCHAR_T_DEFINED__
+typedef uint16 _wchar_t;
+#endif
+
+/* __STRING_OBJECT__ will be deprecated in the future */
+#if !defined(__QIDL_STRING_OBJECT_DEFINED__) && !defined(__STRING_OBJECT__)
+#define __QIDL_STRING_OBJECT_DEFINED__
+#define __STRING_OBJECT__
+typedef struct _cstring_s
+{
+ char *data;
+ int dataLen;
+ int dataLenReq;
+} _cstring_t;
+
+typedef struct _wstring_s
+{
+ _wchar_t *data;
+ int dataLen;
+ int dataLenReq;
+} _wstring_t;
+#endif /* __QIDL_STRING_OBJECT_DEFINED__ */
+
+/*
+=======================================================================
+ DATA STRUCTURES DOCUMENTATION
+=======================================================================
+
+boolean
+
+Description:
+ This type is used to express boolean values (TRUE or FALSE).
+
+Definition:
+ typedef unsigned char boolean
+
+See Also:
+ byte
+ int8
+ int16
+ int32
+ int64
+ uint32
+ uint16
+ uint8
+ uint64
+
+=======================================================================
+
+uint32
+
+Description:
+ This is a 32-bit unsigned integer.
+
+Definition:
+ typedef uint32_t uint32
+
+See Also:
+ boolean
+ byte
+ int8
+ int16
+ int32
+ int64
+ uint8
+ uint16
+ uint64
+
+=======================================================================
+
+uint16
+
+Description:
+ This is a 16-bit unsigned integer.
+
+Definition:
+ typedef unsigned short uint16
+
+See Also:
+ boolean
+ byte
+ int8
+ int16
+ int32
+ int64
+ uint8
+ uint32
+ uint64
+
+=======================================================================
+
+uint8
+
+Description:
+ This is an 8-bit unsigned integer.
+
+Definition:
+ typedef unsigned char uint8
+
+See Also:
+ boolean
+ byte
+ int8
+ int16
+ int32
+ int64
+ uint16
+ uint32
+ uint64
+
+=======================================================================
+
+int32
+
+Description:
+ This is a 32-bit signed integer.
+
+Definition:
+ typedef int32_t int32
+
+See Also:
+ boolean
+ byte
+ int8
+ int16
+ int64
+ uint8
+ uint16
+ uint32
+ uint64
+
+=======================================================================
+
+int16
+
+Description:
+ This is a 16-bit signed integer.
+
+Definition:
+ typedef signed short int16
+
+See Also:
+ boolean
+ byte
+ int8
+ int32
+ int64
+ uint8
+ uint16
+ uint32
+ uint64
+
+=======================================================================
+
+int8
+
+Description:
+ This is an 8-bit signed integer.
+
+Definition:
+ typedef signed char int8
+
+See Also:
+ boolean
+ byte
+ int16
+ int32
+ int64
+ uint8
+ uint16
+ uint32
+ uint64
+
+=======================================================================
+
+uint64
+
+Description:
+ This is a 64-bit unsigned integer.
+
+Definition:
+ typedef unsigned __int64 uint64
+
+See Also:
+ boolean
+ byte
+ int8
+ int16
+ int32
+ int64
+ uint8
+ uint16
+ uint32
+
+=======================================================================
+
+int64
+
+Description:
+ This is a 64-bit signed integer.
+
+Definition:
+ typedef __int64 int64
+
+See Also:
+ boolean
+ byte
+ int8
+ int16
+ int32
+ uint8
+ uint16
+ uint32
+ uint64
+
+=======================================================================
+
+byte
+
+Description:
+ This is a byte.
+
+Definition:
+ typedef unsigned char byte
+
+See Also:
+ boolean
+ int8
+ int16
+ int32
+ int64
+ uint8
+ uint16
+ uint32
+ uint64
+
+=======================================================================
+
+AEEUID
+
+Description:
+ This is a BREW unique ID. Used to express unique types, interfaces, classes
+ groups and privileges. The BREW ClassID Generator generates
+ unique IDs that can be used anywhere you need a new AEEIID, AEECLSID,
+ or AEEPRIVID.
+
+Definition:
+ typedef uint32 AEEUID
+
+See Also:
+ AECHAR
+ AEECLSID
+ AEEIID
+ AEEPRIVID
+ AEEResult
+
+=======================================================================
+
+AEEIID
+
+Description:
+ This is an interface ID type, used to denote a BREW interface. It is a special case
+ of AEEUID.
+
+Definition:
+ typedef uint32 AEEIID
+
+See Also:
+ AECHAR
+ AEECLSID
+ AEEPRIVID
+ AEEResult
+ AEEUID
+
+=======================================================================
+
+AEECLSID
+
+Description:
+ This is a classe ID type, used to denote a BREW class. It is a special case
+ of AEEUID.
+
+Definition:
+ typedef uint32 AEECLSID
+
+See Also:
+ AECHAR
+ AEECLSIDs
+ AEEIID
+ AEEPRIVID
+ AEEResult
+ AEEUID
+
+=======================================================================
+
+AEEPRIVID
+
+Description:
+ This is a privilege ID type, used to express a privilege. It is a special case
+ of AEEUID.
+
+Definition:
+ typedef uint32 AEEPRIVID
+
+See Also:
+ AECHAR
+ AEECLSID
+ AEEIID
+ AEEResult
+ AEEUID
+
+=======================================================================
+
+AECHAR
+
+Description:
+ This is a 16-bit character type.
+
+Definition:
+ typedef uint16 AECHAR
+
+See Also:
+ AEEPRIVID
+ AEECLSID
+ AEEIID
+ AEEResult
+ AEEUID
+
+=======================================================================
+
+AEEResult
+
+Description:
+ This is the standard result type.
+
+Definition:
+ typedef int AEEResult
+
+See Also:
+ AECHAR
+ AEEPRIVID
+ AEECLSID
+ AEEIID
+ AEEUID
+
+=======================================================================
+
+_wchar_t
+
+Description:
+ This is a 16-bit character type corresponding to the IDL 'wchar'
+ type.
+
+Definition:
+ typedef uint16 _wchar_t
+
+See Also:
+ _cstring_t
+ _wstring_t
+
+=======================================================================
+
+_cstring_t
+
+Description:
+ This structure is used to represent an IDL string when used inside a
+ sequence or union.
+
+Definition:
+ typedef struct _cstring_s {
+ char* data;
+ int dataLen;
+ int dataLenReq;
+ } _cstring_t;
+
+Members:
+ data : A pointer to the NULL-terminated string.
+ dataLen : The size, in chars, of the buffer pointed to by 'data',
+ including the NULL terminator. This member is only used
+ when the structure is part of an rout or inrout
+ parameter, but must be supplied by the caller as an
+ input in these cases.
+ dataLenReq : The size that would have been required to store the
+ entire result string. This member is only used when the
+ structure is part of an rout or inrout parameter, when
+ it is an output value set by the callee. The length of
+ the returned string (including the NULL terminator)
+ after a call is the minimum of dataLen and dataLenReq.
+
+See Also:
+ _wchar_t
+ _wstring_t
+
+=======================================================================
+
+_wstring_t
+
+Description:
+ This structure is used to represent an IDL wstring when used inside a
+ sequence or union.
+
+Definition:
+ typedef struct _wstring_s {
+ _wchar_t* data;
+ int dataLen;
+ int dataLenReq;
+ } _wstring_t;
+
+Members:
+ data : A pointer to the NULL-terminated wide string.
+ dataLen : The size, in 16-bit characters, of the buffer pointed to
+ by 'data', including the NULL terminator. This member
+ is only used when the structure is part of an rout or
+ inrout parameter, but must be supplied by the caller as
+ an input in these cases.
+ dataLenReq : The number of 16-bit characters that would have been
+ required to store the entire result string. This member
+ is only used when the structure is part of an rout or
+ inrout parameter, when it is an output value set by the
+ callee. The length of the returned wstring (including
+ the NULL terminator) after a call is the minimum of
+ dataLen and dataLenReq.
+
+See Also:
+ _cstring_t
+ _wchar_t
+
+=======================================================================
+CONSTANTS DOCUMENTATION
+=======================================================================
+
+TRUE
+
+Description:
+ TRUE is the boolean "true."
+
+Definition:
+
+ #define TRUE 1
+
+See Also:
+ FALSE
+ NULL
+
+=======================================================================
+
+FALSE
+
+Description:
+ FALSE is the boolean "false."
+
+Definition:
+
+ #define FALSE 0
+
+See Also:
+ NULL
+ TRUE
+
+=======================================================================
+
+NULL
+
+Description:
+ NULL is the null value, usually used to test a pointer.
+
+Definition:
+
+ #define NULL 0
+
+See Also:
+ FALSE
+ TRUE
+
+=======================================================================
+
+MIN_INT8
+
+Description:
+ MIN_INT8 is the minimum signed 8-bit integer value.
+
+Definition:
+
+ #define MIN_INT8 -128
+
+See Also:
+ MAX_AECHAR
+ MAX_INT8
+ MAX_INT16
+ MAX_INT32
+ MAX_INT64
+ MAX_UINT8
+ MAX_UINT16
+ MAX_UINT32
+ MAX_UINT64
+ MIN_AECHAR
+ MIN_INT16
+ MIN_INT32
+ MIN_INT64
+
+=======================================================================
+
+MIN_INT16
+
+Description:
+ MIN_INT16 is the minimum signed 16-bit integer value
+
+Definition:
+
+ #define MIN_INT16 -32768
+
+See Also:
+ MAX_AECHAR
+ MAX_INT8
+ MAX_INT16
+ MAX_INT32
+ MAX_INT64
+ MAX_UINT8
+ MAX_UINT16
+ MAX_UINT32
+ MAX_UINT64
+ MIN_AECHAR
+ MIN_INT8
+ MIN_INT32
+ MIN_INT64
+
+=======================================================================
+
+MIN_INT32
+
+Description:
+ MIN_INT32 is the minimum signed 32-bit integer value.
+
+Definition:
+
+ #define MIN_INT32 (~0x7fffffff)
+
+Comments:
+ Brew MP uses (~0x7fffffff), because -2147483648 is treated as unsigned by compilers.
+
+See Also:
+ MAX_AECHAR
+ MAX_INT8
+ MAX_INT16
+ MAX_INT32
+ MAX_INT64
+ MAX_UINT8
+ MAX_UINT16
+ MAX_UINT32
+ MAX_UINT64
+ MIN_AECHAR
+ MIN_INT8
+ MIN_INT16
+ MIN_INT64
+
+=======================================================================
+
+MIN_INT64
+
+Description:
+ MIN_INT64 is the minimum signed 64-bit integer value.
+
+Definition:
+
+ #define MIN_INT64 (~0x7fffffffffffffffll)
+
+Comments:
+ Brew MP uses (~0x7fffffffffffffffll), because -9223372036854775808 is
+ treated as unsigned by compilers.
+
+See Also:
+ MAX_AECHAR
+ MAX_INT8
+ MAX_INT16
+ MAX_INT32
+ MAX_INT64
+ MAX_UINT8
+ MAX_UINT16
+ MAX_UINT32
+ MAX_UINT64
+ MIN_AECHAR
+ MIN_INT8
+ MIN_INT16
+ MIN_INT32
+
+=======================================================================
+
+MAX_INT8
+
+Description:
+ MAX_INT8 is the maximum signed 8-bit integer value
+
+Definition:
+
+ #define MAX_INT8 127
+
+See Also:
+ MAX_AECHAR
+ MAX_INT16
+ MAX_INT32
+ MAX_INT64
+ MAX_UINT8
+ MAX_UINT16
+ MAX_UINT32
+ MAX_UINT64
+ MIN_AECHAR
+ MIN_INT8
+ MIN_INT16
+ MIN_INT32
+ MIN_INT64
+
+=======================================================================
+
+MAX_INT16
+
+Description:
+ MAX_INT16 is the maximum signed 16-bit integer value.
+
+Definition:
+
+ #define MAX_INT16 32767
+
+See Also:
+ MAX_AECHAR
+ MAX_INT8
+ MAX_INT32
+ MAX_INT64
+ MAX_UINT8
+ MAX_UINT16
+ MAX_UINT32
+ MAX_UINT64
+ MIN_AECHAR
+ MIN_INT8
+ MIN_INT16
+ MIN_INT32
+ MIN_INT64
+
+=======================================================================
+
+MAX_INT32
+
+Description:
+ MAX_INT32 is the maximum signed 32-bit integer value.
+
+Definition:
+
+ #define MAX_INT32 2147483647
+
+See Also:
+ MAX_AECHAR
+ MAX_INT8
+ MAX_INT16
+ MAX_INT64
+ MAX_UINT8
+ MAX_UINT16
+ MAX_UINT32
+ MAX_UINT64
+ MIN_AECHAR
+ MIN_INT8
+ MIN_INT16
+ MIN_INT32
+ MIN_INT64
+
+=======================================================================
+
+MAX_INT64
+
+Description:
+ MAX_INT64 is the maximum signed 64-bit integer value.
+
+Definition:
+
+ #define MAX_INT64 9223372036854775807ll
+
+See Also:
+ MAX_AECHAR
+ MAX_INT8
+ MAX_INT16
+ MAX_INT32
+ MAX_UINT8
+ MAX_UINT16
+ MAX_UINT32
+ MAX_UINT64
+ MIN_AECHAR
+ MIN_INT8
+ MIN_INT16
+ MIN_INT32
+ MIN_INT64
+
+=======================================================================
+
+MAX_UINT8
+
+Description:
+ MAX_UINT8 is the maximum unsigned 8-bit integer value.
+
+Definition:
+
+ #define MAX_UINT8 255
+
+See Also:
+ MAX_AECHAR
+ MAX_INT8
+ MAX_INT16
+ MAX_INT32
+ MAX_INT64
+ MAX_UINT16
+ MAX_UINT32
+ MAX_UINT64
+ MIN_AECHAR
+ MIN_INT8
+ MIN_INT16
+ MIN_INT32
+ MIN_INT64
+
+=======================================================================
+
+MAX_UINT16
+
+Description:
+ MAX_UINT16 is the maximum unsigned 16-bit integer value.
+
+Definition:
+
+ #define MAX_UINT16 65535
+
+See Also:
+ MAX_AECHAR
+ MAX_INT8
+ MAX_INT16
+ MAX_INT32
+ MAX_INT64
+ MAX_UINT8
+ MAX_UINT32
+ MAX_UINT64
+ MIN_AECHAR
+ MIN_INT8
+ MIN_INT16
+ MIN_INT32
+ MIN_INT64
+
+=======================================================================
+
+MAX_UINT32
+
+Description:
+ MAX_UINT32 is the maximum unsigned 32-bit integer value.
+
+Definition:
+
+ #define MAX_UINT32 4294967295u
+
+See Also:
+ MAX_AECHAR
+ MAX_INT8
+ MAX_INT16
+ MAX_INT32
+ MAX_INT64
+ MAX_UINT8
+ MAX_UINT16
+ MAX_UINT64
+ MIN_AECHAR
+ MIN_INT8
+ MIN_INT16
+ MIN_INT32
+ MIN_INT64
+
+=======================================================================
+
+MAX_UINT64
+
+Description:
+ MAX_UINT64 is the maximum unsigned 64-bit integer value.
+
+Definition:
+
+ #define MAX_UINT64 18446744073709551615ull
+
+See Also:
+ MAX_AECHAR
+ MAX_INT8
+ MAX_INT16
+ MAX_INT32
+ MAX_INT64
+ MAX_UINT8
+ MAX_UINT16
+ MAX_UINT32
+ MIN_AECHAR
+ MIN_INT8
+ MIN_INT16
+ MIN_INT32
+ MIN_INT64
+
+=======================================================================
+
+MIN_AECHAR
+
+Description:
+ MIN_AECHAR is the minimum AECHAR value.
+
+Definition:
+
+ #define MIN_AECHAR 0
+
+See Also:
+ MAX_AECHAR
+ MAX_INT8
+ MAX_INT16
+ MAX_INT32
+ MAX_INT64
+ MAX_UINT8
+ MAX_UINT16
+ MAX_UINT32
+ MAX_UINT64
+ MIN_INT8
+ MIN_INT16
+ MIN_INT32
+ MIN_INT64
+
+=======================================================================
+
+MAX_AECHAR
+
+Description:
+ MAX_AECHAR is the maximum AECHAR value.
+
+Definition:
+
+ #define MAX_AECHAR 65535
+
+See Also:
+ MIN_AECHAR
+ MAX_INT8
+ MAX_INT16
+ MAX_INT32
+ MAX_INT64
+ MAX_UINT8
+ MAX_UINT16
+ MAX_UINT32
+ MAX_UINT64
+ MIN_INT8
+ MIN_INT16
+ MIN_INT32
+ MIN_INT64
+
+=======================================================================
+MACROS DOCUMENTATION
+=======================================================================
+
+__STR__()
+
+Description:
+ The __STR__() makes a token into a string, used to string-ize things already
+ defined.
+
+Definition:
+
+ #define __STR__(x) #x
+
+Parameters:
+ x: token to make into a string
+
+See Also:
+ __TOSTR__()
+ __FILE_LINE__
+
+=======================================================================
+
+__TOSTR__()
+
+Description:
+ The __TOSTR__() makes a token's value into a string, used to string-ize things
+ already defined, used with __STR__.
+
+Definition:
+
+ #define __TOSTR__(x) __STR__(x)
+
+Parameters:
+ x: token to evaluate and string-ize
+
+Evaluation Value:
+ the token's replacement as a string
+
+See Also:
+ __FILE_LINE__
+ __STR__()
+
+=======================================================================
+
+__FILE_LINE__
+
+Description:
+ The compiler's __FILE__ (a string) and __LINE__ (an integer) are pasted
+ together as a single string with a ":" between.
+
+Definition:
+
+ #define __FILE_LINE__ __FILE__ ":" __TOSTR__(__LINE__)
+
+Evaluation Value:
+ __FILE__":""__LINE__"
+
+See Also:
+ __STR__()
+ __TOSTR__()
+
+=======================================================================
+*/
+
+#endif /* #ifndef AEESTDDEF_H */
+
diff --git a/inc/AEEStdErr.h b/inc/AEEStdErr.h
new file mode 100644
index 0000000..c93ac49
--- /dev/null
+++ b/inc/AEEStdErr.h
@@ -0,0 +1,225 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef AEESTDERR_H
+#define AEESTDERR_H
+
+//
+// Basic Error Codes
+//
+//
+
+#define AEE_SUCCESS 0 // no error
+#define AEE_EFAILED 1 // general failure
+#define AEE_ENOMEMORY 2 // insufficient RAM
+#define AEE_ECLASSNOTSUPPORT 3 // specified class unsupported
+#define AEE_EVERSIONNOTSUPPORT 4 // version not supported
+#define AEE_EALREADYLOADED 5 // object already loaded
+#define AEE_EUNABLETOLOAD 6 // unable to load object/applet
+#define AEE_EUNABLETOUNLOAD 7 // unable to unload object/applet
+#define AEE_EALARMPENDING 8 // alarm is pending
+#define AEE_EINVALIDTIME 9 // invalid time
+#define AEE_EBADCLASS 10 // NULL class object
+#define AEE_EBADMETRIC 11 // invalid metric specified
+#define AEE_EEXPIRED 12 // App/Component Expired
+#define AEE_EBADSTATE 13 // invalid state
+#define AEE_EBADPARM 14 // invalid parameter
+#define AEE_ESCHEMENOTSUPPORTED 15 // invalid URL scheme
+#define AEE_EBADITEM 16 // invalid item
+#define AEE_EINVALIDFORMAT 17 // invalid format
+#define AEE_EINCOMPLETEITEM 18 // incomplete item
+#define AEE_ENOPERSISTMEMORY 19 // insufficient flash
+#define AEE_EUNSUPPORTED 20 // API is not supported
+#define AEE_EPRIVLEVEL 21 // privileges are insufficient for this operation
+#define AEE_ERESOURCENOTFOUND 22
+#define AEE_EREENTERED 23
+#define AEE_EBADTASK 24
+#define AEE_EALLOCATED 25 // App/Module left memory allocated when released
+#define AEE_EALREADY 26 // operation is already in progress
+#define AEE_EADSAUTHBAD 27 // ADS mutual authorization failed
+#define AEE_ENEEDSERVICEPROG 28 // need service programming
+#define AEE_EMEMPTR 29 // bad memory pointer
+#define AEE_EHEAP 30 // heap corruption
+#define AEE_EIDLE 31 // context (system, interface, etc.) is idle
+#define AEE_EITEMBUSY 32 // context (system, interface, etc.) is busy
+#define AEE_EBADSID 33 // invalid subscriber ID
+#define AEE_ENOTYPE 34 // no type detected/found
+#define AEE_ENEEDMORE 35 // need more data/info
+#define AEE_EADSCAPS 36 // ADS Capabilities do not match those required for phone
+#define AEE_EBADSHUTDOWN 37 // App failed to close properly
+#define AEE_EBUFFERTOOSMALL 38 // destination buffer given is too small
+#define AEE_ENOSUCH 39 // no such name/port/socket/service exists or valid
+#define AEE_EACKPENDING 40 // ACK pending on application
+#define AEE_ENOTOWNER 41 // not an owner authorized to perform the operation
+#define AEE_EINVALIDITEM 42 // current item is invalid
+#define AEE_ENOTALLOWED 43 // not allowed to perform the operation
+#define AEE_EBADHANDLE 44 // invalid handle
+#define AEE_EOUTOFHANDLES 45 // out of handles
+#define AEE_EINTERRUPTED 46 // waitable call is interrupted
+#define AEE_ENOMORE 47 // no more items available -- reached end
+#define AEE_ECPUEXCEPTION 48 // a CPU exception occurred
+#define AEE_EREADONLY 49 // Cannot change read-only object or parameter
+// a moratorium on adding to AEEStdErr.h is in effect, 50 and later are
+// already spoken for
+
+#define AEE_EWOULDBLOCK 516 // Operation would block if not non-blocking; wait and try again
+
+/*
+============================================================================
+ ERRORS DOCUMENTATION
+==============================================================================
+
+Error Codes
+
+Description:
+This topic lists the categories of error codes that Brew MP returns. The topic for each
+category of error code includes the name of each error, the code that is associated with
+the error, and a description of the error.
+
+===H2>
+List of Error Code Types
+===/H2>
+===p>
+The categories of error codes include: ~
+~
+
+AddrBook error codes ~
+AddrInfo error codes ~
+AEE_IS_REMOTE_ERR(): ~
+AEE_IS_REMOTE_ERR_PRE(): ~
+Basic AEE Error Codes ~
+Database error codes ~
+dbc Error Codes ~
+DNS Resolver error codes ~
+File error codes ~
+FS AEE Error Codes ~
+ICamera error codes ~
+ICMP error codes ~
+ILicenseSystem Error Codes ~
+Indeterminate errors: (transport failure) ~
+ISQL Error Codes ~
+ISVGDOM Error Codes: ~
+ISSL error codes ~
+IX509Chain error codes ~
+ModCollector Errors ~
+ModInstallerCntx Errors ~
+ModMover Errors ~
+Multimedia error codes ~
+Network AEE error codes ~
+Network subsystem error codes ~
+pim_IMessageStore Error Codes ~
+pim_IRecordStore Error Codes ~
+Port AEE Error Codes ~
+PosDet error codes ~
+Post-invocation errors: (remote errors) ~
+Pre-invocation errors: (remote errors) ~
+QoS error codes ~
+Remote error codes: ~
+SSL error codes ~
+VOCODER error codes ~
+VolumeDB Errors ~
+Web error codes ~
+
+*
+
+==================================================================
+Basic AEE Error Codes
+
+Description:
+This section lists the set of basic AEE errors returned, the codes associated
+with the errors, and descriptions of the errors.
+
+Definition:
+
+Error Code Description
+
+AEE_SUCCESS 0 operation Successful
+AEE_EFAILED 1 general failure
+AEE_ENOMEMORY 2 insufficient RAM
+AEE_ECLASSNOTSUPPORT 3 specified class unsupported
+AEE_EVERSIONNOTSUPPORT 4 version not supported
+AEE_EALREADYLOADED 5 object already loaded
+AEE_EUNABLETOLOAD 6 unable to load object/applet
+AEE_EUNABLETOUNLOAD 7 unable to unload object/applet
+AEE_EALARMPENDING 8 alarm is pending
+AEE_EINVALIDTIME 9 invalid time
+AEE_EBADCLASS 10 NULL class object
+AEE_EBADMETRIC 11 invalid metric specified
+AEE_EEXPIRED 12 Application/Component Expired
+AEE_EBADSTATE 13 invalid state
+AEE_EBADPARM 14 invalid parameter
+AEE_ESCHEMENOTSUPPORTED 15 invalid URL scheme
+AEE_EBADITEM 16 invalid item
+AEE_EINVALIDFORMAT 17 invalid format
+AEE_EINCOMPLETEITEM 18 incomplete item
+AEE_ENOPERSISTMEMORY 19 insufficient flash
+AEE_EUNSUPPORTED 20 API is not supported
+AEE_EPRIVLEVEL 21 application privileges are insufficient for this operation
+AEE_ERESOURCENOTFOUND 22 unable to find specified resource
+AEE_EREENTERED 23 non re-entrant API re-entered
+AEE_EBADTASK 24 API called in wrong task context
+AEE_EALLOCATED 25 Application/Module left memory allocated when released
+AEE_EALREADY 26 operation is already in progress
+AEE_EADSAUTHBAD 27 ADS mutual authorization failed
+AEE_ENEEDSERVICEPROG 28 need service programming
+AEE_EMEMPTR 29 bad memory pointer
+AEE_EHEAP 30 heap corruption
+AEE_EIDLE 31 context (system, interface, etc.) is idle
+AEE_EITEMBUSY 32 context (system, interface, etc.) is busy
+AEE_EBADSID 33 invalid subscriber ID
+AEE_ENOTYPE 34 no type detected/found
+AEE_ENEEDMORE 35 need more data/info
+AEE_EADSCAPS 36 capabilities do not match those required
+AEE_EBADSHUTDOWN 37 application failed to close properly
+AEE_EBUFFERTOOSMALL 38 destination buffer given is too small
+AEE_ENOSUCH 39 no such name/port/socket/service exists or valid
+AEE_EACKPENDING 40 ACK pending on application
+AEE_ENOTOWNER 41 not an owner authorized to perform the operation
+AEE_EINVALIDITEM 42 current item is invalid
+AEE_ENOTALLOWED 43 not allowed to perform the operation
+AEE_EBADHANDLE 44 invalid handle
+AEE_EOUTOFHANDLES 45 out of handles
+AEE_EINTERRUPTED 46 waitable call is interrupted
+AEE_ENOMORE 47 no more items available -- reached end
+AEE_ECPUEXCEPTION 48 a CPU exception occurred
+AEE_EREADONLY 49 cannot change read-only object or parameter
+AEE_EWOULDBLOCK 516 operation would block if not non-blocking; wait and try again
+
+Comments:
+These Brew MP error codes have an up-to-date naming convention, and replace older BREW error
+codes that use a naming convention that did not include the "AEE_" prefix.
+
+See Also:
+ Error Codes
+
+==================================================================
+*/
+#endif /* #ifndef AEESTDERR_H */
+
diff --git a/inc/AEEVaList.h b/inc/AEEVaList.h
new file mode 100644
index 0000000..3bf3204
--- /dev/null
+++ b/inc/AEEVaList.h
@@ -0,0 +1,115 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef AEEVALIST_H
+#define AEEVALIST_H
+
+#if defined(__ARMCC_VERSION) || (defined(__GNUC__) && defined(__arm__))
+
+#if (defined(__ARMCC_VERSION) && __ARMCC_VERSION >= 200000 && !defined(__APCS_ADSABI)) || \
+ (defined(__GNUC__) && defined(__arm__) && defined(__ARM_EABI__))
+
+# define __AEEVA_ATPCS 0
+
+#else
+
+# define __AEEVA_ATPCS 1
+
+#endif
+
+typedef void *AEEVaList;
+
+#define __AEEVA_ARGALIGN(t) (((char*)(&((struct{char c;t x;}*)1)->x))-((char*)1))
+#define __AEEVA_ARGSIZE(t) ((sizeof(t)+sizeof(int)-1) & ~(sizeof(int)-1))
+
+static __inline void __cpy(char *d, const char *s, int len)
+{
+ while (len-- > 0)
+ *d++ = *s++;
+}
+
+static __inline AEEVaList __AEEVa_Arg(AEEVaList args, void *pv, int nVSize,
+ int nArgSize, int nArgAlign)
+{
+ int nArgs = (int)args & ~1;
+ char *pcArgs = (char *)args;
+ int bATPCS = (int)args & 1;
+ int nArgsOffset = 0;
+ int nVOffset = 0;
+
+ if (!bATPCS) /* caller was compiled with AAPCS */
+ {
+
+ if (nArgAlign > (int)sizeof(int))
+ {
+ nArgAlign--; /* make a mask */
+ pcArgs += ((nArgs + nArgAlign) & (int)~(unsigned)nArgAlign) - nArgs;
+ /* move pv to next alignment */
+ }
+ }
+
+#if defined(AEE_BIGENDIAN)
+ if (nArgSize < (int)sizeof(int))
+ {
+ nArgsOffset = (int)sizeof(int) - nArgSize;
+ }
+ nVOffset = nVSize - nArgSize;
+#else
+ (void)nVSize;
+#endif /* AEE_BIGENDIAN */
+
+ __cpy((char *)pv + nVOffset, (pcArgs - bATPCS) + nArgsOffset, nArgSize);
+
+ /* round up */
+ nArgSize = (nArgSize + (int)sizeof(int) - 1) & ~((int)sizeof(int) - 1);
+
+ return pcArgs + nArgSize; /* increment va */
+}
+
+#define AEEVA_START(va,v) ((va) = (char*)&(v) + __AEEVA_ARGSIZE(v) + __AEEVA_ATPCS)
+#define AEEVA_ARG(va,v,t) ((void)((va) = __AEEVa_Arg(va,&v,sizeof(v),sizeof(t),__AEEVA_ARGALIGN(t))))
+#define AEEVA_END(va) ((va) = (AEEVaList)0)
+#define AEEVA_COPY(dest, src) ((void)((dest) = (src)))
+
+#else /* defined(__ARMCC_VERSION) || (defined(__GNUC__) && defined(__arm__)) */
+
+#include <stdarg.h>
+
+typedef va_list AEEVaList;
+
+#define AEEVA_START(va,v) (va_start((va), (v)))
+#define AEEVA_ARG(va,v,t) ((v) = va_arg((va),t))
+#define AEEVA_END(va) (va_end((va)))
+#define AEEVA_COPY(dest, src) (va_copy((dest),(src)))
+
+#endif/* defined(__ARMCC_VERSION) || (defined(__GNUC__) && defined(__arm__)) */
+
+#endif /* #ifndef AEEVALIST_H */
+
diff --git a/inc/AEEatomic.h b/inc/AEEatomic.h
new file mode 100644
index 0000000..2911455
--- /dev/null
+++ b/inc/AEEatomic.h
@@ -0,0 +1,197 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef AEEATOMIC_H
+#define AEEATOMIC_H
+/*
+=======================================================================
+
+FILE: AEEatomic.h
+
+SERVICES: atomic
+
+DESCRIPTION: Fast Atomic ops
+
+=======================================================================
+*/
+
+#include "AEEStdDef.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* #ifdef __cplusplus */
+
+uint32 atomic_Add(uint32 *volatile puDest, int nAdd);
+uint32 atomic_Exchange(uint32 *volatile puDest, uint32 uVal);
+uint32 atomic_CompareAndExchange(uint32 *volatile puDest, uint32 uExchange, uint32 uCompare);
+uint32 atomic_CompareOrAdd(uint32 *volatile puDest, uint32 uCompare, int nAdd);
+
+#ifdef __cplusplus
+}
+#endif /* #ifdef __cplusplus */
+
+/*=====================================================================
+INTERFACE DOCUMENTATION
+=======================================================================
+atomic Interface
+
+ The atomic interface provides fast "atomic" operations. The
+ operations are defined to be atomic with respect to each other.
+
+=======================================================================
+
+=======================================================================
+
+atomic_Add()
+
+Description:
+
+ Performs an atomic sum operation.
+
+Prototype:
+
+ uint32 atomic_Add(uint32* puDest, int nInc);
+
+Parameters:
+ puDest [in|out] : Points to unsigned number to add nInc and save
+ nInc : increment
+
+Return Value:
+ result.
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+
+atomic_Exchange()
+
+Description:
+
+ Atomic exchange of 32bit value. Performs an atomic operation of :
+ write uVal to *puDest
+ return the previous value in *puDest
+
+Prototype:
+
+ uint32 atomic_Exchange(uint32* puDest, uint32 uVal);
+
+Parameters:
+ puDest [in|out] : Points to unsigned number to be exchanged
+ uVal : new value to write.
+
+Return Value:
+ previous value at *puDest.
+
+Comments:
+ None
+
+Side Effects:
+ May cause exception if puDest is not a 32 bit aligned address.
+
+See Also:
+ None
+=======================================================================
+
+atomic_CompareAndExchange()
+
+Description:
+
+ Performs an atomic operation of :
+ if (*puDest == uCompare) {
+ *puDest = uExchange;
+ }
+
+ returns the previous value in *puDest
+
+Prototype:
+
+ uint32 atomic_CompareAndExchange(uint32 *puDest, uint32 uExchange,
+ uint32 uCompare);
+
+Parameters:
+ puDest [in|out] : Points to unsigned number.
+ uExchange : A new value to write to *puDest
+ uCompare : Comparand
+
+Return Value:
+ previous value at *puDest.
+
+Comments:
+ None
+
+Side Effects:
+ May cause exception if puDest is not a 32 bit aligned address.
+
+See Also:
+ None
+
+=======================================================================
+atomic_CompareOrAdd()
+
+Description:
+
+ Performs an atomic operation of :
+ if (*puDest != uCompare) {
+ *puDest += nAdd;
+ }
+
+ returns the new value in *puDest
+
+Prototype:
+
+ uint32 atomic_CompareOrAdd(uint32 *puDest, uint32 uCompare, int nAdd);
+
+Parameters:
+ puDest [in|out] : Points to unsigned number.
+ uCompare : Comparand
+ nAdd : Add to *puDest
+
+Return Value:
+ new value at *puDest.
+
+Comments:
+ None
+
+Side Effects:
+ May cause exception if puDest is not a 32 bit aligned address.
+
+See Also:
+ None
+=======================================================================*/
+
+#endif /* #ifndef AEEATOMIC_H */
+
diff --git a/inc/AEEstd.h b/inc/AEEstd.h
new file mode 100644
index 0000000..2cfc653
--- /dev/null
+++ b/inc/AEEstd.h
@@ -0,0 +1,2609 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef AEESTD_H
+#define AEESTD_H
+/*====================================================================
+
+DESCRIPTION: Standard library; general-purpose utility functions.
+
+====================================================================*/
+#include "AEEVaList.h"
+#include "AEEStdDef.h"
+
+#define STD_CONSTRAIN( val, min, max ) (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val))
+#define STD_BETWEEN( val, minGE, maxLT ) \
+ ( (unsigned long)((unsigned long)(val) - (unsigned long)(minGE)) < \
+ (unsigned long)((unsigned long)(maxLT) - (unsigned long)(minGE)) )
+#define STD_ARRAY_SIZE(a) ((int)((sizeof((a))/sizeof((a)[0]))))
+#define STD_ARRAY_MEMBER(p,a) (((p) >= (a)) && ((p) < ((a) + STD_ARRAY_SIZE(a))))
+
+#define STD_SIZEOF(x) ((int)sizeof(x))
+#define STD_OFFSETOF(type,member) (((char*)(&((type*)1)->member))-((char*)1))
+
+#define STD_RECOVER_REC(type,member,p) ((void)((p)-&(((type*)1)->member)),\
+ (type*)(void*)(((char*)(void*)(p))-STD_OFFSETOF(type,member)))
+#define STD_MIN(a,b) ((a)<(b)?(a):(b))
+#define STD_MAX(a,b) ((a)>(b)?(a):(b))
+//lint -emacro(545,STD_ZEROAT)
+#define STD_ZEROAT(p) std_memset((p), 0, sizeof(*p))
+
+#define _STD_BITS_PER(bits) (8*sizeof((bits)[0]))
+
+#define STD_BIT_SET(bits, ix) ((bits)[(ix)/_STD_BITS_PER((bits))] |= 0x1<<((ix) & (_STD_BITS_PER((bits))-1)))
+#define STD_BIT_CLEAR(bits, ix) ((bits)[(ix)/_STD_BITS_PER((bits))] &= ~(0x1<<((ix) & (_STD_BITS_PER((bits))-1))))
+#define STD_BIT_TEST(bits, ix) ((bits)[(ix)/_STD_BITS_PER((bits))] & (0x1<<((ix) & (_STD_BITS_PER((bits))-1))))
+
+//
+// Error codes
+//
+#define STD_NODIGITS 1
+#define STD_NEGATIVE 2
+#define STD_OVERFLOW 3
+#define STD_BADPARAM 4
+#define STD_UNDERFLOW 5
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* #ifdef __cplusplus */
+
+//Version function
+extern int std_getversion(char *pcDst, int nDestSize);
+
+//String functions
+extern int std_strlen(const char *s);
+extern int std_strcmp(const char *s1, const char *s2);
+extern int std_strncmp(const char *s1, const char *s2, int n);
+extern int std_stricmp(const char *s1, const char *s2);
+extern int std_strnicmp(const char *s1, const char *s2, int n);
+extern int std_strlcpy(char *pcDst, const char *pszSrc, int nDestSize);
+extern int std_strlcat(char *pcDst, const char *pszSrc, int nDestSize);
+extern char *std_strstr(const char *pszString, const char *pszSearch);
+
+//Character functions
+extern char std_tolower(char c);
+extern char std_toupper(char c);
+
+// Mem functions
+extern void *std_memset(void *p, int c, int nLen);
+extern void *std_memmove(void *pTo, const void *cpFrom, int nLen);
+extern int std_memcmp(const void *a, const void *b, int length);
+extern void *std_memchr(const void *s, int c, int n);
+extern void *std_memstr(const char *cpHaystack, const char *cpszNeedle, int nHaystackLen);
+extern void *std_memrchr(const void *s, int c, int n);
+extern void *std_memrchrbegin(const void *p, int c, int nLen);
+extern void *std_memchrend(const void *cpcSrch, int c, int nLen);
+extern void *std_memchrsend(const void *cpSrch, const char *cpszChars, int nLen);
+
+//Other String functions
+extern char *std_strchr(const char *s, int c);
+extern char *std_strchrs(const char *sSrch, const char *sChars);
+extern char *std_strrchr(const char *s, int c);
+extern char *std_strchrend(const char *cpszSrch, char c);
+extern char *std_strchrsend(const char *s, const char *cpszSrch);
+extern char *std_strends(const char *cpsz, const char *cpszSuffix);
+extern char *std_striends(const char *cpsz, const char *cpszSuffix);
+extern char *std_strbegins(const char *cpsz, const char *cpszPrefix);
+extern char *std_stribegins(const char *cpsz, const char *cpszPrefix);
+extern int std_strcspn(const char *s, const char *cpszSrch);
+extern int std_strspn(const char *s, const char *cpszSrch);
+
+//Wide char string functions
+extern int std_wstrlen(const AECHAR *s);
+extern int std_wstrlcpy(AECHAR *pcDst, const AECHAR *pszSrc, int nDestSize);
+extern int std_wstrlcat(AECHAR *pcDst, const AECHAR *pszSrc, int nDestSize);
+extern int std_wstrncmp(const AECHAR *s1, const AECHAR *s2, int nLen);
+extern int std_wstrcmp(const AECHAR *s1, const AECHAR *s2);
+extern AECHAR *std_wstrchr(const AECHAR *cpwszText, AECHAR ch);
+extern AECHAR *std_wstrrchr(const AECHAR *cpwszText, AECHAR ch);
+
+//Path functions
+extern int std_makepath(const char *cpszDir,
+ const char *cpszFile,
+ char *pszDest, int nDestSize);
+extern char *std_splitpath(const char *cpszPath, const char *cpszDir);
+extern char *std_cleanpath(char *pszPath);
+extern char *std_basename(const char *pszPath);
+
+//Inet functions, number functions
+extern uint32 std_scanul(const char *pchBuf, int nRadix,
+ const char **ppchEnd, int *pnError);
+extern uint64 std_scanull(const char *pchBuf, int nRadix,
+ const char **ppchEnd, int *pnError);
+extern double std_scand(const char *pchBuf, const char **ppchEnd);
+
+// Rand functions
+extern unsigned std_rand_next(unsigned uRand);
+extern uint32 std_rand(uint32 uSeed, byte *pDest, int nSize);
+
+
+// printf functions
+extern int std_vstrlprintf(char *pszDest, int nDestSize,
+ const char *pszFmt, AEEVaList args);
+
+extern int std_strlprintf(char *pszDest, int nDestSize,
+ const char *pszFmt, ...);
+
+extern int std_vsnprintf(char *pszDest, int nDestSize,
+ const char *cpszFmt, AEEVaList args);
+
+extern int std_snprintf(char *pszDest, int nDestSize,
+ const char *pszFmt, ...);
+
+// endian swapping functions
+extern int std_CopyLE(void *pvDest, int nDestSize,
+ const void *pvSrc, int nSrcSize,
+ const char *pszFields);
+
+extern int std_CopyBE(void *pvDest, int nDestSize,
+ const void *pvSrc, int nSrcSize,
+ const char *pszFields);
+
+// sorting utilities
+extern void std_qsort(void *pElems, int nNumElems, int nElemWidth,
+ int (*pfnCompare)(void *, const void *, const void *),
+ void *pCompareCx);
+
+extern int std_bisect(const void *pElems, int nNumElems, int nElemWidth,
+ const void *pElem,
+ int (*pfnCompare)(void *, const void *, const void *),
+ void *pCompareCx);
+
+extern void std_merge(void *vpDst, int nDst,
+ const void *vpA, int nA,
+ const void *vpB, int nB,
+ int nElemWidth,
+ int (*pfnCompare)(void *, const void *, const void *),
+ void *pCompareCx);
+
+extern int std_uniq(void *vpElems, int nNumElems, int nElemWidth,
+ int (*pfnCompare)(void *, const void *, const void *),
+ void *pCompareCx);
+
+#ifdef __cplusplus
+}
+#endif /* #ifdef __cplusplus */
+
+
+#define STD_SWAPS(us) \
+ ((((us) & 0xff) << 8) + (((us) & 0xff00) >> 8))
+
+
+static __inline unsigned short std_swaps(unsigned short us)
+{
+ return STD_SWAPS(us);
+}
+
+/* note, STD_SWAPL() requires that ul be an l-value, and destroyable.
+ this macro is not intended for use outside AEEstd.h */
+#define STD_SWAPL(ul) \
+ (((ul) = (((ul) & 0x00ff00ff) << 8) | (((ul)>>8) & 0x00ff00ff)),(((ul) >> 16) | ((ul) << 16)))
+
+static __inline unsigned long std_swapl(unsigned long ul)
+{
+ return STD_SWAPL(ul);
+}
+
+#ifdef AEE_BIGENDIAN
+# define STD_HTONL(u) (u)
+# define STD_HTONS(u) (u)
+# define STD_HTOLEL(u) (STD_SWAPL(u))
+# define STD_HTOLES(u) (STD_SWAPS(u))
+#else
+# define STD_HTONL(u) (STD_SWAPL(u))
+# define STD_HTONS(u) (STD_SWAPS(u))
+# define STD_HTOLEL(u) (u)
+# define STD_HTOLES(u) (u)
+#endif
+
+static __inline unsigned short std_letohs(unsigned short us)
+{
+ return STD_HTOLES(us);
+}
+
+static __inline unsigned short std_htoles(unsigned short us)
+{
+ return STD_HTOLES(us);
+}
+
+static __inline unsigned long std_letohl(unsigned long ul)
+{
+ return STD_HTOLEL(ul);
+}
+
+static __inline unsigned long std_htolel(unsigned long ul)
+{
+ return STD_HTOLEL(ul);
+}
+
+static __inline unsigned short std_ntohs(unsigned short us)
+{
+ return STD_HTONS(us);
+}
+
+static __inline unsigned short std_htons(unsigned short us)
+{
+ return STD_HTONS(us);
+}
+
+static __inline unsigned long std_ntohl(unsigned long ul)
+{
+ return STD_HTONL(ul);
+}
+
+static __inline unsigned long std_htonl(unsigned long ul)
+{
+ return STD_HTONL(ul);
+}
+
+
+#undef STD_HTONL // private macro; not exported as a supported API
+#undef STD_HTONS // private macro; not exported as a supported API
+#undef STD_HTOLEL // private macro; not exported as a supported API
+#undef STD_HTOLES // private macro; not exported as a supported API
+#undef STD_SWAPS // private macro; not exported as a supported API
+#undef STD_SWAPL // private macro; not exported as a supported API
+
+
+/*
+=======================================================================
+MACROS DOCUMENTATION
+=======================================================================
+
+STD_CONTSTRAIN()
+
+Description:
+ STD_CONTSTRAIN() constrains a number to be between two other numbers.
+
+Definition:
+ STD_CONSTRAIN( val, min, max ) \
+ (((val) < (min)) ? (min) : ((val) > (max)) ? (max) : (val))
+
+Parameters:
+ val: number to constrain
+ min: number to stay greater than or equal to
+ max: number to stay less than or equal to
+
+Evaluation Value:
+ the constrained number
+
+=======================================================================
+
+STD_BETWEEN()
+
+Description:
+ STD_BETWEEN() tests whether a number is between two other numbers.
+
+Definition:
+ STD_BETWEEN( val, minGE, maxLT ) \
+ ((unsigned)((unsigned)(val) - (unsigned)(minGE)) < \
+ (unsigned)((unsigned)(maxLT) - (unsigned)(minGE)))
+
+Parameters:
+ val: value to test
+ minGE: lower bound
+ maxLT: upper bound
+
+Evaluation Value:
+ 1 if val >= minGE and val < maxLT
+
+=======================================================================
+
+STD_ARRAY_SIZE()
+
+Description:
+ STD_ARRAY_SIZE() gives the number of elements in a statically allocated array.
+
+Definition:
+ STD_ARRAY_SIZE(a) (sizeof((a))/sizeof((a)[0]))
+
+Parameters:
+ a: array to test
+
+Evaluation Value:
+ number of elements in a
+
+=======================================================================
+
+STD_ARRAY_MEMBER()
+
+Description:
+ STD_ARRAY_MEMBER() tests whether an item is a member of a statically allocated array.
+
+Definition:
+ STD_ARRAY_MEMBER(p,a) (((p) >= (a)) && ((p) < ((a) + STD_ARRAY_SIZE(a))))
+
+Parameters:
+ p: item to test
+ a: array to check
+
+Evaluation Value:
+ 1 if p is in a
+
+=======================================================================
+
+STD_OFFSETOF()
+
+Description:
+ STD_OFFSETOF() gives the offset of member of a struct.
+
+Definition:
+ STD_OFFSETOF(type,member) (((char *)(&((type *)0)->member))-((char *)0))
+
+Parameters:
+ type: structured type
+ member: name of member in the struct
+
+Evaluation Value:
+ offset of member (in bytes) in type
+
+=======================================================================
+
+STD_RECOVER_REC()
+
+Description:
+ STD_RECOVER_REC() provides a safe cast from a pointer to a member
+ of a struct to a pointer to the containing struct
+
+Definition:
+ STD_RECOVER_REC(type,member,p) ((type*)(((char*)(p))-STD_OFFSETOF(type,member)))
+
+Parameters:
+ type: structured type
+ member: name of member in the struct
+ p: pointer to the member of the struct
+
+Evaluation Value:
+ a pointer of type type to the containing struct
+
+=======================================================================
+
+STD_MIN()
+
+Description:
+ STD_MIN() finds the smaller of two values.
+
+Definition:
+ STD_MIN(a,b) ((a)<(b)?(a):(b))
+
+Parameters:
+ a, b: values to compare
+
+Evaluation Value:
+ smaller of a and b
+
+=======================================================================
+
+STD_MAX()
+
+Description:
+ STD_MAX() finds the larger of two values.
+
+Definition:
+ STD_MAX(a,b) ((a)>(b)?(a):(b))
+
+Parameters:
+ a, b: values to compare
+
+Evaluation Value:
+ larger of a and b
+
+=======================================================================
+
+STD_ZEROAT()
+
+Description:
+ STD_ZEROAT() zero-initializes the contents of a typed chunk of memory.
+
+Definition:
+ STD_ZEROAT(p) std_memset((p), 0, sizeof(*p))
+
+Parameters:
+ p: the chunk to initialize
+
+Evaluation Value:
+ p
+
+=======================================================================
+
+STD_BIT_SET()
+
+Description:
+ STD_BIT_SET(bits, ix) sets the bit in the memory stored in bits at
+ index ix
+
+Parameters:
+ bits: the memory address holding the bits
+ ix: the index of the bit to set;
+
+=======================================================================
+
+STD_BIT_CLEAR()
+
+Description:
+ STD_BIT_CLEAR(bits, ix) clears the bit in the memory stored in bits
+ at index ix
+
+Parameters:
+ bits: the memory address holding the bits
+ ix: the index of the bit to clear
+
+=======================================================================
+
+STD_BIT_TEST()
+
+Description:
+ STD_BIT_TEST(bits, ix) returns the bit in the memory stored in bits
+ at index ix
+
+Parameters:
+ bits: the memory address holding the bits
+ ix: the index of the bit to test
+
+Evaluation Value:
+ 0x1 if set 0x0 if not set
+
+=====================================================================
+INTERFACES DOCUMENTATION
+=======================================================================
+
+std Interface
+
+Description:
+ This library provides a set of general-purpose utility functions.
+ Functionality may overlap that of a subset of the C standard library, but
+ this library differs in a few respects:
+
+ - Functions are fully reentrant and avoid use of static variables.
+
+ - The library can be supported consistently across all environments.
+ Compiler-supplied libraries sometimes behave inconsistently and are
+ unavailable in some environments.
+
+ - Omits "unsafe" functions. C standard library includes many functions
+ that are best avoided entirely: strcpy, strcat, strtok, etc.
+
+
+=======================================================================
+
+std_getversion()
+
+Description:
+
+ The std_getversion() copies the stdlib version to pcDst. This function
+ takes the size of the destination buffer as an argument and guarantees
+ to zero-terminate the result and not to overflow the nDestSize size.
+
+ This function copies up to size-1 characters from the stdlib version
+ string to pcDest and NUL-terminates the pcDest string.
+
+Prototype:
+ int std_getversion(char *pcDst, int nDestSize)
+
+
+Parameters:
+ pcDst : Destination string
+ nDestSize: Size of the destination buffer in bytes
+
+Return Value:
+
+ Returns the length of the version string (in characters).
+
+=======================================================================
+
+std_strlen()
+
+Description:
+ The std_strlen() computes the length of the given string.
+
+Prototype:
+ int std_strlen(const char *cpszStr)
+
+Parameters:
+ cpszStr : String whose length will be computed
+
+Return Value:
+ Length of the string in characters that precede the terminating NULL character.
+
+=======================================================================
+
+std_strcmp()
+
+Description:
+ The std_strcmp() compares two NUL-terminated character strings.
+ Comparison is strictly by byte values with no character set
+ interpretation.
+
+Prototype:
+
+ int std_strcmp(const char *s1, const char *s2);
+
+Parameters:
+ s1, s2: strings to compare
+
+Return Value:
+ 0 if strings are the same ~
+ < 0 if s1 is less than s2 ~
+ > 0 if s1 is greater than s2
+
+See Also:
+ std_wstrcmp
+
+=======================================================================
+
+std_strncmp()
+
+Description:
+ The std_strncmp() compares at most n bytes of two NUL-terminated character strings.
+
+Prototype:
+
+ int std_strncmp(const char *s1, const char *s2, int n);
+
+Parameters:
+ s1, s2: strings to compare
+ n: maximum number of bytes to compare. if either s1 or s2 is
+ shorter than n, the function terminates there
+
+Return Value:
+ 0 if strings are the same ~
+ < 0 if s1 is less than s2 ~
+ > 0 if s1 is greater than s2
+
+See Also:
+ std_wstrncmp
+
+=======================================================================
+
+std_stricmp()
+
+Description:
+ The std_stricmp() compares two NUL-terminated character strings, case-folding any
+ ASCII characters.
+
+Prototype:
+
+ int std_stricmp(const char *s1, const char *s2);
+
+Parameters:
+ s1, s2: strings to compare
+
+Return Value:
+ 0 if strings are the same ~
+ < 0 if s1 is less than s2 ~
+ > 0 if s1 is greater than s2
+
+=======================================================================
+
+std_strnicmp()
+
+Description:
+ The std_strnicmp() compares at most n bytes of 2 NUL-terminated character strings,
+ case-folding any ASCII characters.
+
+Prototype:
+
+ int std_strnicmp(const char *s1, const char *s2, int n);
+
+Parameters:
+ s1, s2: strings to compare
+ n: maximum number of bytes to compare. if either s1 or s2 is
+ shorter than n, the function terminates there
+
+Return Value:
+ 0 if strings are the same ~
+ < 0 if s1 is less than s2 ~
+ > 0 if s1 is greater than s2
+
+=======================================================================
+
+std_strlcpy()
+
+Description:
+
+ The std_strlcpy() copies pszSrc string to the pcDst. It is a safer
+ alternative to strcpy() or strncpy(). This function takes the size of the
+ destination buffer as an argument and guarantees to NUL-terminate the
+ result and not to overflow the nDestSize size.
+
+ This function copies up to nDestSize-1 characters from the pszSrc string
+ to pcDest and NUL-terminates the pcDest string.
+
+Prototype:
+ int std_strlcpy(char *pcDst, const char *pszSrc, int nDestSize)
+
+Parameters:
+ pcDst : Destination string
+ pcSrc : Source string
+ nDestSize: Size of the destination buffer in bytes
+
+Return Value:
+
+ Returns the length of the string (in characters) it tried to create,
+ which is same as length of pszSrc.
+
+ Example:
+
+ {
+ char buf[64];
+ if (std_strlcpy(buf, file_name, STD_ARRAY_SIZE(buf) >=
+ STD_ARRAY_SIZE(buf)) {
+ //Truncated -- Handle overflow....
+ }
+ }
+
+Comment:
+
+ Unlike strlcpy, std_strlcpy accepts an integer size and does nothing when a
+ negative value is passed. When passing valid sizes for objects on our
+ supported platforms, this should not result in any observed difference.
+ However, calling strlcpy() with UINT_MAX will result in the entire source
+ string being copied, whereas std_strlcpy() will do nothing. Passing INT_MAX
+ to str_strlcpy() will achieve the same result (although both these cases are
+ bad practice since they defeat bounds checking).
+
+
+=======================================================================
+
+std_strlcat()
+
+Description:
+
+ The std_strlcat() function concatenates a string to a string already
+ residing in a buffer. It is a safer alternative to strcat() or strncat().
+ This function takes the size of the destination buffer as an argument and
+ guarantees not to create an improperly terminated string and not to
+ overflow the nDestSize size.
+
+ This function appends pszSrc to pcDst, copying at most nDestSize minus
+ the length of the string in pcDest minus 1 bytes, always NUL-terminating
+ the result.
+
+ For compatibility with "strlcat()", std_strlcat() does *not* zero-terminate
+ the destination buffer in cases where the buffer lacks termination on entry
+ to the function. Do not rely on std_strlcat() to zero-terminate a buffer
+ that is not already zero-terminated; instead ensure that the buffer is
+ properly initialized using std_strlcpy() or some other means.
+
+Prototype:
+
+ int std_strlcat(char *pcDst, const char *pszSrc, int nDestSize)
+
+Parameters:
+
+ pcDst : Destination string
+ pcSrc : Source string
+ nDestSize: Size of the destination buffer in bytes
+
+Return Value:
+
+ Returns the length of the string (in characters) it tried to create,
+ which is same as length of pszSrc plus the length of pszDest.
+
+ Example:
+
+ {
+ char buf[64];
+ if (std_strlcat(buf, file_name, STD_ARRAY_SIZE(buf) >=
+ STD_ARRAY_SIZE(buf)) {
+ //Truncated -- Handle overflow....
+ }
+ }
+
+
+=======================================================================
+
+std_strstr()
+
+Description:
+ The std_strstr() finds the first occurrence of a substring in a string.
+
+Prototype:
+
+ char * std_strstr(const char *pszString, const char *pszSearch);
+
+Parameters:
+ pszString: string to search
+ pszSearch: sub string to search for
+
+Return Value:
+ A pointer to the first character in the first occurrence of the substring if found, NULL otherwise
+
+=======================================================================
+
+std_tolower()
+
+Description:
+ The std_tolower() converts an uppercase letter to the corresponding
+ lowercase letter.
+
+Prototype:
+ char std_tolower(char c);
+
+Parameters:
+ c: A character.
+
+Return Value:
+ the corresponding lowercase letter if c is an ASCII character whose
+ value is representable as an uppercase letter, else the same character
+ c is returned.
+
+=======================================================================
+
+std_toupper()
+
+Description:
+ The std_toupper() converts an lowercase letter to the corresponding
+ uppercase letter.
+
+Prototype:
+ char std_toupper(char c);
+
+Parameters:
+ c: is a character.
+
+Return Value:
+ The corresponding uppercase letter if c is an ASCII character whose
+ value is representable as an lowercase letter; else the same character
+ c is returned.
+
+=======================================================================
+
+std_memset()
+
+Description:
+ The std_memset() sets each byte in a block of memory to a value.
+
+Prototype:
+
+ void *std_memset(void *p, int c, int nLen);
+
+Parameters:
+ p: memory block to set
+ c: value to set each byte to
+ nLen: size of p in bytes
+
+Return Value:
+ p
+
+=======================================================================
+
+std_memmove()
+
+Description:
+ The std_memmove() copies a block of memory from one buffer to another.
+
+Prototype:
+
+ void *std_memmove(void *pTo, const void *cpFrom, int nLen);
+
+Parameters:
+ pTo: destination buffer
+ cpFrom: source buffer
+ nLen: number of bytes to copy
+
+Return Value:
+ pTo
+
+=======================================================================
+
+std_memcmp()
+
+Description:
+ The std_memcmp() compares two memory buffers, byte-wise.
+
+Prototype:
+
+ int std_memcmp(const void *a, const void *b, int length);
+
+Parameters:
+ a, b: buffers to compare
+ length: number of bytes to compare
+
+Return Value:
+ 0 if buffers are the same for nLength ~
+ < 0 if a is less than b ~
+ > 0 if a is greater than b
+
+=======================================================================
+
+std_memchr()
+
+Description:
+ The std_memchr() finds the first occurrence of a character in a memory
+ buffer.
+
+Prototype:
+
+ void *std_memchr(const void* s, int c, int n);
+
+Parameters:
+ s: buffer to search
+ c: value of byte to look for
+ n: size of s in bytes
+
+Return Value:
+ A pointer to the occurrence of c. NULL if not found.
+
+=======================================================================
+
+std_memstr()
+
+Description:
+ The std_memstr() finds the first occurrence of a substring in a memory
+ buffer.
+
+Prototype:
+
+ void *std_memstr(const char* cpHaystack, const char* cpszNeedle,
+ int nHaystackLen);
+
+Parameters:
+ cpHaystack: buffer to search
+ cpszNeedle: NUL-terminated string to search for
+ nHaystackLen: size of cpHaystack in bytes
+
+Return Value:
+ a pointer to the first occurrence of cpszNeedle if found,
+ NULL otherwise
+
+Comments:
+ None
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+
+std_memrchr()
+
+Description:
+
+ The std_memrchr() finds the last occurrence of a character in a memory
+ buffer.
+
+Prototype:
+
+ void *std_memrchr(const void* s, int c, int n);
+
+Parameters:
+ s: buffer to search
+ c: value of byte to look for
+ n: size of s in bytes
+
+Return Value:
+ a pointer to the last occurrence of c, NULL if not found
+
+=======================================================================
+
+std_memrchrbegin()
+
+Description:
+ The std_memrchrbegin() finds the last occurrence of a character in a
+ memory buffer.
+
+Prototype:
+
+ void *std_memrchrbegin(const void* s, int c, int n);
+
+Parameters:
+ s: buffer to search
+ c: value of byte to look for
+ n: size of s in bytes
+
+Return Value:
+ a pointer to the last occurrence of c, or s if not found
+
+=======================================================================
+
+std_memchrend()
+
+Description:
+ The std_memchrend() finds the first occurrence of a character in a
+ memory buffer.
+
+Prototype:
+
+ void *std_memchrend(const void* s, int c, int n);
+
+Parameters:
+ s: buffer to search
+ c: value of byte to look for
+ n: size of s in bytes
+
+Return Value:
+ a pointer to the occurrence of c, s + n if not found
+
+=======================================================================
+std_memchrsend()
+
+Description:
+ The std_memchrsend() finds the first occurrence of any character in a
+ NUL-terminated list of characters in a memory buffer.
+
+Prototype:
+
+ void *std_memchrend(const void* s, const char* cpszChars, int n);
+
+Parameters:
+ s: buffer to search
+ cpszChars: characters to look for
+ n: size of s in bytes
+
+Return Value:
+ a pointer to the first occurrence of one of cpszChars, s + n if not found
+
+=======================================================================
+
+std_strchr()
+
+Description:
+ The std_strchr() finds the first occurrence of a character in a
+ NUL-terminated string.
+
+Prototype:
+
+ char *std_strchr(const char* s, int c);
+
+Parameters:
+ s: string to search
+ c: char to search for
+
+Return Value:
+ pointer to first occurrence, NULL if not found
+
+See Also:
+ std_wstrchr
+
+=======================================================================
+
+std_strchrs()
+
+Description:
+ The std_strchrs() searches s, a NUL-terminated string, for the first
+ occurrence of any characters in cpszSrch, a NUL-terminated list of
+ characters.
+
+Prototype:
+
+ char *std_strchrs(const char* s, const char *cpszSrch);
+
+Parameters:
+ s: string to search
+ cpszSrch: a list of characters to search for
+
+Return Value:
+ first occurrence of any of cpszSrch, NULL if not found
+
+=======================================================================
+
+std_strrchr()
+
+Description:
+ The std_strrchr() finds the last occurrence of a character in a
+ NUL-terminated string.
+
+Prototype:
+
+ char *std_strrchr(const char* s, int c);
+
+Parameters:
+ s: string to search
+ c: char to search for
+
+Return Value:
+ pointer to last occurrence, NULL if not found
+
+See Also:
+ std_wstrrchr
+
+=======================================================================
+
+std_strchrend()
+
+Description:
+ The std_strchrend() finds the first occurrence of a character in a
+ NUL-terminated string.
+
+Prototype:
+
+ char *std_strchrend(const char* s, int c);
+
+Parameters:
+ s: string to search
+ c: char to search for
+
+Return Value:
+ pointer to first occurrence, s + std_strlen(s) if not found
+
+=======================================================================
+
+std_strchrsend()
+
+Description:
+ The std_strchrsend() searches s, a NUL-terminated string, for the first
+ occurrence of any characters in cpszSrch, a NUL-terminated list of
+ characters.
+
+Prototype:
+
+ char *std_strchrsend(const char* s, const char* cpszSrch);
+
+Parameters:
+ s: string to search
+ cpszSrch: a list of characters to search for
+
+Return Value:
+ first occurrence of any of cpszSrch or s+strlen(s) if not found
+
+=======================================================================
+
+std_strends()
+
+Description:
+ The std_strends() tests whether a string ends in a particular suffix.
+
+Prototype:
+
+ char *std_strends(const char* cpsz, const char* cpszSuffix);
+
+Parameters:
+ cpsz: string to test
+ cpszSuffix: suffix to test for
+
+Return Value:
+ the first character of cpsz+std_strlen(cpsz)-std_strlen(cpszSuffix)
+ if cpsz ends with cpszSuffix. NULL otherwise.
+
+=======================================================================
+
+std_striends()
+
+Description:
+ The std_striends() tests whether a string ends in a particular suffix,
+ case-folding ASCII characters.
+
+Prototype:
+
+ char *std_striends(const char* cpsz, const char* cpszSuffix);
+
+Parameters:
+ cpsz: string to test
+ cpszSuffix: suffix to test for
+
+Return Value:
+ the first character of cpsz+std_strlen(cpsz)-std_strlen(cpszSuffix)
+ if cpsz ends with cpszSuffix. NULL otherwise.
+
+=======================================================================
+
+std_strbegins()
+
+Description:
+ The std_strbegins() tests whether a string begins with a particular
+ prefix string.
+
+Prototype:
+
+ char *std_strbegins(const char* cpsz, const char* cpszPrefix);
+
+Parameters:
+ cpsz: string to test
+ cpszPrefix: prefix to test for
+
+Return Value:
+ cpsz + std_strlen(cpszPrefix) if cpsz does begin with cpszPrefix,
+ NULL otherwise
+
+=======================================================================
+
+std_stribegins()
+
+Description:
+ The std_stribegins() tests whether a string begins with a particular
+ prefix string, case-folding ASCII characters.
+
+Prototype:
+
+ char *std_stribegins(const char* cpsz, const char* cpszPrefix);
+
+Parameters:
+ cpsz: string to test
+ cpszPrefix: prefix to test for
+
+Return Value:
+ cpsz + std_strlen(cpszPrefix) if cpsz does begin with cpszPrefix,
+ NULL otherwise
+
+
+=======================================================================
+
+std_strcspn()
+
+Description:
+ The std_strcspn() function searches s, a NUL-terminated string, for
+ the first occurrence of any characters in cpszSrch, a NUL-terminated
+ list of characters. This function returns the length of the longest
+ initial substring of s which consists of characters not present in
+ cpszSrch.
+
+Prototype:
+
+ int std_strcspn(const char* s, const char* cpszSrch);
+
+Parameters:
+ s: string to search
+ cpszSrch: a list of characters to search for
+
+Return Value:
+ The index into the string s of the first occurrence of any of the
+ characters in cpszSrch. If no match is found, then index of the
+ terminating NUL character is returned.
+
+See Also:
+ std_strspn, std_strchr, std_strchrs
+
+=======================================================================
+
+std_strspn()
+
+Description:
+ The std_strspn() functions searches s, a NUL-terminated string, for
+ the first occurrence of a character that matches none of the
+ characters in cpszSrch, a NUL-terminated list of characters. This
+ function returns the length of the longest initial substring of s
+ which consists of characters present in cpszSrch.
+
+Prototype:
+
+ int std_strspn(const char* s, const char* cpszSrch);
+
+Parameters:
+ s: string to search
+ cpszSrch: a list of characters to search for
+
+Return Value:
+ The index into the string s of the first occurrence of any character
+ that matches none of the characters in cpszSrch. If all characters
+ in s are present in cpszSrch, the index of the terminating NUL
+ character is returned.
+
+See Also:
+ std_strcspn, std_strchr, std_strchrs
+
+=======================================================================
+
+std_wstrlcpy()
+
+Description:
+
+ The std_wstrlcpy() function copies a string. It is equivalent to
+ str_strlcpy() except that it operates on wide (16-bit) character strings.
+ See std_strlcpy() for details.
+
+
+Prototype:
+
+ int std_wstrlcpy(AECHAR *pcDest, const AECHAR *pszSrc, int nDestSize);
+
+Parameters:
+ pcDst: destination string
+ pszSrc: source string
+ int nDestSize: size of pcDest __in AECHARs__
+
+Return Value:
+ Returns the length of the string (in AECHARs) it tried to create,
+ which is same as length of pszSrc.
+
+ Example:
+
+ {
+ AECHAR buf[64];
+ if (std_wstrlcpy(buf, file_name, STD_ARRAY_SIZE(buf)) >=
+ STD_ARRAY_SIZE(buf)) {
+ //Truncated -- Handle overflow....
+ }
+ }
+
+See Also:
+ std_wstrlcat
+
+=======================================================================
+
+std_wstrlcat()
+
+Description:
+
+ The std_wstrlcat() function concatenates two strings. It is equivalent to
+ std_strlcat() except that it operates on wide (16-bit) character strings.
+ See std_strlcat() for more information.
+
+Prototype:
+ int std_wstrlcat(AECHAR *pcDst, const AECHAR *pszSrc, int nDestSize)
+
+Parameters:
+ pcDst[out]: Destination string
+ pcSrc : Source string
+ nDestSize: Size of the destination buffer in AECHARs
+
+Return Value:
+ Returns the length of the string (in AECHARs) it tried to create,
+ which is same as length of pszSrc + the length of pszDest.
+
+ Example:
+
+ {
+ char buf[64];
+ if (std_wstrlcat(buf, file_name, STD_ARRAY_SIZE(buf)) >=
+ STD_ARRAY_SIZE(buf)) {
+ //Truncated -- Handle overflow....
+ }
+ }
+
+See Also:
+ std_wstrlcpy
+
+=======================================================================
+
+std_wstrncmp()
+
+Description:
+
+ The std_wstrncmp() function compares up to a specified number of bytes
+ in two NUL-terminated strings. It is equivalent to std_strncmp() except
+ that it operates on wide (16-bit) character strings.
+
+Prototype:
+ int std_wstrncmp(const AECHAR* s1, const AECHAR* s2, int nLen);
+
+Parameters:
+ s1, s2: strings to compare
+ n: maximum number of AECHARs to compare. if either s1 or s2 is
+ shorter than n, the function terminates there.
+
+Return Value:
+ 0 if strings are the same ~
+ < 0 if s1 is less than s2 ~
+ > 0 if s1 is greater than s2
+
+See Also:
+ std_strncmp
+
+=======================================================================
+
+std_wstrcmp()
+
+Description:
+ The std_wstrcmp() compares two NUL-terminated strings. It is equivalent
+ to std_strncmp() except that it operates on wide (16-bit) character
+ strings. Comparison is strictly by byte values with no character set
+ interpretation.
+
+Prototype:
+
+ int std_wstrcmp(const AECHAR* s1, const AECHAR* s2);
+
+Parameters:
+ s1, s2: strings to compare
+
+Return Value:
+ 0 if strings are the same ~
+ < 0 if s1 is less than s2 ~
+ > 0 if s1 is greater than s2
+
+See Also:
+ std_strcmp
+
+=======================================================================
+
+std_wstrchr()
+
+Description:
+ This function is the wide string counterpart of std_strchr().
+ The std_wstrchr() finds the first occurrence of a character in a
+ NUL-terminated wide (16-bit) character string.
+
+Prototype:
+
+ AECHAR* std_wstrchr(const AECHAR* s, AECHAR ch);
+
+Parameters:
+ s: string to search
+ ch: char to search for
+
+Return Value:
+ pointer to first occurrence, NULL if not found
+
+See Also:
+ std_strchr
+
+=======================================================================
+
+std_wstrrchr()
+
+Description:
+ This function is the wide string counterpart of std_strrchr().
+ The std_wstrrchr() finds the last occurrence of a character in a
+ NUL-terminated wide (16-bit) character string.
+
+Prototype:
+
+ AECHAR* std_wstrrchr(const AECHAR* s, AECHAR ch);
+
+Parameters:
+ s: string to search
+ ch: char to search for
+
+Return Value:
+ pointer to last occurrence, NULL if not found
+
+See Also:
+ std_strrchr
+
+=======================================================================
+
+std_makepath()
+
+Description:
+ The std_makepath() constructs a path from a directory portion and a file
+ portion, using forward slashes, adding necessary slashes and deleting extra
+ slashes. This function guarantees NUL-termination of pszDest
+
+Prototype:
+
+ int std_makepath(const char *cpszDir, const char *cpszFile,
+ char *pszDest, int nDestSize)
+
+Parameters:
+ cpszDir: directory part
+ cpszFile: file part
+ pszDest: output buffer
+ nDestSize: size of output buffer in bytes
+
+Return Value:
+ the required length to construct the path, not including
+ NUL-termination
+
+Comments:
+ The following list of examples shows the strings returned by
+ std_makepath() for different paths.
+
+Example:
+
+ cpszDir cpszFile std_makepath()
+ "" "" ""
+ "" "/" ""
+ "/" "" "/"
+ "/" "/" "/"
+ "/" "f" "/f"
+ "/" "/f" "/f"
+ "d" "f" "d/f"
+ "d/" "f" "d/f"
+ "d" "/f" "d/f"
+ "d/" "/f" "d/f"
+
+See Also:
+ std_splitpath
+
+=======================================================================
+
+std_splitpath()
+
+Description:
+ The std_splitpath() finds the filename part of a path given an inclusive
+ directory, tests for cpszPath being in cpszDir. The forward slashes are
+ used as directory delimiters.
+
+Prototype:
+
+ char *std_splitpath(const char *cpszPath, const char *cpszDir);
+
+Parameters:
+ cpszPath: path to test for inclusion
+ cpszDir: directory that cpszPath might be in
+
+Return Value:
+ the part of cpszPath that actually falls beneath cpszDir, NULL if
+ cpszPath is not under cpszDir
+
+Comments:
+ The std_splitpath() is similar to std_strbegins(), but it ignores trailing
+ slashes on cpszDir, and it returns a pointer to the first character of
+ the subpath.
+
+ The return value of std_splitpath() will never begin with a '/'.
+
+ The following list of examples shows the strings returned by
+ std_splitpath() for different paths.
+
+Example:
+ cpszPath cpszDir std_splitpath()
+ "" "" ""
+ "" "/" ""
+ "/" "" ""
+ "/" "/" ""
+ "/d" "d" null
+ "/d" "/" "d"
+ "/d/" "/d" ""
+ "/d/f" "/" "d/f"
+ "/d/f" "/d" "f"
+ "/d/f" "/d/" "f"
+
+See Also:
+ std_makepath
+
+=======================================================================
+
+std_cleanpath()
+
+Description:
+ The std_cleanpath() removes double slashes, ".", and ".." from
+ slash-delimited paths,. It operates in-place.
+
+Prototype:
+
+ char *std_cleanpath(char *pszPath);
+
+Parameters:
+ pszPath[in/out]: path to "clean"
+
+Return Value:
+ pszPath
+
+Comments:
+ Passing an "fs:/" path to this function may produce undesirable
+ results. This function assumes '/' is the root.
+
+Examples:
+ pszPath std_cleanpath()
+ "", "",
+ "/", "/",
+
+ // here"s, mostly alone
+ "./", "/",
+ "/.", "/",
+ "/./", "/",
+
+ // "up"s, mostly alone
+ "..", "",
+ "/..", "/",
+ "../", "/",
+ "/../", "/",
+
+ // fun with x
+ "x/.", "x",
+ "x/./", "x/",
+ "x/..", "",
+ "/x/..", "/",
+ "x/../", "/",
+ "/x/../", "/",
+ "/x/../..", "/",
+ "x/../..", "",
+ "x/../../", "/",
+ "x/./../", "/",
+ "x/././", "x/",
+ "x/.././", "/",
+ "x/../.", "",
+ "x/./..", "",
+ "../x", "/x",
+ "../../x", "/x",
+ "/../x", "/x",
+ "./../x", "/x",
+
+ // double slashes
+ "//", "/",
+ "///", "/",
+ "////", "/",
+ "x//x", "x/x",
+
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+
+=======================================================================
+
+std_basename()
+
+Description:
+ The std_basename() returns the filename part of a string,
+ assuming '/' delimited filenames.
+
+Prototype:
+
+ char *std_basename(const char *cpszPath);
+
+Parameters:
+ cpszPath: path of interest
+
+Return Value:
+ pointer into cpszPath that denotes part of the string immediately
+ following the last '/'
+
+Examples:
+ cpszPath std_basename()
+ "" ""
+ "/" ""
+ "x" "x"
+ "/x" "x"
+ "y/x" "x"
+ "/y/x" "x"
+
+ See Also:
+ None
+
+=======================================================================
+
+std_rand_next()
+
+Description:
+ The std_rand_next() generates pseudo-random bytes.
+
+Prototype:
+
+ unsigned std_rand_next(unsigned uRand);
+
+Parameters:
+ uRand: a seed for the pseudo-random generator
+
+Return Value:
+ the next value in the generator from uRand
+
+Comments:
+ for best results, this function should be called with its last
+ generated output.
+
+ This is an example of code to generate 256 bytes of pseudo-random data.
+
+ This is not crypto quality and should not be used for key generation
+ and the like.
+
+Example:
+ {
+ unsigned rand_buf[256/sizeof(unsigned)];
+ int i;
+ unsigned uLast = std_rand_next(uCurrentTime);
+ for (i = 0; i < STD_ARRAY_SIZE(rand_buf); i++) {
+ rand_buf[i] = (uLast = std_rand_next(uLast));
+ }
+ }
+
+See Also:
+ std_rand()
+
+=======================================================================
+
+std_rand()
+
+Description:
+ The std_rand() functions generates pseudo-random bytes and places it
+ in an output buffer of specified size.
+
+Prototype:
+
+ uint32 std_rand(uint32 uSeed, byte* pDest, int nSize);
+
+Parameters:
+ uSeed: A seed for the pseudo-random generator
+ pDest: The output buffer where the random bytes are placed.
+ nSize: The size in bytes of pDest.
+
+Return Value:
+ The new seed value that can be used in a subsequent call to
+ std_rand().
+
+Comments:
+
+ std_rand() is a linear congruent psuedo-random number generator that
+ is seeded using the input seed. This makes the ouput predictable if
+ you can determine (or influence) the seed value used. Furthermore,
+ the random sequence of bytes generated by two different calls to this
+ function will be identical if both the calls use the same seed value.
+
+ This is not crypto quality and should not be used for key generation
+ and other cryptographic uses.
+
+See Also:
+ std_rand_next()
+
+=======================================================================
+
+std_CopyLE()
+
+Description:
+
+ The std_CopyLE() function copies data while translating numeric values
+ between host byte ordering and "little endian" byte ordering.
+
+ pvDest and pvSrc are NOT required to be 16 or 32-bit word aligned.
+
+ Behavior is undefined when the destination and source arrays overlap,
+ except in the special case where pvDest and pvSrc are equal. In that case,
+ std_CopyLE() modifies the buffer in-place.
+
+ When the target byte ordering (little endian) matches the host byte
+ ordering, in-place translations reduce to a no-op, and copies are
+ delegated directly to std_memmove().
+
+
+Prototype:
+ int std_CopyLE(void *pvDest, int nDestSize,
+ const void *pvSrc, int nSrcSize,
+ const char *pszFields);
+
+Parameters:
+ pvDest: Pointer to destination buffer.
+ nDestSize: Size of the destination buffer.
+ pvSrc: Pointer to buffer containing source data.
+ nSrcSize: Size of source data.
+ pszFields: Description of the fields that comprise the source data.
+
+ Each field size is given by a positive decimal integer or one of
+ the following characters: "S", "L", "Q", or "*". The letters
+ denote fields that should be converted to the desired byte
+ ordering:
+
+===pre>
+ S : a 2 byte (16 bit) value.
+ L : a 4 byte (32 bit) value.
+ Q : a 8 byte (64 bit) value.
+===/pre>
+
+ An integer gives a number of bytes and "*" represents the
+ remainder of the pvSrc[] buffer. No reordering is performed on
+ data in these fields.
+
+ Comparisons are case-sensitive. Behavior is undefined when
+ other characters are supplied in pszFields.
+
+ For example: "L12S*" would be appropriate to copy a structure
+ containing a uint32 followed by a 12 byte character array,
+ followed by a uint16, followed by an arbitrary amount of
+ character data.
+
+ If nSrcSize is greater than the structure size (total of all the
+ sizes in pszFields[]) then pvSrc[] is treated as an array of
+ structures, each of which is described by pszFields.
+
+Return Value:
+
+ The number of bytes actually copied or translated in-place. This will be
+ the smaller of nDestSize and nSrcSize, or zero if one of them are negative.
+
+
+=======================================================================
+
+std_CopyBE()
+
+Description:
+
+ The std_CopyBE() function has the same semantics as std_CopyLE() except it
+ copies between host byte ordering and big-endian ("network") byte order.
+
+ See std_CopyLE() for more details.
+
+
+Prototype:
+ void *std_CopyBE(void *pvDest, const void *pvSrc,
+ int cbDest, int nItems, const char *pszFields);
+
+Parameters:
+ pvDest: Pointer to destination buffer.
+ nDestSize: Size of the destination buffer.
+ pvSrc: Pointer to buffer containing source data.
+ nSrcSize: Size of source data.
+ pszFields: Description of the fields that comprise the source data,
+ as defined in std_CopyLE.
+
+Return Value:
+
+ The number of bytes actually copied or translated in-place. This will be
+ the smaller of nDestSize and nSrcSize, or zero if one of them are negative.
+
+=======================================================================
+
+std_swapl()
+
+Description:
+ The std_swapl() changes endianness of an unsigned long.
+
+Prototype:
+
+ unsigned long std_swapl(unsigned long ul)
+
+Parameters:
+ ul: input unsigned long
+
+Return Value:
+ ul, reversed in byte-ordering
+
+=======================================================================
+
+std_swaps()
+
+Description:
+ The std_swaps() changes endianness of an unsigned short.
+
+Prototype:
+
+ unsigned short std_swaps(unsigned short us)
+
+Parameters:
+ us: input unsigned short
+
+Return Value:
+ us, reversed in byte-ordering
+
+=======================================================================
+
+std_letohs()
+
+Description:
+ The std_letohs() changes a short from little-endian to host byte order.
+
+Prototype:
+
+ unsigned short std_letohs(unsigned short us)
+
+Parameters:
+ us: short to convert
+
+Return Value:
+ us converted from little-endian to host byte order. If the
+ host is little endian, just returns us
+
+=======================================================================
+
+std_htoles()
+
+Description:
+ The std_htoles() converts a short from host byte-order to little-endian.
+
+Prototype:
+
+ unsigned short std_htoles(unsigned short us)
+
+Parameters:
+ us: short to convert
+
+Return Value:
+ us converted from host byte order to little-endian. If the
+ host is little endian, just returns us
+
+=======================================================================
+
+std_letohl()
+
+Description:
+ The std_letohl() changes a long from little-endian to host byte order.
+
+Prototype:
+
+ unsigned long std_letohl(unsigned long ul)
+
+Parameters:
+ ul: long to convert
+
+Return Value:
+ ul converted from little-endian to host byte order. If the
+ host is little endian, just returns ul
+
+=======================================================================
+
+std_htolel()
+
+Description:
+ The std_htolel() converts a long from host byte-order to little-endian.
+
+Prototype:
+
+ unsigned long std_htolel(unsigned long ul)
+
+Parameters:
+ ul: long to convert
+
+Return Value:
+ ul converted from host byte order to little-endian. If the
+ host is little endian, just returns ul.
+
+
+=======================================================================
+
+std_ntohs()
+
+Description:
+ The std_ntohs() changes a short from big-endian to host byte order.
+
+Prototype:
+
+ unsigned short std_ntohs(unsigned short us)
+
+Parameters:
+ us: short to convert
+
+Return Value:
+ us converted from big-endian to host byte order. If the
+ host is big endian, just returns us.
+
+=======================================================================
+
+std_htons()
+
+Description:
+ The std_htons() converts a short from host byte-order to big-endian.
+
+Prototype:
+
+ unsigned short std_htons(unsigned short us)
+
+Parameters:
+ us: short to convert
+
+Return Value:
+ us converted from host byte order to big-endian. If the
+ host is big endian, just returns us.
+
+=======================================================================
+
+std_ntohl()
+
+Description:
+ The std_ntohl() changes a long from big-endian to host byte order.
+
+Prototype:
+
+ unsigned long std_ntohl(unsigned long ul)
+
+Parameters:
+ ul: long to convert
+
+Return Value:
+ ul converted from big-endian to host byte order. If the
+ host is big endian, just returns ul.
+
+=======================================================================
+
+std_htonl()
+
+Description:
+ The std_htonl() converts a long from host byte-order to big-endian.
+
+Prototype:
+
+ unsigned long std_htonl(unsigned long ul)
+
+Parameters:
+ ul: long to convert
+
+Return Value:
+ ul converted from host byte order to big-endian. If the
+ host is big endian, just returns ul.
+
+
+=======================================================================
+
+std_strlprintf()
+
+Description:
+
+ The functions std_strlprintf() and std_vstrlprintf() write formatted
+ output to a string. These functions guarantee NUL-termination of
+ the output buffer when its size is greater than zero.
+
+ A format string is copied to the output buffer, except for conversion
+ specifiers contained within the format string. Conversion specifiers
+ begin with a "%" and specify some action that consumes an argument from
+ the argument list.
+
+ Conversion specifiers have the following form:
+===pre>
+ %[FLAGS] [WIDTH] [.PRECISION] [TYPE] CONV
+===/pre>
+
+ CONV is the only required field. It is always a single character,
+ and determines the action to be taken. Supported values are:
+
+===pre>
+ CONV | Description
+ ======|=======================================================
+ c | Output a single character.
+ |
+ s | Output a NUL-terminated single-byte character string.
+ |
+ d, i | Ouptut a signed decimal integer.
+ |
+ u | Output an unsigned decimal integer.
+ |
+ o | Output an unsigned octal integer.
+ |
+ x | Output an unsigned hexadecimal integer, using
+ | lower case digits.
+ |
+ X | Output an unsigned hexadecimal integer, using
+ | upper case digits.
+ |
+ p | Output a pointer value as eight hexadecimal digits,
+ | using upper case digits.
+===/pre>
+
+ The next argument from the argument list supplies the value to be
+ formatted and output.
+
+ FLAGS, WIDTH, and PRECISION can modify the formatting of the value.
+
+ FLAGS consists of one or more of the following characters:
+
+===pre>
+ Flag | Meaning
+ =====|=================================================================
+ + | Prefix positive numbers with "+" (%d and %i only).
+ -----|-----------------------------------------------------------------
+ - | When padding to meet WIDTH, pad on the right.
+ -----|-----------------------------------------------------------------
+ 0 | Pad with '0' characters when padding on the left to meet WIDTH.
+ -----|-----------------------------------------------------------------
+ blank| Prefix positive numbers with " " (%d and %i only).
+ space|
+ -----|-----------------------------------------------------------------
+ # | With %x or %X: prefixes non-zero values with "0x"/"0X".
+ | With %o, ensure the value begins with "0" (increasing PRECISION
+ | if necessary).
+ | Ignored for all other CONV specifiers.
+ -----|-----------------------------------------------------------------
+===/pre>
+
+ WIDTH is an unsigned decimal integer or the character "*".
+
+ WIDTH gives the minimum number of characters to be written. The
+ formatted value will be padded with spaces until the minimum size is
+ met; it never causes a value to be truncated The sign of the WIDTH
+ integer selects between left and right padding. Padding will be on
+ the left unless the "-" flag is specified.
+
+ When "*" is used, an 'int' argument is consumed from the argument
+ list and used as the WIDTH. A negative argument specifies padding on
+ the right, and its absolute value gives the amount of padding.
+
+ If the "0" flags is specified, any padding on the left will consist
+ of "0" characters. An exception to this rule is that the "0" flag is
+ ignored when precision is specified for a numeric value.
+
+ PRECISION is a non-negative decimal integer or "*" preceded by ".".
+
+ When PRECISION accompanies any of the numeric conversions, it
+ specifies the minimum number of digits to output. Values are padded
+ on the left with '0' to meet the specified size. PRECISION defaults
+ to 1 for numbers.
+
+ When PRECISION accompanies other conversions, it specifies the
+ maximum number of characters from the value to output. The value
+ will be truncated to ensure that at most PRECISION characters are
+ output.
+
+ TYPE provides information about the type of arguments. This is used
+ to determine the size of integer arguments. Values larger than 'int'
+ can be properly obtained from the argument list. Their behavior
+ should be considered undefined for CONV operations other than integer
+ formatting.
+
+===pre>
+ TYPE | Meaning
+ =======|=====================
+ hh | sizeof(char)
+ -------|---------------------
+ h | sizeof(short)
+ -------|---------------------
+ l | sizeof(long)
+ -------|---------------------
+ L, ll | sizeof(long long)
+ -------|---------------------
+ j | sizeof(int64)
+ -------|---------------------
+ z | sizeof(size_t)
+ -------|---------------------
+===/pre>
+
+ For 64-bit integers, "ll" may be the most widely-supported type
+ specifier in other printf implementation, but "j" has been introduced
+ in ISO C99. This implementation supports both.
+
+ Note that arguments to variadic functions are promoted to 'int' when
+ smaller than 'int', so 'h' and 'hh' have no observable effect.
+ Static analysis tools that understand standard format string syntax
+ may use this information for other purposes.
+
+Prototype:
+
+ int std_strlprintf(char *pszDest, int nDestSize,
+ const char *pszFmt, ...);
+Parameters:
+ pszDest [out]: output buffer, where output will be placed
+ nDestSize: size of pszDest in bytes
+ pszFmt: format string
+
+Return Value:
+
+ The size required to hold the entire untruncated output, NOT
+ including NUL-termination.
+
+Comments:
+
+ Notable omissions from std_strlprintf() are lack of support for
+ floating point and lack of support for "%n".
+
+Side Effects:
+ None
+
+See Also:
+ None
+
+=======================================================================
+
+std_vstrlprintf()
+
+Description:
+
+ The std_vstrlprintf() is documented with std_strlprintf(), it's the
+ vector form of std_strlprintf(). See std_strlprintf() for a
+ more complete description.
+
+Prototype:
+ int std_vstrlprintf(char *pszDest, int nDestSize,
+ const char *pszFmt, AEEVaList args);
+
+Parameters:
+ pszDest [out]: output buffer, where output will be placed
+ nDestSize: size of pszDest in bytes
+ pszFmt: format string
+ args: arguments
+
+
+=======================================================================
+
+std_snprintf()
+
+Description:
+
+ The functions std_snprintf() and std_vsnprintf() are similar to
+ std_strlprintf and std_vstrlprintf that write formatted output to a
+ string. Unlike std_strlprintf, std_snprintf also support the floating
+ point conversion specifiers. These functions guarantee NUL-termination
+ of the output buffer when its size is greater than zero.
+
+ A format string is copied to the output buffer, except for conversion
+ specifiers contained within the format string. Conversion specifiers
+ begin with a "%" and specify some action that consumes an argument from
+ the argument list.
+
+ Conversion specifiers have the following form:
+===pre>
+ %[FLAGS] [WIDTH] [.PRECISION] [TYPE] CONV
+===/pre>
+
+ CONV is the only required field. It is always a single character,
+ and determines the action to be taken. For a detailed description of
+ conversion sepcifiers, please refer to the documentation of
+ std_strlprintf(). Here. we only provide description of these fields
+ as it applies to the additional CONV values supported by
+ std_snprintf().
+
+ In addition to the values for CONV supported by std_strlprintf, this
+ function supports the following values:
+
+===pre>
+ CONV | Description
+ ======|=======================================================
+ e, E | Outputs a double value representing a floating point
+ | number in the style [-]d.ddd edd, where there is one
+ | digit (which is nonzero if the argument is nonzero)
+ | before the decimal-point character and the number of
+ | digits after it is equal to the precision. If the
+ | precision is missing, it is taken as 6. If the precision
+ | is zero and the # flag is not specified, no decimal-point
+ | character appears. The value is rounded to the appropriate
+ | number of digits. The E conversion specifier produces a
+ | number with E instead of e introducing the exponent. The
+ | exponent always contains at least two digits, and only as
+ | many more digits as necessary to represent the exponent.
+ | If the value is zero, the exponent is zero.
+ |
+ f, F | Outputs a double value representing a floating point
+ | number in the style [-]ddd.ddd, where the number of
+ | digits after the decimal-point character is equal to the
+ | precision specification. If the precision is missing, it
+ | is taken as 6. If the precision is zero and the # flag is
+ | not specified, no decimal-point character appears. If a
+ | decimal-point character appears, at least one digit
+ | appears before it. The value is rounded to the appropriate
+ | number of digits.
+ |
+ g, G | Outputs a double value representing a floating point
+ | number in the style f or e (or in style F or E in the case
+ | of a G conversion specifier), with the precision specifying
+ | the number of significant digits. If the precision is zero,
+ | it is taken as 1. The style used depends on the value
+ | converted. Style e (or E) is used only if the exponent
+ | resulting from such a conversion is less than -4 or greater
+ | than or equal to the precision. Trailing zeros are removed
+ | from the fractional portion of the result unless the # flag
+ | is specified; a decimal-point character appears only if it
+ | is followed by a digit.
+ |
+ a, A | Outputs a double value representing a floating point
+ | number in the style [-]0xh.hhhh pd, where there is one
+ | non-zero hexadecimal digit before the decimal-point
+ | character and the number of hexadecimal digits after it is
+ | equal to the precision. If the precision is missing then
+ | the precision is assumed to be sufficient for an exact
+ | representation of the value, except that trailing zeros
+ | may be omitted. If the precision is zero and the # flag is
+ | not specified, no decimal point character appears. The
+ | letters 'abcdef' are used for '%a' conversion and the
+ | letters ABCDEF for '%A' conversion. The '%A' conversion
+ | specifier produces a number with 'X' and 'P' instead of 'x'
+ | and 'p'. The exponent always contains at least one digit,
+ | and only as many more digits as necessary to represent the
+ | decimal exponent of 2. If the value is zero, the exponent
+ | is zero.
+ |
+===/pre>
+
+ For 'e', 'f', 'g' and 'a' convervsion specifiers, a double argument
+ representing an infinity is converted in to the style '[-]inf' and
+ a double argument representing a NaN is converted in to the stlye
+ 'nan'. The 'E', 'F', 'G' and 'A' conversion specifiers result in
+ 'INF' or 'NAN' instead of 'inf' or 'nan', respectively.
+
+Prototype:
+
+ int std_snprintf(char *pszDest, int nDestSize,
+ const char *pszFmt, ...);
+Parameters:
+ pszDest [out]: output buffer, where output will be placed
+ nDestSize: size of pszDest in bytes
+ pszFmt: format string
+
+Return Value:
+
+ The size required to hold the entire untruncated output, NOT
+ including NUL-termination.
+
+Comments:
+
+ Notable omissions from std_strlprintf() lack of support for "%n".
+
+Side Effects:
+ None
+
+See Also:
+ std_strlprintf()
+
+=======================================================================
+
+std_vsnprintf()
+
+Description:
+
+ The std_vsnprintf() is documented with std_snprintf(), it's the
+ vector form of std_snprintf(). See std_snprintf() for a more complete
+ description.
+
+Prototype:
+ int std_vsnprintf(char *pszDest, int nDestSize,
+ const char *pszFmt, AEEVaList args);
+
+Parameters:
+ pszDest [out]: output buffer, where output will be placed
+ nDestSize: size of pszDest in bytes
+ pszFmt: format string
+ args: arguments
+
+
+=======================================================================
+
+std_scanul()
+
+Description:
+
+ The std_scanul() converts an ASCII representation of a number to an unsigned
+ long. It expects strings that match the following pattern:
+===pre>
+ spaces [+|-] digits
+===/pre>
+
+ 'Spaces' is zero or more ASCII space or tab characters.
+
+ 'Digits' is any number of digits valid in the radix. Letters 'A' through
+ 'Z' are treated as digits with values 10 through 35. 'Digits' may begin
+ with "0x" when a radix of 0 or 16 is specified.
+
+ Upper and lower case letters can be used interchangeably.
+
+
+Prototype:
+
+ uint32 std_scanul( const char *pchBuf, int nRadix, const char **ppchEnd,
+ int *pnError)
+
+Parameters:
+
+ pchBuf [in] : the start of the string to scan.
+
+ nRadix [in] : the numeric radix (or base) of the number. Valid values are
+ 2 through 36 or zero, which implies auto-detection.
+ Auto-detection examines the digits field. If it begins with
+ "0x", radix 16 is selected. Otherwise, if it begins with
+ "0" radix 8 is selected. Otherwise, radix 10 is selected.
+
+ ppchEnd [out] : if ppchEnd is not NULL, *ppchEnd points to the first
+ character that did not match the expected pattern shown
+ above, except on STD_BADPARAM and STD_OVERFLOW when it is
+ set to the start of the string.
+
+ pnError [out] : If pnError is not NULL, *pnError holds the error code,
+ which is one of the following:
+~
+ 0 : Numeric value is from 0 to MAX_UINT32.
+
+ STD_NEGATIVE : The scanned value was negative and its absolute value was
+ from 1 to MAX_UINT32. The result is the negated value
+ (cast to a uint32).
+
+ STD_NODIGITS : No digits were found. The result is zero.
+
+ STD_OVERFLOW : The absolute value exceeded MAX_UINT32. The result
+ is set to MAX_UINT32 and *ppchEnd is set to pchBuf.
+
+ STD_BADPARAM : An improper value for nRadix was received. The result
+ is set to zero, and *ppchEnd is set to pchBuf.
+*
+
+Return Value:
+
+ The converted numeric result.
+
+Comments:
+
+ The std_scanul() is similar to ANSI C's strtoul() but differs in the following
+ respects:
+
+ 1. It returns an error/success code. strtoul() results are ambiguous
+ unless the caller sets errno to zero before calling it.
+
+ 2. std_scanul() is free of references to current locale and errno. Some
+ strtoul() implementations use locale; some don't.
+
+ 3. It provides more complete reporting of range underflow. strtoul()
+ does not distinguish between "-1" and "0xFFFFFFFF", and underflow is
+ poorly defined.
+
+ 4. std_scanul() reports a "no digits" error code to distinguish "0" from
+ whitespace, "+", etc..
+
+See Also:
+
+ std_scanull()
+
+=======================================================================
+
+std_scanull()
+
+Description:
+
+ The std_scanull() converts an ASCII representation of a number to an
+ unsigned long long. It expects strings that match the following pattern:
+===pre>
+ spaces [+|-] digits
+===/pre>
+
+ 'Spaces' is zero or more ASCII space or tab characters.
+
+ 'Digits' is any number of digits valid in the radix. Letters 'A' through
+ 'Z' are treated as digits with values 10 through 35. 'Digits' may begin
+ with "0x" when a radix of 0 or 16 is specified.
+
+ Upper and lower case letters can be used interchangeably.
+
+
+Prototype:
+
+ uint64 std_scanull(const char *pchBuf, int nRadix, const char **ppchEnd,
+ int *pnError)
+
+Parameters:
+
+ pchBuf [in] : the start of the string to scan.
+
+ nRadix [in] : the numeric radix (or base) of the number. Valid values are
+ 2 through 36 or zero, which implies auto-detection.
+ Auto-detection examines the digits field. If it begins with
+ "0x", radix 16 is selected. Otherwise, if it begins with
+ "0" radix 8 is selected. Otherwise, radix 10 is selected.
+
+ ppchEnd [out] : if ppchEnd is not NULL, *ppchEnd points to the first
+ character that did not match the expected pattern shown
+ above, except on STD_BADPARAM and STD_OVERFLOW when it is
+ set to the start of the string.
+
+ pnError [out] : If pnError is not NULL, *pnError holds the error code,
+ which is one of the following:
+~
+ 0 : Numeric value is from 0 to MAX_UINT64.
+
+ STD_NEGATIVE : The scanned value was negative and its absolute value was
+ from 1 to MAX_UINT64. The result is the negated value
+ (cast to a uint64).
+
+ STD_NODIGITS : No digits were found. The result is zero.
+
+ STD_OVERFLOW : The absolute value exceeded MAX_UINT64. The result
+ is set to MAX_UINT64 and *ppchEnd is set to pchBuf.
+
+ STD_BADPARAM : An improper value for nRadix was received. The result
+ is set to zero, and *ppchEnd is set to pchBuf.
+*
+
+Return Value:
+
+ The converted numeric result.
+
+Comments:
+
+ The std_scanull() is similar to ANSI C's strtoull() but differs in the following
+ respects:
+
+ 1. It returns an error/success code. strtoull() results are ambiguous
+ unless the caller sets errno to zero before calling it.
+
+ 2. std_scanull() is free of references to current locale and errno. Some
+ strtoull() implementations use locale; some don't.
+
+ 3. It provides more complete reporting of range underflow. strtoul()
+ does not distinguish between "-1" and "0xFFFFFFFFFFFFFFFF", and underflow
+ is poorly defined.
+
+ 4. std_scanull() reports a "no digits" error code to distinguish "0" from
+ whitespace, "+", etc..
+
+See Also:
+
+ std_scanul()
+
+=======================================================================
+
+std_qsort()
+
+Description:
+
+ An implementation of the quicksort algorithm, a massively recursive,
+ in-place sorting algorithm for an array.
+
+ The contents of the array are sorted in ascending order according to
+ the comparison function pointed to by pfnCompare.
+
+ pfnCompare must return a value less than, equal to, or
+ greater than zero if the first argument is considered to be
+ less than, equal to, or greater than the second, respectively.
+
+ std_qsort() is not a stable sort.
+
+Prototype:
+ void std_qsort(void* pElems, int nNumElems, int nElemWidth,
+ int (*pfnCompare)(void*, const void*, const void*),
+ void* pCompareCx);
+
+
+Parameters:
+ pElems: array of elements to be sorted in place. It's size
+ must be nNumElems * nElemWidth in bytes.
+ nNumElems: number of elements in pElems
+ nElemWidth: the width, in bytes of each element of pElems
+ pfnCompare: callback comparison function, should return 0, less than
+ zero or greater than zero if the left comparand is equal to, less
+ than, or greater than, the right comparand, respectively.
+ pCompareCx: the context passed as the first parameter by pfnCompare
+
+Return Value:
+ None
+
+Comments:
+ If nElemWidth is 2, 4, or 8, pElems is accessed internally as
+ integer values for the purposes of reading and writing elements.
+ Therefore, pElems must be aligned on a memory boundary compatible
+ with integer access of the array elements. I.e. if you pass 4 as
+ nElemWidth, *(int*)pElems must succeed.
+
+=======================================================================
+
+std_bisect()
+
+Description:
+
+ Find an element in a sorted array of elements. Uses a binary
+ search.
+
+Prototype:
+ int std_bisect(const void* pElems, int nNumElems, int nElemWidth,
+ const void* pElemFind,
+ int (*pfnCompare)(void*, const void*, const void*),
+ void* pCompareCx);
+
+Parameters:
+ pElems: array of elements to be searched. It's size
+ must be nNumElems * nElemWidth in bytes.
+ nNumElems: number of elements in pElems
+ nElemWidth: the width, in bytes of each element of pElems
+ pElemFind: the element value to find in the array
+ pfnCompare: callback comparison function, should return 0, less than
+ zero or greater than zero if the left comparand is equal to, less
+ than, or greater than, the right comparand, respectively.
+ pCompareCx: the context passed as the first parameter by pfnCompare
+
+Return Value:
+ index of the element such that pElems[index] <= elem < pElems[index + 1]
+ nNumElems if elem is greater than all the elements in the list
+ 0 if the elem is less than or equal to the all the elements in the list
+
+=======================================================================
+
+std_merge()
+
+Description:
+
+ Merge two sorted arrays into another array.
+
+Prototype:
+ void std_merge(void* vpDst, int nDst,
+ const void* vpA, int nA,
+ const void* vpB, int nB,
+ int nElemWidth,
+ int (*pfnCompare)(void*, const void*, const void*),
+ void* pCompareCx);
+
+Parameters:
+ vpDst: destination array. It's size must be nDst * nElemWidth in bytes.
+ nDst: number of elements that vpDst can accomodate
+ vpA: array of elements to be merged, it's size must be nA * nElemWidth
+ in bytes.
+ nA: number of elements in vpA
+ vpB: array of elements to be merged, it's size must be nB * nElemWidth
+ in bytes.
+ nB: number of elements in vpB
+ nElemWidth: the width, in bytes of each element of pElems
+ pfnCompare: callback comparison function, should return 0, less than
+ zero or greater than zero if the left comparand is equal to, less
+ than, or greater than, the right comparand, respectively.
+ pCompareCx: the context passed as the first parameter by pfnCompare
+
+Return Value:
+ none
+
+=======================================================================
+
+std_uniq()
+
+Description:
+ Removes duplicate entries from a sorted array.
+
+Prototype:
+ int std_uniq(void* vpElems, int nNumElems, int nElemWidth,
+ int (*pfnCompare)(void*, const void*, const void*),
+ void* pCompareCx);
+
+Parameters:
+ pElems: array of elements to be searched. It's size
+ must be nNumElems * nElemWidth in bytes.
+ nNumElems: number of elements in pElems
+ nElemWidth: the width, in bytes of each element of pElems
+ pfnCompare: callback comparison function, should return 0, less than
+ zero or greater than zero if the left comparand is equal to, less
+ than, or greater than, the right comparand, respectively.
+ pCompareCx: the context passed as the first parameter by pfnCompare
+
+Return Value:
+ the number of uniq elements left in vpElems
+
+=======================================================================
+
+std_scand()
+
+Description:
+
+ The std_scand() converts the initial portion of an input ASCII string
+ to it's corresponding floating point value. It expects the input
+ string to match the following pattern:
+===pre>
+ <Spaces><Subject String><Rest Of The String>
+===/pre>
+
+ 'Spaces' - is zero or more ASCII space or tab characters.
+ 'Subject String' - is the part of the input string that represents a
+ valid floating point constant.
+ 'Rest Of The String' - is the remaining sequence of one or more
+ characters including the terminating null
+ character of the input string.
+
+ A valid subject string can be one of the following:
+ -- <NAN>, ignoring case. This is interpreted as a quiet NAN.
+ -- [+|-]<INF|INFINITY>, ignoring case. This is interpreted as an
+ infinity.
+ -- [+|-]<Valid Floating Point Number>
+
+ In general, a valid floating poing number can either be a decimal
+ number or an hexadecimal number, and has the following form:
+ <Integral Part>[.[<Fractional Part>]][<Exponent>]
+ where the intergral, fractional and the exponent part may consist of
+ sequence of valid decimal or hexadecimal digits. More specifically:
+
+ For a decimal floating point number:
+ 'Integral Part' - <Decimal Digits>
+ 'Fractional Part' - <Decimal Digits>
+ 'Exponent' - <e|E><Decimal Digits>
+ For a hexadecimal floating point number:
+ 'Integral Part' - <Hexadecimal Digits>
+ 'Fractional Part' - <Hexadecimal Digits>
+ 'Exponent' - <p|P><Decimal Digits>
+
+ where:
+ 'Decimal Digits' - is any number of digits in the range [0,10].
+ 'Hexadecimal Digits' - is any number of digits in the range [0,10]
+ or the alphabets A through F.
+ 'e','E','p','P' - represent the exponent characters
+
+Prototype:
+
+ double std_scand(const char *pchBuf, const char **ppchEnd);
+
+Parameters:
+
+ pchBuf [in] : the start of the string to scan.
+
+ ppchEnd [out] : if ppchEnd is not NULL, *ppchEnd points to the first
+ character after the parsed number.
+
+Return Value:
+
+ This function returns the converted numeric result. If the string
+ does not contain a valid floating point number then the function
+ returns zero. If the converted value is outside the range of
+ representable values (overflow), [-]INFINITY is
+ returned. In case of an underflow, the function returns zero.
+
+=======================================================================*/
+
+#endif // AEESTD_H
+
+
diff --git a/inc/adsp_current_process.h b/inc/adsp_current_process.h
new file mode 100644
index 0000000..7be2948
--- /dev/null
+++ b/inc/adsp_current_process.h
@@ -0,0 +1,76 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _ADSP_CURRENT_PROCESS_H
+#define _ADSP_CURRENT_PROCESS_H
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if !defined(__QAIC_STRING1_OBJECT_DEFINED__) && !defined(__STRING1_OBJECT__)
+#define __QAIC_STRING1_OBJECT_DEFINED__
+#define __STRING1_OBJECT__
+typedef struct _cstring1_s
+{
+ char *data;
+ int dataLen;
+} _cstring1_t;
+
+#endif /* __QAIC_STRING1_OBJECT_DEFINED__ */
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_current_process_exit)(void) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_current_process_thread_exit)(void) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_current_process_set_logging_params)(unsigned short mask, const _cstring1_t *filesToLog, int filesToLogLen) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_current_process_getASID)(unsigned int *asid) __QAIC_HEADER_ATTRIBUTE;
+#ifdef __cplusplus
+}
+#endif
+#endif //_ADSP_CURRENT_PROCESS_H
diff --git a/inc/adsp_default_listener.h b/inc/adsp_default_listener.h
new file mode 100644
index 0000000..e9351e5
--- /dev/null
+++ b/inc/adsp_default_listener.h
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _ADSP_DEFAULT_LISTENER_H
+#define _ADSP_DEFAULT_LISTENER_H
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+#ifdef __cplusplus
+extern "C" {
+#endif
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_default_listener_register)(void) __QAIC_HEADER_ATTRIBUTE;
+#ifdef __cplusplus
+}
+#endif
+#endif //_ADSP_DEFAULT_LISTENER_H
diff --git a/inc/adsp_listener.h b/inc/adsp_listener.h
new file mode 100644
index 0000000..a307400
--- /dev/null
+++ b/inc/adsp_listener.h
@@ -0,0 +1,79 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _ADSP_LISTENER_H
+#define _ADSP_LISTENER_H
+#include "AEEStdDef.h"
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define _const_adsp_listener_handle 3
+typedef struct _adsp_listener_buffer__seq_uint8 _adsp_listener_buffer__seq_uint8;
+typedef _adsp_listener_buffer__seq_uint8 adsp_listener_buffer;
+struct _adsp_listener_buffer__seq_uint8
+{
+ uint8 *data;
+ int dataLen;
+};
+typedef uint32 adsp_listener_remote_handle;
+typedef uint32 adsp_listener_invoke_ctx;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_listener_next_invoke)(adsp_listener_invoke_ctx prevCtx, int prevResult, const adsp_listener_buffer *outBufs, int outBufsLen, adsp_listener_invoke_ctx *ctx, adsp_listener_remote_handle *handle, uint32 *sc, adsp_listener_buffer *inBuffers, int inBuffersLen, int *inBufLenReq, int inBufLenReqLen, int *routBufLenReq, int routBufLenReqLen) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_listener_invoke_get_in_bufs)(adsp_listener_invoke_ctx ctx, adsp_listener_buffer *inBuffers, int inBuffersLen) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_listener_init)(void) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_listener_init2)(void) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_listener_next2)(adsp_listener_invoke_ctx prevCtx, int prevResult, const uint8 *prevbufs, int prevbufsLen, adsp_listener_invoke_ctx *ctx, adsp_listener_remote_handle *handle, uint32 *sc, uint8 *bufs, int bufsLen, int *bufsLenReq) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(adsp_listener_get_in_bufs2)(adsp_listener_invoke_ctx ctx, int offset, uint8 *bufs, int bufsLen, int *bufsLenReq) __QAIC_HEADER_ATTRIBUTE;
+#ifdef __cplusplus
+}
+#endif
+#endif //_ADSP_LISTENER_H
diff --git a/inc/apps_mem.h b/inc/apps_mem.h
new file mode 100644
index 0000000..f92a754
--- /dev/null
+++ b/inc/apps_mem.h
@@ -0,0 +1,67 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _APPS_MEM_H
+#define _APPS_MEM_H
+#include "AEEStdDef.h"
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+#ifdef __cplusplus
+extern "C" {
+#endif
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_request_map)(int heapid, uint32 ion_flags, uint32 rflags, uint32 vin, int32 len, uint32 *vapps, uint32 *vadsp) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_request_unmap)(uint32 vadsp, int32 len) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_request_map64)(int heapid, uint32 ion_flags, uint32 rflags, uint64 vin, int64 len, uint64 *vapps, uint64 *vadsp) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_mem_request_unmap64)(uint64 vadsp, int64 len) __QAIC_HEADER_ATTRIBUTE;
+#ifdef __cplusplus
+}
+#endif
+#endif //_APPS_MEM_H
diff --git a/inc/apps_remotectl.h b/inc/apps_remotectl.h
new file mode 100644
index 0000000..41539e2
--- /dev/null
+++ b/inc/apps_remotectl.h
@@ -0,0 +1,75 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _APPS_REMOTECTL_H
+#define _APPS_REMOTECTL_H
+#include "AEEStdDef.h"
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if !defined(__QAIC_STRING1_OBJECT_DEFINED__) && !defined(__STRING1_OBJECT__)
+#define __QAIC_STRING1_OBJECT_DEFINED__
+#define __STRING1_OBJECT__
+typedef struct _cstring1_s
+{
+ char *data;
+ int dataLen;
+} _cstring1_t;
+
+#endif /* __QAIC_STRING1_OBJECT_DEFINED__ */
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_remotectl_open)(const char *name, int *handle, char *dlerror, int dlerrorLen, int *nErr) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_remotectl_close)(int handle, char *dlerror, int dlerrorLen, int *nErr) __QAIC_HEADER_ATTRIBUTE;
+#ifdef __cplusplus
+}
+#endif
+#endif //_APPS_REMOTECTL_H
diff --git a/inc/apps_std.h b/inc/apps_std.h
new file mode 100644
index 0000000..72a68f6
--- /dev/null
+++ b/inc/apps_std.h
@@ -0,0 +1,170 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _APPS_STD_H
+#define _APPS_STD_H
+#include "AEEStdDef.h"
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if !defined(__QAIC_STRING1_OBJECT_DEFINED__) && !defined(__STRING1_OBJECT__)
+#define __QAIC_STRING1_OBJECT_DEFINED__
+#define __STRING1_OBJECT__
+typedef struct _cstring1_s
+{
+ char *data;
+ int dataLen;
+} _cstring1_t;
+
+#endif /* __QAIC_STRING1_OBJECT_DEFINED__ */
+/**
+ * standard library functions remoted from the apps to the dsp
+ */
+typedef int apps_std_FILE;
+enum apps_std_SEEK
+{
+ APPS_STD_SEEK_SET,
+ APPS_STD_SEEK_CUR,
+ APPS_STD_SEEK_END,
+ _32BIT_PLACEHOLDER_apps_std_SEEK = 0x7fffffff
+};
+typedef enum apps_std_SEEK apps_std_SEEK;
+/**
+ * @retval, if operation fails errno is returned
+ */
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fopen)(const char *name, const char *mode, apps_std_FILE *psout) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_freopen)(apps_std_FILE sin, const char *name, const char *mode, apps_std_FILE *psout) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fflush)(apps_std_FILE sin) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fclose)(apps_std_FILE sin) __QAIC_HEADER_ATTRIBUTE;
+/**
+ * @param, bEOF, if read or write bytes <= bufLen bytes then feof() is called
+ * and the result is returned in bEOF, otherwise bEOF is set to 0.
+ * @retval, if read or write return 0 for non zero length buffers, ferror is checked
+ * and a non zero value is returned in case of error with no rout parameters
+ */
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fread)(apps_std_FILE sin, byte *buf, int bufLen, int *bytesRead, int *bEOF) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fwrite)(apps_std_FILE sin, const byte *buf, int bufLen, int *bytesWritten, int *bEOF) __QAIC_HEADER_ATTRIBUTE;
+/**
+ * @param, pos, this buffer is filled up to MIN(posLen, sizeof(fpos_t))
+ * @param, posLenReq, returns sizeof(fpos_t)
+ * @retval, if operation fails errno is returned
+ */
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fgetpos)(apps_std_FILE sin, byte *pos, int posLen, int *posLenReq) __QAIC_HEADER_ATTRIBUTE;
+/**
+ * @param, if size of pos doesn't match the system size an error is returned.
+ * fgetpos can be used to query the size of fpos_t
+ * @retval, if operation fails errno is returned
+ */
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fsetpos)(apps_std_FILE sin, const byte *pos, int posLen) __QAIC_HEADER_ATTRIBUTE;
+/**
+ * @retval, if operation fails errno is returned
+ */
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_ftell)(apps_std_FILE sin, int *pos) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fseek)(apps_std_FILE sin, int offset, apps_std_SEEK whence) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_flen)(apps_std_FILE sin, uint64 *len) __QAIC_HEADER_ATTRIBUTE;
+/**
+ * @retval, only fails if transport fails
+ */
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_rewind)(apps_std_FILE sin) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_feof)(apps_std_FILE sin, int *bEOF) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_ferror)(apps_std_FILE sin, int *err) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_clearerr)(apps_std_FILE sin) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_print_string)(const char *str) __QAIC_HEADER_ATTRIBUTE;
+/**
+ * @param val, must contain space for NULL
+ * @param valLenReq, length required with NULL
+ * @retval, if fails errno is returned
+ */
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_getenv)(const char *name, char *val, int valLen, int *valLenReq) __QAIC_HEADER_ATTRIBUTE;
+/**
+ * @retval, if fails errno is returned
+ */
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_setenv)(const char *name, const char *val, int override) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_unsetenv)(const char *name) __QAIC_HEADER_ATTRIBUTE;
+/**
+ * This function will try to open a file given directories in envvarname separated by
+ * delim.
+ * so given environment variable FOO_PATH=/foo;/bar
+ * fopen_wth_env("FOO_PATH", ";", "path/to/file", "rw", &out);
+ * will try to open /foo/path/to/file, /bar/path/to/file
+ * if the variable is unset, it will open the file directly
+ *
+ * @param envvarname, name of the environment variable containing the path
+ * @param delim, delimiator string, such as ";"
+ * @param name, name of the file
+ * @param mode, mode
+ * @param psout, output handle
+ * @retval, 0 on success errno or -1 on failure
+ */
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fopen_with_env)(const char *envvarname, const char *delim, const char *name, const char *mode, apps_std_FILE *psout) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fgets)(apps_std_FILE sin, byte *buf, int bufLen, int *bEOF) __QAIC_HEADER_ATTRIBUTE;
+/**
+ * This method will return the paths that are searched when looking for a file.
+ * The paths are defined by the environment variable (separated by delimiters)
+ * that is passed to the method.
+ *
+ * @param envvarname, name of the environment variable containing the path
+ * @param delim, delimiator string, such as ";"
+ * @param name, name of the file
+ * @param paths, Search paths
+ * @param numPaths, Actual number of paths found
+ * @param maxPathLen, The max path length
+ * @retval, 0 on success errno or -1 on failure
+ *
+ */
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_get_search_paths_with_env)(const char *envvarname, const char *delim, _cstring1_t *paths, int pathsLen, uint32 *numPaths, uint16 *maxPathLen) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fileExists)(const char *path, boolean *exists) __QAIC_HEADER_ATTRIBUTE;
+#ifdef __cplusplus
+}
+#endif
+#endif //_APPS_STD_H
diff --git a/inc/fastrpc_apps_user.h b/inc/fastrpc_apps_user.h
new file mode 100644
index 0000000..31b4a1b
--- /dev/null
+++ b/inc/fastrpc_apps_user.h
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef FASTRPC_APPS_USER_H
+#define FASTRPC_APPS_USER_H
+
+#include <assert.h>
+#include <fcntl.h>
+#include <asm/ioctl.h>
+#include <errno.h>
+#endif //FASTRPC_APPS_USER_H
diff --git a/inc/fastrpc_internal.h b/inc/fastrpc_internal.h
new file mode 100644
index 0000000..0e42595
--- /dev/null
+++ b/inc/fastrpc_internal.h
@@ -0,0 +1,312 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef FASTRPC_INTERNAL_H
+#define FASTRPC_INTERNAL_H
+
+#include "remote64.h"
+#include "verify.h"
+#include "AEEstd.h"
+#include <linux/types.h>
+
+#define FASTRPC_IOCTL_ALLOC_DMA_BUFF _IOWR('R', 1, struct fastrpc_alloc_dma_buf)
+#define FASTRPC_IOCTL_FREE_DMA_BUFF _IOWR('R', 2, uint32_t)
+#define FASTRPC_IOCTL_INVOKE _IOWR('R', 3, struct fastrpc_invoke)
+#define FASTRPC_IOCTL_INIT_ATTACH _IO('R', 4)
+#define FASTRPC_IOCTL_INIT_CREATE _IOWR('R', 5, struct fastrpc_init_create)
+#define FASTRPC_IOCTL_MMAP _IOWR('R', 6, struct fastrpc_ioctl_mmap)
+#define FASTRPC_IOCTL_MUNMAP _IOWR('R', 7, struct fastrpc_ioctl_munmap)
+#define FASTRPC_IOCTL_SETMODE _IOWR('R', 8, uint32)
+
+#if !(defined __qdsp6__) && !(defined __hexagon__)
+static __inline uint32 Q6_R_cl0_R(uint32 num)
+{
+ int ii;
+ for (ii = 31; ii >= 0; --ii)
+ {
+ if (num & (1 << ii))
+ {
+ return 31 - ii;
+ }
+ }
+ return 0;
+}
+#else
+#include "hexagon_protos.h"
+#include <types.h>
+#endif
+
+struct fastrpc_invoke_args {
+ __u64 ptr;
+ __u64 length;
+ __s32 fd;
+ __u32 reserved;
+};
+
+struct fastrpc_invoke {
+ __u32 handle;
+ __u32 sc;
+ __u64 args;
+};
+
+struct fastrpc_init_create {
+ __u32 filelen; /* elf file length */
+ __s32 filefd; /* fd for the file */
+ __u32 attrs;
+ __u32 siglen;
+ __u64 file; /* pointer to elf file */
+};
+
+struct fastrpc_alloc_dma_buf {
+ __s32 fd; /* fd */
+ __u32 flags; /* flags to map with */
+ __u64 size; /* size */
+};
+
+struct fastrpc_ioctl_munmap
+{
+ uintptr_t vaddrout; /* optional virtual address, if non zero, dsp will use vaaddrin */
+ ssize_t size; /* size */
+};
+
+struct fastrpc_ioctl_mmap
+{
+ int fd; /* ion handle */
+ uint32 flags; /* flags to map with */
+ uintptr_t vaddrin; /* virtual address */
+ ssize_t size; /* size */
+ uintptr_t vaddrout; /* dsps virtual address */
+};
+
+#define FASTRPC_SMD_GUID "fastrpcsmd-apps-dsp"
+
+struct smq_null_invoke32
+{
+ uint32_t ctx; //! invoke caller context
+ remote_handle handle; //! handle to invoke
+ uint32_t sc; //! scalars structure describing the rest of the data
+};
+
+struct smq_null_invoke
+{
+ uint64_t ctx; //! invoke caller context
+ remote_handle handle; //! handle to invoke
+ uint32_t sc; //! scalars structure describing the rest of the data
+};
+
+typedef uint32_t smq_invoke_buf_phy_addr;
+
+struct smq_phy_page
+{
+ uint64_t addr; //! physical address
+ int64_t size; //! size
+};
+
+struct smq_phy_page32
+{
+ uint32_t addr; //! physical address
+ uint32_t size; //! size
+};
+
+struct smq_invoke_buf
+{
+ int num;
+ int pgidx;
+};
+
+struct smq_invoke32
+{
+ struct smq_null_invoke32 header;
+ struct smq_phy_page32 page; //! remote arg and list of pages address
+};
+
+struct smq_invoke
+{
+ struct smq_null_invoke header;
+ struct smq_phy_page page; //! remote arg and list of pages address
+};
+
+struct smq_msg32
+{
+ uint32_t pid;
+ uint32_t tid;
+ struct smq_invoke32 invoke;
+};
+
+struct smq_msg
+{
+ uint32_t pid;
+ uint32_t tid;
+ struct smq_invoke invoke;
+};
+
+struct smq_msg_u
+{
+ union
+ {
+ struct smq_msg32 msg32;
+ struct smq_msg msg64;
+ } msg;
+ int size;
+};
+
+struct smq_invoke_rsp32
+{
+ uint32_t ctx; //! invoke caller context
+ int nRetVal; //! invoke return value
+};
+
+struct smq_invoke_rsp
+{
+ uint64_t ctx; //! invoke caller context
+ int nRetVal; //! invoke return value
+};
+
+struct smq_invoke_rsp_u
+{
+ union
+ {
+ struct smq_invoke_rsp32 rsp32;
+ struct smq_invoke_rsp rsp64;
+ } rsp;
+ int size;
+};
+
+static __inline void to_smq_msg(uint32 mode, struct smq_msg_u *msg, struct smq_msg *msg64)
+{
+ if (0 == mode)
+ {
+ msg64->pid = msg->msg.msg32.pid;
+ msg64->tid = msg->msg.msg32.tid;
+ msg64->invoke.header.ctx = msg->msg.msg32.invoke.header.ctx;
+ msg64->invoke.header.handle = msg->msg.msg32.invoke.header.handle;
+ msg64->invoke.header.sc = msg->msg.msg32.invoke.header.sc;
+ msg64->invoke.page.addr = msg->msg.msg32.invoke.page.addr;
+ msg64->invoke.page.size = msg->msg.msg32.invoke.page.size;
+ }
+ else
+ {
+ std_memmove(msg64, &msg->msg.msg64, sizeof(*msg64));
+ }
+}
+
+static __inline void to_smq_invoke_rsp(uint32 mode, uint64 ctx, int nRetVal, struct smq_invoke_rsp_u *rsp)
+{
+ if (0 == mode)
+ {
+ rsp->rsp.rsp32.ctx = (uint32)ctx;
+ rsp->rsp.rsp32.nRetVal = nRetVal;
+ rsp->size = sizeof(rsp->rsp.rsp32);
+ }
+ else
+ {
+ rsp->rsp.rsp64.ctx = ctx;
+ rsp->rsp.rsp64.nRetVal = nRetVal;
+ rsp->size = sizeof(rsp->rsp.rsp64);
+ }
+}
+
+static __inline struct smq_invoke_buf *to_smq_invoke_buf_start(uint32 mode, void *virt, uint32 sc)
+{
+ struct smq_invoke_buf *buf;
+ int len = REMOTE_SCALARS_LENGTH(sc);
+ if (0 == mode)
+ {
+ remote_arg *pra = (remote_arg *)virt;
+ buf = (struct smq_invoke_buf *)(&pra[len]);
+ }
+ else
+ {
+ remote_arg64 *pra = (remote_arg64 *)virt;
+ buf = (struct smq_invoke_buf *)(&pra[len]);
+ }
+ return buf;
+}
+
+static __inline struct smq_invoke_buf *smq_invoke_buf_start(uint32 mode, void *pv, uint32 sc)
+{
+ int len = REMOTE_SCALARS_LENGTH(sc);
+ if (0 == mode)
+ {
+ remote_arg *pra = (remote_arg *)pv;
+ return (struct smq_invoke_buf *)(&pra[len]);
+ }
+ else
+ {
+ remote_arg64 *pra = (remote_arg64 *)pv;
+ return (struct smq_invoke_buf *)(&pra[len]);
+ }
+}
+
+static __inline struct smq_phy_page *smq_phy_page_start(uint32 sc, struct smq_invoke_buf *buf)
+{
+ int nTotal = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc);
+ return (struct smq_phy_page *)(&buf[nTotal]);
+}
+
+//! size of the out of band data
+static __inline int smq_data_size(uint32 mode, uint32 sc, int nPages)
+{
+ struct smq_invoke_buf *buf = smq_invoke_buf_start(mode, 0, sc);
+ struct smq_phy_page *page = smq_phy_page_start(sc, buf);
+ return (int)(uintptr_t)(&(page[nPages]));
+}
+
+static __inline void to_smq_data(uint32 mode, uint32 sc, int nPages, void *pv, remote_arg64 *rpra)
+{
+ if (0 == mode)
+ {
+ struct smq_phy_page *page;
+ struct smq_phy_page32 *page32;
+ remote_arg *pra = (remote_arg *)pv;
+ int ii, len;
+ len = REMOTE_SCALARS_LENGTH(sc);
+ for (ii = 0; ii < len; ++ii)
+ {
+ rpra[ii].buf.pv = (uint64)(uintptr_t)pra[ii].buf.pv;
+ rpra[ii].buf.nLen = pra[ii].buf.nLen;
+ }
+ len = REMOTE_SCALARS_INBUFS(sc) + REMOTE_SCALARS_OUTBUFS(sc);
+ std_memmove(&rpra[ii], &pra[ii], len * sizeof(struct smq_invoke_buf));
+ page = (struct smq_phy_page *)((struct smq_invoke_buf *)&rpra[ii] + len);
+ page32 = (struct smq_phy_page32 *)((struct smq_invoke_buf *)&pra[ii] + len);
+ for (ii = 0; ii < nPages; ++ii)
+ {
+ page[ii].addr = page32[ii].addr;
+ page[ii].size = page32[ii].size;
+ }
+ }
+ else
+ {
+ std_memmove(rpra, pv, smq_data_size(mode, sc, nPages));
+ }
+}
+
+#endif // FASTRPC_INTERNAL_H
diff --git a/inc/listener.h b/inc/listener.h
new file mode 100644
index 0000000..b85a8e2
--- /dev/null
+++ b/inc/listener.h
@@ -0,0 +1,50 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef LISTENER_H
+#define LISTENER_H
+
+#include <pthread.h>
+#include <dlfcn.h>
+#include "pthread_rw_mutex.h"
+
+#define MSG(a, b, c) printf(__FILE_LINE__ ":" c )
+#define MSG_1(a, b, c, d) printf(__FILE_LINE__ ":" c , d)
+#define MSG_2(a, b, c, d, e) printf(__FILE_LINE__ ":" c , d, e)
+#define MSG_3(a, b, c, d, e, f) printf(__FILE_LINE__ ":" c , d, e, f)
+#define MSG_4(a, b, c, d, e, f,g) printf(__FILE_LINE__ ":" c , d, e, f, g)
+
+#define DLW_RTLD_NOW RTLD_NOW
+#define dlw_Open dlopen
+#define dlw_Sym dlsym
+#define dlw_Close dlclose
+#define dlw_Error dlerror
+
+#endif
diff --git a/inc/listener_buf.h b/inc/listener_buf.h
new file mode 100644
index 0000000..757aae1
--- /dev/null
+++ b/inc/listener_buf.h
@@ -0,0 +1,143 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef LISTENER_BUF_H
+#define LISTENER_BUF_H
+
+#include "sbuf.h"
+#include "remote.h"
+#include "verify.h"
+
+static __inline void pack_in_bufs(struct sbuf *buf, remote_arg *pra, int nBufs)
+{
+ int ii;
+ uint32_t len;
+ C_ASSERT(sizeof(len) == 4);
+ for (ii = 0; ii < nBufs; ++ii)
+ {
+ len = (uint32_t)pra[ii].buf.nLen;
+ sbuf_write(buf, (uint8 *)&len, 4);
+ if (len)
+ {
+ sbuf_align(buf, 8);
+ sbuf_write(buf, pra[ii].buf.pv, len);
+ }
+ }
+}
+
+void pack_out_lens(struct sbuf *buf, remote_arg *pra, int nBufs)
+{
+ int ii;
+ uint32_t len;
+ C_ASSERT(sizeof(len) == 4);
+ for (ii = 0; ii < nBufs; ++ii)
+ {
+ len = (uint32_t)pra[ii].buf.nLen;
+ sbuf_write(buf, (uint8 *)&len, 4);
+ }
+}
+
+void unpack_in_bufs(struct sbuf *buf, remote_arg *pra, int nBufs)
+{
+ int ii;
+ uint32_t len;
+ C_ASSERT(sizeof(len) == 4);
+ for (ii = 0; ii < nBufs; ++ii)
+ {
+ sbuf_read(buf, (uint8 *)&len, 4);
+ pra[ii].buf.nLen = len;
+ if (pra[ii].buf.nLen)
+ {
+ sbuf_align(buf, 8);
+ if ((int)pra[ii].buf.nLen <= sbuf_left(buf))
+ {
+ pra[ii].buf.pv = sbuf_head(buf);
+ }
+ sbuf_advance(buf, pra[ii].buf.nLen);
+ }
+ }
+}
+
+void unpack_out_lens(struct sbuf *buf, remote_arg *pra, int nBufs)
+{
+ int ii;
+ uint32_t len;
+ C_ASSERT(sizeof(len) == 4);
+ for (ii = 0; ii < nBufs; ++ii)
+ {
+ sbuf_read(buf, (uint8 *)&len, 4);
+ pra[ii].buf.nLen = len;
+ }
+}
+
+//map out buffers on the hlos side to the remote_arg array
+//dst is the space required for buffers we coun't map from the adsp
+void pack_out_bufs(struct sbuf *buf, remote_arg *pra, int nBufs)
+{
+ int ii;
+ uint32_t len;
+ C_ASSERT(sizeof(len) == 4);
+ for (ii = 0; ii < nBufs; ++ii)
+ {
+ len = (uint32_t)pra[ii].buf.nLen;
+ sbuf_write(buf, (uint8 *)&len, 4);
+ if (pra[ii].buf.nLen)
+ {
+ sbuf_align(buf, 8);
+ if ((int)pra[ii].buf.nLen <= sbuf_left(buf))
+ {
+ pra[ii].buf.pv = sbuf_head(buf);
+ }
+ sbuf_advance(buf, pra[ii].buf.nLen);
+ }
+ }
+}
+
+//on the aDSP copy the data from buffers we had to copy to the local remote_arg structure
+static __inline int unpack_out_bufs(struct sbuf *buf, remote_arg *pra, int nBufs)
+{
+ int ii, nErr = 0;
+ uint32_t len;
+ C_ASSERT(sizeof(len) == 4);
+ for (ii = 0; ii < nBufs; ++ii)
+ {
+ sbuf_read(buf, (uint8 *)&len, 4);
+ VERIFY(len == pra[ii].buf.nLen);
+ if (pra[ii].buf.nLen)
+ {
+ sbuf_align(buf, 8);
+ sbuf_read(buf, pra[ii].buf.pv, pra[ii].buf.nLen);
+ }
+ }
+bail:
+ return nErr;
+}
+
+#endif
diff --git a/inc/mod_table_imp.h b/inc/mod_table_imp.h
new file mode 100644
index 0000000..80a0f7b
--- /dev/null
+++ b/inc/mod_table_imp.h
@@ -0,0 +1,500 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef MOD_TABLE_IMP_H
+#define MOD_TABLE_IMP_H
+#include "remote.h"
+#include "uthash.h"
+#include "verify.h"
+#include "AEEstd.h"
+#include "qtest_stdlib.h"
+
+/**
+ * structure for the mod table
+ *
+ * you need to define a rw_mutex type and its read/write lock/unlock api's
+ * which are under the RW_MUTEX namespace.
+ *
+ * this library defines 2 functions for opening modules, open_static and
+ * open_dynamic. Both return a handle that should be closed via close.
+ *
+ * you can also register a const handle, an invoke function for a known handle
+ * value. since handle keys are allocated, you should pick handle values that are
+ * not going to be returned by malloc (0, or odd).
+ */
+struct static_mod_table
+{
+ RW_MUTEX_T mut;
+ struct static_mod *staticMods;
+ struct const_mod *constMods;
+ boolean bInit;
+};
+
+struct open_mod_table
+{
+ RW_MUTEX_T mut;
+ struct open_mod *openMods;
+ struct static_mod_table *smt;
+};
+
+
+typedef int (*invoke_fn)(uint32, remote_arg *);
+struct static_mod
+{
+ invoke_fn invoke_func_ptr;
+ UT_hash_handle hh;
+ char name[1];
+};
+
+struct const_mod
+{
+ invoke_fn invoke_func_ptr;
+ uint32 key;
+ UT_hash_handle hh;
+ char name[1];
+};
+
+
+struct open_mod
+{
+ void *dlhandle;
+ invoke_fn invoke_func_ptr;
+ uint32 key;
+ UT_hash_handle hh;
+ char name[1];
+};
+
+static int static_mod_table_ctor_imp(struct static_mod_table *me)
+{
+ if (me->bInit == 0)
+ {
+ RW_MUTEX_CTOR(me->mut);
+ me->staticMods = 0;
+ me->bInit = 1;
+ }
+ return 0;
+}
+
+static void static_mod_table_dtor_imp(struct static_mod_table *me)
+{
+ struct static_mod *sm, *stmp;
+ struct const_mod *dm, *ftmp;
+ if (me->bInit != 0)
+ {
+ if (me->staticMods || me->constMods)
+ {
+ RW_MUTEX_LOCK_WRITE(me->mut);
+ HASH_ITER(hh, me->staticMods, sm, stmp)
+ {
+ HASH_DEL(me->staticMods, sm);
+ FREE(sm);
+ }
+ HASH_ITER(hh, me->constMods, dm, ftmp)
+ {
+ HASH_DEL(me->constMods, dm);
+ FREE(dm);
+ }
+ RW_MUTEX_UNLOCK_WRITE(me->mut);
+ }
+ RW_MUTEX_DTOR(me->mut);
+ me->staticMods = 0;
+ me->bInit = 0;
+ }
+}
+
+static int open_mod_table_ctor_imp(void *ctx, void *data)
+{
+ struct open_mod_table *me = (struct open_mod_table *)data;
+ RW_MUTEX_CTOR(me->mut);
+ me->openMods = 0;
+ me->smt = (struct static_mod_table *) ctx;
+ return 0;
+}
+
+static void open_mod_table_dtor_imp(void *data)
+{
+ struct open_mod_table *me = (struct open_mod_table *)data;
+ struct open_mod *dm, *ftmp;
+ if (me->openMods)
+ {
+ RW_MUTEX_LOCK_WRITE(me->mut);
+ HASH_ITER(hh, me->openMods, dm, ftmp)
+ {
+ HASH_DEL(me->openMods, dm);
+ if (dm->dlhandle)
+ {
+ dlw_Close(dm->dlhandle);
+ }
+ FREE(dm);
+ }
+ RW_MUTEX_UNLOCK_WRITE(me->mut);
+ }
+ RW_MUTEX_DTOR(me->mut);
+ me->openMods = 0;
+}
+
+static int open_mod_table_open_static(struct open_mod_table *me, const char *in_name, remote_handle *handle)
+{
+ int nErr = 0;
+ struct static_mod *sm = 0;
+ struct open_mod *dm = 0, *dmOld = 0;
+ int len = std_strlen(in_name);
+ RW_MUTEX_LOCK_READ(me->mut);
+ HASH_FIND_STR(me->smt->staticMods, in_name, sm);
+ RW_MUTEX_UNLOCK_READ(me->mut);
+ VERIFY(0 != sm);
+ VERIFY(0 != (dm = ((struct open_mod *)CALLOC(1, sizeof(struct open_mod) + len + 1))));
+ std_strlcpy(dm->name, sm->name, len + 1);
+ dm->invoke_func_ptr = sm->invoke_func_ptr;
+ dm->key = (uint32)(uintptr_t)dm;
+
+ RW_MUTEX_LOCK_WRITE(me->mut);
+ do
+ {
+ HASH_FIND_INT(me->openMods, &dm->key, dmOld);
+ if (dmOld)
+ {
+ dm->key++;
+ }
+ }
+ while (dmOld);
+ HASH_ADD_INT(me->openMods, key, dm);
+ RW_MUTEX_UNLOCK_WRITE(me->mut);
+
+ *handle = dm->key;
+bail:
+ return nErr;
+}
+
+
+static int static_mod_table_register_static_imp(struct static_mod_table *me, const char *in_name, int(*pfn)(uint32 sc, remote_arg *pra))
+{
+ int nErr = 0;
+ struct static_mod *sm = 0;
+ int len = std_strlen(in_name) + 1;
+ VERIFY(0 != (sm = ((struct static_mod *)CALLOC(1, sizeof(struct static_mod) + len))));
+ std_strlcpy(sm->name, in_name, len);
+ sm->invoke_func_ptr = pfn;
+ RW_MUTEX_LOCK_WRITE(me->mut);
+ HASH_ADD_STR(me->staticMods, name, sm);
+ RW_MUTEX_UNLOCK_WRITE(me->mut);
+bail:
+ if (nErr)
+ {
+ FREEIF(sm);
+ }
+ return nErr;
+}
+
+static int static_mod_table_register_const_handle_imp(struct static_mod_table *me, remote_handle handle, const char *in_name, int(*pfn)(uint32 sc, remote_arg *pra))
+{
+ int nErr = 0;
+ int len = std_strlen(in_name) + 1;
+ struct const_mod *dm = 0, *dmOld;
+ VERIFY(0 != (dm = ((struct const_mod *)CALLOC(1, sizeof(struct open_mod) + len))));
+ dm->key = (uint32)handle;
+ dm->invoke_func_ptr = pfn;
+ std_strlcpy(dm->name, in_name, len);
+
+ RW_MUTEX_LOCK_WRITE(me->mut);
+ HASH_FIND_INT(me->constMods, &handle, dmOld);
+ if (dmOld == 0)
+ {
+ HASH_ADD_INT(me->constMods, key, dm);
+ }
+ RW_MUTEX_UNLOCK_WRITE(me->mut);
+ nErr = dmOld != 0 ? -1 : nErr;
+
+bail:
+ if (nErr)
+ {
+ FREEIF(dm);
+ }
+ return nErr;
+}
+
+#define FILE_PREFIX "file://"
+#define FILE_PREFIX_LEN 7
+static int open_mod_table_open_dynamic(struct open_mod_table *me, const char *in_name, remote_handle *handle, char *dlStr, int dlerrorLen, int *pdlErr)
+{
+ int nErr = 0, dlErr = 0;
+ struct open_mod *dm = 0, *dmOld;
+ int i, len, snlen;
+ int name_len = std_strlen(in_name);
+ char *pSoName = 0;
+ char *pTestName = 0;
+ char *pQchar = 0;
+
+ len = name_len + STD_MAX(sizeof("_skel_invoke"), sizeof("lib_skel.so"));
+ VERIFY(0 != (dm = ((struct open_mod *)CALLOC(1, sizeof(struct open_mod) + len))));
+
+ pSoName = std_strstr(in_name, FILE_PREFIX);
+ if (pSoName == in_name)
+ {
+ pSoName += FILE_PREFIX_LEN;
+ std_strlcpy(dm->name, pSoName, name_len);
+ pQchar = std_strchr(dm->name, '?');
+ VERIFY(NULL != pQchar);
+ *pQchar = '\0';
+ pTestName = pQchar + 1;
+ VERIFY(NULL != pTestName);
+ snlen = std_strlen(dm->name);
+ }
+ else
+ {
+ snlen = std_snprintf(dm->name, len, "lib%s_skel.so", in_name);
+ }
+
+ VERIFY(len > snlen);
+
+ dm->dlhandle = dlw_Open(dm->name, DLW_RTLD_NOW);
+ if (0 != (nErr = (dlErr = dm->dlhandle == 0 ? -5 : 0)))
+ {
+ goto bail;
+ }
+
+ if (pTestName)
+ {
+ snlen = std_snprintf(dm->name, len, "%s_skel_invoke", pTestName);
+ }
+ else
+ {
+ snlen = std_snprintf(dm->name, len, "%s_skel_invoke", in_name);
+ }
+ VERIFY(len > snlen);
+
+ dm->invoke_func_ptr = (invoke_fn) dlw_Sym(dm->dlhandle, dm->name);
+ VERIFY(0 == (dlErr = dm->invoke_func_ptr == 0 ? -1 : 0));
+
+ dm->key = (uint32)(uintptr_t)dm;
+ RW_MUTEX_LOCK_WRITE(me->mut);
+ do
+ {
+ HASH_FIND_INT(me->openMods, &dm->key, dmOld);
+ if (dmOld)
+ {
+ dm->key++;
+ }
+ }
+ while (dmOld);
+ RW_MUTEX_LOCK_WRITE(me->smt->mut);
+ HASH_FIND_INT(me->smt->constMods, &dm->key, dmOld);
+ RW_MUTEX_UNLOCK_WRITE(me->smt->mut);
+ if (dmOld == 0)
+ {
+ HASH_ADD_INT(me->openMods, key, dm);
+ }
+ RW_MUTEX_UNLOCK_WRITE(me->mut);
+ nErr = dmOld != 0 ? -1 : nErr;
+ if (nErr == 0)
+ {
+ *handle = dm->key;
+ std_strlcpy(dm->name, in_name, name_len);
+ }
+bail:
+ if (nErr)
+ {
+ if (dlErr)
+ {
+ const char *dlerr = dlw_Error();
+ if (dlerr != 0)
+ {
+ std_strlcpy(dlStr, dlerr, dlerrorLen);
+ }
+ nErr = 0;
+ }
+ if (pdlErr)
+ {
+ *pdlErr = dlErr;
+ }
+ if (dm && dm->dlhandle)
+ {
+ dlw_Close(dm->dlhandle);
+ }
+ FREEIF(dm);
+ }
+ return nErr;
+}
+
+static int open_mod_table_open_imp(struct open_mod_table *me, const char *in_name, remote_handle *handle, char *dlerr, int dlerrorLen, int *pdlErr)
+{
+ int nErr = 0, dlErr = 0;
+ if (pdlErr)
+ {
+ *pdlErr = 0;
+ }
+
+ VERIFY(0 == open_mod_table_open_dynamic(me, in_name, handle, dlerr, dlerrorLen, &dlErr));
+ if (dlErr != 0)
+ {
+ if (0 != open_mod_table_open_static(me, in_name, handle))
+ {
+ if (pdlErr)
+ {
+ *pdlErr = dlErr;
+ }
+ }
+ }
+bail:
+ return nErr;
+}
+static int open_mod_table_close_imp(struct open_mod_table *me, remote_handle handle, char *errStr, int errStrLen, int *pdlErr)
+{
+ int nErr = 0;
+ struct open_mod *dm = 0;
+ int dlErr = 0;
+ // First ensure that the handle is valid
+ RW_MUTEX_LOCK_READ(me->mut);
+ HASH_FIND_INT(me->openMods, &handle, dm);
+ RW_MUTEX_UNLOCK_READ(me->mut);
+
+ VERIFY(dm != NULL);
+
+ if (dm)
+ {
+ // Try to close the library
+ RW_MUTEX_LOCK_WRITE(me->mut);
+ HASH_DEL(me->openMods, dm);
+ RW_MUTEX_UNLOCK_WRITE(me->mut);
+ if (dm->dlhandle)
+ {
+ dlErr = dlw_Close(dm->dlhandle);
+ }
+ FREE(dm);
+ }
+
+bail:
+ if (dlErr)
+ {
+ const char *error = dlw_Error();
+ nErr = dlErr;
+ if (error != 0)
+ {
+ std_strlcpy(errStr, error, errStrLen);
+ }
+ }
+ if (pdlErr)
+ {
+ *pdlErr = dlErr;
+ }
+ return nErr;
+}
+
+static invoke_fn open_mod_table_handle_to_invoke(struct open_mod_table *me, remote_handle handle)
+{
+ struct open_mod *om = 0;
+ struct const_mod *cm = 0;
+ invoke_fn pfn = 0;
+ RW_MUTEX_LOCK_READ(me->mut);
+ HASH_FIND_INT(me->openMods, &handle, om);
+ if (0 != om)
+ {
+ pfn = om->invoke_func_ptr;
+ }
+ RW_MUTEX_UNLOCK_READ(me->mut);
+ if (pfn == 0)
+ {
+ RW_MUTEX_LOCK_READ(me->smt->mut);
+ HASH_FIND_INT(me->smt->constMods, &handle, cm);
+ if (0 != cm)
+ {
+ pfn = cm->invoke_func_ptr;
+ }
+ RW_MUTEX_UNLOCK_READ(me->smt->mut);
+ }
+ return pfn;
+}
+
+static int open_mod_table_handle_invoke(struct open_mod_table *me, remote_handle handle, uint32 sc, remote_arg *pra)
+{
+ int nErr = 0;
+ invoke_fn invoke_func_ptr;
+ VERIFY(0 != (invoke_func_ptr = open_mod_table_handle_to_invoke(me, handle)));
+ VERIFY(0 == (nErr = invoke_func_ptr(sc, pra)));
+bail:
+ return nErr;
+}
+
+struct mod_table
+{
+ struct static_mod_table smt;
+ struct open_mod_table omt;
+};
+
+static __inline int mod_table_ctor_imp(struct mod_table *mt)
+{
+ int nErr = 0;
+ VERIFY(0 == static_mod_table_ctor_imp(&mt->smt));
+ VERIFY(0 == open_mod_table_ctor_imp(&mt->smt, &mt->omt));
+bail:
+ return nErr;
+}
+
+static __inline void mod_table_dtor_imp(struct mod_table *mt)
+{
+ open_mod_table_dtor_imp(&mt->omt);
+ static_mod_table_dtor_imp(&mt->smt);
+}
+
+static __inline int mod_table_open_dynamic(struct mod_table *me, const char *in_name, remote_handle *handle, char *dlStr, int dlerrorLen, int *pdlErr)
+{
+ return open_mod_table_open_dynamic(&me->omt, in_name, handle, dlStr, dlerrorLen, pdlErr);
+}
+
+static __inline int mod_table_close_imp(struct mod_table *me, remote_handle handle, char *errStr, int errStrLen, int *pdlErr)
+{
+ return open_mod_table_close_imp(&me->omt, handle, errStr, errStrLen, pdlErr);
+}
+
+static __inline int mod_table_open_static(struct mod_table *me, const char *in_name, remote_handle *handle)
+{
+ return open_mod_table_open_static(&me->omt, in_name, handle);
+}
+
+static __inline int mod_table_register_static_imp(struct mod_table *me, const char *in_name, int(*pfn)(uint32 sc, remote_arg *pra))
+{
+ return static_mod_table_register_static_imp(&me->smt, in_name, pfn);
+}
+
+static __inline int mod_table_handle_invoke(struct mod_table *me, remote_handle handle, uint32 sc, remote_arg *pra)
+{
+ return open_mod_table_handle_invoke(&me->omt, handle, sc, pra);
+}
+
+static __inline int mod_table_register_const_handle_imp(struct mod_table *me, remote_handle handle, const char *in_name, int(*pfn)(uint32 sc, remote_arg *pra))
+{
+ return static_mod_table_register_const_handle_imp(&me->smt, handle, in_name, pfn);
+}
+
+static __inline int mod_table_open_imp(struct mod_table *me, const char *in_name, remote_handle *handle, char *dlerr, int dlerrorLen, int *pdlErr)
+{
+ return open_mod_table_open_imp(&me->omt, in_name, handle, dlerr, dlerrorLen, pdlErr);
+}
+#endif // MOD_TABLE_IMP_H
diff --git a/inc/pthread_rw_mutex.h b/inc/pthread_rw_mutex.h
new file mode 100644
index 0000000..b3947d6
--- /dev/null
+++ b/inc/pthread_rw_mutex.h
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef PTHREAD_RW_MUTEX_H
+#define PTHREAD_RW_MUTEX_H
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/* asserts may be compiled out, this should always be present */
+#define ABORT_FAIL( ff ) \
+ do {\
+ if(! (ff) ) {\
+ fprintf(stderr, "assertion \"%s\" failed: file \"%s\", line %d\n", #ff, __FILE__, __LINE__);\
+ abort();\
+ }\
+ } while(0)
+
+#define RW_MUTEX_T pthread_rwlock_t
+#define RW_MUTEX_CTOR(mut) ABORT_FAIL(0 == pthread_rwlock_init( & (mut), 0))
+#define RW_MUTEX_LOCK_READ(mut) ABORT_FAIL(0 == pthread_rwlock_rdlock( & (mut)))
+
+#define RW_MUTEX_UNLOCK_READ(mut) ABORT_FAIL(0 == pthread_rwlock_unlock( & (mut)))
+
+#define RW_MUTEX_LOCK_WRITE(mut) ABORT_FAIL(0 == pthread_rwlock_wrlock( & (mut)))
+
+#define RW_MUTEX_UNLOCK_WRITE(mut) ABORT_FAIL(0 == pthread_rwlock_unlock( & (mut)))
+
+#define RW_MUTEX_DTOR(mut) ABORT_FAIL(0 == pthread_rwlock_destroy( & (mut)))
+
+
+#endif //PTHREAD_RW_MUTEX_H
diff --git a/inc/qtest_stdlib.h b/inc/qtest_stdlib.h
new file mode 100644
index 0000000..315c261
--- /dev/null
+++ b/inc/qtest_stdlib.h
@@ -0,0 +1,123 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef QTEST_STDLIB_H
+#define QTEST_STDLIB_H
+
+#include <assert.h>
+
+#define FREEIF(pv) \
+ do {\
+ if(pv) { \
+ void* tmp = (void*)pv;\
+ pv = 0;\
+ FREE(tmp);\
+ } \
+ } while(0)
+
+#ifndef QASSERT
+#define QASSERT(st) assert(st)
+#endif
+
+#ifndef QTEST
+//default implementation for stdlib
+#include <stdlib.h>
+
+
+#define IF_QTEST(vv) (void)0
+
+#ifndef QASSERT
+#define QASSERT(st) (void)0
+#endif
+
+#ifndef MALLOC
+#define MALLOC malloc
+#endif
+
+#ifndef CALLOC
+#define CALLOC calloc
+#endif
+
+#ifndef FREE
+#define FREE free
+#endif
+
+#ifndef REALLOC
+#define REALLOC realloc
+#endif
+
+#define qtest_set_failure_mask(mask) (void)mask
+#define qtest_get_failure_mask(mask) (void)mask
+#define qtest_set_pass_count(cnt) (void)cnt
+#define qtest_done() (void)0
+#define qtest_test_failure() 0
+#define qtest_atexit(pfn,ctx) (void)pfn; (void)ctx
+
+#else // QTEST
+
+#include "AEEStdDef.h"
+
+#define IF_QTEST(vv) do {\
+ vv \
+} while (0)
+
+//causes alloc to fail when mask & 0x1 is true
+//each test shifts the mask to the right
+void qtest_set_failure_mask(uint32 mask);
+void qtest_get_failure_mask(uint32 *mask);
+
+//causes alloc to fail when count == 0
+//each test decrements the count
+void qtest_set_pass_count(int count);
+
+//returns 0 if succeeds and shifts the mask
+//usefull for generating controlled failures in functions
+int qtest_test_failure(void);
+
+void qtest_atexit(void (*pfnAtExit)(void *pCtx), void *pvCxt);
+
+void qtest_done(void);
+
+void *qtest_malloc(const char *name, int sz);
+
+void *qtest_calloc(const char *name, int cnt, int sz);
+
+void *qtest_realloc(const char *name, void *ptr, int sz);
+
+void qtest_free(const char *name, void *rv);
+
+
+#define MALLOC(sz) qtest_malloc(__FILE_LINE__, sz)
+#define CALLOC(cnt, sz) qtest_calloc(__FILE_LINE__, cnt, sz)
+#define REALLOC(ptr, sz) qtest_realloc(__FILE_LINE__, ptr, sz)
+#define FREE(ptr) qtest_free(__FILE_LINE__, ptr)
+
+#endif //QTEST
+#endif //QTEST_STDLIB_H
diff --git a/inc/remote.h b/inc/remote.h
new file mode 100644
index 0000000..37670bd
--- /dev/null
+++ b/inc/remote.h
@@ -0,0 +1,186 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef REMOTE_H
+#define REMOTE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+typedef uint32_t remote_handle;
+
+typedef struct
+{
+ void *pv;
+ size_t nLen;
+} remote_buf;
+
+typedef union
+{
+ remote_buf buf;
+ remote_handle h;
+} remote_arg;
+
+/*Retrives method attribute from the scalars parameter*/
+#define REMOTE_SCALARS_METHOD_ATTR(dwScalars) (((dwScalars) >> 29) & 0x7)
+
+/*Retrives method index from the scalars parameter*/
+#define REMOTE_SCALARS_METHOD(dwScalars) (((dwScalars) >> 24) & 0x1f)
+
+/*Retrives number of input buffers from the scalars parameter*/
+#define REMOTE_SCALARS_INBUFS(dwScalars) (((dwScalars) >> 16) & 0x0ff)
+
+/*Retrives number of output buffers from the scalars parameter*/
+#define REMOTE_SCALARS_OUTBUFS(dwScalars) (((dwScalars) >> 8) & 0x0ff)
+
+/*Retrives number of input handles from the scalars parameter*/
+#define REMOTE_SCALARS_INHANDLES(dwScalars) (((dwScalars) >> 4) & 0x0f)
+
+/*Retrives number of output handles from the scalars parameter*/
+#define REMOTE_SCALARS_OUTHANDLES(dwScalars) ((dwScalars) & 0x0f)
+
+#define REMOTE_SCALARS_MAKEX(nAttr,nMethod,nIn,nOut,noIn,noOut) \
+ ((((uint32_t) (nAttr) & 0x7) << 29) | \
+ (((uint32_t) (nMethod) & 0x1f) << 24) | \
+ (((uint32_t) (nIn) & 0xff) << 16) | \
+ (((uint32_t) (nOut) & 0xff) << 8) | \
+ (((uint32_t) (noIn) & 0x0f) << 4) | \
+ ((uint32_t) (noOut) & 0x0f))
+
+#define REMOTE_SCALARS_MAKE(nMethod,nIn,nOut) REMOTE_SCALARS_MAKEX(0,nMethod,nIn,nOut,0,0)
+
+#define REMOTE_SCALARS_LENGTH(sc) (REMOTE_SCALARS_INBUFS(sc) +\
+ REMOTE_SCALARS_OUTBUFS(sc) +\
+ REMOTE_SCALARS_INHANDLES(sc) +\
+ REMOTE_SCALARS_OUTHANDLES(sc))
+
+#ifndef __QAIC_REMOTE
+#define __QAIC_REMOTE(ff) ff
+#endif //__QAIC_REMOTE
+
+#ifndef __QAIC_REMOTE_EXPORT
+#ifdef _WIN32
+#define __QAIC_REMOTE_EXPORT __declspec(dllexport)
+#else //_WIN32
+#define __QAIC_REMOTE_EXPORT
+#endif //_WIN32
+#endif //__QAIC_REMOTE_EXPORT
+
+#ifndef __QAIC_REMOTE_ATTRIBUTE
+#define __QAIC_REMOTE_ATTRIBUTE
+#endif
+
+/* All other values are reserved */
+
+/* opens a remote_handle "name"
+ * returns 0 on success
+ */
+__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_handle_open)(const char *name, remote_handle *ph) __QAIC_REMOTE_ATTRIBUTE;
+
+/* invokes the remote handle
+ * see retrive macro's on dwScalars format
+ * pra, contains the arguments in the following order, inbufs, outbufs, inhandles, outhandles.
+ * implementors should ignore and pass values asis that the transport doesn't understand.
+ */
+__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_handle_invoke)(remote_handle h, uint32_t dwScalars, remote_arg *pra) __QAIC_REMOTE_ATTRIBUTE;
+
+/* closes the remote handle
+ */
+__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_handle_close)(remote_handle h) __QAIC_REMOTE_ATTRIBUTE;
+
+/* map memory to the remote domain
+ *
+ * @param fd, fd assosciated with this memory
+ * @param flags, flags to be used for the mapping
+ * @param vaddrin, input address
+ * @param size, size of buffer
+ * @param vaddrout, output address
+ * @retval, 0 on success
+ */
+__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_mmap)(int fd, uint32_t flags, uint32_t vaddrin, int size, uint32_t *vaddrout) __QAIC_REMOTE_ATTRIBUTE;
+
+/* unmap memory from the remote domain
+ *
+ * @param vaddrout, remote address mapped
+ * @param size, size to unmap. Unmapping a range partially may not be supported.
+ * @retval, 0 on success, may fail if memory is still mapped
+ */
+__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_munmap)(uint32_t vaddrout, int size) __QAIC_REMOTE_ATTRIBUTE;
+
+/* Register a file descriptor for a buffer. This is only valid on
+ * android with ION allocated memory. Users of fastrpc should register
+ * a buffer allocated with ION to enable sharing that buffer to the
+ * dsp via the smmu. Some versions of libadsprpc.so lack this
+ * function, so users should set this symbol as weak.
+ *
+ * #pragma weak remote_register_buf
+ *
+ * @param buf, virtual address of the buffer
+ * @param size, size to of the buffer
+ * @fd, the file descriptor, callers can use -1 to deregister.
+ */
+__QAIC_REMOTE_EXPORT void __QAIC_REMOTE(remote_register_buf)(void *buf, int size, int fd) __QAIC_REMOTE_ATTRIBUTE;
+
+/*
+ * This is the default mode for the driver. While the driver is in parallel
+ * mode it will try to invalidate output buffers after it transfers control
+ * to the dsp. This allows the invalidate operations to overlap with the
+ * dsp processing the call. This mode should be used when output buffers
+ * are only read on the application processor and only written on the aDSP.
+ */
+#define REMOTE_MODE_PARALLEL 0
+
+/*
+ * When operating in SERIAL mode the driver will invalidate output buffers
+ * before calling into the dsp. This mode should be used when output
+ * buffers have been written to somewhere besides the aDSP.
+ */
+#define REMOTE_MODE_SERIAL 1
+
+/*
+ * Internal transport prefix
+ */
+#define ITRANSPORT_PREFIX "'\":;./\\"
+
+/*
+ * Set the mode of operation.
+ *
+ * Some versions of libadsprpc.so lack this function, so users should set
+ * this symbol as weak.
+ *
+ * #pragma weak remote_set_mode
+ *
+ * @param mode, the mode
+ * @retval, 0 on success
+ */
+__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_set_mode)(uint32_t mode) __QAIC_REMOTE_ATTRIBUTE;
+
+
+#endif // REMOTE_H
diff --git a/inc/remote64.h b/inc/remote64.h
new file mode 100644
index 0000000..e16b255
--- /dev/null
+++ b/inc/remote64.h
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef REMOTE64_H
+#define REMOTE64_H
+
+#include "remote.h"
+
+typedef struct
+{
+ uint64_t pv;
+ int64_t nLen;
+} remote_buf64;
+
+typedef union
+{
+ remote_buf64 buf;
+ remote_handle h;
+} remote_arg64;
+
+#ifndef __QAIC_REMOTE
+#define __QAIC_REMOTE(ff) ff
+#endif //__QAIC_REMOTE
+
+#ifndef __QAIC_REMOTE_EXPORT
+#ifdef _WIN32
+#define __QAIC_REMOTE_EXPORT __declspec(dllexport)
+#else //_WIN32
+#define __QAIC_REMOTE_EXPORT
+#endif //_WIN32
+#endif //__QAIC_REMOTE_EXPORT
+
+#ifndef __QAIC_REMOTE_ATTRIBUTE
+#define __QAIC_REMOTE_ATTRIBUTE
+#endif
+
+/* map memory to the remote domain
+ *
+ * @param fd, fd associated with this memory
+ * @param flags, flags to be used for the mapping
+ * @param vaddrin, input address
+ * @param size, size of buffer
+ * @param vaddrout, output address
+ * @retval, 0 on success
+ */
+__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_mmap64)(int fd, uint32_t flags, uintptr_t vaddrin, int64_t size, uintptr_t *vaddrout) __QAIC_REMOTE_ATTRIBUTE;
+
+/* unmap memory from the remote domain
+ *
+ * @param vaddrout, remote address mapped
+ * @param size, size to unmap. Unmapping a range partially may not be supported.
+ * @retval, 0 on success, may fail if memory is still mapped
+ */
+__QAIC_REMOTE_EXPORT int __QAIC_REMOTE(remote_munmap64)(uintptr_t vaddrout, int64_t size) __QAIC_REMOTE_ATTRIBUTE;
+
+#endif // REMOTE64_H
diff --git a/inc/remotectl.h b/inc/remotectl.h
new file mode 100644
index 0000000..1b4b2ff
--- /dev/null
+++ b/inc/remotectl.h
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _REMOTECTL_H
+#define _REMOTECTL_H
+#include "AEEStdDef.h"
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if !defined(__QAIC_STRING1_OBJECT_DEFINED__) && !defined(__STRING1_OBJECT__)
+#define __QAIC_STRING1_OBJECT_DEFINED__
+#define __STRING1_OBJECT__
+typedef struct _cstring1_s
+{
+ char *data;
+ int dataLen;
+} _cstring1_t;
+
+#endif /* __QAIC_STRING1_OBJECT_DEFINED__ */
+#define _const_remotectl_handle 0
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl_open)(const char *name, int *handle, char *dlerror, int dlerrorLen, int *nErr) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl_close)(int handle, char *dlerror, int dlerrorLen, int *nErr) __QAIC_HEADER_ATTRIBUTE;
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(remotectl_grow_heap)(uint32 phyAddr, uint32 nSize) __QAIC_HEADER_ATTRIBUTE;
+#ifdef __cplusplus
+}
+#endif
+#endif //_REMOTECTL_H
diff --git a/inc/rpcmem.h b/inc/rpcmem.h
new file mode 100644
index 0000000..82de2d1
--- /dev/null
+++ b/inc/rpcmem.h
@@ -0,0 +1,138 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef RPCMEM_H
+#define RPCMEM_H
+
+#include "AEEStdDef.h"
+
+/**
+ * RPCMEM_DEFAULT_HEAP
+ * Dynamicaly select the heap to use. This should be ok for most usecases.
+ */
+#define RPCMEM_DEFAULT_HEAP -1
+
+
+/**
+ * RPCMEM_DEFAULT_FLAGS should allocate memory with the same properties
+ * as the ION_FLAG_CACHED flag
+ */
+#ifdef ION_FLAG_CACHED
+#define RPCMEM_DEFAULT_FLAGS ION_FLAG_CACHED
+#else
+#define RPCMEM_DEFAULT_FLAGS 1
+#endif
+
+/**
+ * RPCMEM_FLAG_UNCACHED
+ * ION_FLAG_CACHED should be defined as 1
+ */
+#define RPCMEM_FLAG_UNCACHED 0
+#define RPCMEM_FLAG_CACHED RPCMEM_DEFAULT_FLAGS
+
+/**
+ * examples:
+ *
+ * heap 22, uncached, 1kb
+ * rpcmem_alloc(22, 0, 1024);
+ * rpcmem_alloc(22, RPCMEM_FLAG_UNCACHED, 1024);
+ *
+ * heap 21, cached, 2kb
+ * rpcmem_alloc(21, RPCMEM_FLAG_CACHED, 2048);
+ * #include <ion.h>
+ * rpcmem_alloc(21, ION_FLAG_CACHED, 2048);
+ *
+ * just give me the defaults, 2kb
+ * rpcmem_alloc(RPCMEM_DEFAULT_HEAP, RPCMEM_DEFAULT_FLAGS, 2048);
+ * rpcmem_alloc_def(2048);
+ *
+ * give me the default flags, but from heap 18, 4kb
+ * rpcmem_alloc(18, RPCMEM_DEFAULT_FLAGS, 4096);
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * call once to initialize the library
+ */
+void rpcmem_init(void);
+/**
+ * call once for cleanup
+ */
+void rpcmem_deinit(void);
+
+/**
+ * Allocate via ION a buffer of size
+ * @heapid, the heap id to use
+ * @flags, ion flags to use to when allocating
+ * @size, the buffer size to allocate
+ * @retval, 0 on failure, pointer to buffer on success
+ *
+ * For example:
+ * buf = rpcmem_alloc(RPCMEM_DEFAULT_HEAP, RPCMEM_DEFAULT_FLAGS, size);
+ */
+
+void *rpcmem_alloc(int heapid, uint32 flags, int size);
+
+/**
+ * allocate with default settings
+ */
+#if !defined(WINNT) && !defined (_WIN32_WINNT)
+__attribute__((unused))
+#endif
+static __inline void *rpcmem_alloc_def(int size)
+{
+ return rpcmem_alloc(RPCMEM_DEFAULT_HEAP, RPCMEM_DEFAULT_FLAGS, size);
+}
+
+/**
+ * free buffer, ignores invalid buffers
+ */
+void rpcmem_free(void *po);
+
+/**
+ * returns associated fd
+ */
+int rpcmem_to_fd(void *po);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** these are deprecated
+ */
+#define RPCMEM_HEAP_DEFAULT 0x80000000
+#define RPCMEM_HEAP_NOREG 0x40000000
+#define RPCMEM_HEAP_UNCACHED 0x20000000
+
+#endif //RPCMEM_H
diff --git a/inc/sbuf.h b/inc/sbuf.h
new file mode 100644
index 0000000..611f535
--- /dev/null
+++ b/inc/sbuf.h
@@ -0,0 +1,158 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef SBUF_H
+#define SBUF_H
+
+#include "AEEStdDef.h"
+#include "AEEstd.h"
+#include <string.h>
+
+/**
+ * lightweight serialize/deserialize buffer.
+
+ For example
+
+ struct sbuf;
+ //initialize empty buffer;
+ sbuf_init(&sbuf, 0, 0, 0);
+
+ //fill it with data
+ sbuf_align(&sbuf, 8);
+ sbuf_write(&sbuf, ptr1, 10);
+ sbuf_align(&sbuf, 8);
+ sbuf_write(&sbuf, ptr2, 20);
+
+ //allocate the memory needed
+ mem = malloc(sbuf_needed(&sbuf));
+
+ //initialize with the data
+ sbuf_init(&sbuf, 0, mem, sbuf_needed(&sbuf));
+
+ //fill it with data, since it has memory, it will actually copy
+ sbuf_align(&sbuf, 8);
+ sbuf_write(&sbuf, ptr1, 10);
+ sbuf_align(&sbuf, 8);
+ sbuf_write(&sbuf, ptr2, 20);
+
+ See sbuf_q.h for more examples
+ */
+
+
+struct sbuf
+{
+ uint8 *buf; //start of valid memory
+ uint8 *bufEnd; //end of valid memory
+ uint8 *bufStart; //start with optinal offset from valid mem
+ uint8 *bufCur; //current buffer, could be outside of valid range (greater then bufEnd)
+};
+
+static __inline void sbuf_init(struct sbuf *buf, int offset, uint8 *data, int dataLen)
+{
+ buf->buf = data;
+ buf->bufStart = buf->bufCur = data - offset;
+ buf->bufEnd = data + dataLen;
+}
+
+static __inline void sbuf_advance(struct sbuf *buf, int len)
+{
+ buf->bufCur += len;
+}
+
+//needed for everything from the start (with the offset) to the end (past the current valid memory end)
+static __inline int sbuf_needed(struct sbuf *buf)
+{
+ return buf->bufCur - buf->bufStart;
+}
+
+//space left in buffer, a negative value indicates overflow
+//a positive value includes the offset
+static __inline int sbuf_left(struct sbuf *buf)
+{
+ return buf->bufEnd - buf->bufCur;
+}
+
+static __inline uint8 *sbuf_head(struct sbuf *buf)
+{
+ return buf->bufCur;
+}
+
+
+//advances the head pointer so the "needed" is aligned to the align value
+#define _SBUF_ALIGN(x, y) (((x) + ((y)-1)) & ~((y)-1))
+static __inline void sbuf_align(struct sbuf *buf, uint32 align)
+{
+ sbuf_advance(buf, _SBUF_ALIGN(sbuf_needed(buf), align) - sbuf_needed(buf));
+}
+
+
+static __inline void sbuf_write(struct sbuf *buf, uint8 *src, int srcLen)
+{
+ if (buf->bufCur + srcLen > buf->buf)
+ {
+ int writeLen;
+ if (buf->bufCur < buf->buf)
+ {
+ int len = buf->buf - buf->bufCur;
+ srcLen -= len;
+ src += len;
+ sbuf_advance(buf, len);
+ }
+ writeLen = STD_MIN(srcLen, sbuf_left(buf));
+ if (writeLen > 0)
+ {
+ memmove(buf->bufCur, src, writeLen);
+ }
+ }
+ sbuf_advance(buf, srcLen);
+}
+
+static __inline void sbuf_read(struct sbuf *buf, uint8 *dst, int dstLen)
+{
+ if (buf->bufCur + dstLen > buf->buf)
+ {
+ int readLen;
+ if (buf->bufCur < buf->buf)
+ {
+ int len = buf->buf - buf->bufCur;
+ dstLen -= len;
+ dst += len;
+ sbuf_advance(buf, len);
+ }
+ readLen = STD_MIN(dstLen, sbuf_left(buf));
+ if (readLen > 0)
+ {
+ memmove(dst, buf->bufCur, readLen);
+ }
+ }
+ sbuf_advance(buf, dstLen);
+}
+
+#endif
diff --git a/inc/shared.h b/inc/shared.h
new file mode 100644
index 0000000..b05742f
--- /dev/null
+++ b/inc/shared.h
@@ -0,0 +1,77 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef SHARED_H
+#define SHARED_H
+
+#ifdef _WIN32
+#include <windows.h>
+
+typedef int __so_cb(void);
+static __so_cb *__so_get_ctor();
+static __so_cb *__so_get_dtor();
+
+typedef void __so_func(void);
+static void __so_ctor()
+{
+ (void)(__so_get_ctor())();
+}
+
+static void __so_dtor()
+{
+ (void)(__so_get_dtor())();
+}
+
+#pragma data_seg(".CRT$XIU")
+static __so_func *__autostart[] = { (__so_func *)__so_ctor };
+#pragma data_seg(".CRT$XPU")
+static __so_func *__autoexit[] = { (__so_func *)__so_dtor };
+#pragma data_seg()
+
+#define SHARED_OBJECT_API_ENTRY(ctor, dtor)\
+ static __so_cb *__so_get_ctor() { return (__so_cb*)ctor; }\
+ static __so_cb *__so_get_dtor() { return (__so_cb*)dtor; }
+
+#else //better be gcc
+
+#define SHARED_OBJECT_API_ENTRY(ctor, dtor)\
+__attribute__((constructor)) \
+static void __ctor__##ctor(void) {\
+ (void)ctor();\
+}\
+\
+__attribute__((destructor))\
+static void __dtor__##dtor(void) {\
+ (void)dtor();\
+}
+
+#endif //ifdef _WIN32
+
+#endif // SHARED_H
diff --git a/inc/uthash.h b/inc/uthash.h
new file mode 100644
index 0000000..73f5006
--- /dev/null
+++ b/inc/uthash.h
@@ -0,0 +1,915 @@
+/*
+Copyright (c) 2003-2011, Troy D. Hanson http://uthash.sourceforge.net
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef UTHASH_H
+#define UTHASH_H
+
+#include <string.h> /* memcmp,strlen */
+#include <stddef.h> /* ptrdiff_t */
+#include <stdlib.h> /* exit() */
+
+/* These macros use decltype or the earlier __typeof GNU extension.
+ As decltype is only available in newer compilers (VS2010 or gcc 4.3+
+ when compiling c++ source) this code uses whatever method is needed
+ or, for VS2008 where neither is available, uses casting workarounds. */
+#ifdef _MSC_VER /* MS compiler */
+#if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */
+#define DECLTYPE(x) (decltype(x))
+#else /* VS2008 or older (or VS2010 in C mode) */
+#define NO_DECLTYPE
+#define DECLTYPE(x)
+#endif
+#else /* GNU, Sun and other compilers */
+#define DECLTYPE(x) (__typeof(x))
+#endif
+
+#ifdef NO_DECLTYPE
+#define DECLTYPE_ASSIGN(dst,src) \
+do { \
+ char **_da_dst = (char**)(&(dst)); \
+ *_da_dst = (char*)(src); \
+} while(0)
+#else
+#define DECLTYPE_ASSIGN(dst,src) \
+do { \
+ (dst) = DECLTYPE(dst)(src); \
+} while(0)
+#endif
+
+/* a number of the hash function use uint32_t which isn't defined on win32 */
+#ifdef _MSC_VER
+typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
+#else
+#include <inttypes.h> /* uint32_t */
+#endif
+
+#define UTHASH_VERSION 1.9.4
+
+#define uthash_fatal(msg) exit(-1) /* fatal error (out of memory,etc) */
+#define uthash_malloc(sz) malloc(sz) /* malloc fcn */
+#define uthash_free(ptr,sz) free(ptr) /* free fcn */
+
+#define uthash_noexpand_fyi(tbl) /* can be defined to log noexpand */
+#define uthash_expand_fyi(tbl) /* can be defined to log expands */
+
+/* initial number of buckets */
+#define HASH_INITIAL_NUM_BUCKETS 32 /* initial number of buckets */
+#define HASH_INITIAL_NUM_BUCKETS_LOG2 5 /* lg2 of initial number of buckets */
+#define HASH_BKT_CAPACITY_THRESH 10 /* expand when bucket count reaches */
+
+/* calculate the element whose hash handle address is hhe */
+#define ELMT_FROM_HH(tbl,hhp) ((void*)(((char*)(hhp)) - ((tbl)->hho)))
+
+#define HASH_FIND(hh,head,keyptr,keylen,out) \
+do { \
+ unsigned _hf_bkt,_hf_hashv; \
+ out=NULL; \
+ if (head) { \
+ HASH_FCN(keyptr,keylen, (head)->hh.tbl->num_buckets, _hf_hashv, _hf_bkt); \
+ if (HASH_BLOOM_TEST((head)->hh.tbl, _hf_hashv)) { \
+ HASH_FIND_IN_BKT((head)->hh.tbl, hh, (head)->hh.tbl->buckets[ _hf_bkt ], \
+ keyptr,keylen,out); \
+ } \
+ } \
+} while (0)
+
+#ifdef HASH_BLOOM
+#define HASH_BLOOM_BITLEN (1ULL << HASH_BLOOM)
+#define HASH_BLOOM_BYTELEN (HASH_BLOOM_BITLEN/8) + ((HASH_BLOOM_BITLEN%8) ? 1:0)
+#define HASH_BLOOM_MAKE(tbl) \
+do { \
+ (tbl)->bloom_nbits = HASH_BLOOM; \
+ (tbl)->bloom_bv = (uint8_t*)uthash_malloc(HASH_BLOOM_BYTELEN); \
+ if (!((tbl)->bloom_bv)) { uthash_fatal( "out of memory"); } \
+ memset((tbl)->bloom_bv, 0, HASH_BLOOM_BYTELEN); \
+ (tbl)->bloom_sig = HASH_BLOOM_SIGNATURE; \
+} while (0);
+
+#define HASH_BLOOM_FREE(tbl) \
+do { \
+ uthash_free((tbl)->bloom_bv, HASH_BLOOM_BYTELEN); \
+} while (0);
+
+#define HASH_BLOOM_BITSET(bv,idx) (bv[(idx)/8] |= (1U << ((idx)%8)))
+#define HASH_BLOOM_BITTEST(bv,idx) (bv[(idx)/8] & (1U << ((idx)%8)))
+
+#define HASH_BLOOM_ADD(tbl,hashv) \
+ HASH_BLOOM_BITSET((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
+
+#define HASH_BLOOM_TEST(tbl,hashv) \
+ HASH_BLOOM_BITTEST((tbl)->bloom_bv, (hashv & (uint32_t)((1ULL << (tbl)->bloom_nbits) - 1)))
+
+#else
+#define HASH_BLOOM_MAKE(tbl)
+#define HASH_BLOOM_FREE(tbl)
+#define HASH_BLOOM_ADD(tbl,hashv)
+#define HASH_BLOOM_TEST(tbl,hashv) (1)
+#endif
+
+#define HASH_MAKE_TABLE(hh,head) \
+do { \
+ (head)->hh.tbl = (UT_hash_table*)uthash_malloc( \
+ sizeof(UT_hash_table)); \
+ if (!((head)->hh.tbl)) { uthash_fatal( "out of memory"); } \
+ memset((head)->hh.tbl, 0, sizeof(UT_hash_table)); \
+ (head)->hh.tbl->tail = &((head)->hh); \
+ (head)->hh.tbl->num_buckets = HASH_INITIAL_NUM_BUCKETS; \
+ (head)->hh.tbl->log2_num_buckets = HASH_INITIAL_NUM_BUCKETS_LOG2; \
+ (head)->hh.tbl->hho = (char*)(&(head)->hh) - (char*)(head); \
+ (head)->hh.tbl->buckets = (UT_hash_bucket*)uthash_malloc( \
+ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
+ if (! (head)->hh.tbl->buckets) { uthash_fatal( "out of memory"); } \
+ memset((head)->hh.tbl->buckets, 0, \
+ HASH_INITIAL_NUM_BUCKETS*sizeof(struct UT_hash_bucket)); \
+ HASH_BLOOM_MAKE((head)->hh.tbl); \
+ (head)->hh.tbl->signature = HASH_SIGNATURE; \
+} while(0)
+
+#define HASH_ADD(hh,head,fieldname,keylen_in,add) \
+ HASH_ADD_KEYPTR(hh,head,&add->fieldname,keylen_in,add)
+
+#define HASH_ADD_KEYPTR(hh,head,keyptr,keylen_in,add) \
+do { \
+ unsigned _ha_bkt; \
+ (add)->hh.next = NULL; \
+ (add)->hh.key = (char*)keyptr; \
+ (add)->hh.keylen = keylen_in; \
+ if (!(head)) { \
+ head = (add); \
+ (head)->hh.prev = NULL; \
+ HASH_MAKE_TABLE(hh,head); \
+ } else { \
+ (head)->hh.tbl->tail->next = (add); \
+ (add)->hh.prev = ELMT_FROM_HH((head)->hh.tbl, (head)->hh.tbl->tail); \
+ (head)->hh.tbl->tail = &((add)->hh); \
+ } \
+ (head)->hh.tbl->num_items++; \
+ (add)->hh.tbl = (head)->hh.tbl; \
+ HASH_FCN(keyptr,keylen_in, (head)->hh.tbl->num_buckets, \
+ (add)->hh.hashv, _ha_bkt); \
+ HASH_ADD_TO_BKT((head)->hh.tbl->buckets[_ha_bkt],&(add)->hh); \
+ HASH_BLOOM_ADD((head)->hh.tbl,(add)->hh.hashv); \
+ HASH_EMIT_KEY(hh,head,keyptr,keylen_in); \
+ HASH_FSCK(hh,head); \
+} while(0)
+
+#define HASH_TO_BKT( hashv, num_bkts, bkt ) \
+do { \
+ bkt = ((hashv) & ((num_bkts) - 1)); \
+} while(0)
+
+/* delete "delptr" from the hash table.
+ * "the usual" patch-up process for the app-order doubly-linked-list.
+ * The use of _hd_hh_del below deserves special explanation.
+ * These used to be expressed using (delptr) but that led to a bug
+ * if someone used the same symbol for the head and deletee, like
+ * HASH_DELETE(hh,users,users);
+ * We want that to work, but by changing the head (users) below
+ * we were forfeiting our ability to further refer to the deletee (users)
+ * in the patch-up process. Solution: use scratch space to
+ * copy the deletee pointer, then the latter references are via that
+ * scratch pointer rather than through the repointed (users) symbol.
+ */
+#define HASH_DELETE(hh,head,delptr) \
+do { \
+ unsigned _hd_bkt; \
+ struct UT_hash_handle *_hd_hh_del; \
+ if ( ((delptr)->hh.prev == NULL) && ((delptr)->hh.next == NULL) ) { \
+ uthash_free((head)->hh.tbl->buckets, \
+ (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
+ HASH_BLOOM_FREE((head)->hh.tbl); \
+ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
+ head = NULL; \
+ } else { \
+ _hd_hh_del = &((delptr)->hh); \
+ if ((delptr) == ELMT_FROM_HH((head)->hh.tbl,(head)->hh.tbl->tail)) { \
+ (head)->hh.tbl->tail = \
+ (UT_hash_handle*)((char*)((delptr)->hh.prev) + \
+ (head)->hh.tbl->hho); \
+ } \
+ if ((delptr)->hh.prev) { \
+ ((UT_hash_handle*)((char*)((delptr)->hh.prev) + \
+ (head)->hh.tbl->hho))->next = (delptr)->hh.next; \
+ } else { \
+ DECLTYPE_ASSIGN(head,(delptr)->hh.next); \
+ } \
+ if (_hd_hh_del->next) { \
+ ((UT_hash_handle*)((char*)_hd_hh_del->next + \
+ (head)->hh.tbl->hho))->prev = \
+ _hd_hh_del->prev; \
+ } \
+ HASH_TO_BKT( _hd_hh_del->hashv, (head)->hh.tbl->num_buckets, _hd_bkt); \
+ HASH_DEL_IN_BKT(hh,(head)->hh.tbl->buckets[_hd_bkt], _hd_hh_del); \
+ (head)->hh.tbl->num_items--; \
+ } \
+ HASH_FSCK(hh,head); \
+} while (0)
+
+/* use this function to delete an item from a table only if its in that table */
+#define HASH_DELETE_IF(hh,group,ptr) \
+do {\
+ if(ptr && group && ptr->hh.tbl) { \
+ HASH_DELETE(hh,group,ptr); \
+ ptr->hh.tbl = 0;\
+ } \
+} while(0)
+
+/* convenience forms of HASH_FIND/HASH_ADD/HASH_DEL */
+#define HASH_FIND_STR(head,findstr,out) \
+ HASH_FIND(hh,head,findstr,strlen(findstr),out)
+#define HASH_ADD_STR(head,strfield,add) \
+ HASH_ADD(hh,head,strfield,strlen(add->strfield),add)
+#define HASH_FIND_INT(head,findint,out) \
+ HASH_FIND(hh,head,findint,sizeof(int),out)
+#define HASH_ADD_INT(head,intfield,add) \
+ HASH_ADD(hh,head,intfield,sizeof(int),add)
+#define HASH_FIND_PTR(head,findptr,out) \
+ HASH_FIND(hh,head,findptr,sizeof(void *),out)
+#define HASH_ADD_PTR(head,ptrfield,add) \
+ HASH_ADD(hh,head,ptrfield,sizeof(void *),add)
+#define HASH_DEL(head,delptr) \
+ HASH_DELETE(hh,head,delptr)
+
+/* HASH_FSCK checks hash integrity on every add/delete when HASH_DEBUG is defined.
+ * This is for uthash developer only; it compiles away if HASH_DEBUG isn't defined.
+ */
+#ifdef HASH_DEBUG
+#define HASH_OOPS(...) do { fprintf(stderr,__VA_ARGS__); exit(-1); } while (0)
+#define HASH_FSCK(hh,head) \
+do { \
+ unsigned _bkt_i; \
+ unsigned _count, _bkt_count; \
+ char *_prev; \
+ struct UT_hash_handle *_thh; \
+ if (head) { \
+ _count = 0; \
+ for( _bkt_i = 0; _bkt_i < (head)->hh.tbl->num_buckets; _bkt_i++) { \
+ _bkt_count = 0; \
+ _thh = (head)->hh.tbl->buckets[_bkt_i].hh_head; \
+ _prev = NULL; \
+ while (_thh) { \
+ if (_prev != (char*)(_thh->hh_prev)) { \
+ HASH_OOPS("invalid hh_prev %p, actual %p\n", \
+ _thh->hh_prev, _prev ); \
+ } \
+ _bkt_count++; \
+ _prev = (char*)(_thh); \
+ _thh = _thh->hh_next; \
+ } \
+ _count += _bkt_count; \
+ if ((head)->hh.tbl->buckets[_bkt_i].count != _bkt_count) { \
+ HASH_OOPS("invalid bucket count %d, actual %d\n", \
+ (head)->hh.tbl->buckets[_bkt_i].count, _bkt_count); \
+ } \
+ } \
+ if (_count != (head)->hh.tbl->num_items) { \
+ HASH_OOPS("invalid hh item count %d, actual %d\n", \
+ (head)->hh.tbl->num_items, _count ); \
+ } \
+ /* traverse hh in app order; check next/prev integrity, count */ \
+ _count = 0; \
+ _prev = NULL; \
+ _thh = &(head)->hh; \
+ while (_thh) { \
+ _count++; \
+ if (_prev !=(char*)(_thh->prev)) { \
+ HASH_OOPS("invalid prev %p, actual %p\n", \
+ _thh->prev, _prev ); \
+ } \
+ _prev = (char*)ELMT_FROM_HH((head)->hh.tbl, _thh); \
+ _thh = ( _thh->next ? (UT_hash_handle*)((char*)(_thh->next) + \
+ (head)->hh.tbl->hho) : NULL ); \
+ } \
+ if (_count != (head)->hh.tbl->num_items) { \
+ HASH_OOPS("invalid app item count %d, actual %d\n", \
+ (head)->hh.tbl->num_items, _count ); \
+ } \
+ } \
+} while (0)
+#else
+#define HASH_FSCK(hh,head)
+#endif
+
+/* When compiled with -DHASH_EMIT_KEYS, length-prefixed keys are emitted to
+ * the descriptor to which this macro is defined for tuning the hash function.
+ * The app can #include <unistd.h> to get the prototype for write(2). */
+#ifdef HASH_EMIT_KEYS
+#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen) \
+do { \
+ unsigned _klen = fieldlen; \
+ write(HASH_EMIT_KEYS, &_klen, sizeof(_klen)); \
+ write(HASH_EMIT_KEYS, keyptr, fieldlen); \
+} while (0)
+#else
+#define HASH_EMIT_KEY(hh,head,keyptr,fieldlen)
+#endif
+
+/* default to Jenkin's hash unless overridden e.g. DHASH_FUNCTION=HASH_SAX */
+#ifdef HASH_FUNCTION
+#define HASH_FCN HASH_FUNCTION
+#else
+#define HASH_FCN HASH_JEN
+#endif
+
+/* The Bernstein hash function, used in Perl prior to v5.6 */
+#define HASH_BER(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ unsigned _hb_keylen=keylen; \
+ char *_hb_key=(char*)(key); \
+ (hashv) = 0; \
+ while (_hb_keylen--) { (hashv) = ((hashv) * 33) + *_hb_key++; } \
+ bkt = (hashv) & (num_bkts-1); \
+} while (0)
+
+
+/* SAX/FNV/OAT/JEN hash functions are macro variants of those listed at
+ * http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx */
+#define HASH_SAX(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ unsigned _sx_i; \
+ char *_hs_key=(char*)(key); \
+ hashv = 0; \
+ for(_sx_i=0; _sx_i < keylen; _sx_i++) \
+ hashv ^= (hashv << 5) + (hashv >> 2) + _hs_key[_sx_i]; \
+ bkt = hashv & (num_bkts-1); \
+} while (0)
+
+#define HASH_FNV(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ unsigned _fn_i; \
+ char *_hf_key=(char*)(key); \
+ hashv = 2166136261UL; \
+ for(_fn_i=0; _fn_i < keylen; _fn_i++) \
+ hashv = (hashv * 16777619) ^ _hf_key[_fn_i]; \
+ bkt = hashv & (num_bkts-1); \
+} while(0);
+
+#define HASH_OAT(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ unsigned _ho_i; \
+ char *_ho_key=(char*)(key); \
+ hashv = 0; \
+ for(_ho_i=0; _ho_i < keylen; _ho_i++) { \
+ hashv += _ho_key[_ho_i]; \
+ hashv += (hashv << 10); \
+ hashv ^= (hashv >> 6); \
+ } \
+ hashv += (hashv << 3); \
+ hashv ^= (hashv >> 11); \
+ hashv += (hashv << 15); \
+ bkt = hashv & (num_bkts-1); \
+} while(0)
+
+#define HASH_JEN_MIX(a,b,c) \
+do { \
+ a -= b; a -= c; a ^= ( c >> 13 ); \
+ b -= c; b -= a; b ^= ( a << 8 ); \
+ c -= a; c -= b; c ^= ( b >> 13 ); \
+ a -= b; a -= c; a ^= ( c >> 12 ); \
+ b -= c; b -= a; b ^= ( a << 16 ); \
+ c -= a; c -= b; c ^= ( b >> 5 ); \
+ a -= b; a -= c; a ^= ( c >> 3 ); \
+ b -= c; b -= a; b ^= ( a << 10 ); \
+ c -= a; c -= b; c ^= ( b >> 15 ); \
+} while (0)
+
+#define HASH_JEN(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ unsigned _hj_i,_hj_j,_hj_k; \
+ char *_hj_key=(char*)(key); \
+ hashv = 0xfeedbeef; \
+ _hj_i = _hj_j = 0x9e3779b9; \
+ _hj_k = keylen; \
+ while (_hj_k >= 12) { \
+ _hj_i += (_hj_key[0] + ( (unsigned)_hj_key[1] << 8 ) \
+ + ( (unsigned)_hj_key[2] << 16 ) \
+ + ( (unsigned)_hj_key[3] << 24 ) ); \
+ _hj_j += (_hj_key[4] + ( (unsigned)_hj_key[5] << 8 ) \
+ + ( (unsigned)_hj_key[6] << 16 ) \
+ + ( (unsigned)_hj_key[7] << 24 ) ); \
+ hashv += (_hj_key[8] + ( (unsigned)_hj_key[9] << 8 ) \
+ + ( (unsigned)_hj_key[10] << 16 ) \
+ + ( (unsigned)_hj_key[11] << 24 ) ); \
+ \
+ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
+ \
+ _hj_key += 12; \
+ _hj_k -= 12; \
+ } \
+ hashv += keylen; \
+ switch ( _hj_k ) { \
+ case 11: hashv += ( (unsigned)_hj_key[10] << 24 ); \
+ case 10: hashv += ( (unsigned)_hj_key[9] << 16 ); \
+ case 9: hashv += ( (unsigned)_hj_key[8] << 8 ); \
+ case 8: _hj_j += ( (unsigned)_hj_key[7] << 24 ); \
+ case 7: _hj_j += ( (unsigned)_hj_key[6] << 16 ); \
+ case 6: _hj_j += ( (unsigned)_hj_key[5] << 8 ); \
+ case 5: _hj_j += _hj_key[4]; \
+ case 4: _hj_i += ( (unsigned)_hj_key[3] << 24 ); \
+ case 3: _hj_i += ( (unsigned)_hj_key[2] << 16 ); \
+ case 2: _hj_i += ( (unsigned)_hj_key[1] << 8 ); \
+ case 1: _hj_i += _hj_key[0]; \
+ } \
+ HASH_JEN_MIX(_hj_i, _hj_j, hashv); \
+ bkt = hashv & (num_bkts-1); \
+} while(0)
+
+/* The Paul Hsieh hash function */
+#undef get16bits
+#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
+ || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
+#define get16bits(d) (*((const uint16_t *) (d)))
+#endif
+
+#if !defined (get16bits)
+#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8) \
+ +(uint32_t)(((const uint8_t *)(d))[0]) )
+#endif
+#define HASH_SFH(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ char *_sfh_key=(char*)(key); \
+ uint32_t _sfh_tmp, _sfh_len = keylen; \
+ \
+ int _sfh_rem = _sfh_len & 3; \
+ _sfh_len >>= 2; \
+ hashv = 0xcafebabe; \
+ \
+ /* Main loop */ \
+ for (;_sfh_len > 0; _sfh_len--) { \
+ hashv += get16bits (_sfh_key); \
+ _sfh_tmp = (get16bits (_sfh_key+2) << 11) ^ hashv; \
+ hashv = (hashv << 16) ^ _sfh_tmp; \
+ _sfh_key += 2*sizeof (uint16_t); \
+ hashv += hashv >> 11; \
+ } \
+ \
+ /* Handle end cases */ \
+ switch (_sfh_rem) { \
+ case 3: hashv += get16bits (_sfh_key); \
+ hashv ^= hashv << 16; \
+ hashv ^= _sfh_key[sizeof (uint16_t)] << 18; \
+ hashv += hashv >> 11; \
+ break; \
+ case 2: hashv += get16bits (_sfh_key); \
+ hashv ^= hashv << 11; \
+ hashv += hashv >> 17; \
+ break; \
+ case 1: hashv += *_sfh_key; \
+ hashv ^= hashv << 10; \
+ hashv += hashv >> 1; \
+ } \
+ \
+ /* Force "avalanching" of final 127 bits */ \
+ hashv ^= hashv << 3; \
+ hashv += hashv >> 5; \
+ hashv ^= hashv << 4; \
+ hashv += hashv >> 17; \
+ hashv ^= hashv << 25; \
+ hashv += hashv >> 6; \
+ bkt = hashv & (num_bkts-1); \
+} while(0);
+
+#ifdef HASH_USING_NO_STRICT_ALIASING
+/* The MurmurHash exploits some CPU's (x86,x86_64) tolerance for unaligned reads.
+ * For other types of CPU's (e.g. Sparc) an unaligned read causes a bus error.
+ * MurmurHash uses the faster approach only on CPU's where we know it's safe.
+ *
+ * Note the preprocessor built-in defines can be emitted using:
+ *
+ * gcc -m64 -dM -E - < /dev/null (on gcc)
+ * cc -## a.c (where a.c is a simple test file) (Sun Studio)
+ */
+#if (defined(__i386__) || defined(__x86_64__))
+#define MUR_GETBLOCK(p,i) p[i]
+#else /* non intel */
+#define MUR_PLUS0_ALIGNED(p) (((unsigned long)p & 0x3) == 0)
+#define MUR_PLUS1_ALIGNED(p) (((unsigned long)p & 0x3) == 1)
+#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 0x3) == 2)
+#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 0x3) == 3)
+#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL))
+#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__))
+#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))
+#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))
+#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8))
+#else /* assume little endian non-intel */
+#define MUR_THREE_ONE(p) ((((*WP(p))&0xffffff00) >> 8) | (((*(WP(p)+1))&0x000000ff) << 24))
+#define MUR_TWO_TWO(p) ((((*WP(p))&0xffff0000) >>16) | (((*(WP(p)+1))&0x0000ffff) << 16))
+#define MUR_ONE_THREE(p) ((((*WP(p))&0xff000000) >>24) | (((*(WP(p)+1))&0x00ffffff) << 8))
+#endif
+#define MUR_GETBLOCK(p,i) (MUR_PLUS0_ALIGNED(p) ? ((p)[i]) : \
+ (MUR_PLUS1_ALIGNED(p) ? MUR_THREE_ONE(p) : \
+ (MUR_PLUS2_ALIGNED(p) ? MUR_TWO_TWO(p) : \
+ MUR_ONE_THREE(p))))
+#endif
+#define MUR_ROTL32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
+#define MUR_FMIX(_h) \
+do { \
+ _h ^= _h >> 16; \
+ _h *= 0x85ebca6b; \
+ _h ^= _h >> 13; \
+ _h *= 0xc2b2ae35l; \
+ _h ^= _h >> 16; \
+} while(0)
+
+#define HASH_MUR(key,keylen,num_bkts,hashv,bkt) \
+do { \
+ const uint8_t *_mur_data = (const uint8_t*)(key); \
+ const int _mur_nblocks = (keylen) / 4; \
+ uint32_t _mur_h1 = 0xf88D5353; \
+ uint32_t _mur_c1 = 0xcc9e2d51; \
+ uint32_t _mur_c2 = 0x1b873593; \
+ const uint32_t *_mur_blocks = (const uint32_t*)(_mur_data+_mur_nblocks*4); \
+ int _mur_i; \
+ for(_mur_i = -_mur_nblocks; _mur_i; _mur_i++) { \
+ uint32_t _mur_k1 = MUR_GETBLOCK(_mur_blocks,_mur_i); \
+ _mur_k1 *= _mur_c1; \
+ _mur_k1 = MUR_ROTL32(_mur_k1,15); \
+ _mur_k1 *= _mur_c2; \
+ \
+ _mur_h1 ^= _mur_k1; \
+ _mur_h1 = MUR_ROTL32(_mur_h1,13); \
+ _mur_h1 = _mur_h1*5+0xe6546b64; \
+ } \
+ const uint8_t *_mur_tail = (const uint8_t*)(_mur_data + _mur_nblocks*4); \
+ uint32_t _mur_k1=0; \
+ switch((keylen) & 3) { \
+ case 3: _mur_k1 ^= _mur_tail[2] << 16; \
+ case 2: _mur_k1 ^= _mur_tail[1] << 8; \
+ case 1: _mur_k1 ^= _mur_tail[0]; \
+ _mur_k1 *= _mur_c1; \
+ _mur_k1 = MUR_ROTL32(_mur_k1,15); \
+ _mur_k1 *= _mur_c2; \
+ _mur_h1 ^= _mur_k1; \
+ } \
+ _mur_h1 ^= (keylen); \
+ MUR_FMIX(_mur_h1); \
+ hashv = _mur_h1; \
+ bkt = hashv & (num_bkts-1); \
+} while(0)
+#endif /* HASH_USING_NO_STRICT_ALIASING */
+
+/* key comparison function; return 0 if keys equal */
+#define HASH_KEYCMP(a,b,len) memcmp(a,b,len)
+
+/* iterate over items in a known bucket to find desired item */
+#define HASH_FIND_IN_BKT(tbl,hh,head,keyptr,keylen_in,out) \
+do { \
+ if (head.hh_head) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,head.hh_head)); \
+ else out=NULL; \
+ while (out) { \
+ if (out->hh.keylen == keylen_in) { \
+ if ((HASH_KEYCMP(out->hh.key,keyptr,keylen_in)) == 0) break; \
+ } \
+ if (out->hh.hh_next) DECLTYPE_ASSIGN(out,ELMT_FROM_HH(tbl,out->hh.hh_next)); \
+ else out = NULL; \
+ } \
+} while(0)
+
+/* add an item to a bucket */
+#define HASH_ADD_TO_BKT(head,addhh) \
+do { \
+ head.count++; \
+ (addhh)->hh_next = head.hh_head; \
+ (addhh)->hh_prev = NULL; \
+ if (head.hh_head) { (head).hh_head->hh_prev = (addhh); } \
+ (head).hh_head=addhh; \
+ if (head.count >= ((head.expand_mult+1) * HASH_BKT_CAPACITY_THRESH) \
+ && (addhh)->tbl->noexpand != 1) { \
+ HASH_EXPAND_BUCKETS((addhh)->tbl); \
+ } \
+} while(0)
+
+/* remove an item from a given bucket */
+#define HASH_DEL_IN_BKT(hh,head,hh_del) \
+ (head).count--; \
+ if ((head).hh_head == hh_del) { \
+ (head).hh_head = hh_del->hh_next; \
+ } \
+ if (hh_del->hh_prev) { \
+ hh_del->hh_prev->hh_next = hh_del->hh_next; \
+ } \
+ if (hh_del->hh_next) { \
+ hh_del->hh_next->hh_prev = hh_del->hh_prev; \
+ }
+
+/* Bucket expansion has the effect of doubling the number of buckets
+ * and redistributing the items into the new buckets. Ideally the
+ * items will distribute more or less evenly into the new buckets
+ * (the extent to which this is true is a measure of the quality of
+ * the hash function as it applies to the key domain).
+ *
+ * With the items distributed into more buckets, the chain length
+ * (item count) in each bucket is reduced. Thus by expanding buckets
+ * the hash keeps a bound on the chain length. This bounded chain
+ * length is the essence of how a hash provides constant time lookup.
+ *
+ * The calculation of tbl->ideal_chain_maxlen below deserves some
+ * explanation. First, keep in mind that we're calculating the ideal
+ * maximum chain length based on the *new* (doubled) bucket count.
+ * In fractions this is just n/b (n=number of items,b=new num buckets).
+ * Since the ideal chain length is an integer, we want to calculate
+ * ceil(n/b). We don't depend on floating point arithmetic in this
+ * hash, so to calculate ceil(n/b) with integers we could write
+ *
+ * ceil(n/b) = (n/b) + ((n%b)?1:0)
+ *
+ * and in fact a previous version of this hash did just that.
+ * But now we have improved things a bit by recognizing that b is
+ * always a power of two. We keep its base 2 log handy (call it lb),
+ * so now we can write this with a bit shift and logical AND:
+ *
+ * ceil(n/b) = (n>>lb) + ( (n & (b-1)) ? 1:0)
+ *
+ */
+#define HASH_EXPAND_BUCKETS(tbl) \
+do { \
+ unsigned _he_bkt; \
+ unsigned _he_bkt_i; \
+ struct UT_hash_handle *_he_thh, *_he_hh_nxt; \
+ UT_hash_bucket *_he_new_buckets, *_he_newbkt; \
+ _he_new_buckets = (UT_hash_bucket*)uthash_malloc( \
+ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
+ if (!_he_new_buckets) { uthash_fatal( "out of memory"); } \
+ memset(_he_new_buckets, 0, \
+ 2 * tbl->num_buckets * sizeof(struct UT_hash_bucket)); \
+ tbl->ideal_chain_maxlen = \
+ (tbl->num_items >> (tbl->log2_num_buckets+1)) + \
+ ((tbl->num_items & ((tbl->num_buckets*2)-1)) ? 1 : 0); \
+ tbl->nonideal_items = 0; \
+ for(_he_bkt_i = 0; _he_bkt_i < tbl->num_buckets; _he_bkt_i++) \
+ { \
+ _he_thh = tbl->buckets[ _he_bkt_i ].hh_head; \
+ while (_he_thh) { \
+ _he_hh_nxt = _he_thh->hh_next; \
+ HASH_TO_BKT( _he_thh->hashv, tbl->num_buckets*2, _he_bkt); \
+ _he_newbkt = &(_he_new_buckets[ _he_bkt ]); \
+ if (++(_he_newbkt->count) > tbl->ideal_chain_maxlen) { \
+ tbl->nonideal_items++; \
+ _he_newbkt->expand_mult = _he_newbkt->count / \
+ tbl->ideal_chain_maxlen; \
+ } \
+ _he_thh->hh_prev = NULL; \
+ _he_thh->hh_next = _he_newbkt->hh_head; \
+ if (_he_newbkt->hh_head) _he_newbkt->hh_head->hh_prev = \
+ _he_thh; \
+ _he_newbkt->hh_head = _he_thh; \
+ _he_thh = _he_hh_nxt; \
+ } \
+ } \
+ uthash_free( tbl->buckets, tbl->num_buckets*sizeof(struct UT_hash_bucket) ); \
+ tbl->num_buckets *= 2; \
+ tbl->log2_num_buckets++; \
+ tbl->buckets = _he_new_buckets; \
+ tbl->ineff_expands = (tbl->nonideal_items > (tbl->num_items >> 1)) ? \
+ (tbl->ineff_expands+1) : 0; \
+ if (tbl->ineff_expands > 1) { \
+ tbl->noexpand=1; \
+ uthash_noexpand_fyi(tbl); \
+ } \
+ uthash_expand_fyi(tbl); \
+} while(0)
+
+
+/* This is an adaptation of Simon Tatham's O(n log(n)) mergesort */
+/* Note that HASH_SORT assumes the hash handle name to be hh.
+ * HASH_SRT was added to allow the hash handle name to be passed in. */
+#define HASH_SORT(head,cmpfcn) HASH_SRT(hh,head,cmpfcn)
+#define HASH_SRT(hh,head,cmpfcn) \
+do { \
+ unsigned _hs_i; \
+ unsigned _hs_looping,_hs_nmerges,_hs_insize,_hs_psize,_hs_qsize; \
+ struct UT_hash_handle *_hs_p, *_hs_q, *_hs_e, *_hs_list, *_hs_tail; \
+ if (head) { \
+ _hs_insize = 1; \
+ _hs_looping = 1; \
+ _hs_list = &((head)->hh); \
+ while (_hs_looping) { \
+ _hs_p = _hs_list; \
+ _hs_list = NULL; \
+ _hs_tail = NULL; \
+ _hs_nmerges = 0; \
+ while (_hs_p) { \
+ _hs_nmerges++; \
+ _hs_q = _hs_p; \
+ _hs_psize = 0; \
+ for ( _hs_i = 0; _hs_i < _hs_insize; _hs_i++ ) { \
+ _hs_psize++; \
+ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \
+ ((void*)((char*)(_hs_q->next) + \
+ (head)->hh.tbl->hho)) : NULL); \
+ if (! (_hs_q) ) break; \
+ } \
+ _hs_qsize = _hs_insize; \
+ while ((_hs_psize > 0) || ((_hs_qsize > 0) && _hs_q )) { \
+ if (_hs_psize == 0) { \
+ _hs_e = _hs_q; \
+ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \
+ ((void*)((char*)(_hs_q->next) + \
+ (head)->hh.tbl->hho)) : NULL); \
+ _hs_qsize--; \
+ } else if ( (_hs_qsize == 0) || !(_hs_q) ) { \
+ _hs_e = _hs_p; \
+ _hs_p = (UT_hash_handle*)((_hs_p->next) ? \
+ ((void*)((char*)(_hs_p->next) + \
+ (head)->hh.tbl->hho)) : NULL); \
+ _hs_psize--; \
+ } else if (( \
+ cmpfcn(DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_p)), \
+ DECLTYPE(head)(ELMT_FROM_HH((head)->hh.tbl,_hs_q))) \
+ ) <= 0) { \
+ _hs_e = _hs_p; \
+ _hs_p = (UT_hash_handle*)((_hs_p->next) ? \
+ ((void*)((char*)(_hs_p->next) + \
+ (head)->hh.tbl->hho)) : NULL); \
+ _hs_psize--; \
+ } else { \
+ _hs_e = _hs_q; \
+ _hs_q = (UT_hash_handle*)((_hs_q->next) ? \
+ ((void*)((char*)(_hs_q->next) + \
+ (head)->hh.tbl->hho)) : NULL); \
+ _hs_qsize--; \
+ } \
+ if ( _hs_tail ) { \
+ _hs_tail->next = ((_hs_e) ? \
+ ELMT_FROM_HH((head)->hh.tbl,_hs_e) : NULL); \
+ } else { \
+ _hs_list = _hs_e; \
+ } \
+ _hs_e->prev = ((_hs_tail) ? \
+ ELMT_FROM_HH((head)->hh.tbl,_hs_tail) : NULL); \
+ _hs_tail = _hs_e; \
+ } \
+ _hs_p = _hs_q; \
+ } \
+ _hs_tail->next = NULL; \
+ if ( _hs_nmerges <= 1 ) { \
+ _hs_looping=0; \
+ (head)->hh.tbl->tail = _hs_tail; \
+ DECLTYPE_ASSIGN(head,ELMT_FROM_HH((head)->hh.tbl, _hs_list)); \
+ } \
+ _hs_insize *= 2; \
+ } \
+ HASH_FSCK(hh,head); \
+ } \
+} while (0)
+
+/* This function selects items from one hash into another hash.
+ * The end result is that the selected items have dual presence
+ * in both hashes. There is no copy of the items made; rather
+ * they are added into the new hash through a secondary hash
+ * hash handle that must be present in the structure. */
+#define HASH_SELECT(hh_dst, dst, hh_src, src, cond) \
+do { \
+ unsigned _src_bkt, _dst_bkt; \
+ void *_last_elt=NULL, *_elt; \
+ UT_hash_handle *_src_hh, *_dst_hh, *_last_elt_hh=NULL; \
+ ptrdiff_t _dst_hho = ((char*)(&(dst)->hh_dst) - (char*)(dst)); \
+ if (src) { \
+ for(_src_bkt=0; _src_bkt < (src)->hh_src.tbl->num_buckets; _src_bkt++) { \
+ for(_src_hh = (src)->hh_src.tbl->buckets[_src_bkt].hh_head; \
+ _src_hh; \
+ _src_hh = _src_hh->hh_next) { \
+ _elt = ELMT_FROM_HH((src)->hh_src.tbl, _src_hh); \
+ if (cond(_elt)) { \
+ _dst_hh = (UT_hash_handle*)(((char*)_elt) + _dst_hho); \
+ _dst_hh->key = _src_hh->key; \
+ _dst_hh->keylen = _src_hh->keylen; \
+ _dst_hh->hashv = _src_hh->hashv; \
+ _dst_hh->prev = _last_elt; \
+ _dst_hh->next = NULL; \
+ if (_last_elt_hh) { _last_elt_hh->next = _elt; } \
+ if (!dst) { \
+ DECLTYPE_ASSIGN(dst,_elt); \
+ HASH_MAKE_TABLE(hh_dst,dst); \
+ } else { \
+ _dst_hh->tbl = (dst)->hh_dst.tbl; \
+ } \
+ HASH_TO_BKT(_dst_hh->hashv, _dst_hh->tbl->num_buckets, _dst_bkt); \
+ HASH_ADD_TO_BKT(_dst_hh->tbl->buckets[_dst_bkt],_dst_hh); \
+ (dst)->hh_dst.tbl->num_items++; \
+ _last_elt = _elt; \
+ _last_elt_hh = _dst_hh; \
+ } \
+ } \
+ } \
+ } \
+ HASH_FSCK(hh_dst,dst); \
+} while (0)
+
+#define HASH_CLEAR(hh,head) \
+do { \
+ if (head) { \
+ uthash_free((head)->hh.tbl->buckets, \
+ (head)->hh.tbl->num_buckets*sizeof(struct UT_hash_bucket)); \
+ uthash_free((head)->hh.tbl, sizeof(UT_hash_table)); \
+ (head)=NULL; \
+ } \
+} while(0)
+
+#ifdef NO_DECLTYPE
+#define HASH_ITER(hh,head,el,tmp) \
+for((el)=(head), (*(char**)(&(tmp)))=(char*)((head)?(head)->hh.next:NULL); \
+ el; (el)=(tmp),(*(char**)(&(tmp)))=(char*)((tmp)?(tmp)->hh.next:NULL))
+#else
+#define HASH_ITER(hh,head,el,tmp) \
+for((el)=(head),(tmp)=DECLTYPE(el)((head)?(head)->hh.next:NULL); \
+ el; (el)=(tmp),(tmp)=DECLTYPE(el)((tmp)?(tmp)->hh.next:NULL))
+#endif
+
+/* obtain a count of items in the hash */
+#define HASH_COUNT(head) HASH_CNT(hh,head)
+#define HASH_CNT(hh,head) ((head)?((head)->hh.tbl->num_items):0)
+
+typedef struct UT_hash_bucket
+{
+ struct UT_hash_handle *hh_head;
+ unsigned count;
+
+ /* expand_mult is normally set to 0. In this situation, the max chain length
+ * threshold is enforced at its default value, HASH_BKT_CAPACITY_THRESH. (If
+ * the bucket's chain exceeds this length, bucket expansion is triggered).
+ * However, setting expand_mult to a non-zero value delays bucket expansion
+ * (that would be triggered by additions to this particular bucket)
+ * until its chain length reaches a *multiple* of HASH_BKT_CAPACITY_THRESH.
+ * (The multiplier is simply expand_mult+1). The whole idea of this
+ * multiplier is to reduce bucket expansions, since they are expensive, in
+ * situations where we know that a particular bucket tends to be overused.
+ * It is better to let its chain length grow to a longer yet-still-bounded
+ * value, than to do an O(n) bucket expansion too often.
+ */
+ unsigned expand_mult;
+
+} UT_hash_bucket;
+
+/* random signature used only to find hash tables in external analysis */
+#define HASH_SIGNATURE 0xa0111fe1
+#define HASH_BLOOM_SIGNATURE 0xb12220f2
+
+typedef struct UT_hash_table
+{
+ UT_hash_bucket *buckets;
+ unsigned num_buckets, log2_num_buckets;
+ unsigned num_items;
+ struct UT_hash_handle *tail; /* tail hh in app order, for fast append */
+ ptrdiff_t hho; /* hash handle offset (byte pos of hash handle in element */
+
+ /* in an ideal situation (all buckets used equally), no bucket would have
+ * more than ceil(#items/#buckets) items. that's the ideal chain length. */
+ unsigned ideal_chain_maxlen;
+
+ /* nonideal_items is the number of items in the hash whose chain position
+ * exceeds the ideal chain maxlen. these items pay the penalty for an uneven
+ * hash distribution; reaching them in a chain traversal takes >ideal steps */
+ unsigned nonideal_items;
+
+ /* ineffective expands occur when a bucket doubling was performed, but
+ * afterward, more than half the items in the hash had nonideal chain
+ * positions. If this happens on two consecutive expansions we inhibit any
+ * further expansion, as it's not helping; this happens when the hash
+ * function isn't a good fit for the key domain. When expansion is inhibited
+ * the hash will still work, albeit no longer in constant time. */
+ unsigned ineff_expands, noexpand;
+
+ uint32_t signature; /* used only to find hash tables in external analysis */
+#ifdef HASH_BLOOM
+ uint32_t bloom_sig; /* used only to test bloom exists in external analysis */
+ uint8_t *bloom_bv;
+ char bloom_nbits;
+#endif
+
+} UT_hash_table;
+
+typedef struct UT_hash_handle
+{
+ struct UT_hash_table *tbl;
+ void *prev; /* prev element in app order */
+ void *next; /* next element in app order */
+ struct UT_hash_handle *hh_prev; /* previous hh in bucket order */
+ struct UT_hash_handle *hh_next; /* next hh in bucket order */
+ void *key; /* ptr to enclosing struct's key */
+ unsigned keylen; /* enclosing struct's key len */
+ unsigned hashv; /* result of hash-fcn(key) */
+} UT_hash_handle;
+
+#endif /* UTHASH_H */
diff --git a/inc/verify.h b/inc/verify.h
new file mode 100644
index 0000000..663d496
--- /dev/null
+++ b/inc/verify.h
@@ -0,0 +1,131 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef VERIFY_H
+#define VERIFY_H
+
+
+#ifndef _WIN32
+#define C_ASSERT(test) \
+ switch(0) {\
+ case 0:\
+ case test:;\
+ }
+#endif // _WIN32
+
+#ifndef __V_STR__
+#define __V_STR__(x) #x ":"
+#endif //__STR__
+#ifndef __V_TOSTR__
+#define __V_TOSTR__(x) __V_STR__(x)
+#endif // __TOSTR__
+#ifndef __V_FILE_LINE__
+#define __V_FILE_LINE__ __FILE__ ":" __V_TOSTR__(__LINE__)
+#endif /*__FILE_LINE__*/
+
+#if (defined __hexagon__) || (defined __qdsp6__)
+/* q6 */
+
+#ifdef VERIFY_PRINT_INFO
+#define FARF_VERIFY_LOW 1
+#define FARF_VERIFY_LOW_LEVEL HAP_LEVEL_LOW
+#define VERIFY_IPRINTF(args...) FARF(VERIFY_LOW, args)
+#endif
+
+#ifdef VERIFY_PRINT_ERROR
+#define FARF_VERIFY_ERROR 1
+#define FARF_VERIFY_ERROR_LEVEL HAP_LEVEL_ERROR
+#define VERIFY_EPRINTF(args...) FARF(VERIFY_ERROR, args)
+#endif
+
+#if (defined VERIFY_PRINT_INFO) || (defined VERIFY_PRINT_ERROR)
+#include "HAP_farf.h"
+#endif
+
+/* end q6 */
+#elif (defined USE_SYSLOG)
+/* syslog */
+#if (defined VERIFY_PRINT_INFO) || (defined VERIFY_PRINT_ERROR)
+#include <syslog.h>
+#endif
+
+#ifdef VERIFY_PRINT_INFO
+#define VERIFY_IPRINTF(format, ...) syslog(LOG_USER|LOG_INFO, __V_FILE_LINE__ format, ##__VA_ARGS__)
+//#define VERIFY_IPRINTF(format, ...) printf(__V_FILE_LINE__ format "\n", ##__VA_ARGS__)
+#endif
+
+#ifdef VERIFY_PRINT_ERROR
+//#define VERIFY_EPRINTF(format, ...) printf(__V_FILE_LINE__ format "\n", ##__VA_ARGS__)
+#define VERIFY_EPRINTF(format, ...) syslog(LOG_USER|LOG_ERR, __V_FILE_LINE__ format, ##__VA_ARGS__)
+#endif
+
+/* end syslog */
+#else
+/* generic */
+
+#if (defined VERIFY_PRINT_INFO) || (defined VERIFY_PRINT_ERROR)
+#include <stdio.h>
+#endif
+
+#ifdef VERIFY_PRINT_INFO
+#define VERIFY_IPRINTF(format, ...) printf(__V_FILE_LINE__ format "\n", ##__VA_ARGS__)
+#endif
+
+#ifdef VERIFY_PRINT_ERROR
+#define VERIFY_EPRINTF(format, ...) printf(__V_FILE_LINE__ format "\n", ##__VA_ARGS__)
+#endif
+
+/* end generic */
+#endif
+
+#ifndef VERIFY_PRINT_INFO
+#define VERIFY_IPRINTF(format, ...) (void)0
+#endif
+
+#ifndef VERIFY_PRINT_ERROR
+#define VERIFY_EPRINTF(format, ...) (void)0
+#endif
+
+#ifndef VERIFY
+#define VERIFY(val) \
+ do {\
+ VERIFY_IPRINTF(":info: calling: %s", #val);\
+ if(0 == (val)) {\
+ nErr = nErr == 0 ? -1 : nErr;\
+ VERIFY_EPRINTF(":error: %d: %s", nErr, #val);\
+ goto bail;\
+ } else {\
+ VERIFY_IPRINTF(":info: passed: %s", #val);\
+ }\
+ } while(0)
+#endif //VERIFY
+
+#endif //VERIFY_H
+
diff --git a/inc/version.h b/inc/version.h
new file mode 100644
index 0000000..f89814d
--- /dev/null
+++ b/inc/version.h
@@ -0,0 +1,129 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef VERSION_H
+#define VERSION_H
+/*===========================================================================
+
+FILE: version.h
+
+GENERAL DESCRIPTION:
+ Definitions for versioning
+
+===========================================================================*/
+
+#if !defined(VERSION_CL)
+#define VERSION_CL "?"
+#endif
+
+#if !defined(VERSION_PROD)
+#define VERSION_PROD "unknown"
+#endif
+
+#if !defined(VERSION_BRANCH)
+#define VERSION_BRANCH "?"
+#endif
+
+#if !defined(VERSION_NUM)
+#define VERSION_NUM "?.?.?.?"
+#endif
+
+#define VERSION_STRING \
+ VERSION_PROD " " \
+ VERSION_NUM " " \
+ "(br=" VERSION_BRANCH "; cl=" VERSION_CL ")"
+
+/*
+=======================================================================
+MACROS DOCUMENTATION
+=======================================================================
+
+VERSION_MAJOR
+
+Description:
+ Defines the major release number of the version.
+
+Comments:
+ It has to be a valid numerical value
+=======================================================================
+
+VERSION_MINOR
+
+Description:
+ Defines the minor release number of the version.
+
+Comments:
+ It has to be a valid numerical value
+=======================================================================
+
+VERSION_MAINT
+
+Description:
+ Defines the maintenance release of the version.
+
+Comments:
+ It has to be a valid numerical value
+=======================================================================
+
+VERSION_BUILD
+
+Description:
+ Defines the build ID of the version.
+
+Comments:
+ It has to be a valid numerical value
+=======================================================================
+
+VERSION_STRING
+
+Description:
+ Defines the version string that specifies the version number.
+
+Definition:
+
+ #define VERSION_STRING "a.b.c.d (name=value;name=value;...)"
+ where a=major release number
+ b=minor release number
+ c=maintenance release number
+ d=build number
+
+ name=value pair provides additional information about the build.
+ Example:
+ patch/feature=comma separated list of features/patches that have been installed.
+ br=p4 branch that was used for the build
+ cl=p4 change list number
+ machine=hostname of the machine that was used for the build.
+
+Comments:
+
+=======================================================================
+*/
+
+#endif // VERSION_H
diff --git a/src/AEEsmath.h b/src/AEEsmath.h
new file mode 100644
index 0000000..491b92f
--- /dev/null
+++ b/src/AEEsmath.h
@@ -0,0 +1,12 @@
+/*====================================================================
+Copyright (c) 200-2006,2013 QUALCOMM Technologies Inc. All Rights Reserved.
+Qualcomm Technologies Confidential and Proprietary
+======================================================================
+
+DESCRIPTION: Safe math library; implements saturating add.
+
+====================================================================*/
+
+extern int smath_Add(int a, int b);
+extern int smath_Sub(int a, int b);
+extern int smath_Mul(int a, int b);
diff --git a/src/BufBound.c b/src/BufBound.c
new file mode 100644
index 0000000..ab85e86
--- /dev/null
+++ b/src/BufBound.c
@@ -0,0 +1,228 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <limits.h>
+#include "AEEBufBound.h"
+#include "AEEstd.h"
+
+/* Note on bounds-checking logic and saturation:
+ Simple pointer comparisons are not adequate for bounds checking. pcBuf
+ and pcEnd are assumed to be valid pointers in the address space. But
+ pcWrite is not ... it is a theoretical value that can exceed pcEnd, and
+ may in fact wrap around the end of the address space. In that case the
+ test for (pcWrite < pcEnd) will yield TRUE, although pcWrite is outside
+ the buffer. Use (pcEnd-pcWrite) > 0 to be accurate.
+
+ In order to ensure this works in all cases, we need to avoid integer
+ overflows. We do this by restricting pcWrite to the range
+ [pcBuf..pcBuf+INT_MAX]. The ensures that pcWrite-pcBuf and pcWrite-pcBuf
+ will always be valid integers. It also allows us to ensure that
+ BufBound_Wrote() will not return wildly misleading results.
+
+ PCSAT
+ pcBuf pcEnd pcBuf+MAXINT
+ |-------------------| . . . . . . . . . |
+ ^ ^
+ pcWrite: (a) (b) */
+
+#define PCSAT(me) ((me)->pcBuf + INT_MAX)
+
+
+/* Advance me->pcWrite, saturating.
+ On entry:
+ *pnLen = number of bytes to be written (non-negative)
+ On exit:
+ return value = where to write (pointer into the buffer)
+ *pnLen = number of bytes to write */
+static char *BufBound_ValidateWrite(BufBound *me, int *pnLen)
+{
+ int nLen = *pnLen;
+ char *pcWrite = me->pcWrite;
+ int nMaxCopy = me->pcEnd - pcWrite; /* could be negative! */
+
+ if (nMaxCopy < nLen)
+ {
+ /* Must check PCSAT to validate advance */
+ int nMaxAdvance = PCSAT(me) - pcWrite; /* max amount to advance */
+
+ if (nLen > nMaxAdvance)
+ {
+ nLen = nMaxAdvance;
+ }
+ if (nMaxCopy < 0)
+ {
+ nMaxCopy = 0;
+ }
+ }
+ else
+ {
+ /* Simple case: all fits in the buffer */
+ nMaxCopy = nLen;
+ }
+
+ *pnLen = nMaxCopy;
+ me->pcWrite = pcWrite + nLen;
+ return pcWrite;
+}
+
+void BufBound_Write(BufBound *me, const char *pc, int nLen)
+{
+ if (nLen > 0)
+ {
+ char *pcDest = BufBound_ValidateWrite(me, &nLen);
+
+ while (--nLen >= 0)
+ {
+ pcDest[nLen] = pc[nLen];
+ }
+ }
+}
+
+void BufBound_Putnc(BufBound *me, char c, int nLen)
+{
+ if (nLen > 0)
+ {
+ char *pcDest = BufBound_ValidateWrite(me, &nLen);
+
+ while (--nLen >= 0)
+ {
+ pcDest[nLen] = c;
+ }
+ }
+}
+
+void BufBound_Advance(BufBound *me, int nLen)
+{
+ uint32 uOffset = (uint32)((me->pcWrite - me->pcBuf) + nLen);
+
+ if (uOffset > INT_MAX)
+ {
+ uOffset = INT_MAX;
+ if (nLen < 0)
+ {
+ uOffset = 0;
+ }
+ }
+ me->pcWrite = me->pcBuf + uOffset;
+}
+
+void BufBound_Init(BufBound *me, char *pBuf, int nLen)
+{
+ if (nLen < 0)
+ {
+ nLen = 0;
+ }
+ me->pcWrite = me->pcBuf = pBuf;
+ me->pcEnd = pBuf + nLen;
+}
+
+void BufBound_Putc(BufBound *me, char c)
+{
+ if ((me->pcEnd - me->pcWrite) > 0)
+ {
+ *me->pcWrite++ = c;
+ }
+ else if (me->pcWrite != PCSAT(me))
+ {
+ ++me->pcWrite;
+ }
+}
+
+void BufBound_ForceNullTerm(BufBound *me)
+{
+ if ((me->pcEnd - me->pcWrite) > 0)
+ {
+ *me->pcWrite++ = '\0';
+ }
+ else
+ {
+ if (me->pcWrite != PCSAT(me))
+ {
+ ++me->pcWrite;
+ }
+ /* Ensure null termination if non-empty buffer */
+ if (me->pcEnd != me->pcBuf)
+ {
+ me->pcEnd[-1] = '\0';
+ }
+ }
+}
+
+void BufBound_Puts(BufBound *me, const char *cpsz)
+{
+ BufBound_Write(me, cpsz, std_strlen(cpsz));
+}
+
+int BufBound_BufSize(BufBound *me)
+{
+ return me->pcEnd - me->pcBuf;
+}
+
+int BufBound_Left(BufBound *me)
+{
+ return (me->pcEnd - me->pcWrite);
+}
+
+int BufBound_ReallyWrote(BufBound *me)
+{
+ return STD_MIN(me->pcEnd - me->pcBuf, me->pcWrite - me->pcBuf);
+}
+
+int BufBound_Wrote(BufBound *me)
+{
+ return (me->pcWrite - me->pcBuf);
+}
+
+void BufBound_WriteLE(BufBound *me,
+ const void *pvSrc, int nSrcSize,
+ const char *pszFields)
+{
+ if (nSrcSize > 0)
+ {
+ int nLen = nSrcSize;
+ char *pcDest = BufBound_ValidateWrite(me, &nLen);
+
+ (void)std_CopyLE(pcDest, nLen, pvSrc, nSrcSize, pszFields);
+ }
+}
+
+void BufBound_WriteBE(BufBound *me,
+ const void *pvSrc, int nSrcSize,
+ const char *pszFields)
+{
+ if (nSrcSize > 0)
+ {
+ int nLen = nSrcSize;
+ char *pcDest = BufBound_ValidateWrite(me, &nLen);
+
+ (void)std_CopyBE(pcDest, nLen, pvSrc, nSrcSize, pszFields);
+ }
+}
+
diff --git a/src/adsp_current_process_stub.c b/src/adsp_current_process_stub.c
new file mode 100644
index 0000000..ab11e21
--- /dev/null
+++ b/src/adsp_current_process_stub.c
@@ -0,0 +1,727 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _ADSP_CURRENT_PROCESS_STUB_H
+#define _ADSP_CURRENT_PROCESS_STUB_H
+
+#include "adsp_current_process.h"
+#ifndef _QAIC_ENV_H
+#define _QAIC_ENV_H
+
+#ifdef __GNUC__
+#ifdef __clang__
+#pragma GCC diagnostic ignored "-Wunknown-pragmas"
+#else
+#pragma GCC diagnostic ignored "-Wpragmas"
+#endif
+#pragma GCC diagnostic ignored "-Wuninitialized"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+#ifndef _ATTRIBUTE_UNUSED
+
+#ifdef _WIN32
+#define _ATTRIBUTE_UNUSED
+#else
+#define _ATTRIBUTE_UNUSED __attribute__ ((unused))
+#endif
+
+#endif // _ATTRIBUTE_UNUSED
+
+#ifndef __QAIC_REMOTE
+#define __QAIC_REMOTE(ff) ff
+#endif //__QAIC_REMOTE
+
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+
+#ifndef __QAIC_STUB
+#define __QAIC_STUB(ff) ff
+#endif //__QAIC_STUB
+
+#ifndef __QAIC_STUB_EXPORT
+#define __QAIC_STUB_EXPORT
+#endif // __QAIC_STUB_EXPORT
+
+#ifndef __QAIC_STUB_ATTRIBUTE
+#define __QAIC_STUB_ATTRIBUTE
+#endif // __QAIC_STUB_ATTRIBUTE
+
+#ifndef __QAIC_SKEL
+#define __QAIC_SKEL(ff) ff
+#endif //__QAIC_SKEL__
+
+#ifndef __QAIC_SKEL_EXPORT
+#define __QAIC_SKEL_EXPORT
+#endif // __QAIC_SKEL_EXPORT
+
+#ifndef __QAIC_SKEL_ATTRIBUTE
+#define __QAIC_SKEL_ATTRIBUTE
+#endif // __QAIC_SKEL_ATTRIBUTE
+
+#ifdef __QAIC_DEBUG__
+#ifndef __QAIC_DBG_PRINTF__
+#include <stdio.h>
+#define __QAIC_DBG_PRINTF__( ee ) do { printf ee ; } while(0)
+#endif
+#else
+#define __QAIC_DBG_PRINTF__( ee ) (void)0
+#endif
+
+
+#define _OFFSET(src, sof) ((void*)(((char*)(src)) + (sof)))
+
+#define _COPY(dst, dof, src, sof, sz) \
+ do {\
+ struct __copy { \
+ char ar[sz]; \
+ };\
+ *(struct __copy*)_OFFSET(dst, dof) = *(struct __copy*)_OFFSET(src, sof);\
+ } while (0)
+
+#define _COPYIF(dst, dof, src, sof, sz) \
+ do {\
+ if(_OFFSET(dst, dof) != _OFFSET(src, sof)) {\
+ _COPY(dst, dof, src, sof, sz); \
+ } \
+ } while (0)
+
+_ATTRIBUTE_UNUSED
+static __inline void _qaic_memmove(void *dst, void *src, int size)
+{
+ int i;
+ for (i = 0; i < size; ++i)
+ {
+ ((char *)dst)[i] = ((char *)src)[i];
+ }
+}
+
+#define _MEMMOVEIF(dst, src, sz) \
+ do {\
+ if(dst != src) {\
+ _qaic_memmove(dst, src, sz);\
+ } \
+ } while (0)
+
+
+#define _ASSIGN(dst, src, sof) \
+ do {\
+ dst = OFFSET(src, sof); \
+ } while (0)
+
+#define _STD_STRLEN_IF(str) (str == 0 ? 0 : strlen(str))
+
+#include "AEEStdErr.h"
+
+#define _TRY(ee, func) \
+ do { \
+ if (AEE_SUCCESS != ((ee) = func)) {\
+ __QAIC_DBG_PRINTF__((__FILE__ ":%d:error:%d:%s\n", __LINE__, (int)(ee),#func));\
+ goto ee##bail;\
+ } \
+ } while (0)
+
+#define _CATCH(exception) exception##bail: if (exception != AEE_SUCCESS)
+
+#define _ASSERT(nErr, ff) _TRY(nErr, 0 == (ff) ? AEE_EBADPARM : AEE_SUCCESS)
+
+#ifdef __QAIC_DEBUG__
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, _allocator_alloc(pal, __FILE_LINE__, size, alignment, (void**)&pv))
+#else
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, _allocator_alloc(pal, 0, size, alignment, (void**)&pv))
+#endif
+
+
+#endif // _QAIC_ENV_H
+
+#include "remote.h"
+#include <string.h>
+#ifndef _ALLOCATOR_H
+#define _ALLOCATOR_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef struct _heap _heap;
+struct _heap
+{
+ _heap *pPrev;
+ const char *loc;
+ uint64_t buf;
+};
+
+typedef struct _allocator
+{
+ _heap *pheap;
+ uint8_t *stack;
+ uint8_t *stackEnd;
+ int nSize;
+} _allocator;
+
+_ATTRIBUTE_UNUSED
+static __inline int _heap_alloc(_heap **ppa, const char *loc, int size, void **ppbuf)
+{
+ _heap *pn = 0;
+ pn = malloc(size + sizeof(_heap) - sizeof(uint64_t));
+ if (pn != 0)
+ {
+ pn->pPrev = *ppa;
+ pn->loc = loc;
+ *ppa = pn;
+ *ppbuf = (void *) & (pn->buf);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+#define _ALIGN_SIZE(x, y) (((x) + (y-1)) & ~(y-1))
+
+_ATTRIBUTE_UNUSED
+static __inline int _allocator_alloc(_allocator *me,
+ const char *loc,
+ int size,
+ unsigned int al,
+ void **ppbuf)
+{
+ if (size < 0)
+ {
+ return -1;
+ }
+ else if (size == 0)
+ {
+ *ppbuf = 0;
+ return 0;
+ }
+ if ((_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size) < (uintptr_t)me->stack + me->nSize)
+ {
+ *ppbuf = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al);
+ me->stackEnd = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size;
+ return 0;
+ }
+ else
+ {
+ return _heap_alloc(&me->pheap, loc, size, ppbuf);
+ }
+}
+
+_ATTRIBUTE_UNUSED
+static __inline void _allocator_deinit(_allocator *me)
+{
+ _heap *pa = me->pheap;
+ while (pa != 0)
+ {
+ _heap *pn = pa;
+ const char *loc = pn->loc;
+ (void)loc;
+ pa = pn->pPrev;
+ free(pn);
+ }
+}
+
+_ATTRIBUTE_UNUSED
+static __inline void _allocator_init(_allocator *me, uint8_t *stack, int stackSize)
+{
+ me->stack = stack;
+ me->stackEnd = stack + stackSize;
+ me->nSize = stackSize;
+ me->pheap = 0;
+}
+
+
+#endif // _ALLOCATOR_H
+
+#ifndef SLIM_H
+#define SLIM_H
+
+#include <stdint.h>
+
+//a C data structure for the idl types that can be used to implement
+//static and dynamic language bindings fairly efficiently.
+//
+//the goal is to have a minimal ROM and RAM footprint and without
+//doing too many allocations. A good way to package these things seemed
+//like the module boundary, so all the idls within one module can share
+//all the type references.
+
+
+#define PARAMETER_IN 0x0
+#define PARAMETER_OUT 0x1
+#define PARAMETER_INOUT 0x2
+#define PARAMETER_ROUT 0x3
+#define PARAMETER_INROUT 0x4
+
+//the types that we get from idl
+#define TYPE_OBJECT 0x0
+#define TYPE_INTERFACE 0x1
+#define TYPE_PRIMITIVE 0x2
+#define TYPE_ENUM 0x3
+#define TYPE_STRING 0x4
+#define TYPE_WSTRING 0x5
+#define TYPE_STRUCTURE 0x6
+#define TYPE_UNION 0x7
+#define TYPE_ARRAY 0x8
+#define TYPE_SEQUENCE 0x9
+
+//these require the pack/unpack to recurse
+//so it's a hint to those languages that can optimize in cases where
+//recursion isn't necessary.
+#define TYPE_COMPLEX_STRUCTURE (0x10 | TYPE_STRUCTURE)
+#define TYPE_COMPLEX_UNION (0x10 | TYPE_UNION)
+#define TYPE_COMPLEX_ARRAY (0x10 | TYPE_ARRAY)
+#define TYPE_COMPLEX_SEQUENCE (0x10 | TYPE_SEQUENCE)
+
+
+typedef struct Type Type;
+
+#define INHERIT_TYPE\
+ int32_t nativeSize; /*in the simple case its the same as wire size and alignment*/\
+ union {\
+ struct {\
+ const uintptr_t p1;\
+ const uintptr_t p2;\
+ } _cast;\
+ struct {\
+ uint32_t iid;\
+ uint32_t bNotNil;\
+ } object;\
+ struct {\
+ const Type *arrayType;\
+ int32_t nItems;\
+ } array;\
+ struct {\
+ const Type *seqType;\
+ int32_t nMaxLen;\
+ } seqSimple; \
+ struct {\
+ uint32_t bFloating;\
+ uint32_t bSigned;\
+ } prim; \
+ const SequenceType* seqComplex;\
+ const UnionType *unionType;\
+ const StructType *structType;\
+ int32_t stringMaxLen;\
+ uint8_t bInterfaceNotNil;\
+ } param;\
+ uint8_t type;\
+ uint8_t nativeAlignment\
+
+typedef struct UnionType UnionType;
+typedef struct StructType StructType;
+typedef struct SequenceType SequenceType;
+struct Type
+{
+ INHERIT_TYPE;
+};
+
+struct SequenceType
+{
+ const Type *seqType;
+ uint32_t nMaxLen;
+ uint32_t inSize;
+ uint32_t routSizePrimIn;
+ uint32_t routSizePrimROut;
+};
+
+//byte offset from the start of the case values for
+//this unions case value array. it MUST be aligned
+//at the alignment requrements for the descriptor
+//
+//if negative it means that the unions cases are
+//simple enumerators, so the value read from the descriptor
+//can be used directly to find the correct case
+typedef union CaseValuePtr CaseValuePtr;
+union CaseValuePtr
+{
+ const uint8_t *value8s;
+ const uint16_t *value16s;
+ const uint32_t *value32s;
+ const uint64_t *value64s;
+};
+
+//these are only used in complex cases
+//so I pulled them out of the type definition as references to make
+//the type smaller
+struct UnionType
+{
+ const Type *descriptor;
+ uint32_t nCases;
+ const CaseValuePtr caseValues;
+ const Type *const *cases;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+ uint8_t inCaseAlignment;
+ uint8_t routCaseAlignmentPrimIn;
+ uint8_t routCaseAlignmentPrimROut;
+ uint8_t nativeCaseAlignment;
+ uint8_t bDefaultCase;
+};
+
+struct StructType
+{
+ uint32_t nMembers;
+ const Type *const *members;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+};
+
+typedef struct Parameter Parameter;
+struct Parameter
+{
+ INHERIT_TYPE;
+ uint8_t mode;
+ uint8_t bNotNil;
+};
+
+#define SLIM_IFPTR32(is32,is64) (sizeof(uintptr_t) == 4 ? (is32) : (is64))
+#define SLIM_SCALARS_IS_DYNAMIC(u) (((u) & 0x00ffffff) == 0x00ffffff)
+
+typedef struct Method Method;
+struct Method
+{
+ uint32_t uScalars; //no method index
+ int32_t primInSize;
+ int32_t primROutSize;
+ int maxArgs;
+ int numParams;
+ const Parameter *const *params;
+ uint8_t primInAlignment;
+ uint8_t primROutAlignment;
+};
+
+typedef struct Interface Interface;
+
+struct Interface
+{
+ int nMethods;
+ const Method *const *methodArray;
+ int nIIds;
+ const uint32_t *iids;
+ const uint16_t *methodStringArray;
+ const uint16_t *methodStrings;
+ const char *strings;
+};
+
+
+#endif //SLIM_H
+
+
+#ifndef _ADSP_CURRENT_PROCESS_SLIM_H
+#define _ADSP_CURRENT_PROCESS_SLIM_H
+#include "remote.h"
+#include <stdint.h>
+
+#ifndef __QAIC_SLIM
+#define __QAIC_SLIM(ff) ff
+#endif
+#ifndef __QAIC_SLIM_EXPORT
+#define __QAIC_SLIM_EXPORT
+#endif
+
+static const Type types[1];
+static const SequenceType sequenceTypes[1] = {{&(types[0]), 0x0, 0x4, 0x4, 0x0}};
+static const Type types[1] = {{SLIM_IFPTR32(0x8, 0x10), {{(const uintptr_t)0x0, 0}}, 4, SLIM_IFPTR32(0x4, 0x8)}};
+static const Parameter parameters[3] = {{0x2, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x2, 0, 0}, {SLIM_IFPTR32(0x8, 0x10), {{(const uintptr_t) &(sequenceTypes[0]), 0}}, 25, SLIM_IFPTR32(0x4, 0x8), 0, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x4, 3, 0}};
+static const Parameter *const parameterArrays[3] = {(&(parameters[0])), (&(parameters[1])), (&(parameters[2]))};
+static const Method methods[3] = {{REMOTE_SCALARS_MAKEX(0, 0, 0x0, 0x0, 0x0, 0x0), 0x0, 0x0, 0, 0, 0, 0x0, 0x0}, {REMOTE_SCALARS_MAKEX(0, 0, 255, 255, 15, 15), 0x8, 0x0, 3, 2, (&(parameterArrays[0])), 0x4, 0x0}, {REMOTE_SCALARS_MAKEX(0, 0, 0x0, 0x1, 0x0, 0x0), 0x0, 0x4, 1, 1, (&(parameterArrays[2])), 0x1, 0x4}};
+static const Method *const methodArrays[4] = {&(methods[0]), &(methods[0]), &(methods[1]), &(methods[2])};
+static const char strings[60] = "set_logging_params\0thread_exit\0filesToLog\0getASID\0asid\0mask\0";
+static const uint16_t methodStrings[7] = {0, 55, 31, 42, 50, 19, 26};
+static const uint16_t methodStringsArrays[4] = {6, 5, 0, 3};
+__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(adsp_current_process_slim) = {4, &(methodArrays[0]), 0, 0, &(methodStringsArrays [0]), methodStrings, strings};
+#endif //_ADSP_CURRENT_PROCESS_SLIM_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _const_adsp_current_process_handle
+#define _const_adsp_current_process_handle ((remote_handle)-1)
+#endif //_const_adsp_current_process_handle
+
+static void _adsp_current_process_pls_dtor(void *data)
+{
+ remote_handle *ph = (remote_handle *)data;
+ if (_const_adsp_current_process_handle != *ph)
+ {
+ (void)__QAIC_REMOTE(remote_handle_close)(*ph);
+ *ph = _const_adsp_current_process_handle;
+ }
+}
+
+static int _adsp_current_process_pls_ctor(void *ctx, void *data)
+{
+ remote_handle *ph = (remote_handle *)data;
+ *ph = _const_adsp_current_process_handle;
+ if (*ph == (remote_handle) - 1)
+ {
+ return __QAIC_REMOTE(remote_handle_open)((const char *)ctx, ph);
+ }
+ return 0;
+}
+
+#if (defined __qdsp6__) || (defined __hexagon__)
+#pragma weak adsp_pls_add_lookup
+extern int adsp_pls_add_lookup(uint32_t type, uint32_t key, int size, int (*ctor)(void *ctx, void *data), void *ctx, void (*dtor)(void *ctx), void **ppo);
+#pragma weak HAP_pls_add_lookup
+extern int HAP_pls_add_lookup(uint32_t type, uint32_t key, int size, int (*ctor)(void *ctx, void *data), void *ctx, void (*dtor)(void *ctx), void **ppo);
+
+__QAIC_STUB_EXPORT remote_handle _adsp_current_process_handle(void)
+{
+ remote_handle *ph;
+ if (adsp_pls_add_lookup)
+ {
+ if (0 == adsp_pls_add_lookup((uint32_t)_adsp_current_process_handle, 0, sizeof(*ph), _adsp_current_process_pls_ctor, "adsp_current_process", _adsp_current_process_pls_dtor, (void **)&ph))
+ {
+ return *ph;
+ }
+ return (remote_handle) - 1;
+ }
+ else if (HAP_pls_add_lookup)
+ {
+ if (0 == HAP_pls_add_lookup((uint32_t)_adsp_current_process_handle, 0, sizeof(*ph), _adsp_current_process_pls_ctor, "adsp_current_process", _adsp_current_process_pls_dtor, (void **)&ph))
+ {
+ return *ph;
+ }
+ return (remote_handle) - 1;
+ }
+ return (remote_handle) - 1;
+}
+
+#else //__qdsp6__ || __hexagon__
+
+uint32_t _adsp_current_process_atomic_CompareAndExchange(uint32_t *volatile puDest, uint32_t uExchange, uint32_t uCompare);
+
+#ifdef _WIN32
+#include "Windows.h"
+uint32_t _adsp_current_process_atomic_CompareAndExchange(uint32_t *volatile puDest, uint32_t uExchange, uint32_t uCompare)
+{
+ return (uint32_t)InterlockedCompareExchange((volatile LONG *)puDest, (LONG)uExchange, (LONG)uCompare);
+}
+#elif __GNUC__
+uint32_t _adsp_current_process_atomic_CompareAndExchange(uint32_t *volatile puDest, uint32_t uExchange, uint32_t uCompare)
+{
+ return __sync_val_compare_and_swap(puDest, uCompare, uExchange);
+}
+#endif //_WIN32
+
+
+__QAIC_STUB_EXPORT remote_handle _adsp_current_process_handle(void)
+{
+ static remote_handle handle = _const_adsp_current_process_handle;
+ if ((remote_handle) - 1 != handle)
+ {
+ return handle;
+ }
+ else
+ {
+ remote_handle tmp;
+ int nErr = _adsp_current_process_pls_ctor("adsp_current_process", (void *)&tmp);
+ if (nErr)
+ {
+ return (remote_handle) - 1;
+ }
+ if (((remote_handle) - 1 != handle) || ((remote_handle) - 1 != (remote_handle)_adsp_current_process_atomic_CompareAndExchange((uint32_t *)&handle, (uint32_t)tmp, (uint32_t) - 1)))
+ {
+ _adsp_current_process_pls_dtor(&tmp);
+ }
+ return handle;
+ }
+}
+
+#endif //__qdsp6__
+
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_current_process_skel_invoke)(uint32_t _sc, remote_arg *_pra) __QAIC_STUB_ATTRIBUTE
+{
+ return __QAIC_REMOTE(remote_handle_invoke)(_adsp_current_process_handle(), _sc, _pra);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+static __inline int _stub_method(remote_handle _handle, uint32_t _mid)
+{
+ remote_arg *_pra = 0;
+ int _nErr = 0;
+ _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 0, 0, 0, 0), _pra));
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_current_process_exit)(void) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 0;
+ return _stub_method(_adsp_current_process_handle(), _mid);
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_current_process_thread_exit)(void) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 1;
+ return _stub_method(_adsp_current_process_handle(), _mid);
+}
+static __inline int _stub_unpack(remote_arg *_praROutPost, remote_arg *_ppraROutPost[1], void *_primROut, char *_in0[1], uint32_t _in0Len[1])
+{
+ int _nErr = 0;
+ remote_arg *_praROutPostStart = _praROutPost;
+ remote_arg **_ppraROutPostStart = _ppraROutPost;
+ _ppraROutPost = &_praROutPost;
+ _ppraROutPostStart[0] += (_praROutPost - _praROutPostStart) + 0;
+ return _nErr;
+}
+static __inline int _stub_pack(_allocator *_al, remote_arg *_praIn, remote_arg *_ppraIn[1], remote_arg *_praROut, remote_arg *_ppraROut[1], void *_primIn, void *_primROut, char *_in0[1], uint32_t _in0Len[1])
+{
+ int _nErr = 0;
+ remote_arg *_praInStart = _praIn;
+ remote_arg **_ppraInStart = _ppraIn;
+ remote_arg *_praROutStart = _praROut;
+ remote_arg **_ppraROutStart = _ppraROut;
+ _ppraIn = &_praIn;
+ _ppraROut = &_praROut;
+ _in0Len[0] = (1 + strlen(_in0[0]));
+ _COPY(_primIn, 0, _in0Len, 0, 4);
+ _praIn[0].buf.pv = _in0[0];
+ _praIn[0].buf.nLen = (1 * _in0Len[0]);
+ _ppraInStart[0] += (_praIn - _praInStart) + 1;
+ _ppraROutStart[0] += (_praROut - _praROutStart) + 0;
+ return _nErr;
+}
+static __inline void _count(int _numIn[1], int _numROut[1], char *_in0[1], uint32_t _in0Len[1])
+{
+ _numIn[0] += 1;
+ _numROut[0] += 0;
+}
+static __inline int _stub_method_1(remote_handle _handle, uint32_t _mid, uint16_t _in0[1], void *_in1[1], uint32_t _in1Len[1])
+{
+ remote_arg *_pra;
+ int _numIn[1];
+ int _numROut[1];
+ char *_seq_nat1;
+ int _ii;
+ _allocator _al[1] = {{0}};
+ uint32_t _primIn[2];
+ remote_arg *_praIn;
+ remote_arg **_ppraIn = &_praIn;
+ remote_arg *_praROut;
+ remote_arg **_ppraROut = &_praROut;
+ char *_seq_primIn1;
+ int _nErr = 0;
+ remote_arg *_praROutPost;
+ remote_arg **_ppraROutPost = &_praROutPost;
+ _numIn[0] = 1;
+ _numROut[0] = 0;
+ for (_ii = 0, _seq_nat1 = (char *)_in1[0]; _ii < (int)_in1Len[0]; ++_ii, _seq_nat1 = (_seq_nat1 + SLIM_IFPTR32(8, 16)))
+ {
+ _count(_numIn, _numROut, SLIM_IFPTR32((char **) & (((uint32_t *)_seq_nat1)[0]), (char **) & (((uint64_t *)_seq_nat1)[0])), SLIM_IFPTR32((uint32_t *) & (((uint32_t *)_seq_nat1)[1]), (uint32_t *) & (((uint32_t *)_seq_nat1)[2])));
+ }
+ _allocator_init(_al, 0, 0);
+ _ALLOCATE(_nErr, _al, ((((_numIn[0] + _numROut[0]) + 1) + 0) * sizeof(_pra[0])), 4, _pra);
+ _pra[0].buf.pv = (void *)_primIn;
+ _pra[0].buf.nLen = sizeof(_primIn);
+ _COPY(_primIn, 0, _in0, 0, 2);
+ _COPY(_primIn, 4, _in1Len, 0, 4);
+ _praIn = (_pra + 1);
+ _praROut = (_praIn + _numIn[0] + 0);
+ _ALLOCATE(_nErr, _al, (_in1Len[0] * 4), 4, _praIn[0].buf.pv);
+ _praIn[0].buf.nLen = (4 * _in1Len[0]);
+ for (_ii = 0, _seq_primIn1 = (char *)_praIn[0].buf.pv, _seq_nat1 = (char *)_in1[0]; _ii < (int)_in1Len[0]; ++_ii, _seq_primIn1 = (_seq_primIn1 + 4), _seq_nat1 = (_seq_nat1 + SLIM_IFPTR32(8, 16)))
+ {
+ _TRY(_nErr, _stub_pack(_al, (_praIn + 1), _ppraIn, (_praROut + 0), _ppraROut, _seq_primIn1, 0, SLIM_IFPTR32((char **) & (((uint32_t *)_seq_nat1)[0]), (char **) & (((uint64_t *)_seq_nat1)[0])), SLIM_IFPTR32((uint32_t *) & (((uint32_t *)_seq_nat1)[1]), (uint32_t *) & (((uint32_t *)_seq_nat1)[2]))));
+ }
+ _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, (_numIn[0] + 1), (_numROut[0] + 0), 0, 0), _pra));
+ _praROutPost = _praROut;
+ for (_ii = 0, _seq_nat1 = (char *)_in1[0]; _ii < (int)_in1Len[0]; ++_ii, _seq_nat1 = (_seq_nat1 + SLIM_IFPTR32(8, 16)))
+ {
+ _TRY(_nErr, _stub_unpack((_praROutPost + 0), _ppraROutPost, 0, SLIM_IFPTR32((char **) & (((uint32_t *)_seq_nat1)[0]), (char **) & (((uint64_t *)_seq_nat1)[0])), SLIM_IFPTR32((uint32_t *) & (((uint32_t *)_seq_nat1)[1]), (uint32_t *) & (((uint32_t *)_seq_nat1)[2]))));
+ }
+ _CATCH(_nErr) {}
+ _allocator_deinit(_al);
+ return _nErr;
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_current_process_set_logging_params)(unsigned short mask, const _cstring1_t *filesToLog, int filesToLogLen) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 2;
+ return _stub_method_1(_adsp_current_process_handle(), _mid, (uint16_t *)&mask, (void **)&filesToLog, (uint32_t *)&filesToLogLen);
+}
+static __inline int _stub_method_2(remote_handle _handle, uint32_t _mid, uint32_t _rout0[1])
+{
+ int _numIn[1];
+ remote_arg _pra[1];
+ uint32_t _primROut[1];
+ int _nErr = 0;
+ _numIn[0] = 0;
+ _pra[(_numIn[0] + 0)].buf.pv = (void *)_primROut;
+ _pra[(_numIn[0] + 0)].buf.nLen = sizeof(_primROut);
+ _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 0, 1, 0, 0), _pra));
+ _COPY(_rout0, 0, _primROut, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_current_process_getASID)(unsigned int *asid) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 3;
+ return _stub_method_2(_adsp_current_process_handle(), _mid, (uint32_t *)asid);
+}
+#ifdef __cplusplus
+}
+#endif
+#endif //_ADSP_CURRENT_PROCESS_STUB_H
diff --git a/src/adsp_default_listener_stub.c b/src/adsp_default_listener_stub.c
new file mode 100644
index 0000000..aa19e0c
--- /dev/null
+++ b/src/adsp_default_listener_stub.c
@@ -0,0 +1,564 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _ADSP_DEFAULT_LISTENER_STUB_H
+#define _ADSP_DEFAULT_LISTENER_STUB_H
+#include "adsp_default_listener.h"
+#include "remote.h"
+#ifndef ALLOCATOR_H
+#define ALLOCATOR_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef struct _heap _heap;
+struct _heap
+{
+ _heap *pPrev;
+ const char *loc;
+ uint64_t buf;
+};
+
+typedef struct allocator
+{
+ _heap *pheap;
+ uint8_t *stack;
+ uint8_t *stackEnd;
+ int nSize;
+} allocator;
+
+static __inline int _heap_alloc(_heap **ppa, const char *loc, int size, void **ppbuf)
+{
+ _heap *pn = 0;
+ pn = malloc(size + sizeof(_heap) - sizeof(uint64_t));
+ if (pn != 0)
+ {
+ pn->pPrev = *ppa;
+ pn->loc = loc;
+ *ppa = pn;
+ *ppbuf = (void *) & (pn->buf);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+#define _ALIGN_SIZE(x, y) (((x) + (y-1)) & ~(y-1))
+
+
+static __inline int allocator_alloc(allocator *me,
+ const char *loc,
+ int size,
+ unsigned int al,
+ void **ppbuf)
+{
+ if (size < 0)
+ {
+ return -1;
+ }
+ else if (size == 0)
+ {
+ *ppbuf = 0;
+ return 0;
+ }
+ if ((_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size) < (uintptr_t)me->stack + me->nSize)
+ {
+ *ppbuf = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al);
+ me->stackEnd = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size;
+ return 0;
+ }
+ else
+ {
+ return _heap_alloc(&me->pheap, loc, size, ppbuf);
+ }
+}
+
+
+static __inline void allocator_deinit(allocator *me)
+{
+ _heap *pa = me->pheap;
+ while (pa != 0)
+ {
+ _heap *pn = pa;
+ const char *loc = pn->loc;
+ (void)loc;
+ pa = pn->pPrev;
+ free(pn);
+ }
+}
+
+static __inline void allocator_init(allocator *me, uint8_t *stack, int stackSize)
+{
+ me->stack = stack;
+ me->stackEnd = stack + stackSize;
+ me->nSize = stackSize;
+ me->pheap = 0;
+}
+
+
+#endif // ALLOCATOR_H
+
+#ifndef SLIM_H
+#define SLIM_H
+
+#include <stdint.h>
+
+//a C data structure for the idl types that can be used to implement
+//static and dynamic language bindings fairly efficiently.
+//
+//the goal is to have a minimal ROM and RAM footprint and without
+//doing too many allocations. A good way to package these things seemed
+//like the module boundary, so all the idls within one module can share
+//all the type references.
+
+
+#define PARAMETER_IN 0x0
+#define PARAMETER_OUT 0x1
+#define PARAMETER_INOUT 0x2
+#define PARAMETER_ROUT 0x3
+#define PARAMETER_INROUT 0x4
+
+//the types that we get from idl
+#define TYPE_OBJECT 0x0
+#define TYPE_INTERFACE 0x1
+#define TYPE_PRIMITIVE 0x2
+#define TYPE_ENUM 0x3
+#define TYPE_STRING 0x4
+#define TYPE_WSTRING 0x5
+#define TYPE_STRUCTURE 0x6
+#define TYPE_UNION 0x7
+#define TYPE_ARRAY 0x8
+#define TYPE_SEQUENCE 0x9
+
+//these require the pack/unpack to recurse
+//so it's a hint to those languages that can optimize in cases where
+//recursion isn't necessary.
+#define TYPE_COMPLEX_STRUCTURE (0x10 | TYPE_STRUCTURE)
+#define TYPE_COMPLEX_UNION (0x10 | TYPE_UNION)
+#define TYPE_COMPLEX_ARRAY (0x10 | TYPE_ARRAY)
+#define TYPE_COMPLEX_SEQUENCE (0x10 | TYPE_SEQUENCE)
+
+
+typedef struct Type Type;
+
+#define INHERIT_TYPE\
+ int32_t nativeSize; /*in the simple case its the same as wire size and alignment*/\
+ union {\
+ struct {\
+ const uintptr_t p1;\
+ const uintptr_t p2;\
+ } _cast;\
+ struct {\
+ uint32_t iid;\
+ uint32_t bNotNil;\
+ } object;\
+ struct {\
+ const Type *arrayType;\
+ int32_t nItems;\
+ } array;\
+ struct {\
+ const Type *seqType;\
+ int32_t nMaxLen;\
+ } seqSimple; \
+ struct {\
+ uint32_t bFloating;\
+ uint32_t bSigned;\
+ } prim; \
+ const SequenceType* seqComplex;\
+ const UnionType *unionType;\
+ const StructType *structType;\
+ int32_t stringMaxLen;\
+ uint8_t bInterfaceNotNil;\
+ } param;\
+ uint8_t type;\
+ uint8_t nativeAlignment\
+
+typedef struct UnionType UnionType;
+typedef struct StructType StructType;
+typedef struct SequenceType SequenceType;
+struct Type
+{
+ INHERIT_TYPE;
+};
+
+struct SequenceType
+{
+ const Type *seqType;
+ uint32_t nMaxLen;
+ uint32_t inSize;
+ uint32_t routSizePrimIn;
+ uint32_t routSizePrimROut;
+};
+
+//byte offset from the start of the case values for
+//this unions case value array. it MUST be aligned
+//at the alignment requrements for the descriptor
+//
+//if negative it means that the unions cases are
+//simple enumerators, so the value read from the descriptor
+//can be used directly to find the correct case
+typedef union CaseValuePtr CaseValuePtr;
+union CaseValuePtr
+{
+ const uint8_t *value8s;
+ const uint16_t *value16s;
+ const uint32_t *value32s;
+ const uint64_t *value64s;
+};
+
+//these are only used in complex cases
+//so I pulled them out of the type definition as references to make
+//the type smaller
+struct UnionType
+{
+ const Type *descriptor;
+ uint32_t nCases;
+ const CaseValuePtr caseValues;
+ const Type *const *cases;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+ uint8_t inCaseAlignment;
+ uint8_t routCaseAlignmentPrimIn;
+ uint8_t routCaseAlignmentPrimROut;
+ uint8_t nativeCaseAlignment;
+ uint8_t bDefaultCase;
+};
+
+struct StructType
+{
+ uint32_t nMembers;
+ const Type *const *members;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+};
+
+typedef struct Parameter Parameter;
+struct Parameter
+{
+ INHERIT_TYPE;
+ uint8_t mode;
+ uint8_t bNotNil;
+};
+
+#define SLIM_SCALARS_IS_DYNAMIC(u) (((u) & 0x00ffffff) == 0x00ffffff)
+
+typedef struct Method Method;
+struct Method
+{
+ uint32_t uScalars; //no method index
+ int32_t primInSize;
+ int32_t primROutSize;
+ int maxArgs;
+ int numParams;
+ const Parameter *const *params;
+ uint8_t primInAlignment;
+ uint8_t primROutAlignment;
+};
+
+typedef struct Interface Interface;
+
+struct Interface
+{
+ int nMethods;
+ const Method *const *methodArray;
+ int nIIds;
+ const uint32_t *iids;
+ const uint16_t *methodStringArray;
+ const uint16_t *methodStrings;
+ const char *strings;
+};
+
+
+#endif //SLIM_H
+
+
+#ifndef _ADSP_DEFAULT_LISTENER_SLIM_H
+#define _ADSP_DEFAULT_LISTENER_SLIM_H
+#include "remote.h"
+#include <stdint.h>
+
+#ifndef __QAIC_SLIM
+#define __QAIC_SLIM(ff) ff
+#endif
+#ifndef __QAIC_SLIM_EXPORT
+#define __QAIC_SLIM_EXPORT
+#endif
+
+static const Method methods[1] = {{REMOTE_SCALARS_MAKEX(0, 0, 0x0, 0x0, 0x0, 0x0), 0x0, 0x0, 0, 0, 0, 0x0, 0x0}};
+static const Method *const methodArrays[1] = {&(methods[0])};
+static const char strings[9] = "register\0";
+static const uint16_t methodStrings[1] = {0};
+static const uint16_t methodStringsArrays[1] = {0};
+__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(adsp_default_listener_slim) = {1, &(methodArrays[0]), 0, 0, &(methodStringsArrays [0]), methodStrings, strings};
+#endif //_ADSP_DEFAULT_LISTENER_SLIM_H
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wpragmas"
+#pragma GCC diagnostic ignored "-Wuninitialized"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#ifndef __QAIC_REMOTE
+#define __QAIC_REMOTE(ff) ff
+#endif //__QAIC_REMOTE
+
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+
+#ifndef __QAIC_STUB
+#define __QAIC_STUB(ff) ff
+#endif //__QAIC_STUB
+
+#ifndef __QAIC_STUB_EXPORT
+#define __QAIC_STUB_EXPORT
+#endif // __QAIC_STUB_EXPORT
+
+#ifndef __QAIC_STUB_ATTRIBUTE
+#define __QAIC_STUB_ATTRIBUTE
+#endif // __QAIC_STUB_ATTRIBUTE
+
+#ifndef __QAIC_SKEL
+#define __QAIC_SKEL(ff) ff
+#endif //__QAIC_SKEL__
+
+#ifndef __QAIC_SKEL_EXPORT
+#define __QAIC_SKEL_EXPORT
+#endif // __QAIC_SKEL_EXPORT
+
+#ifndef __QAIC_SKEL_ATTRIBUTE
+#define __QAIC_SKEL_ATTRIBUTE
+#endif // __QAIC_SKEL_ATTRIBUTE
+
+#ifdef __QAIC_DEBUG__
+#ifndef __QAIC_DBG_PRINTF__
+#define __QAIC_DBG_PRINTF__( ee ) do { printf ee ; } while(0)
+#endif
+#else
+#define __QAIC_DBG_PRINTF__( ee ) (void)0
+#endif
+
+
+#define _OFFSET(src, sof) ((void*)(((char*)(src)) + (sof)))
+
+#define _COPY(dst, dof, src, sof, sz) \
+ do {\
+ struct __copy { \
+ char ar[sz]; \
+ };\
+ *(struct __copy*)_OFFSET(dst, dof) = *(struct __copy*)_OFFSET(src, sof);\
+ } while (0)
+
+#define _ASSIGN(dst, src, sof) \
+ do {\
+ dst = OFFSET(src, sof); \
+ } while (0)
+
+#define _STD_STRLEN_IF(str) (str == 0 ? 0 : strlen(str))
+
+#include "AEEStdErr.h"
+
+#define _TRY(ee, func) \
+ do { \
+ if (AEE_SUCCESS != ((ee) = func)) {\
+ __QAIC_DBG_PRINTF__((__FILE_LINE__ ": error: %d\n", (int)(ee)));\
+ goto ee##bail;\
+ } \
+ } while (0)
+
+#define _CATCH(exception) exception##bail: if (exception != AEE_SUCCESS)
+
+#define _ASSERT(nErr, ff) _TRY(nErr, 0 == (ff) ? AEE_EBADPARM : AEE_SUCCESS)
+
+#ifdef __QAIC_DEBUG__
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, allocator_alloc(pal, __FILE_LINE__, size, alignment, (void**)&pv))
+#else
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, allocator_alloc(pal, 0, size, alignment, (void**)&pv))
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _const_adsp_default_listener_handle
+#define _const_adsp_default_listener_handle ((remote_handle)-1)
+#endif //_const_adsp_default_listener_handle
+
+static void _adsp_default_listener_pls_dtor(void *data)
+{
+ remote_handle *ph = (remote_handle *)data;
+ if (_const_adsp_default_listener_handle != *ph)
+ {
+ (void)__QAIC_REMOTE(remote_handle_close)(*ph);
+ *ph = _const_adsp_default_listener_handle;
+ }
+}
+
+static int _adsp_default_listener_pls_ctor(void *ctx, void *data)
+{
+ remote_handle *ph = (remote_handle *)data;
+ *ph = _const_adsp_default_listener_handle;
+ if (*ph == (remote_handle) - 1)
+ {
+ return __QAIC_REMOTE(remote_handle_open)((const char *)ctx, ph);
+ }
+ return 0;
+}
+
+#if (defined __qdsp6__) || (defined __hexagon__)
+#pragma weak adsp_pls_add_lookup
+extern int adsp_pls_add_lookup(uint32_t type, uint32_t key, int size, int (*ctor)(void *ctx, void *data), void *ctx, void (*dtor)(void *ctx), void **ppo);
+#pragma weak HAP_pls_add_lookup
+extern int HAP_pls_add_lookup(uint32_t type, uint32_t key, int size, int (*ctor)(void *ctx, void *data), void *ctx, void (*dtor)(void *ctx), void **ppo);
+
+__QAIC_STUB_EXPORT remote_handle _adsp_default_listener_handle(void)
+{
+ remote_handle *ph;
+ if (adsp_pls_add_lookup)
+ {
+ if (0 == adsp_pls_add_lookup((uint32_t)_adsp_default_listener_handle, 0, sizeof(*ph), _adsp_default_listener_pls_ctor, "adsp_default_listener", _adsp_default_listener_pls_dtor, (void **)&ph))
+ {
+ return *ph;
+ }
+ return (remote_handle) - 1;
+ }
+ else if (HAP_pls_add_lookup)
+ {
+ if (0 == HAP_pls_add_lookup((uint32_t)_adsp_default_listener_handle, 0, sizeof(*ph), _adsp_default_listener_pls_ctor, "adsp_default_listener", _adsp_default_listener_pls_dtor, (void **)&ph))
+ {
+ return *ph;
+ }
+ return (remote_handle) - 1;
+ }
+ return (remote_handle) - 1;
+}
+
+#else //__qdsp6__ || __hexagon__
+
+uint32_t _adsp_default_listener_atomic_CompareAndExchange(uint32_t *volatile puDest, uint32_t uExchange, uint32_t uCompare);
+
+#ifdef _WIN32
+#include "Windows.h"
+uint32_t _adsp_default_listener_atomic_CompareAndExchange(uint32_t *volatile puDest, uint32_t uExchange, uint32_t uCompare)
+{
+ return (uint32_t)InterlockedCompareExchange((volatile LONG *)puDest, (LONG)uExchange, (LONG)uCompare);
+}
+#elif __GNUC__
+uint32_t _adsp_default_listener_atomic_CompareAndExchange(uint32_t *volatile puDest, uint32_t uExchange, uint32_t uCompare)
+{
+ return __sync_val_compare_and_swap(puDest, uCompare, uExchange);
+}
+#endif //_WIN32
+
+
+__QAIC_STUB_EXPORT remote_handle _adsp_default_listener_handle(void)
+{
+ static remote_handle handle = _const_adsp_default_listener_handle;
+ if ((remote_handle) - 1 != handle)
+ {
+ return handle;
+ }
+ else
+ {
+ remote_handle tmp;
+ int nErr = _adsp_default_listener_pls_ctor("adsp_default_listener", (void *)&tmp);
+ if (nErr)
+ {
+ return (remote_handle) - 1;
+ }
+ if (((remote_handle) - 1 != handle) || ((remote_handle) - 1 != (remote_handle)_adsp_default_listener_atomic_CompareAndExchange((uint32_t *)&handle, (uint32_t)tmp, (uint32_t) - 1)))
+ {
+ _adsp_default_listener_pls_dtor(&tmp);
+ }
+ return handle;
+ }
+}
+
+#endif //__qdsp6__
+
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_default_listener_skel_invoke)(uint32_t _sc, remote_arg *_pra) __QAIC_STUB_ATTRIBUTE
+{
+ return __QAIC_REMOTE(remote_handle_invoke)(_adsp_default_listener_handle(), _sc, _pra);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+static __inline int _stub_method(remote_handle _handle, uint32_t _mid)
+{
+ remote_arg *_pra = 0;
+ int _nErr = 0;
+ _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 0, 0, 0, 0), _pra));
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_default_listener_register)(void) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 0;
+ return _stub_method(_adsp_default_listener_handle(), _mid);
+}
+#ifdef __cplusplus
+}
+#endif
+#endif //_ADSP_DEFAULT_LISTENER_STUB_H
diff --git a/src/adsp_default_listener_stub.d b/src/adsp_default_listener_stub.d
new file mode 100644
index 0000000..a6669d9
--- /dev/null
+++ b/src/adsp_default_listener_stub.d
@@ -0,0 +1,8 @@
+src/adsp_default_listener_stub.o: src/adsp_default_listener_stub.c \
+ inc/adsp_default_listener.h inc/remote.h inc/AEEStdErr.h
+
+inc/adsp_default_listener.h:
+
+inc/remote.h:
+
+inc/AEEStdErr.h:
diff --git a/src/adsp_default_listener_stub.o b/src/adsp_default_listener_stub.o
new file mode 100644
index 0000000..e320444
--- /dev/null
+++ b/src/adsp_default_listener_stub.o
Binary files differ
diff --git a/src/adsp_listener_stub.c b/src/adsp_listener_stub.c
new file mode 100644
index 0000000..900da9a
--- /dev/null
+++ b/src/adsp_listener_stub.c
@@ -0,0 +1,861 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _ADSP_LISTENER_STUB_H
+#define _ADSP_LISTENER_STUB_H
+#include "adsp_listener.h"
+#include "remote.h"
+#ifndef ALLOCATOR_H
+#define ALLOCATOR_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef struct _heap _heap;
+struct _heap
+{
+ _heap *pPrev;
+ const char *loc;
+ uint64_t buf;
+};
+
+typedef struct allocator
+{
+ _heap *pheap;
+ uint8_t *stack;
+ uint8_t *stackEnd;
+ int nSize;
+} allocator;
+
+static __inline int _heap_alloc(_heap **ppa, const char *loc, int size, void **ppbuf)
+{
+ _heap *pn = 0;
+ pn = malloc(size + sizeof(_heap) - sizeof(uint64_t));
+ if (pn != 0)
+ {
+ pn->pPrev = *ppa;
+ pn->loc = loc;
+ *ppa = pn;
+ *ppbuf = (void *) & (pn->buf);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+#define _ALIGN_SIZE(x, y) (((x) + (y-1)) & ~(y-1))
+
+
+static __inline int allocator_alloc(allocator *me,
+ const char *loc,
+ int size,
+ unsigned int al,
+ void **ppbuf)
+{
+ if (size < 0)
+ {
+ return -1;
+ }
+ else if (size == 0)
+ {
+ *ppbuf = 0;
+ return 0;
+ }
+ if ((_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size) < (uintptr_t)me->stack + me->nSize)
+ {
+ *ppbuf = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al);
+ me->stackEnd = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size;
+ return 0;
+ }
+ else
+ {
+ return _heap_alloc(&me->pheap, loc, size, ppbuf);
+ }
+}
+
+
+static __inline void allocator_deinit(allocator *me)
+{
+ _heap *pa = me->pheap;
+ while (pa != 0)
+ {
+ _heap *pn = pa;
+ const char *loc = pn->loc;
+ (void)loc;
+ pa = pn->pPrev;
+ free(pn);
+ }
+}
+
+static __inline void allocator_init(allocator *me, uint8_t *stack, int stackSize)
+{
+ me->stack = stack;
+ me->stackEnd = stack + stackSize;
+ me->nSize = stackSize;
+ me->pheap = 0;
+}
+
+
+#endif // ALLOCATOR_H
+
+#ifndef SLIM_H
+#define SLIM_H
+
+#include <stdint.h>
+
+//a C data structure for the idl types that can be used to implement
+//static and dynamic language bindings fairly efficiently.
+//
+//the goal is to have a minimal ROM and RAM footprint and without
+//doing too many allocations. A good way to package these things seemed
+//like the module boundary, so all the idls within one module can share
+//all the type references.
+
+
+#define PARAMETER_IN 0x0
+#define PARAMETER_OUT 0x1
+#define PARAMETER_INOUT 0x2
+#define PARAMETER_ROUT 0x3
+#define PARAMETER_INROUT 0x4
+
+//the types that we get from idl
+#define TYPE_OBJECT 0x0
+#define TYPE_INTERFACE 0x1
+#define TYPE_PRIMITIVE 0x2
+#define TYPE_ENUM 0x3
+#define TYPE_STRING 0x4
+#define TYPE_WSTRING 0x5
+#define TYPE_STRUCTURE 0x6
+#define TYPE_UNION 0x7
+#define TYPE_ARRAY 0x8
+#define TYPE_SEQUENCE 0x9
+
+//these require the pack/unpack to recurse
+//so it's a hint to those languages that can optimize in cases where
+//recursion isn't necessary.
+#define TYPE_COMPLEX_STRUCTURE (0x10 | TYPE_STRUCTURE)
+#define TYPE_COMPLEX_UNION (0x10 | TYPE_UNION)
+#define TYPE_COMPLEX_ARRAY (0x10 | TYPE_ARRAY)
+#define TYPE_COMPLEX_SEQUENCE (0x10 | TYPE_SEQUENCE)
+
+
+typedef struct Type Type;
+
+#define INHERIT_TYPE\
+ int32_t nativeSize; /*in the simple case its the same as wire size and alignment*/\
+ union {\
+ struct {\
+ const uintptr_t p1;\
+ const uintptr_t p2;\
+ } _cast;\
+ struct {\
+ uint32_t iid;\
+ uint32_t bNotNil;\
+ } object;\
+ struct {\
+ const Type *arrayType;\
+ int32_t nItems;\
+ } array;\
+ struct {\
+ const Type *seqType;\
+ int32_t nMaxLen;\
+ } seqSimple; \
+ struct {\
+ uint32_t bFloating;\
+ uint32_t bSigned;\
+ } prim; \
+ const SequenceType* seqComplex;\
+ const UnionType *unionType;\
+ const StructType *structType;\
+ int32_t stringMaxLen;\
+ uint8_t bInterfaceNotNil;\
+ } param;\
+ uint8_t type;\
+ uint8_t nativeAlignment\
+
+typedef struct UnionType UnionType;
+typedef struct StructType StructType;
+typedef struct SequenceType SequenceType;
+struct Type
+{
+ INHERIT_TYPE;
+};
+
+struct SequenceType
+{
+ const Type *seqType;
+ uint32_t nMaxLen;
+ uint32_t inSize;
+ uint32_t routSizePrimIn;
+ uint32_t routSizePrimROut;
+};
+
+//byte offset from the start of the case values for
+//this unions case value array. it MUST be aligned
+//at the alignment requrements for the descriptor
+//
+//if negative it means that the unions cases are
+//simple enumerators, so the value read from the descriptor
+//can be used directly to find the correct case
+typedef union CaseValuePtr CaseValuePtr;
+union CaseValuePtr
+{
+ const uint8_t *value8s;
+ const uint16_t *value16s;
+ const uint32_t *value32s;
+ const uint64_t *value64s;
+};
+
+//these are only used in complex cases
+//so I pulled them out of the type definition as references to make
+//the type smaller
+struct UnionType
+{
+ const Type *descriptor;
+ uint32_t nCases;
+ const CaseValuePtr caseValues;
+ const Type *const *cases;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+ uint8_t inCaseAlignment;
+ uint8_t routCaseAlignmentPrimIn;
+ uint8_t routCaseAlignmentPrimROut;
+ uint8_t nativeCaseAlignment;
+ uint8_t bDefaultCase;
+};
+
+struct StructType
+{
+ uint32_t nMembers;
+ const Type *const *members;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+};
+
+typedef struct Parameter Parameter;
+struct Parameter
+{
+ INHERIT_TYPE;
+ uint8_t mode;
+ uint8_t bNotNil;
+};
+
+#define SLIM_SCALARS_IS_DYNAMIC(u) (((u) & 0x00ffffff) == 0x00ffffff)
+
+typedef struct Method Method;
+struct Method
+{
+ uint32_t uScalars; //no method index
+ int32_t primInSize;
+ int32_t primROutSize;
+ int maxArgs;
+ int numParams;
+ const Parameter *const *params;
+ uint8_t primInAlignment;
+ uint8_t primROutAlignment;
+};
+
+typedef struct Interface Interface;
+
+struct Interface
+{
+ int nMethods;
+ const Method *const *methodArray;
+ int nIIds;
+ const uint32_t *iids;
+ const uint16_t *methodStringArray;
+ const uint16_t *methodStrings;
+ const char *strings;
+};
+
+
+#endif //SLIM_H
+
+
+#ifndef _ADSP_LISTENER_SLIM_H
+#define _ADSP_LISTENER_SLIM_H
+#include "remote.h"
+#include <stdint.h>
+
+#ifndef __QAIC_SLIM
+#define __QAIC_SLIM(ff) ff
+#endif
+#ifndef __QAIC_SLIM_EXPORT
+#define __QAIC_SLIM_EXPORT
+#endif
+
+static const Type types[3];
+static const SequenceType sequenceTypes[1] = {{&(types[0]), 0x0, 0x4, 0x4, 0x0}};
+static const Type types[3] = {{0x8, {{(const uintptr_t) &(types[1]), (const uintptr_t)0x0}}, 9, 0x4}, {0x1, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x1}, {0x4, {{(const uintptr_t)0, (const uintptr_t)1}}, 2, 0x4}};
+static const Parameter parameters[9] = {{0x4, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x4, 0, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)1}}, 2, 0x4, 0, 0}, {0x8, {{(const uintptr_t) &(sequenceTypes[0]), 0}}, 25, 0x4, 0, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x4, 3, 0}, {0x8, {{(const uintptr_t) &(sequenceTypes[0]), 0}}, 25, 0x4, 3, 0}, {0x8, {{(const uintptr_t) &(types[2]), (const uintptr_t)0x0}}, 9, 0x4, 3, 0}, {0x8, {{(const uintptr_t) &(types[1]), (const uintptr_t)0x0}}, 9, 0x4, 0, 0}, {0x8, {{(const uintptr_t) &(types[1]), (const uintptr_t)0x0}}, 9, 0x4, 3, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)1}}, 2, 0x4, 3, 0}};
+static const Parameter *const parameterArrays[23] = {(&(parameters[0])), (&(parameters[1])), (&(parameters[2])), (&(parameters[3])), (&(parameters[3])), (&(parameters[3])), (&(parameters[4])), (&(parameters[5])), (&(parameters[5])), (&(parameters[0])), (&(parameters[1])), (&(parameters[6])), (&(parameters[3])), (&(parameters[3])), (&(parameters[3])), (&(parameters[7])), (&(parameters[8])), (&(parameters[0])), (&(parameters[1])), (&(parameters[7])), (&(parameters[8])), (&(parameters[0])), (&(parameters[4]))};
+static const Method methods[5] = {{REMOTE_SCALARS_MAKEX(0, 0, 255, 255, 15, 15), 0x18, 0xc, 16, 9, (&(parameterArrays[0])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 255, 255, 15, 15), 0x8, 0x0, 4, 2, (&(parameterArrays[21])), 0x4, 0x1}, {REMOTE_SCALARS_MAKEX(0, 0, 0x0, 0x0, 0x0, 0x0), 0x0, 0x0, 0, 0, 0, 0x0, 0x0}, {REMOTE_SCALARS_MAKEX(0, 0, 0x2, 0x2, 0x0, 0x0), 0x10, 0x10, 11, 8, (&(parameterArrays[9])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x2, 0x0, 0x0), 0xc, 0x4, 6, 4, (&(parameterArrays[17])), 0x4, 0x4}};
+static const Method *const methodArrays[6] = {&(methods[0]), &(methods[1]), &(methods[2]), &(methods[2]), &(methods[3]), &(methods[4])};
+static const char strings[165] = "invoke_get_in_bufs\0routBufLenReq\0get_in_bufs2\0inBufLenReq\0next_invoke\0bufsLenReq\0prevResult\0inBuffers\0prevbufs\0outBufs\0prevCtx\0offset\0handle\0next2\0init2\0init\0ctx\0sc\0";
+static const uint16_t methodStrings[29] = {58, 119, 81, 111, 158, 134, 162, 92, 46, 19, 141, 119, 81, 102, 158, 134, 162, 14, 70, 33, 158, 127, 14, 70, 0, 158, 92, 147, 153};
+static const uint16_t methodStringsArrays[6] = {0, 24, 28, 27, 10, 19};
+__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(adsp_listener_slim) = {6, &(methodArrays[0]), 0, 0, &(methodStringsArrays [0]), methodStrings, strings};
+#endif //_ADSP_LISTENER_SLIM_H
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wpragmas"
+#pragma GCC diagnostic ignored "-Wuninitialized"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#ifndef __QAIC_REMOTE
+#define __QAIC_REMOTE(ff) ff
+#endif //__QAIC_REMOTE
+
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+
+#ifndef __QAIC_STUB
+#define __QAIC_STUB(ff) ff
+#endif //__QAIC_STUB
+
+#ifndef __QAIC_STUB_EXPORT
+#define __QAIC_STUB_EXPORT
+#endif // __QAIC_STUB_EXPORT
+
+#ifndef __QAIC_STUB_ATTRIBUTE
+#define __QAIC_STUB_ATTRIBUTE
+#endif // __QAIC_STUB_ATTRIBUTE
+
+#ifndef __QAIC_SKEL
+#define __QAIC_SKEL(ff) ff
+#endif //__QAIC_SKEL__
+
+#ifndef __QAIC_SKEL_EXPORT
+#define __QAIC_SKEL_EXPORT
+#endif // __QAIC_SKEL_EXPORT
+
+#ifndef __QAIC_SKEL_ATTRIBUTE
+#define __QAIC_SKEL_ATTRIBUTE
+#endif // __QAIC_SKEL_ATTRIBUTE
+
+#ifdef __QAIC_DEBUG__
+#ifndef __QAIC_DBG_PRINTF__
+#define __QAIC_DBG_PRINTF__( ee ) do { printf ee ; } while(0)
+#endif
+#else
+#define __QAIC_DBG_PRINTF__( ee ) (void)0
+#endif
+
+
+#define _OFFSET(src, sof) ((void*)(((char*)(src)) + (sof)))
+
+#define _COPY(dst, dof, src, sof, sz) \
+ do {\
+ struct __copy { \
+ char ar[sz]; \
+ };\
+ *(struct __copy*)_OFFSET(dst, dof) = *(struct __copy*)_OFFSET(src, sof);\
+ } while (0)
+
+#define _ASSIGN(dst, src, sof) \
+ do {\
+ dst = OFFSET(src, sof); \
+ } while (0)
+
+#define _STD_STRLEN_IF(str) (str == 0 ? 0 : strlen(str))
+
+#include "AEEStdErr.h"
+
+#define _TRY(ee, func) \
+ do { \
+ if (AEE_SUCCESS != ((ee) = func)) {\
+ __QAIC_DBG_PRINTF__((__FILE_LINE__ ": error: %d\n", (int)(ee)));\
+ goto ee##bail;\
+ } \
+ } while (0)
+
+#define _CATCH(exception) exception##bail: if (exception != AEE_SUCCESS)
+
+#define _ASSERT(nErr, ff) _TRY(nErr, 0 == (ff) ? AEE_EBADPARM : AEE_SUCCESS)
+
+#ifdef __QAIC_DEBUG__
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, allocator_alloc(pal, __FILE_LINE__, size, alignment, (void**)&pv))
+#else
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, allocator_alloc(pal, 0, size, alignment, (void**)&pv))
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _const_adsp_listener_handle
+#define _const_adsp_listener_handle ((remote_handle)-1)
+#endif //_const_adsp_listener_handle
+
+static void _adsp_listener_pls_dtor(void *data)
+{
+ remote_handle *ph = (remote_handle *)data;
+ if (_const_adsp_listener_handle != *ph)
+ {
+ (void)__QAIC_REMOTE(remote_handle_close)(*ph);
+ *ph = _const_adsp_listener_handle;
+ }
+}
+
+static int _adsp_listener_pls_ctor(void *ctx, void *data)
+{
+ remote_handle *ph = (remote_handle *)data;
+ *ph = _const_adsp_listener_handle;
+ if (*ph == (remote_handle) - 1)
+ {
+ return __QAIC_REMOTE(remote_handle_open)((const char *)ctx, ph);
+ }
+ return 0;
+}
+
+#if (defined __qdsp6__) || (defined __hexagon__)
+#pragma weak adsp_pls_add_lookup
+extern int adsp_pls_add_lookup(uint32_t type, uint32_t key, int size, int (*ctor)(void *ctx, void *data), void *ctx, void (*dtor)(void *ctx), void **ppo);
+#pragma weak HAP_pls_add_lookup
+extern int HAP_pls_add_lookup(uint32_t type, uint32_t key, int size, int (*ctor)(void *ctx, void *data), void *ctx, void (*dtor)(void *ctx), void **ppo);
+
+__QAIC_STUB_EXPORT remote_handle _adsp_listener_handle(void)
+{
+ remote_handle *ph;
+ if (adsp_pls_add_lookup)
+ {
+ if (0 == adsp_pls_add_lookup((uint32_t)_adsp_listener_handle, 0, sizeof(*ph), _adsp_listener_pls_ctor, "adsp_listener", _adsp_listener_pls_dtor, (void **)&ph))
+ {
+ return *ph;
+ }
+ return (remote_handle) - 1;
+ }
+ else if (HAP_pls_add_lookup)
+ {
+ if (0 == HAP_pls_add_lookup((uint32_t)_adsp_listener_handle, 0, sizeof(*ph), _adsp_listener_pls_ctor, "adsp_listener", _adsp_listener_pls_dtor, (void **)&ph))
+ {
+ return *ph;
+ }
+ return (remote_handle) - 1;
+ }
+ return (remote_handle) - 1;
+}
+
+#else //__qdsp6__ || __hexagon__
+
+uint32_t _adsp_listener_atomic_CompareAndExchange(uint32_t *volatile puDest, uint32_t uExchange, uint32_t uCompare);
+
+#ifdef _WIN32
+#include "Windows.h"
+uint32_t _adsp_listener_atomic_CompareAndExchange(uint32_t *volatile puDest, uint32_t uExchange, uint32_t uCompare)
+{
+ return (uint32_t)InterlockedCompareExchange((volatile LONG *)puDest, (LONG)uExchange, (LONG)uCompare);
+}
+#elif __GNUC__
+uint32_t _adsp_listener_atomic_CompareAndExchange(uint32_t *volatile puDest, uint32_t uExchange, uint32_t uCompare)
+{
+ return __sync_val_compare_and_swap(puDest, uCompare, uExchange);
+}
+#endif //_WIN32
+
+
+__QAIC_STUB_EXPORT remote_handle _adsp_listener_handle(void)
+{
+ static remote_handle handle = _const_adsp_listener_handle;
+ if ((remote_handle) - 1 != handle)
+ {
+ return handle;
+ }
+ else
+ {
+ remote_handle tmp;
+ int nErr = _adsp_listener_pls_ctor("adsp_listener", (void *)&tmp);
+ if (nErr)
+ {
+ return (remote_handle) - 1;
+ }
+ if (((remote_handle) - 1 != handle) || ((remote_handle) - 1 != (remote_handle)_adsp_listener_atomic_CompareAndExchange((uint32_t *)&handle, (uint32_t)tmp, (uint32_t) - 1)))
+ {
+ _adsp_listener_pls_dtor(&tmp);
+ }
+ return handle;
+ }
+}
+
+#endif //__qdsp6__
+
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_listener_skel_invoke)(uint32_t _sc, remote_arg *_pra) __QAIC_STUB_ATTRIBUTE
+{
+ return __QAIC_REMOTE(remote_handle_invoke)(_adsp_listener_handle(), _sc, _pra);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+static __inline int _stub_unpack(remote_arg *_praROutPost, remote_arg *_ppraROutPost[1], void *_primROut, char *_rout0[1], uint32_t _rout0Len[1])
+{
+ int _nErr = 0;
+ remote_arg *_praROutPostStart = _praROutPost;
+ remote_arg **_ppraROutPostStart = _ppraROutPost;
+ _ppraROutPost = &_praROutPost;
+ _ppraROutPostStart[0] += (_praROutPost - _praROutPostStart) + 1;
+ return _nErr;
+}
+static __inline int _stub_unpack_1(remote_arg *_praROutPost, remote_arg *_ppraROutPost[1], void *_primROut, char *_in0[1], uint32_t _in0Len[1])
+{
+ int _nErr = 0;
+ remote_arg *_praROutPostStart = _praROutPost;
+ remote_arg **_ppraROutPostStart = _ppraROutPost;
+ _ppraROutPost = &_praROutPost;
+ _ppraROutPostStart[0] += (_praROutPost - _praROutPostStart) + 0;
+ return _nErr;
+}
+static __inline int _stub_pack(allocator *_al, remote_arg *_praIn, remote_arg *_ppraIn[1], remote_arg *_praROut, remote_arg *_ppraROut[1], void *_primIn, void *_primROut, char *_rout0[1], uint32_t _rout0Len[1])
+{
+ int _nErr = 0;
+ remote_arg *_praInStart = _praIn;
+ remote_arg **_ppraInStart = _ppraIn;
+ remote_arg *_praROutStart = _praROut;
+ remote_arg **_ppraROutStart = _ppraROut;
+ _ppraIn = &_praIn;
+ _ppraROut = &_praROut;
+ _COPY(_primIn, 0, _rout0Len, 0, 4);
+ _praROut[0].buf.pv = _rout0[0];
+ _praROut[0].buf.nLen = (1 * _rout0Len[0]);
+ _ppraInStart[0] += (_praIn - _praInStart) + 0;
+ _ppraROutStart[0] += (_praROut - _praROutStart) + 1;
+ return _nErr;
+}
+static __inline int _stub_pack_1(allocator *_al, remote_arg *_praIn, remote_arg *_ppraIn[1], remote_arg *_praROut, remote_arg *_ppraROut[1], void *_primIn, void *_primROut, char *_in0[1], uint32_t _in0Len[1])
+{
+ int _nErr = 0;
+ remote_arg *_praInStart = _praIn;
+ remote_arg **_ppraInStart = _ppraIn;
+ remote_arg *_praROutStart = _praROut;
+ remote_arg **_ppraROutStart = _ppraROut;
+ _ppraIn = &_praIn;
+ _ppraROut = &_praROut;
+ _COPY(_primIn, 0, _in0Len, 0, 4);
+ _praIn[0].buf.pv = _in0[0];
+ _praIn[0].buf.nLen = (1 * _in0Len[0]);
+ _ppraInStart[0] += (_praIn - _praInStart) + 1;
+ _ppraROutStart[0] += (_praROut - _praROutStart) + 0;
+ return _nErr;
+}
+static __inline void _count(int _numIn[1], int _numROut[1], char *_rout0[1], uint32_t _rout0Len[1])
+{
+ _numIn[0] += 0;
+ _numROut[0] += 1;
+}
+static __inline void _count_1(int _numIn[1], int _numROut[1], char *_in0[1], uint32_t _in0Len[1])
+{
+ _numIn[0] += 1;
+ _numROut[0] += 0;
+}
+static __inline int _stub_method(remote_handle _handle, uint32_t _mid, uint32_t _in0[1], uint32_t _in1[1], void *_in2[1], uint32_t _in2Len[1], uint32_t _rout3[1], uint32_t _rout4[1], uint32_t _rout5[1], void *_rout6[1], uint32_t _rout6Len[1], char *_rout7[1], uint32_t _rout7Len[1], char *_rout8[1], uint32_t _rout8Len[1])
+{
+ remote_arg *_pra;
+ int _numIn[1];
+ int _numROut[1];
+ char *_seq_nat2;
+ int _ii;
+ char *_seq_nat6;
+ allocator _al[1] = {{0}};
+ uint32_t _primIn[6];
+ uint32_t _primROut[3];
+ remote_arg *_praIn;
+ remote_arg *_praROut;
+ remote_arg *_praROutPost;
+ remote_arg **_ppraROutPost = &_praROutPost;
+ remote_arg **_ppraIn = &_praIn;
+ remote_arg **_ppraROut = &_praROut;
+ char *_seq_primIn2;
+ int _nErr = 0;
+ char *_seq_primIn6;
+ _numIn[0] = 2;
+ _numROut[0] = 2;
+ for (_ii = 0, _seq_nat2 = (char *)_in2[0]; _ii < (int)_in2Len[0]; ++_ii, _seq_nat2 = (_seq_nat2 + 8))
+ {
+ _count_1(_numIn, _numROut, (char **) & (((uint32_t *)_seq_nat2)[0]), (uint32_t *) & (((uint32_t *)_seq_nat2)[1]));
+ }
+ for (_ii = 0, _seq_nat6 = (char *)_rout6[0]; _ii < (int)_rout6Len[0]; ++_ii, _seq_nat6 = (_seq_nat6 + 8))
+ {
+ _count(_numIn, _numROut, (char **) & (((uint32_t *)_seq_nat6)[0]), (uint32_t *) & (((uint32_t *)_seq_nat6)[1]));
+ }
+ allocator_init(_al, 0, 0);
+ _ALLOCATE(_nErr, _al, ((((_numIn[0] + _numROut[0]) + 1) + 1) * sizeof(_pra[0])), 4, _pra);
+ _pra[0].buf.pv = (void *)_primIn;
+ _pra[0].buf.nLen = sizeof(_primIn);
+ _pra[(_numIn[0] + 1)].buf.pv = (void *)_primROut;
+ _pra[(_numIn[0] + 1)].buf.nLen = sizeof(_primROut);
+ _praIn = (_pra + 1);
+ _praROut = (_praIn + _numIn[0] + 1);
+ _praROutPost = _praROut;
+ _COPY(_primIn, 0, _in0, 0, 4);
+ _COPY(_primIn, 4, _in1, 0, 4);
+ _COPY(_primIn, 8, _in2Len, 0, 4);
+ _ALLOCATE(_nErr, _al, (_in2Len[0] * 4), 4, _praIn[0].buf.pv);
+ _praIn[0].buf.nLen = (4 * _in2Len[0]);
+ for (_ii = 0, _seq_primIn2 = (char *)_praIn[0].buf.pv, _seq_nat2 = (char *)_in2[0]; _ii < (int)_in2Len[0]; ++_ii, _seq_primIn2 = (_seq_primIn2 + 4), _seq_nat2 = (_seq_nat2 + 8))
+ {
+ _TRY(_nErr, _stub_pack_1(_al, (_praIn + 1), _ppraIn, (_praROut + 0), _ppraROut, _seq_primIn2, 0, (char **) & (((uint32_t *)_seq_nat2)[0]), (uint32_t *) & (((uint32_t *)_seq_nat2)[1])));
+ }
+ _COPY(_primIn, 12, _rout6Len, 0, 4);
+ _ALLOCATE(_nErr, _al, (_rout6Len[0] * 4), 4, _praIn[1].buf.pv);
+ _praIn[1].buf.nLen = (4 * _rout6Len[0]);
+ for (_ii = 0, _seq_primIn6 = (char *)_praIn[1].buf.pv, _seq_nat6 = (char *)_rout6[0]; _ii < (int)_rout6Len[0]; ++_ii, _seq_primIn6 = (_seq_primIn6 + 4), _seq_nat6 = (_seq_nat6 + 8))
+ {
+ _TRY(_nErr, _stub_pack(_al, (_praIn + 2), _ppraIn, (_praROut + 0), _ppraROut, _seq_primIn6, 0, (char **) & (((uint32_t *)_seq_nat6)[0]), (uint32_t *) & (((uint32_t *)_seq_nat6)[1])));
+ }
+ _COPY(_primIn, 16, _rout7Len, 0, 4);
+ _praROut[0].buf.pv = _rout7[0];
+ _praROut[0].buf.nLen = (4 * _rout7Len[0]);
+ _COPY(_primIn, 20, _rout8Len, 0, 4);
+ _praROut[1].buf.pv = _rout8[0];
+ _praROut[1].buf.nLen = (4 * _rout8Len[0]);
+ _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, (_numIn[0] + 1), (_numROut[0] + 1), 0, 0), _pra));
+ for (_ii = 0, _seq_nat2 = (char *)_in2[0]; _ii < (int)_in2Len[0]; ++_ii, _seq_nat2 = (_seq_nat2 + 8))
+ {
+ _TRY(_nErr, _stub_unpack_1((_praROutPost + 0), _ppraROutPost, 0, (char **) & (((uint32_t *)_seq_nat2)[0]), (uint32_t *) & (((uint32_t *)_seq_nat2)[1])));
+ }
+ _COPY(_rout3, 0, _primROut, 0, 4);
+ _COPY(_rout4, 0, _primROut, 4, 4);
+ _COPY(_rout5, 0, _primROut, 8, 4);
+ for (_ii = 0, _seq_nat6 = (char *)_rout6[0]; _ii < (int)_rout6Len[0]; ++_ii, _seq_nat6 = (_seq_nat6 + 8))
+ {
+ _TRY(_nErr, _stub_unpack((_praROutPost + 0), _ppraROutPost, 0, (char **) & (((uint32_t *)_seq_nat6)[0]), (uint32_t *) & (((uint32_t *)_seq_nat6)[1])));
+ }
+ _CATCH(_nErr) {}
+ allocator_deinit(_al);
+ return _nErr;
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_listener_next_invoke)(adsp_listener_invoke_ctx prevCtx, int prevResult, const adsp_listener_buffer *outBufs, int outBufsLen, adsp_listener_invoke_ctx *ctx, adsp_listener_remote_handle *handle, uint32 *sc, adsp_listener_buffer *inBuffers, int inBuffersLen, int *inBufLenReq, int inBufLenReqLen, int *routBufLenReq, int routBufLenReqLen) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 0;
+ return _stub_method(_adsp_listener_handle(), _mid, (uint32_t *)&prevCtx, (uint32_t *)&prevResult, (void **)&outBufs, (uint32_t *)&outBufsLen, (uint32_t *)ctx, (uint32_t *)handle, (uint32_t *)sc, (void **)&inBuffers, (uint32_t *)&inBuffersLen, (char **)&inBufLenReq, (uint32_t *)&inBufLenReqLen, (char **)&routBufLenReq, (uint32_t *)&routBufLenReqLen);
+}
+static __inline int _stub_unpack_2(remote_arg *_praROutPost, remote_arg *_ppraROutPost[1], void *_primROut, char *_rout0[1], uint32_t _rout0Len[1])
+{
+ int _nErr = 0;
+ remote_arg *_praROutPostStart = _praROutPost;
+ remote_arg **_ppraROutPostStart = _ppraROutPost;
+ _ppraROutPost = &_praROutPost;
+ _ppraROutPostStart[0] += (_praROutPost - _praROutPostStart) + 1;
+ return _nErr;
+}
+static __inline int _stub_pack_2(allocator *_al, remote_arg *_praIn, remote_arg *_ppraIn[1], remote_arg *_praROut, remote_arg *_ppraROut[1], void *_primIn, void *_primROut, char *_rout0[1], uint32_t _rout0Len[1])
+{
+ int _nErr = 0;
+ remote_arg *_praInStart = _praIn;
+ remote_arg **_ppraInStart = _ppraIn;
+ remote_arg *_praROutStart = _praROut;
+ remote_arg **_ppraROutStart = _ppraROut;
+ _ppraIn = &_praIn;
+ _ppraROut = &_praROut;
+ _COPY(_primIn, 0, _rout0Len, 0, 4);
+ _praROut[0].buf.pv = _rout0[0];
+ _praROut[0].buf.nLen = (1 * _rout0Len[0]);
+ _ppraInStart[0] += (_praIn - _praInStart) + 0;
+ _ppraROutStart[0] += (_praROut - _praROutStart) + 1;
+ return _nErr;
+}
+static __inline int _stub_method_1(remote_handle _handle, uint32_t _mid, uint32_t _in0[1], void *_rout1[1], uint32_t _rout1Len[1])
+{
+ remote_arg *_pra;
+ int _numIn[1];
+ int _numROut[1];
+ char *_seq_nat1;
+ int _ii;
+ allocator _al[1] = {{0}};
+ uint32_t _primIn[2];
+ remote_arg *_praIn;
+ remote_arg *_praROut;
+ remote_arg *_praROutPost;
+ remote_arg **_ppraROutPost = &_praROutPost;
+ remote_arg **_ppraIn = &_praIn;
+ remote_arg **_ppraROut = &_praROut;
+ char *_seq_primIn1;
+ int _nErr = 0;
+ _numIn[0] = 1;
+ _numROut[0] = 0;
+ for (_ii = 0, _seq_nat1 = (char *)_rout1[0]; _ii < (int)_rout1Len[0]; ++_ii, _seq_nat1 = (_seq_nat1 + 8))
+ {
+ _count(_numIn, _numROut, (char **) & (((uint32_t *)_seq_nat1)[0]), (uint32_t *) & (((uint32_t *)_seq_nat1)[1]));
+ }
+ allocator_init(_al, 0, 0);
+ _ALLOCATE(_nErr, _al, ((((_numIn[0] + _numROut[0]) + 1) + 0) * sizeof(_pra[0])), 4, _pra);
+ _pra[0].buf.pv = (void *)_primIn;
+ _pra[0].buf.nLen = sizeof(_primIn);
+ _praIn = (_pra + 1);
+ _praROut = (_praIn + _numIn[0] + 0);
+ _praROutPost = _praROut;
+ _COPY(_primIn, 0, _in0, 0, 4);
+ _COPY(_primIn, 4, _rout1Len, 0, 4);
+ _ALLOCATE(_nErr, _al, (_rout1Len[0] * 4), 4, _praIn[0].buf.pv);
+ _praIn[0].buf.nLen = (4 * _rout1Len[0]);
+ for (_ii = 0, _seq_primIn1 = (char *)_praIn[0].buf.pv, _seq_nat1 = (char *)_rout1[0]; _ii < (int)_rout1Len[0]; ++_ii, _seq_primIn1 = (_seq_primIn1 + 4), _seq_nat1 = (_seq_nat1 + 8))
+ {
+ _TRY(_nErr, _stub_pack_2(_al, (_praIn + 1), _ppraIn, (_praROut + 0), _ppraROut, _seq_primIn1, 0, (char **) & (((uint32_t *)_seq_nat1)[0]), (uint32_t *) & (((uint32_t *)_seq_nat1)[1])));
+ }
+ _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, (_numIn[0] + 1), (_numROut[0] + 0), 0, 0), _pra));
+ for (_ii = 0, _seq_nat1 = (char *)_rout1[0]; _ii < (int)_rout1Len[0]; ++_ii, _seq_nat1 = (_seq_nat1 + 8))
+ {
+ _TRY(_nErr, _stub_unpack_2((_praROutPost + 0), _ppraROutPost, 0, (char **) & (((uint32_t *)_seq_nat1)[0]), (uint32_t *) & (((uint32_t *)_seq_nat1)[1])));
+ }
+ _CATCH(_nErr) {}
+ allocator_deinit(_al);
+ return _nErr;
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_listener_invoke_get_in_bufs)(adsp_listener_invoke_ctx ctx, adsp_listener_buffer *inBuffers, int inBuffersLen) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 1;
+ return _stub_method_1(_adsp_listener_handle(), _mid, (uint32_t *)&ctx, (void **)&inBuffers, (uint32_t *)&inBuffersLen);
+}
+static __inline int _stub_method_2(remote_handle _handle, uint32_t _mid)
+{
+ remote_arg *_pra = 0;
+ int _nErr = 0;
+ _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 0, 0, 0, 0), _pra));
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_listener_init)(void) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 2;
+ return _stub_method_2(_adsp_listener_handle(), _mid);
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_listener_init2)(void) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 3;
+ return _stub_method_2(_adsp_listener_handle(), _mid);
+}
+static __inline int _stub_method_3(remote_handle _handle, uint32_t _mid, uint32_t _in0[1], uint32_t _in1[1], char *_in2[1], uint32_t _in2Len[1], uint32_t _rout3[1], uint32_t _rout4[1], uint32_t _rout5[1], char *_rout6[1], uint32_t _rout6Len[1], uint32_t _rout7[1])
+{
+ int _numIn[1];
+ remote_arg _pra[4];
+ uint32_t _primIn[4];
+ uint32_t _primROut[4];
+ remote_arg *_praIn;
+ remote_arg *_praROut;
+ int _nErr = 0;
+ _numIn[0] = 1;
+ _pra[0].buf.pv = (void *)_primIn;
+ _pra[0].buf.nLen = sizeof(_primIn);
+ _pra[(_numIn[0] + 1)].buf.pv = (void *)_primROut;
+ _pra[(_numIn[0] + 1)].buf.nLen = sizeof(_primROut);
+ _COPY(_primIn, 0, _in0, 0, 4);
+ _COPY(_primIn, 4, _in1, 0, 4);
+ _COPY(_primIn, 8, _in2Len, 0, 4);
+ _praIn = (_pra + 1);
+ _praIn[0].buf.pv = _in2[0];
+ _praIn[0].buf.nLen = (1 * _in2Len[0]);
+ _COPY(_primIn, 12, _rout6Len, 0, 4);
+ _praROut = (_praIn + _numIn[0] + 1);
+ _praROut[0].buf.pv = _rout6[0];
+ _praROut[0].buf.nLen = (1 * _rout6Len[0]);
+ _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 2, 2, 0, 0), _pra));
+ _COPY(_rout3, 0, _primROut, 0, 4);
+ _COPY(_rout4, 0, _primROut, 4, 4);
+ _COPY(_rout5, 0, _primROut, 8, 4);
+ _COPY(_rout7, 0, _primROut, 12, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_listener_next2)(adsp_listener_invoke_ctx prevCtx, int prevResult, const uint8 *prevbufs, int prevbufsLen, adsp_listener_invoke_ctx *ctx, adsp_listener_remote_handle *handle, uint32 *sc, uint8 *bufs, int bufsLen, int *bufsLenReq) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 4;
+ return _stub_method_3(_adsp_listener_handle(), _mid, (uint32_t *)&prevCtx, (uint32_t *)&prevResult, (char **)&prevbufs, (uint32_t *)&prevbufsLen, (uint32_t *)ctx, (uint32_t *)handle, (uint32_t *)sc, (char **)&bufs, (uint32_t *)&bufsLen, (uint32_t *)bufsLenReq);
+}
+static __inline int _stub_method_4(remote_handle _handle, uint32_t _mid, uint32_t _in0[1], uint32_t _in1[1], char *_rout2[1], uint32_t _rout2Len[1], uint32_t _rout3[1])
+{
+ int _numIn[1];
+ remote_arg _pra[3];
+ uint32_t _primIn[3];
+ uint32_t _primROut[1];
+ remote_arg *_praIn;
+ remote_arg *_praROut;
+ int _nErr = 0;
+ _numIn[0] = 0;
+ _pra[0].buf.pv = (void *)_primIn;
+ _pra[0].buf.nLen = sizeof(_primIn);
+ _pra[(_numIn[0] + 1)].buf.pv = (void *)_primROut;
+ _pra[(_numIn[0] + 1)].buf.nLen = sizeof(_primROut);
+ _COPY(_primIn, 0, _in0, 0, 4);
+ _COPY(_primIn, 4, _in1, 0, 4);
+ _COPY(_primIn, 8, _rout2Len, 0, 4);
+ _praIn = (_pra + 1);
+ _praROut = (_praIn + _numIn[0] + 1);
+ _praROut[0].buf.pv = _rout2[0];
+ _praROut[0].buf.nLen = (1 * _rout2Len[0]);
+ _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 1, 2, 0, 0), _pra));
+ _COPY(_rout3, 0, _primROut, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(adsp_listener_get_in_bufs2)(adsp_listener_invoke_ctx ctx, int offset, uint8 *bufs, int bufsLen, int *bufsLenReq) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 5;
+ return _stub_method_4(_adsp_listener_handle(), _mid, (uint32_t *)&ctx, (uint32_t *)&offset, (char **)&bufs, (uint32_t *)&bufsLen, (uint32_t *)bufsLenReq);
+}
+#ifdef __cplusplus
+}
+#endif
+#endif //_ADSP_LISTENER_STUB_H
diff --git a/src/adsp_listener_stub.d b/src/adsp_listener_stub.d
new file mode 100644
index 0000000..350ba43
--- /dev/null
+++ b/src/adsp_listener_stub.d
@@ -0,0 +1,10 @@
+src/adsp_listener_stub.o: src/adsp_listener_stub.c inc/adsp_listener.h \
+ inc/AEEStdDef.h inc/remote.h inc/AEEStdErr.h
+
+inc/adsp_listener.h:
+
+inc/AEEStdDef.h:
+
+inc/remote.h:
+
+inc/AEEStdErr.h:
diff --git a/src/adsp_listener_stub.o b/src/adsp_listener_stub.o
new file mode 100644
index 0000000..b443997
--- /dev/null
+++ b/src/adsp_listener_stub.o
Binary files differ
diff --git a/src/apps_mem_imp.c b/src/apps_mem_imp.c
new file mode 100644
index 0000000..d50d0ad
--- /dev/null
+++ b/src/apps_mem_imp.c
@@ -0,0 +1,172 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include "apps_mem.h"
+#include "remote64.h"
+#include "rpcmem.h"
+#include "verify.h"
+#include "rpcmem.h"
+#include "AEEQList.h"
+#include "AEEstd.h"
+
+#define ADSP_MMAP_HEAP_ADDR 4
+
+static QList memlst;
+static pthread_mutex_t memmt;
+
+struct mem_info
+{
+ QNode qn;
+ uint64 vapps;
+ uint64 vadsp;
+ int32 size;
+};
+
+/* These should be called in some static constructor of the .so that
+uses rpcmem.
+
+I moved them into fastrpc_apps_user.c because there is no gurantee in
+the order of when constructors are called. */
+
+void apps_mem_init(void)
+{
+ QList_Ctor(&memlst);
+ pthread_mutex_init(&memmt, 0);
+}
+
+void apps_mem_deinit(void)
+{
+ QNode *pn;
+ while ((pn = QList_PopZ(&memlst)) != NULL)
+ {
+ struct mem_info *mfree = STD_RECOVER_REC(struct mem_info, qn, pn);
+ rpcmem_free((void *)(uintptr_t)mfree->vapps);
+ free(mfree);
+ }
+ pthread_mutex_destroy(&memmt);
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_mem_request_map64)(int heapid, uint32 lflags, uint32 rflags, uint64 vin, int64 len, uint64 *vapps, uint64 *vadsp) __QAIC_IMPL_ATTRIBUTE
+{
+ struct mem_info *minfo = 0;
+ int nErr = 0;
+ void *buf = 0;
+ uintptr_t pbuf;
+ int fd;
+ (void)vin;
+ VERIFY(0 != (minfo = malloc(sizeof(*minfo))));
+ QNode_CtorZ(&minfo->qn);
+ *vadsp = 0;
+ if (rflags == ADSP_MMAP_HEAP_ADDR)
+ {
+ VERIFY(0 == remote_mmap64(-1, rflags, 0, len, (uintptr_t *)vadsp));
+ *vapps = 0;
+ minfo->vapps = 0;
+ }
+ else
+ {
+ lflags |= RPCMEM_HEAP_NOREG;
+ VERIFY(0 != (buf = rpcmem_alloc(heapid, lflags, len)));
+ fd = rpcmem_to_fd(buf);
+ VERIFY(fd > 0);
+ VERIFY(0 == remote_mmap64(fd, rflags, (uintptr_t)buf, len, (uintptr_t *)vadsp));
+ pbuf = (uintptr_t)buf;
+ *vapps = (uint64)pbuf;
+ minfo->vapps = *vapps;
+ }
+ minfo->vadsp = *vadsp;
+ minfo->size = len;
+ pthread_mutex_lock(&memmt);
+ QList_AppendNode(&memlst, &minfo->qn);
+ pthread_mutex_unlock(&memmt);
+bail:
+ if (nErr)
+ {
+ if (buf)
+ {
+ rpcmem_free(buf);
+ }
+ if (minfo)
+ {
+ free(minfo);
+ }
+ }
+ return nErr;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_mem_request_map)(int heapid, uint32 lflags, uint32 rflags, uint32 vin, int32 len, uint32 *vapps, uint32 *vadsp) __QAIC_IMPL_ATTRIBUTE
+{
+ uint64 vin1, vapps1, vadsp1;
+ int64 len1;
+ int nErr;
+ vin1 = (uint64)vin;
+ len1 = (int64)len;
+ nErr = apps_mem_request_map64(heapid, lflags, rflags, vin1, len1, &vapps1, &vadsp1);
+ *vapps = (uint32)vapps1;
+ *vadsp = (uint32)vadsp1;
+ return nErr;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_mem_request_unmap64)(uint64 vadsp, int64 len) __QAIC_IMPL_ATTRIBUTE
+{
+ int nErr = 0;
+ struct mem_info * minfo, *mfree = 0;
+ QNode * pn, *pnn;
+ VERIFY(0 == remote_munmap64((uintptr_t)vadsp, len));
+ pthread_mutex_lock(&memmt);
+ QLIST_NEXTSAFE_FOR_ALL(&memlst, pn, pnn)
+ {
+ minfo = STD_RECOVER_REC(struct mem_info, qn, pn);
+ if (minfo->vadsp == vadsp)
+ {
+ mfree = minfo;
+ QNode_Dequeue(&minfo->qn);
+ break;
+ }
+ }
+ pthread_mutex_unlock(&memmt);
+ VERIFY(mfree);
+ rpcmem_free((void *)(uintptr_t)mfree->vapps);
+ free(mfree);
+bail:
+ return nErr;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_mem_request_unmap)(uint32 vadsp, int32 len) __QAIC_IMPL_ATTRIBUTE
+{
+ uint64 vadsp1 = (uint64)vadsp;
+ int64 len1 = (int64)len;
+ return apps_mem_request_unmap64(vadsp1, len1);
+}
+
diff --git a/src/apps_mem_skel.c b/src/apps_mem_skel.c
new file mode 100644
index 0000000..13be7a8
--- /dev/null
+++ b/src/apps_mem_skel.c
@@ -0,0 +1,556 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _APPS_MEM_SKEL_H
+#define _APPS_MEM_SKEL_H
+#include "apps_mem.h"
+#include "remote.h"
+#ifndef ALLOCATOR_H
+#define ALLOCATOR_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef struct _heap _heap;
+struct _heap
+{
+ _heap *pPrev;
+ const char *loc;
+ uint64_t buf;
+};
+
+typedef struct allocator
+{
+ _heap *pheap;
+ uint8_t *stack;
+ uint8_t *stackEnd;
+ int nSize;
+} allocator;
+
+static __inline int _heap_alloc(_heap **ppa, const char *loc, int size, void **ppbuf)
+{
+ _heap *pn = 0;
+ pn = malloc(size + sizeof(_heap) - sizeof(uint64_t));
+ if (pn != 0)
+ {
+ pn->pPrev = *ppa;
+ pn->loc = loc;
+ *ppa = pn;
+ *ppbuf = (void *) & (pn->buf);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+#define _ALIGN_SIZE(x, y) (((x) + (y-1)) & ~(y-1))
+
+
+static __inline int allocator_alloc(allocator *me,
+ const char *loc,
+ int size,
+ unsigned int al,
+ void **ppbuf)
+{
+ if (size < 0)
+ {
+ return -1;
+ }
+ else if (size == 0)
+ {
+ *ppbuf = 0;
+ return 0;
+ }
+ if ((_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size) < (uintptr_t)me->stack + me->nSize)
+ {
+ *ppbuf = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al);
+ me->stackEnd = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size;
+ return 0;
+ }
+ else
+ {
+ return _heap_alloc(&me->pheap, loc, size, ppbuf);
+ }
+}
+
+
+static __inline void allocator_deinit(allocator *me)
+{
+ _heap *pa = me->pheap;
+ while (pa != 0)
+ {
+ _heap *pn = pa;
+ const char *loc = pn->loc;
+ (void)loc;
+ pa = pn->pPrev;
+ free(pn);
+ }
+}
+
+static __inline void allocator_init(allocator *me, uint8_t *stack, int stackSize)
+{
+ me->stack = stack;
+ me->stackEnd = stack + stackSize;
+ me->nSize = stackSize;
+ me->pheap = 0;
+}
+
+
+#endif // ALLOCATOR_H
+
+#ifndef SLIM_H
+#define SLIM_H
+
+#include <stdint.h>
+
+//a C data structure for the idl types that can be used to implement
+//static and dynamic language bindings fairly efficiently.
+//
+//the goal is to have a minimal ROM and RAM footprint and without
+//doing too many allocations. A good way to package these things seemed
+//like the module boundary, so all the idls within one module can share
+//all the type references.
+
+
+#define PARAMETER_IN 0x0
+#define PARAMETER_OUT 0x1
+#define PARAMETER_INOUT 0x2
+#define PARAMETER_ROUT 0x3
+#define PARAMETER_INROUT 0x4
+
+//the types that we get from idl
+#define TYPE_OBJECT 0x0
+#define TYPE_INTERFACE 0x1
+#define TYPE_PRIMITIVE 0x2
+#define TYPE_ENUM 0x3
+#define TYPE_STRING 0x4
+#define TYPE_WSTRING 0x5
+#define TYPE_STRUCTURE 0x6
+#define TYPE_UNION 0x7
+#define TYPE_ARRAY 0x8
+#define TYPE_SEQUENCE 0x9
+
+//these require the pack/unpack to recurse
+//so it's a hint to those languages that can optimize in cases where
+//recursion isn't necessary.
+#define TYPE_COMPLEX_STRUCTURE (0x10 | TYPE_STRUCTURE)
+#define TYPE_COMPLEX_UNION (0x10 | TYPE_UNION)
+#define TYPE_COMPLEX_ARRAY (0x10 | TYPE_ARRAY)
+#define TYPE_COMPLEX_SEQUENCE (0x10 | TYPE_SEQUENCE)
+
+
+typedef struct Type Type;
+
+#define INHERIT_TYPE\
+ int32_t nativeSize; /*in the simple case its the same as wire size and alignment*/\
+ union {\
+ struct {\
+ const uintptr_t p1;\
+ const uintptr_t p2;\
+ } _cast;\
+ struct {\
+ uint32_t iid;\
+ uint32_t bNotNil;\
+ } object;\
+ struct {\
+ const Type *arrayType;\
+ int32_t nItems;\
+ } array;\
+ struct {\
+ const Type *seqType;\
+ int32_t nMaxLen;\
+ } seqSimple; \
+ struct {\
+ uint32_t bFloating;\
+ uint32_t bSigned;\
+ } prim; \
+ const SequenceType* seqComplex;\
+ const UnionType *unionType;\
+ const StructType *structType;\
+ int32_t stringMaxLen;\
+ uint8_t bInterfaceNotNil;\
+ } param;\
+ uint8_t type;\
+ uint8_t nativeAlignment\
+
+typedef struct UnionType UnionType;
+typedef struct StructType StructType;
+typedef struct SequenceType SequenceType;
+struct Type
+{
+ INHERIT_TYPE;
+};
+
+struct SequenceType
+{
+ const Type *seqType;
+ uint32_t nMaxLen;
+ uint32_t inSize;
+ uint32_t routSizePrimIn;
+ uint32_t routSizePrimROut;
+};
+
+//byte offset from the start of the case values for
+//this unions case value array. it MUST be aligned
+//at the alignment requrements for the descriptor
+//
+//if negative it means that the unions cases are
+//simple enumerators, so the value read from the descriptor
+//can be used directly to find the correct case
+typedef union CaseValuePtr CaseValuePtr;
+union CaseValuePtr
+{
+ const uint8_t *value8s;
+ const uint16_t *value16s;
+ const uint32_t *value32s;
+ const uint64_t *value64s;
+};
+
+//these are only used in complex cases
+//so I pulled them out of the type definition as references to make
+//the type smaller
+struct UnionType
+{
+ const Type *descriptor;
+ uint32_t nCases;
+ const CaseValuePtr caseValues;
+ const Type *const *cases;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+ uint8_t inCaseAlignment;
+ uint8_t routCaseAlignmentPrimIn;
+ uint8_t routCaseAlignmentPrimROut;
+ uint8_t nativeCaseAlignment;
+ uint8_t bDefaultCase;
+};
+
+struct StructType
+{
+ uint32_t nMembers;
+ const Type *const *members;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+};
+
+typedef struct Parameter Parameter;
+struct Parameter
+{
+ INHERIT_TYPE;
+ uint8_t mode;
+ uint8_t bNotNil;
+};
+
+#define SLIM_SCALARS_IS_DYNAMIC(u) (((u) & 0x00ffffff) == 0x00ffffff)
+
+typedef struct Method Method;
+struct Method
+{
+ uint32_t uScalars; //no method index
+ int32_t primInSize;
+ int32_t primROutSize;
+ int maxArgs;
+ int numParams;
+ const Parameter *const *params;
+ uint8_t primInAlignment;
+ uint8_t primROutAlignment;
+};
+
+typedef struct Interface Interface;
+
+struct Interface
+{
+ int nMethods;
+ const Method *const *methodArray;
+ int nIIds;
+ const uint32_t *iids;
+ const uint16_t *methodStringArray;
+ const uint16_t *methodStrings;
+ const char *strings;
+};
+
+
+#endif //SLIM_H
+
+
+#ifndef _APPS_MEM_SLIM_H
+#define _APPS_MEM_SLIM_H
+#include "remote.h"
+#include <stdint.h>
+
+#ifndef __QAIC_SLIM
+#define __QAIC_SLIM(ff) ff
+#endif
+#ifndef __QAIC_SLIM_EXPORT
+#define __QAIC_SLIM_EXPORT
+#endif
+
+static const Parameter parameters[6] = {{0x4, {{(const uintptr_t)0, (const uintptr_t)1}}, 2, 0x4, 0, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x4, 0, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x4, 3, 0}, {0x8, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x8, 0, 0}, {0x8, {{(const uintptr_t)0, (const uintptr_t)1}}, 2, 0x8, 0, 0}, {0x8, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x8, 3, 0}};
+static const Parameter *const parameterArrays[14] = {(&(parameters[0])), (&(parameters[1])), (&(parameters[1])), (&(parameters[3])), (&(parameters[4])), (&(parameters[5])), (&(parameters[5])), (&(parameters[0])), (&(parameters[1])), (&(parameters[1])), (&(parameters[1])), (&(parameters[0])), (&(parameters[2])), (&(parameters[2]))};
+static const Method methods[4] = {{REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x1, 0x0, 0x0), 0x14, 0x8, 7, 7, (&(parameterArrays[7])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x0, 0x0, 0x0), 0x8, 0x0, 2, 2, (&(parameterArrays[10])), 0x4, 0x0}, {REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x1, 0x0, 0x0), 0x20, 0x10, 11, 7, (&(parameterArrays[0])), 0x8, 0x8}, {REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x0, 0x0, 0x0), 0x10, 0x0, 6, 2, (&(parameterArrays[3])), 0x8, 0x0}};
+static const Method *const methodArrays[4] = {&(methods[0]), &(methods[1]), &(methods[2]), &(methods[3])};
+static const char strings[100] = "request_unmap64\0request_map64\0request_unmap\0request_map\0ion_flags\0rflags\0heapid\0vadsp\0vapps\0len\0vin\0";
+static const uint16_t methodStrings[22] = {16, 73, 56, 66, 96, 92, 86, 80, 44, 73, 56, 66, 96, 92, 86, 80, 0, 80, 92, 30, 80, 92};
+static const uint16_t methodStringsArrays[4] = {8, 19, 0, 16};
+__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(apps_mem_slim) = {4, &(methodArrays[0]), 0, 0, &(methodStringsArrays [0]), methodStrings, strings};
+#endif //_APPS_MEM_SLIM_H
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wpragmas"
+#pragma GCC diagnostic ignored "-Wuninitialized"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#ifndef __QAIC_REMOTE
+#define __QAIC_REMOTE(ff) ff
+#endif //__QAIC_REMOTE
+
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+
+#ifndef __QAIC_STUB
+#define __QAIC_STUB(ff) ff
+#endif //__QAIC_STUB
+
+#ifndef __QAIC_STUB_EXPORT
+#define __QAIC_STUB_EXPORT
+#endif // __QAIC_STUB_EXPORT
+
+#ifndef __QAIC_STUB_ATTRIBUTE
+#define __QAIC_STUB_ATTRIBUTE
+#endif // __QAIC_STUB_ATTRIBUTE
+
+#ifndef __QAIC_SKEL
+#define __QAIC_SKEL(ff) ff
+#endif //__QAIC_SKEL__
+
+#ifndef __QAIC_SKEL_EXPORT
+#define __QAIC_SKEL_EXPORT
+#endif // __QAIC_SKEL_EXPORT
+
+#ifndef __QAIC_SKEL_ATTRIBUTE
+#define __QAIC_SKEL_ATTRIBUTE
+#endif // __QAIC_SKEL_ATTRIBUTE
+
+#ifdef __QAIC_DEBUG__
+#ifndef __QAIC_DBG_PRINTF__
+#define __QAIC_DBG_PRINTF__( ee ) do { printf ee ; } while(0)
+#endif
+#else
+#define __QAIC_DBG_PRINTF__( ee ) (void)0
+#endif
+
+
+#define _OFFSET(src, sof) ((void*)(((char*)(src)) + (sof)))
+
+#define _COPY(dst, dof, src, sof, sz) \
+ do {\
+ struct __copy { \
+ char ar[sz]; \
+ };\
+ *(struct __copy*)_OFFSET(dst, dof) = *(struct __copy*)_OFFSET(src, sof);\
+ } while (0)
+
+#define _ASSIGN(dst, src, sof) \
+ do {\
+ dst = OFFSET(src, sof); \
+ } while (0)
+
+#define _STD_STRLEN_IF(str) (str == 0 ? 0 : strlen(str))
+
+#include "AEEStdErr.h"
+
+#define _TRY(ee, func) \
+ do { \
+ if (AEE_SUCCESS != ((ee) = func)) {\
+ __QAIC_DBG_PRINTF__((__FILE_LINE__ ": error: %d\n", (int)(ee)));\
+ goto ee##bail;\
+ } \
+ } while (0)
+
+#define _CATCH(exception) exception##bail: if (exception != AEE_SUCCESS)
+
+#define _ASSERT(nErr, ff) _TRY(nErr, 0 == (ff) ? AEE_EBADPARM : AEE_SUCCESS)
+
+#ifdef __QAIC_DEBUG__
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, allocator_alloc(pal, __FILE_LINE__, size, alignment, (void**)&pv))
+#else
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, allocator_alloc(pal, 0, size, alignment, (void**)&pv))
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+static __inline int _skel_method(int (*_pfn)(uint64_t, uint64_t), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint64_t _in0[1];
+ uint64_t _in1[1];
+ uint64_t *_primIn;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 1) <= _praEnd);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 16);
+ _primIn = _pra[0].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 8);
+ _COPY(_in1, 0, _primIn, 8, 8);
+ _TRY(_nErr, _pfn(*_in0, *_in1));
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_1(int (*_pfn)(uint32_t, uint32_t, uint32_t, uint64_t, uint64_t, uint64_t *, uint64_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint32_t _in0[1];
+ uint32_t _in1[1];
+ uint32_t _in2[1];
+ uint64_t _in3[1];
+ uint64_t _in4[1];
+ uint64_t _rout5[1];
+ uint64_t _rout6[1];
+ uint64_t *_primIn;
+ int _numIn[1];
+ uint64_t *_primROut;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 2) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 32);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 16);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 4);
+ _COPY(_in1, 0, _primIn, 4, 4);
+ _COPY(_in2, 0, _primIn, 8, 4);
+ _COPY(_in3, 0, _primIn, 16, 8);
+ _COPY(_in4, 0, _primIn, 24, 8);
+ _TRY(_nErr, _pfn(*_in0, *_in1, *_in2, *_in3, *_in4, _rout5, _rout6));
+ _COPY(_primROut, 0, _rout5, 0, 8);
+ _COPY(_primROut, 8, _rout6, 0, 8);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_2(int (*_pfn)(uint32_t, uint32_t), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint32_t _in0[1];
+ uint32_t _in1[1];
+ uint32_t *_primIn;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 1) <= _praEnd);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 8);
+ _primIn = _pra[0].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 4);
+ _COPY(_in1, 0, _primIn, 4, 4);
+ _TRY(_nErr, _pfn(*_in0, *_in1));
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_3(int (*_pfn)(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t *, uint32_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint32_t _in0[1];
+ uint32_t _in1[1];
+ uint32_t _in2[1];
+ uint32_t _in3[1];
+ uint32_t _in4[1];
+ uint32_t _rout5[1];
+ uint32_t _rout6[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint32_t *_primROut;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 2) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 20);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 8);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 4);
+ _COPY(_in1, 0, _primIn, 4, 4);
+ _COPY(_in2, 0, _primIn, 8, 4);
+ _COPY(_in3, 0, _primIn, 12, 4);
+ _COPY(_in4, 0, _primIn, 16, 4);
+ _TRY(_nErr, _pfn(*_in0, *_in1, *_in2, *_in3, *_in4, _rout5, _rout6));
+ _COPY(_primROut, 0, _rout5, 0, 4);
+ _COPY(_primROut, 4, _rout6, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+__QAIC_SKEL_EXPORT int __QAIC_SKEL(apps_mem_skel_invoke)(uint32_t _sc, remote_arg *_pra) __QAIC_SKEL_ATTRIBUTE
+{
+ switch (REMOTE_SCALARS_METHOD(_sc))
+ {
+ case 0:
+ return _skel_method_3((void *)__QAIC_IMPL(apps_mem_request_map), _sc, _pra);
+ case 1:
+ return _skel_method_2((void *)__QAIC_IMPL(apps_mem_request_unmap), _sc, _pra);
+ case 2:
+ return _skel_method_1((void *)__QAIC_IMPL(apps_mem_request_map64), _sc, _pra);
+ case 3:
+ return _skel_method((void *)__QAIC_IMPL(apps_mem_request_unmap64), _sc, _pra);
+ }
+ return AEE_EUNSUPPORTED;
+}
+#ifdef __cplusplus
+}
+#endif
+#endif //_APPS_MEM_SKEL_H
diff --git a/src/apps_remotectl_skel.c b/src/apps_remotectl_skel.c
new file mode 100644
index 0000000..603a0f1
--- /dev/null
+++ b/src/apps_remotectl_skel.c
@@ -0,0 +1,528 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _APPS_REMOTECTL_SKEL_H
+#define _APPS_REMOTECTL_SKEL_H
+#include "apps_remotectl.h"
+#include "remote.h"
+#include <string.h>
+#ifndef ALLOCATOR_H
+#define ALLOCATOR_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef struct _heap _heap;
+struct _heap
+{
+ _heap *pPrev;
+ const char *loc;
+ uint64_t buf;
+};
+
+typedef struct allocator
+{
+ _heap *pheap;
+ uint8_t *stack;
+ uint8_t *stackEnd;
+ int nSize;
+} allocator;
+
+static __inline int _heap_alloc(_heap **ppa, const char *loc, int size, void **ppbuf)
+{
+ _heap *pn = 0;
+ pn = malloc(size + sizeof(_heap) - sizeof(uint64_t));
+ if (pn != 0)
+ {
+ pn->pPrev = *ppa;
+ pn->loc = loc;
+ *ppa = pn;
+ *ppbuf = (void *) & (pn->buf);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+#define _ALIGN_SIZE(x, y) (((x) + (y-1)) & ~(y-1))
+
+
+static __inline int allocator_alloc(allocator *me,
+ const char *loc,
+ int size,
+ unsigned int al,
+ void **ppbuf)
+{
+ if (size < 0)
+ {
+ return -1;
+ }
+ else if (size == 0)
+ {
+ *ppbuf = 0;
+ return 0;
+ }
+ if ((_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size) < (uintptr_t)me->stack + me->nSize)
+ {
+ *ppbuf = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al);
+ me->stackEnd = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size;
+ return 0;
+ }
+ else
+ {
+ return _heap_alloc(&me->pheap, loc, size, ppbuf);
+ }
+}
+
+
+static __inline void allocator_deinit(allocator *me)
+{
+ _heap *pa = me->pheap;
+ while (pa != 0)
+ {
+ _heap *pn = pa;
+ const char *loc = pn->loc;
+ (void)loc;
+ pa = pn->pPrev;
+ free(pn);
+ }
+}
+
+static __inline void allocator_init(allocator *me, uint8_t *stack, int stackSize)
+{
+ me->stack = stack;
+ me->stackEnd = stack + stackSize;
+ me->nSize = stackSize;
+ me->pheap = 0;
+}
+
+
+#endif // ALLOCATOR_H
+
+#ifndef SLIM_H
+#define SLIM_H
+
+#include <stdint.h>
+
+//a C data structure for the idl types that can be used to implement
+//static and dynamic language bindings fairly efficiently.
+//
+//the goal is to have a minimal ROM and RAM footprint and without
+//doing too many allocations. A good way to package these things seemed
+//like the module boundary, so all the idls within one module can share
+//all the type references.
+
+
+#define PARAMETER_IN 0x0
+#define PARAMETER_OUT 0x1
+#define PARAMETER_INOUT 0x2
+#define PARAMETER_ROUT 0x3
+#define PARAMETER_INROUT 0x4
+
+//the types that we get from idl
+#define TYPE_OBJECT 0x0
+#define TYPE_INTERFACE 0x1
+#define TYPE_PRIMITIVE 0x2
+#define TYPE_ENUM 0x3
+#define TYPE_STRING 0x4
+#define TYPE_WSTRING 0x5
+#define TYPE_STRUCTURE 0x6
+#define TYPE_UNION 0x7
+#define TYPE_ARRAY 0x8
+#define TYPE_SEQUENCE 0x9
+
+//these require the pack/unpack to recurse
+//so it's a hint to those languages that can optimize in cases where
+//recursion isn't necessary.
+#define TYPE_COMPLEX_STRUCTURE (0x10 | TYPE_STRUCTURE)
+#define TYPE_COMPLEX_UNION (0x10 | TYPE_UNION)
+#define TYPE_COMPLEX_ARRAY (0x10 | TYPE_ARRAY)
+#define TYPE_COMPLEX_SEQUENCE (0x10 | TYPE_SEQUENCE)
+
+
+typedef struct Type Type;
+
+#define INHERIT_TYPE\
+ int32_t nativeSize; /*in the simple case its the same as wire size and alignment*/\
+ union {\
+ struct {\
+ const uintptr_t p1;\
+ const uintptr_t p2;\
+ } _cast;\
+ struct {\
+ uint32_t iid;\
+ uint32_t bNotNil;\
+ } object;\
+ struct {\
+ const Type *arrayType;\
+ int32_t nItems;\
+ } array;\
+ struct {\
+ const Type *seqType;\
+ int32_t nMaxLen;\
+ } seqSimple; \
+ struct {\
+ uint32_t bFloating;\
+ uint32_t bSigned;\
+ } prim; \
+ const SequenceType* seqComplex;\
+ const UnionType *unionType;\
+ const StructType *structType;\
+ int32_t stringMaxLen;\
+ uint8_t bInterfaceNotNil;\
+ } param;\
+ uint8_t type;\
+ uint8_t nativeAlignment\
+
+typedef struct UnionType UnionType;
+typedef struct StructType StructType;
+typedef struct SequenceType SequenceType;
+struct Type
+{
+ INHERIT_TYPE;
+};
+
+struct SequenceType
+{
+ const Type *seqType;
+ uint32_t nMaxLen;
+ uint32_t inSize;
+ uint32_t routSizePrimIn;
+ uint32_t routSizePrimROut;
+};
+
+//byte offset from the start of the case values for
+//this unions case value array. it MUST be aligned
+//at the alignment requrements for the descriptor
+//
+//if negative it means that the unions cases are
+//simple enumerators, so the value read from the descriptor
+//can be used directly to find the correct case
+typedef union CaseValuePtr CaseValuePtr;
+union CaseValuePtr
+{
+ const uint8_t *value8s;
+ const uint16_t *value16s;
+ const uint32_t *value32s;
+ const uint64_t *value64s;
+};
+
+//these are only used in complex cases
+//so I pulled them out of the type definition as references to make
+//the type smaller
+struct UnionType
+{
+ const Type *descriptor;
+ uint32_t nCases;
+ const CaseValuePtr caseValues;
+ const Type *const *cases;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+ uint8_t inCaseAlignment;
+ uint8_t routCaseAlignmentPrimIn;
+ uint8_t routCaseAlignmentPrimROut;
+ uint8_t nativeCaseAlignment;
+ uint8_t bDefaultCase;
+};
+
+struct StructType
+{
+ uint32_t nMembers;
+ const Type *const *members;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+};
+
+typedef struct Parameter Parameter;
+struct Parameter
+{
+ INHERIT_TYPE;
+ uint8_t mode;
+ uint8_t bNotNil;
+};
+
+#define SLIM_SCALARS_IS_DYNAMIC(u) (((u) & 0x00ffffff) == 0x00ffffff)
+
+typedef struct Method Method;
+struct Method
+{
+ uint32_t uScalars; //no method index
+ int32_t primInSize;
+ int32_t primROutSize;
+ int maxArgs;
+ int numParams;
+ const Parameter *const *params;
+ uint8_t primInAlignment;
+ uint8_t primROutAlignment;
+};
+
+typedef struct Interface Interface;
+
+struct Interface
+{
+ int nMethods;
+ const Method *const *methodArray;
+ int nIIds;
+ const uint32_t *iids;
+ const uint16_t *methodStringArray;
+ const uint16_t *methodStrings;
+ const char *strings;
+};
+
+
+#endif //SLIM_H
+
+
+#ifndef _APPS_REMOTECTL_SLIM_H
+#define _APPS_REMOTECTL_SLIM_H
+#include "remote.h"
+#include <stdint.h>
+
+#ifndef __QAIC_SLIM
+#define __QAIC_SLIM(ff) ff
+#endif
+#ifndef __QAIC_SLIM_EXPORT
+#define __QAIC_SLIM_EXPORT
+#endif
+
+static const Type types[1];
+static const Type types[1] = {{0x1, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x1}};
+static const Parameter parameters[4] = {{0x8, {{(const uintptr_t)0x0, 0}}, 4, 0x4, 0, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)1}}, 2, 0x4, 3, 0}, {0x8, {{(const uintptr_t) &(types[0]), (const uintptr_t)0x0}}, 9, 0x4, 3, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)1}}, 2, 0x4, 0, 0}};
+static const Parameter *const parameterArrays[7] = {(&(parameters[0])), (&(parameters[1])), (&(parameters[2])), (&(parameters[1])), (&(parameters[3])), (&(parameters[2])), (&(parameters[1]))};
+static const Method methods[2] = {{REMOTE_SCALARS_MAKEX(0, 0, 0x2, 0x2, 0x0, 0x0), 0x8, 0x8, 6, 4, (&(parameterArrays[0])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x2, 0x0, 0x0), 0x8, 0x4, 5, 3, (&(parameterArrays[4])), 0x4, 0x4}};
+static const Method *const methodArrays[2] = {&(methods[0]), &(methods[1])};
+static const char strings[36] = "dlerror\0handle\0close\0nErr\0name\0open\0";
+static const uint16_t methodStrings[9] = {31, 26, 8, 0, 21, 15, 8, 0, 21};
+static const uint16_t methodStringsArrays[2] = {0, 5};
+__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(apps_remotectl_slim) = {2, &(methodArrays[0]), 0, 0, &(methodStringsArrays [0]), methodStrings, strings};
+#endif //_APPS_REMOTECTL_SLIM_H
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wpragmas"
+#pragma GCC diagnostic ignored "-Wuninitialized"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#ifndef __QAIC_REMOTE
+#define __QAIC_REMOTE(ff) ff
+#endif //__QAIC_REMOTE
+
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+
+#ifndef __QAIC_STUB
+#define __QAIC_STUB(ff) ff
+#endif //__QAIC_STUB
+
+#ifndef __QAIC_STUB_EXPORT
+#define __QAIC_STUB_EXPORT
+#endif // __QAIC_STUB_EXPORT
+
+#ifndef __QAIC_STUB_ATTRIBUTE
+#define __QAIC_STUB_ATTRIBUTE
+#endif // __QAIC_STUB_ATTRIBUTE
+
+#ifndef __QAIC_SKEL
+#define __QAIC_SKEL(ff) ff
+#endif //__QAIC_SKEL__
+
+#ifndef __QAIC_SKEL_EXPORT
+#define __QAIC_SKEL_EXPORT
+#endif // __QAIC_SKEL_EXPORT
+
+#ifndef __QAIC_SKEL_ATTRIBUTE
+#define __QAIC_SKEL_ATTRIBUTE
+#endif // __QAIC_SKEL_ATTRIBUTE
+
+#ifdef __QAIC_DEBUG__
+#ifndef __QAIC_DBG_PRINTF__
+#define __QAIC_DBG_PRINTF__( ee ) do { printf ee ; } while(0)
+#endif
+#else
+#define __QAIC_DBG_PRINTF__( ee ) (void)0
+#endif
+
+
+#define _OFFSET(src, sof) ((void*)(((char*)(src)) + (sof)))
+
+#define _COPY(dst, dof, src, sof, sz) \
+ do {\
+ struct __copy { \
+ char ar[sz]; \
+ };\
+ *(struct __copy*)_OFFSET(dst, dof) = *(struct __copy*)_OFFSET(src, sof);\
+ } while (0)
+
+#define _ASSIGN(dst, src, sof) \
+ do {\
+ dst = OFFSET(src, sof); \
+ } while (0)
+
+#define _STD_STRLEN_IF(str) (str == 0 ? 0 : strlen(str))
+
+#include "AEEStdErr.h"
+
+#define _TRY(ee, func) \
+ do { \
+ if (AEE_SUCCESS != ((ee) = func)) {\
+ __QAIC_DBG_PRINTF__((__FILE_LINE__ ": error: %d\n", (int)(ee)));\
+ goto ee##bail;\
+ } \
+ } while (0)
+
+#define _CATCH(exception) exception##bail: if (exception != AEE_SUCCESS)
+
+#define _ASSERT(nErr, ff) _TRY(nErr, 0 == (ff) ? AEE_EBADPARM : AEE_SUCCESS)
+
+#ifdef __QAIC_DEBUG__
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, allocator_alloc(pal, __FILE_LINE__, size, alignment, (void**)&pv))
+#else
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, allocator_alloc(pal, 0, size, alignment, (void**)&pv))
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+static __inline int _skel_method(int (*_pfn)(uint32_t, char *, uint32_t, uint32_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint32_t _in0[1];
+ char *_rout1[1];
+ uint32_t _rout1Len[1];
+ uint32_t _rout2[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint32_t *_primROut;
+ remote_arg *_praIn;
+ remote_arg *_praROut;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 3) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 8);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 4);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 4);
+ _COPY(_rout1Len, 0, _primIn, 4, 4);
+ _praIn = (_pra + 1);
+ _praROut = (_praIn + _numIn[0] + 1);
+ _ASSERT(_nErr, (int)((_praROut[0].buf.nLen / 1)) >= (int)(_rout1Len[0]));
+ _rout1[0] = _praROut[0].buf.pv;
+ _TRY(_nErr, _pfn(*_in0, *_rout1, *_rout1Len, _rout2));
+ _COPY(_primROut, 0, _rout2, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_1(int (*_pfn)(char *, uint32_t *, char *, uint32_t, uint32_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ char *_in0[1];
+ uint32_t _in0Len[1];
+ uint32_t _rout1[1];
+ char *_rout2[1];
+ uint32_t _rout2Len[1];
+ uint32_t _rout3[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint32_t *_primROut;
+ remote_arg *_praIn;
+ remote_arg *_praROut;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 4) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 8);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 8);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0Len, 0, _primIn, 0, 4);
+ _praIn = (_pra + 1);
+ _ASSERT(_nErr, (int)((_praIn[0].buf.nLen / 1)) >= (int)(_in0Len[0]));
+ _in0[0] = _praIn[0].buf.pv;
+ if (_in0Len[0] > 0)
+ {
+ _in0[0][(_in0Len[0] - 1)] = 0;
+ }
+ _COPY(_rout2Len, 0, _primIn, 4, 4);
+ _praROut = (_praIn + _numIn[0] + 1);
+ _ASSERT(_nErr, (int)((_praROut[0].buf.nLen / 1)) >= (int)(_rout2Len[0]));
+ _rout2[0] = _praROut[0].buf.pv;
+ _TRY(_nErr, _pfn(*_in0, _rout1, *_rout2, *_rout2Len, _rout3));
+ _COPY(_primROut, 0, _rout1, 0, 4);
+ _COPY(_primROut, 4, _rout3, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+__QAIC_SKEL_EXPORT int __QAIC_SKEL(apps_remotectl_skel_invoke)(uint32_t _sc, remote_arg *_pra) __QAIC_SKEL_ATTRIBUTE
+{
+ switch (REMOTE_SCALARS_METHOD(_sc))
+ {
+ case 0:
+ return _skel_method_1((void *)__QAIC_IMPL(apps_remotectl_open), _sc, _pra);
+ case 1:
+ return _skel_method((void *)__QAIC_IMPL(apps_remotectl_close), _sc, _pra);
+ }
+ return AEE_EUNSUPPORTED;
+}
+#ifdef __cplusplus
+}
+#endif
+#endif //_APPS_REMOTECTL_SKEL_H
diff --git a/src/apps_std_imp.c b/src/apps_std_imp.c
new file mode 100644
index 0000000..2c84c8c
--- /dev/null
+++ b/src/apps_std_imp.c
@@ -0,0 +1,583 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifdef _WIN32
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#pragma warning( disable : 4996 )
+#endif
+
+#include "verify.h"
+#include "qtest_stdlib.h"
+#include "AEEstd.h"
+#include "AEEatomic.h"
+#include "AEEQList.h"
+#include "apps_std.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
+#ifndef C_ASSERT
+#define C_ASSERT(test) \
+ switch(0) {\
+ case 0:\
+ case test:;\
+ }
+#endif
+
+#define APPS_FD_BASE 100
+#define ERRNO (errno == 0 ? -1 : errno)
+
+struct apps_std_info
+{
+ QNode qn;
+ FILE *stream;
+ apps_std_FILE fd;
+};
+
+static QList apps_std_qlst;
+static pthread_mutex_t apps_std_mt;
+
+int setenv(const char *name, const char *value, int overwrite);
+int unsetenv(const char *name);
+
+void apps_std_init(void)
+{
+ QList_Ctor(&apps_std_qlst);
+ pthread_mutex_init(&apps_std_mt, 0);
+}
+
+void apps_std_deinit(void)
+{
+ pthread_mutex_destroy(&apps_std_mt);
+}
+
+static int apps_std_FILE_free(apps_std_FILE fd)
+{
+ struct apps_std_info *sinfo, *sfree = 0;
+ QNode *pn, *pnn;
+ int nErr = 0;
+
+ pthread_mutex_lock(&apps_std_mt);
+ QLIST_NEXTSAFE_FOR_ALL(&apps_std_qlst, pn, pnn)
+ {
+ sinfo = STD_RECOVER_REC(struct apps_std_info, qn, pn);
+ if (sinfo->fd == fd)
+ {
+ sfree = sinfo;
+ QNode_Dequeue(&sinfo->qn);
+ break;
+ }
+ }
+ pthread_mutex_unlock(&apps_std_mt);
+ VERIFY(sfree);
+ FREE(sfree);
+
+bail:
+ return nErr;
+}
+
+static int apps_std_FILE_alloc(FILE *stream, apps_std_FILE *fd)
+{
+ struct apps_std_info *sinfo = 0, *info;
+ QNode *pn = 0;
+ apps_std_FILE prevfd = APPS_FD_BASE - 1;
+ int nErr = 0;
+
+ VERIFY(0 != (sinfo = MALLOC(sizeof(*sinfo))));
+ QNode_CtorZ(&sinfo->qn);
+ pthread_mutex_lock(&apps_std_mt);
+ pn = QList_GetFirst(&apps_std_qlst);
+ if (pn)
+ {
+ info = STD_RECOVER_REC(struct apps_std_info, qn, pn);
+ prevfd = info->fd;
+ QLIST_FOR_REST(&apps_std_qlst, pn)
+ {
+ info = STD_RECOVER_REC(struct apps_std_info, qn, pn);
+ if (info->fd != prevfd + 1)
+ {
+ sinfo->fd = prevfd + 1;
+ QNode_InsPrev(pn, &sinfo->qn);
+ break;
+ }
+ prevfd = info->fd;
+ }
+ }
+ if (!QNode_IsQueuedZ(&sinfo->qn))
+ {
+ sinfo->fd = prevfd + 1;
+ QList_AppendNode(&apps_std_qlst, &sinfo->qn);
+ }
+ pthread_mutex_unlock(&apps_std_mt);
+
+ sinfo->stream = stream;
+ *fd = sinfo->fd;
+
+bail:
+ if (nErr)
+ {
+ FREEIF(sinfo);
+ }
+ return nErr;
+}
+
+static FILE *apps_std_FILE_get(apps_std_FILE fd)
+{
+ struct apps_std_info *sinfo = 0;
+ QNode *pn, *pnn;
+ FILE *stream = 0;
+
+ pthread_mutex_lock(&apps_std_mt);
+ QLIST_NEXTSAFE_FOR_ALL(&apps_std_qlst, pn, pnn)
+ {
+ sinfo = STD_RECOVER_REC(struct apps_std_info, qn, pn);
+ if (sinfo->fd == fd)
+ {
+ stream = sinfo->stream;
+ break;
+ }
+ }
+ pthread_mutex_unlock(&apps_std_mt);
+
+ return stream;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fopen)(const char *name, const char *mode, apps_std_FILE *psout) __QAIC_IMPL_ATTRIBUTE
+{
+ FILE *stream = fopen(name, mode);
+ if (stream)
+ {
+ return apps_std_FILE_alloc(stream, psout);
+ }
+ VERIFY_IPRINTF("fopen did not find: %s %s\n", name, strerror(ERRNO));
+ return ERRNO;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_freopen)(apps_std_FILE sin, const char *name, const char *mode, apps_std_FILE *psout) __QAIC_IMPL_ATTRIBUTE
+{
+ FILE *stream = freopen(name, mode, apps_std_FILE_get(sin));
+ if (stream)
+ {
+ return apps_std_FILE_alloc(stream, psout);
+ }
+ return ERRNO;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fflush)(apps_std_FILE sin) __QAIC_IMPL_ATTRIBUTE
+{
+ if (0 == fflush(apps_std_FILE_get(sin)))
+ {
+ return 0;
+ }
+ return ERRNO;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fclose)(apps_std_FILE sin) __QAIC_IMPL_ATTRIBUTE
+{
+ if (0 == fclose(apps_std_FILE_get(sin)))
+ {
+ apps_std_FILE_free(sin);
+ return 0;
+ }
+ return ERRNO;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fread)(apps_std_FILE sin, byte *buf, int bufLen, int *bytesRead, int *bEOF) __QAIC_IMPL_ATTRIBUTE
+{
+ int out = fread(buf, 1, bufLen, apps_std_FILE_get(sin));
+ *bEOF = FALSE;
+ if (out <= bufLen)
+ {
+ int err;
+ if (0 == out && (0 != (err = ferror(apps_std_FILE_get(sin)))))
+ {
+ return err;
+ }
+ *bEOF = feof(apps_std_FILE_get(sin));
+ }
+ *bytesRead = out;
+ return 0;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fwrite)(apps_std_FILE sin, const byte *buf, int bufLen, int *bytesRead, int *bEOF) __QAIC_IMPL_ATTRIBUTE
+{
+ int out = fwrite(buf, 1, bufLen, apps_std_FILE_get(sin));
+ *bEOF = FALSE;
+ if (out <= bufLen)
+ {
+ int err;
+ if (0 == out && (0 != (err = ferror(apps_std_FILE_get(sin)))))
+ {
+ return err;
+ }
+ *bEOF = feof(apps_std_FILE_get(sin));
+ }
+ *bytesRead = out;
+ return 0;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fgetpos)(apps_std_FILE sin, byte *pos, int posLen, int *posLenReq) __QAIC_IMPL_ATTRIBUTE
+{
+ fpos_t fpos;
+ if (0 == fgetpos(apps_std_FILE_get(sin), &fpos))
+ {
+ std_memmove(pos, &fpos, STD_MIN((int)sizeof(fpos), posLen));
+ *posLenReq = sizeof(fpos);
+ return 0;
+ }
+ return ERRNO;
+}
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fsetpos)(apps_std_FILE sin, const byte *pos, int posLen) __QAIC_IMPL_ATTRIBUTE
+{
+ fpos_t fpos;
+ if (sizeof(fpos) != posLen)
+ {
+ return -1;
+ }
+ std_memmove(&fpos, pos, sizeof(fpos));
+ if (0 == fsetpos(apps_std_FILE_get(sin), &fpos))
+ {
+ return 0;
+ }
+ return ERRNO;
+}
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_ftell)(apps_std_FILE sin, int *pos) __QAIC_IMPL_ATTRIBUTE
+{
+ if ((*pos = ftell(apps_std_FILE_get(sin))) >= 0)
+ {
+ return 0;
+ }
+ return ERRNO;
+}
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fseek)(apps_std_FILE sin, int offset, apps_std_SEEK whence) __QAIC_IMPL_ATTRIBUTE
+{
+ C_ASSERT(APPS_STD_SEEK_SET == SEEK_SET);
+ C_ASSERT(APPS_STD_SEEK_CUR == SEEK_CUR);
+ C_ASSERT(APPS_STD_SEEK_END == SEEK_END);
+ if (0 == fseek(apps_std_FILE_get(sin), offset, whence))
+ {
+ return 0;
+ }
+ return ERRNO;
+}
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_rewind)(apps_std_FILE sin) __QAIC_IMPL_ATTRIBUTE
+{
+ rewind(apps_std_FILE_get(sin));
+ return 0;
+}
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_feof)(apps_std_FILE sin, int *bEOF) __QAIC_IMPL_ATTRIBUTE
+{
+ *bEOF = feof(apps_std_FILE_get(sin));
+ return 0;
+}
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_ferror)(apps_std_FILE sin, int *err) __QAIC_IMPL_ATTRIBUTE
+{
+ *err = ferror(apps_std_FILE_get(sin));
+ return 0;
+}
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_clearerr)(apps_std_FILE sin) __QAIC_IMPL_ATTRIBUTE
+{
+ clearerr(apps_std_FILE_get(sin));
+ return 0;
+}
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_flen)(apps_std_FILE sin, uint64 *len) __QAIC_IMPL_ATTRIBUTE
+{
+ struct stat st_buf;
+ int fd = fileno(apps_std_FILE_get(sin));
+ C_ASSERT(sizeof(st_buf.st_size) <= sizeof(*len));
+ if (fd == -1)
+ {
+ return ERRNO;
+ }
+ if (0 != fstat(fd, &st_buf))
+ {
+ return ERRNO;
+ }
+ *len = st_buf.st_size;
+ return 0;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_print_string)(const char *str) __QAIC_IMPL_ATTRIBUTE
+{
+ printf("%s", str);
+ return 0;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_getenv)(const char *name, char *val, int valLen, int *valLenReq) __QAIC_IMPL_ATTRIBUTE
+{
+ char *vv = getenv(name);
+ if (vv)
+ {
+ *valLenReq = std_strlen(vv) + 1;
+ std_strlcpy(val, vv, valLen);
+ return 0;
+ }
+ VERIFY_IPRINTF("apps_std getenv failed: %s %s\n", name, strerror(ERRNO));
+ return ERRNO;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_setenv)(const char *name, const char *val, int override) __QAIC_IMPL_ATTRIBUTE
+{
+#ifdef _WIN32
+ return -1;
+#else
+ if (0 != setenv(name, val, override))
+ {
+ return ERRNO;
+ }
+ return 0;
+#endif
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_unsetenv)(const char *name) __QAIC_IMPL_ATTRIBUTE
+{
+#ifdef _WIN32
+ return -1;
+#else
+ if (0 != unsetenv(name))
+ {
+ return ERRNO;
+ }
+ return 0;
+#endif
+}
+
+#if (defined _WIN32)
+static char *ADSP_LIBRARY_PATH = ";c:\\Program Files\\Qualcomm\\RFSA\\aDSP";
+#elif (defined __QNX__)
+static char *ADSP_LIBRARY_PATH = "/radio/lib/firmware";
+#else
+static char *ADSP_LIBRARY_PATH = ";/usr/local/lib";
+#endif
+
+#define EMTPY_STR ""
+#define ENV_LEN_GUESS 256
+
+static int get_dirlist_from_env(const char *envvarname, char **ppDirList)
+{
+ char *envList = NULL;
+ char *envListBuf = NULL;
+ char *dirList = NULL;
+ char *dirListBuf = NULL;
+ char *srcStr = NULL;
+ int nErr = 0;
+ int envListLen = 0;
+ int listLen = 0;
+ int envLenGuess = STD_MAX(ENV_LEN_GUESS, 1 + std_strlen(ADSP_LIBRARY_PATH));
+
+ VERIFY(NULL != ppDirList);
+
+ VERIFY(envListBuf = (char *)MALLOC(sizeof(char) * envLenGuess));
+ envList = envListBuf;
+ *envList = '\0';
+ if (0 == apps_std_getenv(envvarname, envList, envLenGuess, &envListLen))
+ {
+ if (envLenGuess < envListLen)
+ {
+ FREEIF(envListBuf);
+ VERIFY(envListBuf = REALLOC(envListBuf, sizeof(char) * envListLen));
+ envList = envListBuf;
+ VERIFY(0 == apps_std_getenv(envvarname, envList, envListLen, &listLen));
+ }
+ }
+ else if (std_strcmp(envvarname, "ADSP_LIBRARY_PATH") == 0)
+ {
+ envListLen = listLen = 1 + std_strlcpy(envListBuf, ADSP_LIBRARY_PATH, envLenGuess);
+ }
+
+ /* Allocate mem. to copy envvarname.
+ If envvarname not set, allocate mem to create an empty string.*/
+ if ('\0' != *envList)
+ {
+ srcStr = envList;
+ }
+ else
+ {
+ srcStr = EMTPY_STR;
+ envListLen = std_strlen(EMTPY_STR) + 1;
+ }
+ VERIFY(dirListBuf = (char *)MALLOC(sizeof(char) * envListLen));
+ dirList = dirListBuf;
+ std_strlcpy(dirList, srcStr, envListLen);
+ *ppDirList = dirListBuf;
+
+bail:
+ FREEIF(envListBuf);
+ return nErr;
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fopen_with_env)(const char *envvarname,
+ const char *delim, const char *name, const char *mode,
+ apps_std_FILE *psout) __QAIC_IMPL_ATTRIBUTE
+{
+
+ int nErr = 0;
+ char *dirName = NULL;
+ char *pos = NULL;
+ char *dirListBuf = NULL;
+ char *dirList = NULL;
+ char *absName = NULL;
+ uint16 absNameLen = 0;
+
+ VERIFY(NULL != mode);
+ VERIFY(NULL != delim);
+ VERIFY(NULL != name);
+
+ VERIFY(0 == get_dirlist_from_env(envvarname, &dirListBuf));
+ VERIFY(NULL != (dirList = dirListBuf));
+
+ while (dirList)
+ {
+ pos = strstr(dirList, delim);
+ dirName = dirList;
+ if (pos)
+ {
+ *pos = '\0';
+ dirList = pos + std_strlen(delim);
+ }
+ else
+ {
+ dirList = 0;
+ }
+
+ absNameLen = std_strlen(dirName) + std_strlen(name) + 2;
+ VERIFY(absName = (char *)MALLOC(sizeof(char) * absNameLen));
+ if ('\0' != *dirName)
+ {
+ std_strlcpy(absName, dirName, absNameLen);
+ std_strlcat(absName, "/", absNameLen);
+ std_strlcat(absName, name, absNameLen);
+ }
+ else
+ {
+ std_strlcpy(absName, name, absNameLen);
+ }
+
+ nErr = apps_std_fopen(absName, mode, psout);
+ FREEIF(absName);
+ if (0 == nErr)
+ {
+ goto bail;
+ }
+ }
+
+bail:
+ FREEIF(absName);
+ FREEIF(dirListBuf);
+
+ return nErr;
+}
+
+__QAIC_HEADER_EXPORT int __QAIC_IMPL(apps_std_get_search_paths_with_env)(
+ const char *envvarname, const char *delim, _cstring1_t *paths,
+ int pathsLen, uint32 *numPaths, uint16 *maxPathLen) __QAIC_IMPL_ATTRIBUTE
+{
+
+ char *path = NULL;
+ int nErr = 0;
+ char *dirListBuf = NULL;
+ int i = 0;
+ char *saveptr = NULL;
+ struct stat st;
+
+ VERIFY(NULL != numPaths);
+ VERIFY(NULL != delim);
+ VERIFY(NULL != maxPathLen);
+
+ VERIFY(0 == get_dirlist_from_env(envvarname, &dirListBuf));
+
+ *numPaths = 0;
+ *maxPathLen = 0;
+
+ /* Get the number of folders */
+ path = strtok_r(dirListBuf, delim, &saveptr);
+ while (path != NULL)
+ {
+ /* If the path exists, add it to the return */
+ if ((stat(path, &st) == 0) && (S_ISDIR(st.st_mode)))
+ {
+ *maxPathLen = STD_MAX(*maxPathLen, std_strlen(path) + 1);
+ if (paths && paths[i].data && paths[i].dataLen >= std_strlen(path))
+ {
+ std_strlcpy(paths[i].data, path, paths[i].dataLen);
+ }
+ i++;
+ }
+ path = strtok_r(NULL, delim, &saveptr);
+ }
+ *numPaths = i;
+
+bail:
+ FREEIF(dirListBuf);
+ return nErr;
+}
+
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_std_fgets)(apps_std_FILE sin, byte *buf, int bufLen, int *bEOF) __QAIC_IMPL_ATTRIBUTE
+{
+ char *out = fgets((char *)buf, bufLen, apps_std_FILE_get(sin));
+ *bEOF = FALSE;
+ if (!out)
+ {
+ int err;
+ if (0 != (err = ferror(apps_std_FILE_get(sin))))
+ {
+ return err;
+ }
+ *bEOF = feof(apps_std_FILE_get(sin));
+ }
+ return 0;
+}
+
+__QAIC_HEADER_EXPORT int __QAIC_HEADER(apps_std_fileExists)(const char *path, boolean *exists) __QAIC_HEADER_ATTRIBUTE
+{
+ int nErr = 0;
+ struct stat buffer;
+
+ VERIFY(path != NULL);
+ VERIFY(exists != NULL);
+
+ *exists = (stat(path, &buffer) == 0);
+
+bail:
+ return nErr;
+}
+
diff --git a/src/apps_std_skel.c b/src/apps_std_skel.c
new file mode 100644
index 0000000..bd5873b
--- /dev/null
+++ b/src/apps_std_skel.c
@@ -0,0 +1,1093 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _APPS_STD_SKEL_H
+#define _APPS_STD_SKEL_H
+
+#include "apps_std.h"
+#ifndef _QAIC_ENV_H
+#define _QAIC_ENV_H
+
+#ifdef __GNUC__
+#ifdef __clang__
+#pragma GCC diagnostic ignored "-Wunknown-pragmas"
+#else
+#pragma GCC diagnostic ignored "-Wpragmas"
+#endif
+#pragma GCC diagnostic ignored "-Wuninitialized"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+#ifndef _ATTRIBUTE_UNUSED
+
+#ifdef _WIN32
+#define _ATTRIBUTE_UNUSED
+#else
+#define _ATTRIBUTE_UNUSED __attribute__ ((unused))
+#endif
+
+#endif // _ATTRIBUTE_UNUSED
+
+#ifndef __QAIC_REMOTE
+#define __QAIC_REMOTE(ff) ff
+#endif //__QAIC_REMOTE
+
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+
+#ifndef __QAIC_STUB
+#define __QAIC_STUB(ff) ff
+#endif //__QAIC_STUB
+
+#ifndef __QAIC_STUB_EXPORT
+#define __QAIC_STUB_EXPORT
+#endif // __QAIC_STUB_EXPORT
+
+#ifndef __QAIC_STUB_ATTRIBUTE
+#define __QAIC_STUB_ATTRIBUTE
+#endif // __QAIC_STUB_ATTRIBUTE
+
+#ifndef __QAIC_SKEL
+#define __QAIC_SKEL(ff) ff
+#endif //__QAIC_SKEL__
+
+#ifndef __QAIC_SKEL_EXPORT
+#define __QAIC_SKEL_EXPORT
+#endif // __QAIC_SKEL_EXPORT
+
+#ifndef __QAIC_SKEL_ATTRIBUTE
+#define __QAIC_SKEL_ATTRIBUTE
+#endif // __QAIC_SKEL_ATTRIBUTE
+
+#ifdef __QAIC_DEBUG__
+#ifndef __QAIC_DBG_PRINTF__
+#include <stdio.h>
+#define __QAIC_DBG_PRINTF__( ee ) do { printf ee ; } while(0)
+#endif
+#else
+#define __QAIC_DBG_PRINTF__( ee ) (void)0
+#endif
+
+
+#define _OFFSET(src, sof) ((void*)(((char*)(src)) + (sof)))
+
+#define _COPY(dst, dof, src, sof, sz) \
+ do {\
+ struct __copy { \
+ char ar[sz]; \
+ };\
+ *(struct __copy*)_OFFSET(dst, dof) = *(struct __copy*)_OFFSET(src, sof);\
+ } while (0)
+
+#define _COPYIF(dst, dof, src, sof, sz) \
+ do {\
+ if(_OFFSET(dst, dof) != _OFFSET(src, sof)) {\
+ _COPY(dst, dof, src, sof, sz); \
+ } \
+ } while (0)
+
+_ATTRIBUTE_UNUSED
+static __inline void _qaic_memmove(void *dst, void *src, int size)
+{
+ int i;
+ for (i = 0; i < size; ++i)
+ {
+ ((char *)dst)[i] = ((char *)src)[i];
+ }
+}
+
+#define _MEMMOVEIF(dst, src, sz) \
+ do {\
+ if(dst != src) {\
+ _qaic_memmove(dst, src, sz);\
+ } \
+ } while (0)
+
+
+#define _ASSIGN(dst, src, sof) \
+ do {\
+ dst = OFFSET(src, sof); \
+ } while (0)
+
+#define _STD_STRLEN_IF(str) (str == 0 ? 0 : strlen(str))
+
+#include "AEEStdErr.h"
+
+#define _TRY(ee, func) \
+ do { \
+ if (AEE_SUCCESS != ((ee) = func)) {\
+ __QAIC_DBG_PRINTF__((__FILE__ ":%d:error:%d:%s\n", __LINE__, (int)(ee),#func));\
+ goto ee##bail;\
+ } \
+ } while (0)
+
+#define _CATCH(exception) exception##bail: if (exception != AEE_SUCCESS)
+
+#define _ASSERT(nErr, ff) _TRY(nErr, 0 == (ff) ? AEE_EBADPARM : AEE_SUCCESS)
+
+#ifdef __QAIC_DEBUG__
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, _allocator_alloc(pal, __FILE_LINE__, size, alignment, (void**)&pv))
+#else
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, _allocator_alloc(pal, 0, size, alignment, (void**)&pv))
+#endif
+
+
+#endif // _QAIC_ENV_H
+
+#include "remote.h"
+#include <string.h>
+#ifndef _ALLOCATOR_H
+#define _ALLOCATOR_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef struct _heap _heap;
+struct _heap
+{
+ _heap *pPrev;
+ const char *loc;
+ uint64_t buf;
+};
+
+typedef struct _allocator
+{
+ _heap *pheap;
+ uint8_t *stack;
+ uint8_t *stackEnd;
+ int nSize;
+} _allocator;
+
+_ATTRIBUTE_UNUSED
+static __inline int _heap_alloc(_heap **ppa, const char *loc, int size, void **ppbuf)
+{
+ _heap *pn = 0;
+ pn = malloc(size + sizeof(_heap) - sizeof(uint64_t));
+ if (pn != 0)
+ {
+ pn->pPrev = *ppa;
+ pn->loc = loc;
+ *ppa = pn;
+ *ppbuf = (void *) & (pn->buf);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+#define _ALIGN_SIZE(x, y) (((x) + (y-1)) & ~(y-1))
+
+_ATTRIBUTE_UNUSED
+static __inline int _allocator_alloc(_allocator *me,
+ const char *loc,
+ int size,
+ unsigned int al,
+ void **ppbuf)
+{
+ if (size < 0)
+ {
+ return -1;
+ }
+ else if (size == 0)
+ {
+ *ppbuf = 0;
+ return 0;
+ }
+ if ((_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size) < (uintptr_t)me->stack + me->nSize)
+ {
+ *ppbuf = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al);
+ me->stackEnd = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size;
+ return 0;
+ }
+ else
+ {
+ return _heap_alloc(&me->pheap, loc, size, ppbuf);
+ }
+}
+
+_ATTRIBUTE_UNUSED
+static __inline void _allocator_deinit(_allocator *me)
+{
+ _heap *pa = me->pheap;
+ while (pa != 0)
+ {
+ _heap *pn = pa;
+ const char *loc = pn->loc;
+ (void)loc;
+ pa = pn->pPrev;
+ free(pn);
+ }
+}
+
+_ATTRIBUTE_UNUSED
+static __inline void _allocator_init(_allocator *me, uint8_t *stack, int stackSize)
+{
+ me->stack = stack;
+ me->stackEnd = stack + stackSize;
+ me->nSize = stackSize;
+ me->pheap = 0;
+}
+
+
+#endif // _ALLOCATOR_H
+
+#ifndef SLIM_H
+#define SLIM_H
+
+#include <stdint.h>
+
+//a C data structure for the idl types that can be used to implement
+//static and dynamic language bindings fairly efficiently.
+//
+//the goal is to have a minimal ROM and RAM footprint and without
+//doing too many allocations. A good way to package these things seemed
+//like the module boundary, so all the idls within one module can share
+//all the type references.
+
+
+#define PARAMETER_IN 0x0
+#define PARAMETER_OUT 0x1
+#define PARAMETER_INOUT 0x2
+#define PARAMETER_ROUT 0x3
+#define PARAMETER_INROUT 0x4
+
+//the types that we get from idl
+#define TYPE_OBJECT 0x0
+#define TYPE_INTERFACE 0x1
+#define TYPE_PRIMITIVE 0x2
+#define TYPE_ENUM 0x3
+#define TYPE_STRING 0x4
+#define TYPE_WSTRING 0x5
+#define TYPE_STRUCTURE 0x6
+#define TYPE_UNION 0x7
+#define TYPE_ARRAY 0x8
+#define TYPE_SEQUENCE 0x9
+
+//these require the pack/unpack to recurse
+//so it's a hint to those languages that can optimize in cases where
+//recursion isn't necessary.
+#define TYPE_COMPLEX_STRUCTURE (0x10 | TYPE_STRUCTURE)
+#define TYPE_COMPLEX_UNION (0x10 | TYPE_UNION)
+#define TYPE_COMPLEX_ARRAY (0x10 | TYPE_ARRAY)
+#define TYPE_COMPLEX_SEQUENCE (0x10 | TYPE_SEQUENCE)
+
+
+typedef struct Type Type;
+
+#define INHERIT_TYPE\
+ int32_t nativeSize; /*in the simple case its the same as wire size and alignment*/\
+ union {\
+ struct {\
+ const uintptr_t p1;\
+ const uintptr_t p2;\
+ } _cast;\
+ struct {\
+ uint32_t iid;\
+ uint32_t bNotNil;\
+ } object;\
+ struct {\
+ const Type *arrayType;\
+ int32_t nItems;\
+ } array;\
+ struct {\
+ const Type *seqType;\
+ int32_t nMaxLen;\
+ } seqSimple; \
+ struct {\
+ uint32_t bFloating;\
+ uint32_t bSigned;\
+ } prim; \
+ const SequenceType* seqComplex;\
+ const UnionType *unionType;\
+ const StructType *structType;\
+ int32_t stringMaxLen;\
+ uint8_t bInterfaceNotNil;\
+ } param;\
+ uint8_t type;\
+ uint8_t nativeAlignment\
+
+typedef struct UnionType UnionType;
+typedef struct StructType StructType;
+typedef struct SequenceType SequenceType;
+struct Type
+{
+ INHERIT_TYPE;
+};
+
+struct SequenceType
+{
+ const Type *seqType;
+ uint32_t nMaxLen;
+ uint32_t inSize;
+ uint32_t routSizePrimIn;
+ uint32_t routSizePrimROut;
+};
+
+//byte offset from the start of the case values for
+//this unions case value array. it MUST be aligned
+//at the alignment requrements for the descriptor
+//
+//if negative it means that the unions cases are
+//simple enumerators, so the value read from the descriptor
+//can be used directly to find the correct case
+typedef union CaseValuePtr CaseValuePtr;
+union CaseValuePtr
+{
+ const uint8_t *value8s;
+ const uint16_t *value16s;
+ const uint32_t *value32s;
+ const uint64_t *value64s;
+};
+
+//these are only used in complex cases
+//so I pulled them out of the type definition as references to make
+//the type smaller
+struct UnionType
+{
+ const Type *descriptor;
+ uint32_t nCases;
+ const CaseValuePtr caseValues;
+ const Type *const *cases;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+ uint8_t inCaseAlignment;
+ uint8_t routCaseAlignmentPrimIn;
+ uint8_t routCaseAlignmentPrimROut;
+ uint8_t nativeCaseAlignment;
+ uint8_t bDefaultCase;
+};
+
+struct StructType
+{
+ uint32_t nMembers;
+ const Type *const *members;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+};
+
+typedef struct Parameter Parameter;
+struct Parameter
+{
+ INHERIT_TYPE;
+ uint8_t mode;
+ uint8_t bNotNil;
+};
+
+#define SLIM_IFPTR32(is32,is64) (sizeof(uintptr_t) == 4 ? (is32) : (is64))
+#define SLIM_SCALARS_IS_DYNAMIC(u) (((u) & 0x00ffffff) == 0x00ffffff)
+
+typedef struct Method Method;
+struct Method
+{
+ uint32_t uScalars; //no method index
+ int32_t primInSize;
+ int32_t primROutSize;
+ int maxArgs;
+ int numParams;
+ const Parameter *const *params;
+ uint8_t primInAlignment;
+ uint8_t primROutAlignment;
+};
+
+typedef struct Interface Interface;
+
+struct Interface
+{
+ int nMethods;
+ const Method *const *methodArray;
+ int nIIds;
+ const uint32_t *iids;
+ const uint16_t *methodStringArray;
+ const uint16_t *methodStrings;
+ const char *strings;
+};
+
+
+#endif //SLIM_H
+
+
+#ifndef _APPS_STD_SLIM_H
+#define _APPS_STD_SLIM_H
+#include "remote.h"
+#include <stdint.h>
+
+#ifndef __QAIC_SLIM
+#define __QAIC_SLIM(ff) ff
+#endif
+#ifndef __QAIC_SLIM_EXPORT
+#define __QAIC_SLIM_EXPORT
+#endif
+
+static const Type types[2];
+static const SequenceType sequenceTypes[1] = {{&(types[1]), 0x0, 0x4, 0x4, 0x0}};
+static const Type types[2] = {{0x1, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x1}, {SLIM_IFPTR32(0x8, 0x10), {{(const uintptr_t)0x0, 0}}, 4, SLIM_IFPTR32(0x4, 0x8)}};
+static const Parameter parameters[12] = {{SLIM_IFPTR32(0x8, 0x10), {{(const uintptr_t)0x0, 0}}, 4, SLIM_IFPTR32(0x4, 0x8), 0, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)1}}, 2, 0x4, 3, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)1}}, 2, 0x4, 0, 0}, {SLIM_IFPTR32(0x8, 0x10), {{(const uintptr_t) &(types[0]), (const uintptr_t)0x0}}, 9, SLIM_IFPTR32(0x4, 0x8), 3, 0}, {SLIM_IFPTR32(0x8, 0x10), {{(const uintptr_t) &(types[0]), (const uintptr_t)0x0}}, 9, SLIM_IFPTR32(0x4, 0x8), 0, 0}, {0x4, {{0, 0}}, 3, 0x4, 0, 0}, {0x8, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x8, 3, 0}, {SLIM_IFPTR32(0x8, 0x10), {{(const uintptr_t)0x0, 0}}, 4, SLIM_IFPTR32(0x4, 0x8), 3, 0}, {SLIM_IFPTR32(0x8, 0x10), {{(const uintptr_t) &(sequenceTypes[0]), 0}}, 25, SLIM_IFPTR32(0x4, 0x8), 3, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x4, 3, 0}, {0x2, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x2, 3, 0}, {0x1, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x1, 3, 0}};
+static const Parameter *const parameterArrays[37] = {(&(parameters[0])), (&(parameters[0])), (&(parameters[8])), (&(parameters[9])), (&(parameters[10])), (&(parameters[0])), (&(parameters[0])), (&(parameters[0])), (&(parameters[0])), (&(parameters[1])), (&(parameters[2])), (&(parameters[4])), (&(parameters[1])), (&(parameters[1])), (&(parameters[2])), (&(parameters[3])), (&(parameters[1])), (&(parameters[1])), (&(parameters[2])), (&(parameters[0])), (&(parameters[0])), (&(parameters[1])), (&(parameters[0])), (&(parameters[0])), (&(parameters[2])), (&(parameters[0])), (&(parameters[7])), (&(parameters[1])), (&(parameters[2])), (&(parameters[2])), (&(parameters[5])), (&(parameters[0])), (&(parameters[11])), (&(parameters[2])), (&(parameters[6])), (&(parameters[2])), (&(parameters[1]))};
+static const Method methods[16] = {{REMOTE_SCALARS_MAKEX(0, 0, 0x3, 0x1, 0x0, 0x0), 0x8, 0x4, 3, 3, (&(parameterArrays[7])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 0x3, 0x1, 0x0, 0x0), 0xc, 0x4, 4, 4, (&(parameterArrays[18])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x0, 0x0, 0x0), 0x4, 0x0, 1, 1, (&(parameterArrays[10])), 0x4, 0x0}, {REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x2, 0x0, 0x0), 0x8, 0x8, 6, 4, (&(parameterArrays[14])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 0x2, 0x1, 0x0, 0x0), 0x8, 0x8, 5, 4, (&(parameterArrays[10])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x2, 0x0, 0x0), 0x8, 0x4, 5, 3, (&(parameterArrays[14])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 0x2, 0x0, 0x0, 0x0), 0x8, 0x0, 3, 2, (&(parameterArrays[10])), 0x4, 0x0}, {REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x1, 0x0, 0x0), 0x4, 0x4, 2, 2, (&(parameterArrays[35])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x0, 0x0, 0x0), 0xc, 0x0, 3, 3, (&(parameterArrays[28])), 0x4, 0x0}, {REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x1, 0x0, 0x0), 0x4, 0x8, 2, 2, (&(parameterArrays[33])), 0x4, 0x8}, {REMOTE_SCALARS_MAKEX(0, 0, 0x2, 0x0, 0x0, 0x0), 0x4, 0x0, 1, 1, (&(parameterArrays[0])), 0x4, 0x0}, {REMOTE_SCALARS_MAKEX(0, 0, 0x2, 0x2, 0x0, 0x0), 0x8, 0x4, 5, 3, (&(parameterArrays[25])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 0x3, 0x0, 0x0, 0x0), 0xc, 0x0, 3, 3, (&(parameterArrays[22])), 0x4, 0x0}, {REMOTE_SCALARS_MAKEX(0, 0, 0x5, 0x1, 0x0, 0x0), 0x10, 0x4, 5, 5, (&(parameterArrays[5])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 255, 255, 15, 15), 0xc, 0x6, 7, 5, (&(parameterArrays[0])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 0x2, 0x1, 0x0, 0x0), 0x4, 0x1, 2, 2, (&(parameterArrays[31])), 0x4, 0x1}};
+static const Method *const methodArrays[23] = {&(methods[0]), &(methods[1]), &(methods[2]), &(methods[2]), &(methods[3]), &(methods[4]), &(methods[5]), &(methods[6]), &(methods[7]), &(methods[8]), &(methods[9]), &(methods[2]), &(methods[7]), &(methods[7]), &(methods[2]), &(methods[10]), &(methods[11]), &(methods[12]), &(methods[10]), &(methods[13]), &(methods[5]), &(methods[14]), &(methods[15])};
+static const char strings[342] = "get_search_paths_with_env\0fopen_with_env\0print_string\0bytesWritten\0fileExists\0maxPathLen\0envvarname\0valLenReq\0posLenReq\0bytesRead\0numPaths\0unsetenv\0override\0clearerr\0fsetpos\0fgetpos\0freopen\0exists\0getenv\0ferror\0rewind\0whence\0offset\0fwrite\0fclose\0fflush\0paths\0fgets\0delim\0fseek\0ftell\0fread\0psout\0fopen\0path\0feof\0flen\0bEOF\0mode\0val\0str\0buf\0sin\0";
+static const uint16_t methodStrings[81] = {0, 89, 265, 253, 130, 78, 26, 89, 265, 95, 321, 289, 232, 338, 334, 54, 316, 283, 338, 334, 120, 316, 182, 338, 95, 321, 289, 259, 338, 334, 316, 141, 95, 326, 148, 197, 95, 326, 100, 271, 338, 225, 218, 174, 338, 170, 110, 295, 95, 321, 289, 67, 301, 190, 204, 338, 162, 306, 338, 316, 311, 338, 312, 277, 338, 170, 166, 338, 170, 139, 95, 41, 330, 157, 338, 211, 338, 239, 338, 246, 338};
+static const uint16_t methodStringsArrays[23] = {47, 22, 79, 77, 17, 12, 43, 66, 63, 39, 60, 75, 57, 54, 73, 71, 35, 31, 69, 6, 27, 0, 51};
+__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(apps_std_slim) = {23, &(methodArrays[0]), 0, 0, &(methodStringsArrays [0]), methodStrings, strings};
+#endif //_APPS_STD_SLIM_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+static __inline int _skel_method(int (*_pfn)(char *, uint8_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ char *_in0[1];
+ uint32_t _in0Len[1];
+ uint8_t _rout1[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint8_t *_primROut;
+ remote_arg *_praIn;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 3) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 4);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 1);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0Len, 0, _primIn, 0, 4);
+ _praIn = (_pra + 1);
+ _ASSERT(_nErr, (int)((_praIn[0].buf.nLen / 1)) >= (int)(_in0Len[0]));
+ _in0[0] = _praIn[0].buf.pv;
+ if (_in0Len[0] > 0)
+ {
+ _in0[0][(_in0Len[0] - 1)] = 0;
+ }
+ _TRY(_nErr, _pfn(*_in0, _rout1));
+ _COPY(_primROut, 0, _rout1, 0, 1);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_pack(remote_arg *_praROutPost, remote_arg *_ppraROutPost[1], void *_primROut, char *_rout0[1], uint32_t _rout0Len[1])
+{
+ int _nErr = 0;
+ remote_arg *_praROutPostStart = _praROutPost;
+ remote_arg **_ppraROutPostStart = _ppraROutPost;
+ _ppraROutPost = &_praROutPost;
+ _ppraROutPostStart[0] += (_praROutPost - _praROutPostStart) + 1;
+ return _nErr;
+}
+static __inline int _skel_unpack(_allocator *_al, remote_arg *_praIn, remote_arg *_ppraIn[1], remote_arg *_praROut, remote_arg *_ppraROut[1], void *_primIn, void *_primROut, char *_rout0[1], uint32_t _rout0Len[1])
+{
+ int _nErr = 0;
+ remote_arg *_praInStart = _praIn;
+ remote_arg **_ppraInStart = _ppraIn;
+ remote_arg *_praROutStart = _praROut;
+ remote_arg **_ppraROutStart = _ppraROut;
+ _ppraIn = &_praIn;
+ _ppraROut = &_praROut;
+ _COPY(_rout0Len, 0, _primIn, 0, 4);
+ _ASSERT(_nErr, (int)((_praROut[0].buf.nLen / 1)) >= (int)(_rout0Len[0]));
+ _rout0[0] = _praROut[0].buf.pv;
+ _ppraInStart[0] += (_praIn - _praInStart) + 0;
+ _ppraROutStart[0] += (_praROut - _praROutStart) + 1;
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_1(int (*_pfn)(char *, char *, void *, uint32_t, uint32_t *, uint16_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ char *_in0[1];
+ uint32_t _in0Len[1];
+ char *_in1[1];
+ uint32_t _in1Len[1];
+ void *_rout2[1];
+ uint32_t _rout2Len[1];
+ uint32_t _rout3[1];
+ uint16_t _rout4[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint32_t *_primROut;
+ remote_arg *_praIn;
+ remote_arg *_praROut;
+ remote_arg *_praROutPost;
+ remote_arg **_ppraROutPost = &_praROutPost;
+ _allocator _al[1] = {{0}};
+ remote_arg **_ppraIn = &_praIn;
+ remote_arg **_ppraROut = &_praROut;
+ char *_seq_primIn2;
+ char *_seq_nat2;
+ int _ii;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 5) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 12);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 6);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _praIn = (_pra + 1);
+ _praROut = (_praIn + _numIn[0] + 1);
+ _praROutPost = _praROut;
+ _COPY(_in0Len, 0, _primIn, 0, 4);
+ _ASSERT(_nErr, (int)((_praIn[0].buf.nLen / 1)) >= (int)(_in0Len[0]));
+ _in0[0] = _praIn[0].buf.pv;
+ if (_in0Len[0] > 0)
+ {
+ _in0[0][(_in0Len[0] - 1)] = 0;
+ }
+ _COPY(_in1Len, 0, _primIn, 4, 4);
+ _ASSERT(_nErr, (int)((_praIn[1].buf.nLen / 1)) >= (int)(_in1Len[0]));
+ _in1[0] = _praIn[1].buf.pv;
+ if (_in1Len[0] > 0)
+ _in1[0][(_in1Len[0] - 1)] = 0;
+ _COPY(_rout2Len, 0, _primIn, 8, 4);
+ _allocator_init(_al, 0, 0);
+ _ASSERT(_nErr, (int)((_praIn[2].buf.nLen / 4)) >= (int)(_rout2Len[0]));
+ _ALLOCATE(_nErr, _al, (_rout2Len[0] * SLIM_IFPTR32(8, 16)), SLIM_IFPTR32(4, 8), _rout2[0]);
+ for (_ii = 0, _seq_primIn2 = (char *)_praIn[2].buf.pv, _seq_nat2 = (char *)_rout2[0]; _ii < (int)_rout2Len[0]; ++_ii, _seq_primIn2 = (_seq_primIn2 + 4), _seq_nat2 = (_seq_nat2 + SLIM_IFPTR32(8, 16)))
+ {
+ _TRY(_nErr, _skel_unpack(_al, (_praIn + 3), _ppraIn, (_praROut + 0), _ppraROut, _seq_primIn2, 0, SLIM_IFPTR32((char **) & (((uint32_t *)_seq_nat2)[0]), (char **) & (((uint64_t *)_seq_nat2)[0])), SLIM_IFPTR32((uint32_t *) & (((uint32_t *)_seq_nat2)[1]), (uint32_t *) & (((uint32_t *)_seq_nat2)[2]))));
+ }
+ _TRY(_nErr, _pfn(*_in0, *_in1, *_rout2, *_rout2Len, _rout3, _rout4));
+ for (_ii = 0, _seq_nat2 = (char *)_rout2[0]; _ii < (int)_rout2Len[0]; ++_ii, _seq_nat2 = (_seq_nat2 + SLIM_IFPTR32(8, 16)))
+ {
+ _TRY(_nErr, _skel_pack((_praROutPost + 0), _ppraROutPost, 0, SLIM_IFPTR32((char **) & (((uint32_t *)_seq_nat2)[0]), (char **) & (((uint64_t *)_seq_nat2)[0])), SLIM_IFPTR32((uint32_t *) & (((uint32_t *)_seq_nat2)[1]), (uint32_t *) & (((uint32_t *)_seq_nat2)[2]))));
+ }
+ _COPY(_primROut, 0, _rout3, 0, 4);
+ _COPY(_primROut, 4, _rout4, 0, 2);
+ _CATCH(_nErr) {}
+ _allocator_deinit(_al);
+ return _nErr;
+}
+static __inline int _skel_method_2(int (*_pfn)(uint32_t, char *, uint32_t, uint32_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint32_t _in0[1];
+ char *_rout1[1];
+ uint32_t _rout1Len[1];
+ uint32_t _rout2[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint32_t *_primROut;
+ remote_arg *_praIn;
+ remote_arg *_praROut;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 3) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 8);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 4);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 4);
+ _COPY(_rout1Len, 0, _primIn, 4, 4);
+ _praIn = (_pra + 1);
+ _praROut = (_praIn + _numIn[0] + 1);
+ _ASSERT(_nErr, (int)((_praROut[0].buf.nLen / 1)) >= (int)(_rout1Len[0]));
+ _rout1[0] = _praROut[0].buf.pv;
+ _TRY(_nErr, _pfn(*_in0, *_rout1, *_rout1Len, _rout2));
+ _COPY(_primROut, 0, _rout2, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_3(int (*_pfn)(char *, char *, char *, char *, uint32_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ char *_in0[1];
+ uint32_t _in0Len[1];
+ char *_in1[1];
+ uint32_t _in1Len[1];
+ char *_in2[1];
+ uint32_t _in2Len[1];
+ char *_in3[1];
+ uint32_t _in3Len[1];
+ uint32_t _rout4[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint32_t *_primROut;
+ remote_arg *_praIn;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 6) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 16);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 4);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0Len, 0, _primIn, 0, 4);
+ _praIn = (_pra + 1);
+ _ASSERT(_nErr, (int)((_praIn[0].buf.nLen / 1)) >= (int)(_in0Len[0]));
+ _in0[0] = _praIn[0].buf.pv;
+ if (_in0Len[0] > 0)
+ {
+ _in0[0][(_in0Len[0] - 1)] = 0;
+ }
+ _COPY(_in1Len, 0, _primIn, 4, 4);
+ _ASSERT(_nErr, (int)((_praIn[1].buf.nLen / 1)) >= (int)(_in1Len[0]));
+ _in1[0] = _praIn[1].buf.pv;
+ if (_in1Len[0] > 0)
+ _in1[0][(_in1Len[0] - 1)] = 0;
+ _COPY(_in2Len, 0, _primIn, 8, 4);
+ _ASSERT(_nErr, (int)((_praIn[2].buf.nLen / 1)) >= (int)(_in2Len[0]));
+ _in2[0] = _praIn[2].buf.pv;
+ if (_in2Len[0] > 0)
+ _in2[0][(_in2Len[0] - 1)] = 0;
+ _COPY(_in3Len, 0, _primIn, 12, 4);
+ _ASSERT(_nErr, (int)((_praIn[3].buf.nLen / 1)) >= (int)(_in3Len[0]));
+ _in3[0] = _praIn[3].buf.pv;
+ if (_in3Len[0] > 0)
+ _in3[0][(_in3Len[0] - 1)] = 0;
+ _TRY(_nErr, _pfn(*_in0, *_in1, *_in2, *_in3, _rout4));
+ _COPY(_primROut, 0, _rout4, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_4(int (*_pfn)(char *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ char *_in0[1];
+ uint32_t _in0Len[1];
+ uint32_t *_primIn;
+ remote_arg *_praIn;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 2) <= _praEnd);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 4);
+ _primIn = _pra[0].buf.pv;
+ _COPY(_in0Len, 0, _primIn, 0, 4);
+ _praIn = (_pra + 1);
+ _ASSERT(_nErr, (int)((_praIn[0].buf.nLen / 1)) >= (int)(_in0Len[0]));
+ _in0[0] = _praIn[0].buf.pv;
+ if (_in0Len[0] > 0)
+ {
+ _in0[0][(_in0Len[0] - 1)] = 0;
+ }
+ _TRY(_nErr, _pfn(*_in0));
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_5(int (*_pfn)(char *, char *, uint32_t), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ char *_in0[1];
+ uint32_t _in0Len[1];
+ char *_in1[1];
+ uint32_t _in1Len[1];
+ uint32_t _in2[1];
+ uint32_t *_primIn;
+ remote_arg *_praIn;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 3) <= _praEnd);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 12);
+ _primIn = _pra[0].buf.pv;
+ _COPY(_in0Len, 0, _primIn, 0, 4);
+ _praIn = (_pra + 1);
+ _ASSERT(_nErr, (int)((_praIn[0].buf.nLen / 1)) >= (int)(_in0Len[0]));
+ _in0[0] = _praIn[0].buf.pv;
+ if (_in0Len[0] > 0)
+ {
+ _in0[0][(_in0Len[0] - 1)] = 0;
+ }
+ _COPY(_in1Len, 0, _primIn, 4, 4);
+ _ASSERT(_nErr, (int)((_praIn[1].buf.nLen / 1)) >= (int)(_in1Len[0]));
+ _in1[0] = _praIn[1].buf.pv;
+ if (_in1Len[0] > 0)
+ _in1[0][(_in1Len[0] - 1)] = 0;
+ _COPY(_in2, 0, _primIn, 8, 4);
+ _TRY(_nErr, _pfn(*_in0, *_in1, *_in2));
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_6(int (*_pfn)(char *, char *, uint32_t, uint32_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ char *_in0[1];
+ uint32_t _in0Len[1];
+ char *_rout1[1];
+ uint32_t _rout1Len[1];
+ uint32_t _rout2[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint32_t *_primROut;
+ remote_arg *_praIn;
+ remote_arg *_praROut;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 4) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 8);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 4);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0Len, 0, _primIn, 0, 4);
+ _praIn = (_pra + 1);
+ _ASSERT(_nErr, (int)((_praIn[0].buf.nLen / 1)) >= (int)(_in0Len[0]));
+ _in0[0] = _praIn[0].buf.pv;
+ if (_in0Len[0] > 0)
+ {
+ _in0[0][(_in0Len[0] - 1)] = 0;
+ }
+ _COPY(_rout1Len, 0, _primIn, 4, 4);
+ _praROut = (_praIn + _numIn[0] + 1);
+ _ASSERT(_nErr, (int)((_praROut[0].buf.nLen / 1)) >= (int)(_rout1Len[0]));
+ _rout1[0] = _praROut[0].buf.pv;
+ _TRY(_nErr, _pfn(*_in0, *_rout1, *_rout1Len, _rout2));
+ _COPY(_primROut, 0, _rout2, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_7(int (*_pfn)(uint32_t), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint32_t _in0[1];
+ uint32_t *_primIn;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 1) <= _praEnd);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 4);
+ _primIn = _pra[0].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 4);
+ _TRY(_nErr, _pfn(*_in0));
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_8(int (*_pfn)(uint32_t, uint32_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint32_t _in0[1];
+ uint32_t _rout1[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint32_t *_primROut;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 2) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 4);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 4);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 4);
+ _TRY(_nErr, _pfn(*_in0, _rout1));
+ _COPY(_primROut, 0, _rout1, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_9(int (*_pfn)(uint32_t, uint64_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint32_t _in0[1];
+ uint64_t _rout1[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint64_t *_primROut;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 2) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 4);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 8);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 4);
+ _TRY(_nErr, _pfn(*_in0, _rout1));
+ _COPY(_primROut, 0, _rout1, 0, 8);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_10(int (*_pfn)(uint32_t, uint32_t, uint32_t), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint32_t _in0[1];
+ uint32_t _in1[1];
+ uint32_t _in2[1];
+ uint32_t *_primIn;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 1) <= _praEnd);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 12);
+ _primIn = _pra[0].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 4);
+ _COPY(_in1, 0, _primIn, 4, 4);
+ _COPY(_in2, 0, _primIn, 8, 4);
+ _TRY(_nErr, _pfn(*_in0, *_in1, *_in2));
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_11(int (*_pfn)(uint32_t, char *, uint32_t), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint32_t _in0[1];
+ char *_in1[1];
+ uint32_t _in1Len[1];
+ uint32_t *_primIn;
+ remote_arg *_praIn;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 2) <= _praEnd);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 8);
+ _primIn = _pra[0].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 4);
+ _COPY(_in1Len, 0, _primIn, 4, 4);
+ _praIn = (_pra + 1);
+ _ASSERT(_nErr, (int)((_praIn[0].buf.nLen / 1)) >= (int)(_in1Len[0]));
+ _in1[0] = _praIn[0].buf.pv;
+ _TRY(_nErr, _pfn(*_in0, *_in1, *_in1Len));
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_12(int (*_pfn)(uint32_t, char *, uint32_t, uint32_t *, uint32_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint32_t _in0[1];
+ char *_in1[1];
+ uint32_t _in1Len[1];
+ uint32_t _rout2[1];
+ uint32_t _rout3[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint32_t *_primROut;
+ remote_arg *_praIn;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 3) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 8);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 8);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 4);
+ _COPY(_in1Len, 0, _primIn, 4, 4);
+ _praIn = (_pra + 1);
+ _ASSERT(_nErr, (int)((_praIn[0].buf.nLen / 1)) >= (int)(_in1Len[0]));
+ _in1[0] = _praIn[0].buf.pv;
+ _TRY(_nErr, _pfn(*_in0, *_in1, *_in1Len, _rout2, _rout3));
+ _COPY(_primROut, 0, _rout2, 0, 4);
+ _COPY(_primROut, 4, _rout3, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_13(int (*_pfn)(uint32_t, char *, uint32_t, uint32_t *, uint32_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint32_t _in0[1];
+ char *_rout1[1];
+ uint32_t _rout1Len[1];
+ uint32_t _rout2[1];
+ uint32_t _rout3[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint32_t *_primROut;
+ remote_arg *_praIn;
+ remote_arg *_praROut;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 3) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 8);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 8);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 4);
+ _COPY(_rout1Len, 0, _primIn, 4, 4);
+ _praIn = (_pra + 1);
+ _praROut = (_praIn + _numIn[0] + 1);
+ _ASSERT(_nErr, (int)((_praROut[0].buf.nLen / 1)) >= (int)(_rout1Len[0]));
+ _rout1[0] = _praROut[0].buf.pv;
+ _TRY(_nErr, _pfn(*_in0, *_rout1, *_rout1Len, _rout2, _rout3));
+ _COPY(_primROut, 0, _rout2, 0, 4);
+ _COPY(_primROut, 4, _rout3, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_14(int (*_pfn)(uint32_t, char *, char *, uint32_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ uint32_t _in0[1];
+ char *_in1[1];
+ uint32_t _in1Len[1];
+ char *_in2[1];
+ uint32_t _in2Len[1];
+ uint32_t _rout3[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint32_t *_primROut;
+ remote_arg *_praIn;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 4) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 12);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 4);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0, 0, _primIn, 0, 4);
+ _COPY(_in1Len, 0, _primIn, 4, 4);
+ _praIn = (_pra + 1);
+ _ASSERT(_nErr, (int)((_praIn[0].buf.nLen / 1)) >= (int)(_in1Len[0]));
+ _in1[0] = _praIn[0].buf.pv;
+ if (_in1Len[0] > 0)
+ {
+ _in1[0][(_in1Len[0] - 1)] = 0;
+ }
+ _COPY(_in2Len, 0, _primIn, 8, 4);
+ _ASSERT(_nErr, (int)((_praIn[1].buf.nLen / 1)) >= (int)(_in2Len[0]));
+ _in2[0] = _praIn[1].buf.pv;
+ if (_in2Len[0] > 0)
+ _in2[0][(_in2Len[0] - 1)] = 0;
+ _TRY(_nErr, _pfn(*_in0, *_in1, *_in2, _rout3));
+ _COPY(_primROut, 0, _rout3, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+static __inline int _skel_method_15(int (*_pfn)(char *, char *, uint32_t *), uint32_t _sc, remote_arg *_pra)
+{
+ remote_arg *_praEnd;
+ char *_in0[1];
+ uint32_t _in0Len[1];
+ char *_in1[1];
+ uint32_t _in1Len[1];
+ uint32_t _rout2[1];
+ uint32_t *_primIn;
+ int _numIn[1];
+ uint32_t *_primROut;
+ remote_arg *_praIn;
+ int _nErr = 0;
+ _praEnd = ((_pra + REMOTE_SCALARS_INBUFS(_sc)) + REMOTE_SCALARS_OUTBUFS(_sc));
+ _ASSERT(_nErr, (_pra + 4) <= _praEnd);
+ _numIn[0] = (REMOTE_SCALARS_INBUFS(_sc) - 1);
+ _ASSERT(_nErr, _pra[0].buf.nLen >= 8);
+ _primIn = _pra[0].buf.pv;
+ _ASSERT(_nErr, _pra[(_numIn[0] + 1)].buf.nLen >= 4);
+ _primROut = _pra[(_numIn[0] + 1)].buf.pv;
+ _COPY(_in0Len, 0, _primIn, 0, 4);
+ _praIn = (_pra + 1);
+ _ASSERT(_nErr, (int)((_praIn[0].buf.nLen / 1)) >= (int)(_in0Len[0]));
+ _in0[0] = _praIn[0].buf.pv;
+ if (_in0Len[0] > 0)
+ {
+ _in0[0][(_in0Len[0] - 1)] = 0;
+ }
+ _COPY(_in1Len, 0, _primIn, 4, 4);
+ _ASSERT(_nErr, (int)((_praIn[1].buf.nLen / 1)) >= (int)(_in1Len[0]));
+ _in1[0] = _praIn[1].buf.pv;
+ if (_in1Len[0] > 0)
+ _in1[0][(_in1Len[0] - 1)] = 0;
+ _TRY(_nErr, _pfn(*_in0, *_in1, _rout2));
+ _COPY(_primROut, 0, _rout2, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+__QAIC_SKEL_EXPORT int __QAIC_SKEL(apps_std_skel_invoke)(uint32_t _sc, remote_arg *_pra) __QAIC_SKEL_ATTRIBUTE
+{
+ switch (REMOTE_SCALARS_METHOD(_sc))
+ {
+ case 0:
+ return _skel_method_15((void *)__QAIC_IMPL(apps_std_fopen), _sc, _pra);
+ case 1:
+ return _skel_method_14((void *)__QAIC_IMPL(apps_std_freopen), _sc, _pra);
+ case 2:
+ return _skel_method_7((void *)__QAIC_IMPL(apps_std_fflush), _sc, _pra);
+ case 3:
+ return _skel_method_7((void *)__QAIC_IMPL(apps_std_fclose), _sc, _pra);
+ case 4:
+ return _skel_method_13((void *)__QAIC_IMPL(apps_std_fread), _sc, _pra);
+ case 5:
+ return _skel_method_12((void *)__QAIC_IMPL(apps_std_fwrite), _sc, _pra);
+ case 6:
+ return _skel_method_2((void *)__QAIC_IMPL(apps_std_fgetpos), _sc, _pra);
+ case 7:
+ return _skel_method_11((void *)__QAIC_IMPL(apps_std_fsetpos), _sc, _pra);
+ case 8:
+ return _skel_method_8((void *)__QAIC_IMPL(apps_std_ftell), _sc, _pra);
+ case 9:
+ return _skel_method_10((void *)__QAIC_IMPL(apps_std_fseek), _sc, _pra);
+ case 10:
+ return _skel_method_9((void *)__QAIC_IMPL(apps_std_flen), _sc, _pra);
+ case 11:
+ return _skel_method_7((void *)__QAIC_IMPL(apps_std_rewind), _sc, _pra);
+ case 12:
+ return _skel_method_8((void *)__QAIC_IMPL(apps_std_feof), _sc, _pra);
+ case 13:
+ return _skel_method_8((void *)__QAIC_IMPL(apps_std_ferror), _sc, _pra);
+ case 14:
+ return _skel_method_7((void *)__QAIC_IMPL(apps_std_clearerr), _sc, _pra);
+ case 15:
+ return _skel_method_4((void *)__QAIC_IMPL(apps_std_print_string), _sc, _pra);
+ case 16:
+ return _skel_method_6((void *)__QAIC_IMPL(apps_std_getenv), _sc, _pra);
+ case 17:
+ return _skel_method_5((void *)__QAIC_IMPL(apps_std_setenv), _sc, _pra);
+ case 18:
+ return _skel_method_4((void *)__QAIC_IMPL(apps_std_unsetenv), _sc, _pra);
+ case 19:
+ return _skel_method_3((void *)__QAIC_IMPL(apps_std_fopen_with_env), _sc, _pra);
+ case 20:
+ return _skel_method_2((void *)__QAIC_IMPL(apps_std_fgets), _sc, _pra);
+ case 21:
+ return _skel_method_1((void *)__QAIC_IMPL(apps_std_get_search_paths_with_env), _sc, _pra);
+ case 22:
+ return _skel_method((void *)__QAIC_IMPL(apps_std_fileExists), _sc, _pra);
+ }
+ return AEE_EUNSUPPORTED;
+}
+#ifdef __cplusplus
+}
+#endif
+#endif //_APPS_STD_SKEL_H
diff --git a/src/atomic.c b/src/atomic.c
new file mode 100644
index 0000000..9084638
--- /dev/null
+++ b/src/atomic.c
@@ -0,0 +1,81 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#include "AEEatomic.h"
+
+uint32 atomic_Add(uint32 *volatile puDest, int nAdd)
+{
+ uint32 previous;
+ uint32 current;
+ do
+ {
+ current = *puDest;
+ previous = atomic_CompareAndExchange(puDest, current + nAdd, current);
+ }
+ while (previous != current);
+ return (current + nAdd);
+}
+
+uint32 atomic_Exchange(uint32 *volatile puDest, uint32 uVal)
+{
+ uint32 previous;
+ uint32 current;
+ do
+ {
+ current = *puDest;
+ previous = atomic_CompareAndExchange(puDest, uVal, current);
+ }
+ while (previous != current);
+ return previous;
+}
+
+uint32 atomic_CompareOrAdd(uint32 *volatile puDest, uint32 uCompare, int nAdd)
+{
+ uint32 previous;
+ uint32 current;
+ uint32 result;
+ do
+ {
+ current = *puDest;
+ previous = current;
+ result = current;
+ if (current != uCompare)
+ {
+ previous = atomic_CompareAndExchange(puDest, current + nAdd, current);
+ if (previous == current)
+ {
+ result = current + nAdd;
+ }
+ }
+ }
+ while (previous != current);
+ return result;
+}
+
diff --git a/src/cae.c b/src/cae.c
new file mode 100644
index 0000000..8c9c4f7
--- /dev/null
+++ b/src/cae.c
@@ -0,0 +1,72 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#include "AEEatomic.h"
+
+#ifdef _WIN32
+#include "Windows.h"
+uint32 atomic_CompareAndExchange(uint32 *volatile puDest, uint32 uExchange, uint32 uCompare)
+{
+ return (uint32)InterlockedCompareExchange(puDest, uExchange, uCompare);
+}
+
+#elif __hexagon__
+static inline unsigned int
+qurt_atomic_compare_val_and_set(unsigned int *target,
+ unsigned int old_val,
+ unsigned int new_val)
+{
+ unsigned int current_val;
+
+ __asm__ __volatile__(
+ "1: %0 = memw_locked(%2)\n"
+ " p0 = cmp.eq(%0, %3)\n"
+ " if !p0 jump 2f\n"
+ " memw_locked(%2, p0) = %4\n"
+ " if !p0 jump 1b\n"
+ "2:\n"
+ : "=&r"(current_val), "+m"(*target)
+ : "r"(target), "r"(old_val), "r"(new_val)
+ : "p0");
+
+ return current_val;
+}
+uint32 atomic_CompareAndExchange(uint32 *volatile puDest, uint32 uExchange, uint32 uCompare)
+{
+ return (uint32)qurt_atomic_compare_val_and_set((unsigned int *)puDest, uCompare, uExchange);
+}
+
+#elif __GNUC__
+uint32 atomic_CompareAndExchange(uint32 *volatile puDest, uint32 uExchange, uint32 uCompare)
+{
+ return __sync_val_compare_and_swap(puDest, uCompare, uExchange);
+}
+#endif
+
diff --git a/src/fastrpc_apps_user.c b/src/fastrpc_apps_user.c
new file mode 100644
index 0000000..19ea601
--- /dev/null
+++ b/src/fastrpc_apps_user.c
@@ -0,0 +1,938 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef VERIFY_PRINT_ERROR
+#define VERIFY_PRINT_ERROR
+#endif
+
+#include "verify.h"
+
+#include "remote.h"
+#include "shared.h"
+#include "fastrpc_internal.h"
+#include "fastrpc_apps_user.h"
+#include "adsp_current_process.h"
+#include "remotectl.h"
+#include "rpcmem.h"
+#include "AEEstd.h"
+#include "AEEQList.h"
+#include "apps_std.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/types.h>
+#include <errno.h>
+
+#ifndef _WIN32
+#include <pthread.h>
+#include <sys/inotify.h>
+#include <sys/eventfd.h>
+#include <poll.h>
+#endif
+
+#ifndef INT_MAX
+#define INT_MAX (int)(-1)
+#endif
+
+#ifndef FASTRPC_DEVICE
+#define FASTRPC_DEVICE "/dev/fastrpc-adsp"
+#endif
+
+#define EVENT_SIZE ( sizeof (struct inotify_event) )
+#define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )
+
+struct mem_to_fd
+{
+ QNode qn;
+ void *buf;
+ int size;
+ int fd;
+ uintptr_t vaddr;
+};
+
+struct mem_to_fd_list
+{
+ QList ql;
+ pthread_mutex_t mut;
+};
+
+struct log_config_watcher_params
+{
+ int fd;
+ int event_fd; /* Duplicate fd to quit the poll */
+ _cstring1_t *paths;
+ int *wd;
+ uint32 numPaths;
+ pthread_t thread;
+ unsigned char stopThread;
+ int asidToWatch;
+ char *fileToWatch;
+ char *asidFileToWatch;
+ char *pidFileToWatch;
+};
+
+static struct mem_to_fd_list fdlist;
+static struct log_config_watcher_params log_config_watcher = {0};
+extern const char *__progname;
+static int gdev = -1;
+static int glist = -1;
+static struct fastrpc_init_create ginit = {0};
+static pthread_key_t tlsKey = 0;
+
+int listener_init(void);
+void apps_mem_init(void);
+void apps_mem_deinit(void);
+void apps_std_init(void);
+void apps_std_deinit(void);
+
+void remote_register_buf(void *buf, int size, int fd)
+{
+ struct mem_to_fd *tofd = 0, *freefd = 0;
+ int nErr = 0;
+ if (fd != -1)
+ {
+ VERIFY(0 != (tofd = malloc(sizeof(*tofd))));
+ QNode_CtorZ(&tofd->qn);
+ tofd->buf = buf;
+ tofd->size = size;
+ tofd->fd = fd;
+ tofd->vaddr = 0;
+ pthread_mutex_lock(&fdlist.mut);
+ QList_AppendNode(&fdlist.ql, &tofd->qn);
+ pthread_mutex_unlock(&fdlist.mut);
+ if (gdev != -1)
+ {
+ (void)remote_mmap64(fd, 0, (uintptr_t)buf, size, &tofd->vaddr);
+ }
+ }
+ else
+ {
+ QNode *pn, *pnn;
+ pthread_mutex_lock(&fdlist.mut);
+ QLIST_NEXTSAFE_FOR_ALL(&fdlist.ql, pn, pnn)
+ {
+ tofd = STD_RECOVER_REC(struct mem_to_fd, qn, pn);
+ if (tofd->buf == buf && tofd->size == size)
+ {
+ QNode_DequeueZ(&tofd->qn);
+ freefd = tofd;
+ break;
+ }
+ }
+ pthread_mutex_unlock(&fdlist.mut);
+ if (freefd)
+ {
+ if (freefd->vaddr)
+ {
+ (void)remote_munmap64(freefd->vaddr, freefd->size);
+ }
+ free(freefd);
+ }
+ }
+bail:
+ return;
+}
+
+static int fdlist_fd_to_buf(void *buf)
+{
+ QNode *pn;
+ int fd = -1;
+ pthread_mutex_lock(&fdlist.mut);
+ QLIST_FOR_ALL(&fdlist.ql, pn)
+ {
+ if (fd != -1)
+ {
+ break;
+ }
+ else
+ {
+ struct mem_to_fd *tofd = STD_RECOVER_REC(struct mem_to_fd, qn, pn);
+ if (STD_BETWEEN(buf, tofd->buf, (unsigned long)tofd->buf + tofd->size))
+ {
+ fd = tofd->fd;
+ }
+ }
+ }
+ pthread_mutex_unlock(&fdlist.mut);
+ return fd;
+}
+
+static void exit_thread(void *value)
+{
+ (void)value;
+ VERIFY_IPRINTF("exiting thread");
+ (void)adsp_current_process_thread_exit();
+}
+
+static void create_key(void)
+{
+ (void)pthread_key_create(&tlsKey, exit_thread);
+}
+
+static void attach_dev(void)
+{
+ int nErr = 0;
+ int dev = gdev;
+ if (dev == -1)
+ {
+ dev = open(FASTRPC_DEVICE, O_NONBLOCK);
+ VERIFY(dev >= 0);
+ }
+
+ VERIFY((0 == ioctl(dev, FASTRPC_IOCTL_INIT_ATTACH)) || errno == ENOTTY);
+ gdev = dev;
+bail:
+ if (nErr && (dev >= 0))
+ {
+ close(dev);
+ gdev = -1;
+ }
+}
+
+static void free_init_mem(void)
+{
+ if (1)
+ {
+ if (ginit.file)
+ {
+ rpcmem_free(ginit.file);
+ ginit.file = 0;
+ }
+ }
+}
+
+static void create_dev(void)
+{
+ int nErr = 0;
+ apps_std_FILE fh = -1;
+ uint64 len;
+ int dev = -1;
+ if (gdev == -1)
+ {
+ int readlen = 0, eof;
+
+ dev = open(FASTRPC_DEVICE, O_NONBLOCK);
+ VERIFY(dev >= 0);
+ gdev = dev;
+ VERIFY(!apps_std_fopen_with_env("ADSP_LIBRARY_PATH", ";", "fastrpc_shell_0", "r", &fh));
+ VERIFY(!apps_std_flen(fh, &len));
+ VERIFY(len < INT_MAX);
+ ginit.file = rpcmem_alloc(0, RPCMEM_HEAP_DEFAULT, (int)len);
+ VERIFY(ginit.file);
+ ginit.filelen = (int)len;
+ VERIFY(!apps_std_fread(fh, ginit.file, len, &readlen, &eof));
+ VERIFY(ginit.filelen == readlen);
+ ginit.filefd = rpcmem_to_fd((void *)ginit.file);
+ VERIFY(0 == ioctl(dev, FASTRPC_IOCTL_INIT_CREATE, (unsigned long)&ginit));
+ dev = -1;
+ }
+bail:
+ if (nErr)
+ {
+ free_init_mem();
+ }
+ if (fh > -1)
+ {
+ if (dev >= 0)
+ {
+ close(dev);
+ }
+ apps_std_fclose(fh);
+ }
+ else
+ {
+ gdev = dev;
+ attach_dev();
+ }
+}
+
+static void create_listener(void)
+{
+ glist = listener_init();
+}
+
+int open_dev(int attach)
+{
+ if (gdev == -1)
+ {
+ static pthread_once_t once_dev = PTHREAD_ONCE_INIT;
+ static pthread_once_t once_listener = PTHREAD_ONCE_INIT;
+ static pthread_once_t once_ck = PTHREAD_ONCE_INIT;
+ int rv = 0;
+ if (attach)
+ {
+ rv = pthread_once(&once_dev, attach_dev);
+ }
+ else
+ {
+ rv = pthread_once(&once_dev, create_dev);
+ }
+ if (rv != 0 || gdev == -1)
+ {
+ VERIFY_EPRINTF("%s device initialization error: %s\n", FASTRPC_DEVICE, strerror(errno));
+ return gdev;
+ }
+ rv = pthread_once(&once_listener, create_listener);
+ if (rv != 0 || glist != 0)
+ {
+ VERIFY_EPRINTF("listener unsupported: %d", glist);
+ return gdev;
+ }
+ rv = pthread_once(&once_ck, create_key);
+ if (rv != 0 || tlsKey == 0)
+ {
+ VERIFY_EPRINTF("failed to create tls key");
+ return gdev;
+ }
+
+ }
+ return gdev;
+}
+
+static int parseLogConfig(unsigned short mask, char *filenames)
+{
+ _cstring1_t *filesToLog = NULL;
+ int filesToLogLen = 0;
+ char *tempFiles = NULL;
+ int nErr = 0;
+ char *saveptr = NULL;
+ char *path = NULL;
+ char delim[] = {','};
+ int maxPathLen = 0;
+ int i = 0;
+
+ VERIFY(filenames != NULL);
+
+ VERIFY(NULL != (tempFiles = malloc(sizeof(char) * (std_strlen(filenames) + 1))));
+ std_strlcpy(tempFiles, filenames, std_strlen(filenames) + 1);
+
+ /* Get the number of folders and max size needed */
+ path = strtok_r(tempFiles, delim, &saveptr);
+ while (path != NULL)
+ {
+ maxPathLen = STD_MAX(maxPathLen, std_strlen(path)) + 1;
+ filesToLogLen++;
+ path = strtok_r(NULL, delim, &saveptr);
+ }
+
+ VERIFY_IPRINTF("%s: #files: %d max_len: %d\n", log_config_watcher.fileToWatch, filesToLogLen, maxPathLen);
+
+ /* Allocate memory */
+ VERIFY(NULL != (filesToLog = malloc(sizeof(_cstring1_t) * filesToLogLen)));
+ for (i = 0; i < filesToLogLen; ++i)
+ {
+ VERIFY(NULL != (filesToLog[i].data = malloc(sizeof(char) * maxPathLen)));
+ filesToLog[i].dataLen = maxPathLen;
+ }
+
+ /* Get the number of folders and max size needed */
+ std_strlcpy(tempFiles, filenames, std_strlen(filenames) + 1);
+ i = 0;
+ path = strtok_r(tempFiles, delim, &saveptr);
+ while (path != NULL)
+ {
+ VERIFY((filesToLog != NULL) && (filesToLog[i].data != NULL) &&
+ filesToLog[i].dataLen >= strlen(path));
+ std_strlcpy(filesToLog[i].data, path, filesToLog[i].dataLen);
+ VERIFY_IPRINTF("%s: %s\n", log_config_watcher.fileToWatch, filesToLog[i].data);
+ path = strtok_r(NULL, delim, &saveptr);
+ i++;
+ }
+
+ VERIFY(0 == adsp_current_process_set_logging_params(mask, filesToLog, filesToLogLen));
+
+bail:
+ if (filesToLog)
+ {
+ for (i = 0; i < filesToLogLen; ++i)
+ {
+ if (filesToLog[i].data != NULL)
+ {
+ free(filesToLog[i].data);
+ filesToLog[i].data = NULL;
+ }
+ }
+ free(filesToLog);
+ filesToLog = NULL;
+ }
+
+ if (tempFiles)
+ {
+ free(tempFiles);
+ tempFiles = NULL;
+ }
+ return nErr;
+}
+
+/* Read log config given the filename */
+static int readLogConfigFromPath(const char *base, const char *file)
+{
+ int nErr = 0;
+ apps_std_FILE fp = -1;
+ uint64 len;
+ byte *buf = NULL;
+ int readlen = 0, eof;
+ unsigned short mask = 0;
+ char *path = NULL;
+ char *filenames = NULL;
+ boolean fileExists = FALSE;
+
+ len = std_snprintf(0, 0, "%s/%s", base, file) + 1;
+ VERIFY(NULL != (path = malloc(sizeof(char) * len)));
+ VERIFY(len >= std_snprintf(path, len, "%s/%s", base, file));
+
+ VERIFY(0 == apps_std_fileExists(path, &fileExists));
+ if (fileExists == FALSE)
+ {
+ VERIFY_IPRINTF("%s: Couldn't find file: %s\n", log_config_watcher.fileToWatch, path);
+ nErr = -1;
+ goto bail;
+ }
+
+ VERIFY(0 == apps_std_fopen(path, "r", &fp));
+ VERIFY(0 == apps_std_flen(fp, &len));
+
+ VERIFY(len < INT_MAX);
+
+ VERIFY(NULL != (buf = malloc(sizeof(byte) * len)));
+ VERIFY(NULL != (filenames = malloc(sizeof(byte) * len)));
+ VERIFY(!apps_std_fread(fp, buf, len, &readlen, &eof));
+ VERIFY(len == readlen);
+
+ VERIFY_IPRINTF("%s: Config file %s contents: %s\n", log_config_watcher.fileToWatch, path, buf);
+
+ len = sscanf((const char *)buf, "0x%hx %s", &mask, filenames);
+ switch (len)
+ {
+ case 1:
+ VERIFY_IPRINTF("%s: Setting log mask:0x%x", log_config_watcher.fileToWatch, mask);
+ VERIFY(0 == adsp_current_process_set_logging_params(mask, NULL, 0));
+ break;
+ case 2:
+ VERIFY(0 == parseLogConfig(mask, filenames));
+ VERIFY_IPRINTF("%s: Setting log mask:0x%x, filename:%s", log_config_watcher.fileToWatch, mask, filenames);
+ break;
+ default:
+ VERIFY_EPRINTF("%s: No valid data found in config file %s", log_config_watcher.fileToWatch, path);
+ nErr = -1;
+ goto bail;
+ }
+
+bail:
+ if (buf != NULL)
+ {
+ free(buf);
+ buf = NULL;
+ }
+
+ if (filenames != NULL)
+ {
+ free(filenames);
+ filenames = NULL;
+ }
+
+ if (fp != -1)
+ {
+ apps_std_fclose(fp);
+ }
+
+ if (path != NULL)
+ {
+ free(path);
+ path = NULL;
+ }
+
+
+ return nErr;
+}
+
+/* Read log config given the watch descriptor */
+static int readLogConfigFromEvent(struct inotify_event *event)
+{
+ int i = 0;
+
+ /* Ensure we are looking at the right file */
+ for (i = 0; i < log_config_watcher.numPaths; ++i)
+ {
+ if (log_config_watcher.wd[i] == event->wd)
+ {
+ if (std_strcmp(log_config_watcher.fileToWatch, event->name) == 0)
+ {
+ return readLogConfigFromPath(log_config_watcher.paths[i].data, log_config_watcher.fileToWatch);
+ }
+ else if (std_strcmp(log_config_watcher.asidFileToWatch, event->name) == 0)
+ {
+ return readLogConfigFromPath(log_config_watcher.paths[i].data, log_config_watcher.asidFileToWatch);
+ }
+ else if (std_strcmp(log_config_watcher.pidFileToWatch, event->name) == 0)
+ {
+ return readLogConfigFromPath(log_config_watcher.paths[i].data, log_config_watcher.pidFileToWatch);
+ }
+ }
+ }
+ VERIFY_IPRINTF("%s: Watch descriptor %d not valid for current process", log_config_watcher.fileToWatch, event->wd);
+ return 0;
+}
+
+/* Read log config given the watch descriptor */
+static int resetLogConfigFromEvent(struct inotify_event *event)
+{
+ int i = 0;
+
+ /* Ensure we are looking at the right file */
+ for (i = 0; i < log_config_watcher.numPaths; ++i)
+ {
+ if (log_config_watcher.wd[i] == event->wd)
+ {
+ if ((std_strcmp(log_config_watcher.fileToWatch, event->name) == 0) ||
+ (std_strcmp(log_config_watcher.asidFileToWatch, event->name) == 0) ||
+ (std_strcmp(log_config_watcher.pidFileToWatch, event->name) == 0))
+ {
+ return adsp_current_process_set_logging_params(0, NULL, 0);
+ }
+ }
+ }
+ VERIFY_IPRINTF("%s: Watch descriptor %d not valid for current process", log_config_watcher.fileToWatch, event->wd);
+ return 0;
+}
+
+static void *file_watcher_thread(void *arg)
+{
+ int ret = 0;
+ int length = 0;
+ int nErr = 0;
+ int i = 0;
+ char buffer[EVENT_BUF_LEN];
+ struct pollfd pfd[] =
+ {
+ {log_config_watcher.fd, POLLIN, 0},
+ {log_config_watcher.event_fd, POLLIN, 0}
+ };
+ const char *fileExtension = ".farf";
+ int len = 0;
+
+ /* Check for the presence of the <process_name>.farf file at bootup */
+ for (i = 0; i < log_config_watcher.numPaths; ++i)
+ {
+ if (0 == readLogConfigFromPath(log_config_watcher.paths[i].data, log_config_watcher.fileToWatch))
+ {
+ VERIFY_IPRINTF("%s: Log config File %s found.\n", log_config_watcher.fileToWatch, log_config_watcher.paths[i].data);
+ }
+ }
+
+ while (log_config_watcher.stopThread == 0)
+ {
+ /* Block forever */
+ ret = poll(pfd, 2, -1);
+ if (ret < 0)
+ {
+ VERIFY_EPRINTF("%s: Error polling for file change. Runtime FARF will not work for this process. errno=%d !", log_config_watcher.fileToWatch, errno);
+ break;
+ }
+ else if (pfd[1].revents & POLLIN) /* Check for exit */
+ {
+ VERIFY_EPRINTF("Received exit.\n");
+ break;
+ }
+ else
+ {
+ length = read(log_config_watcher.fd, buffer, EVENT_BUF_LEN);
+ i = 0;
+ while (i < length)
+ {
+ struct inotify_event *event = (struct inotify_event *) &buffer[ i ];
+ if (event->len)
+ {
+ /* Get the asiD for the current process.
+ Do it once only */
+ if (log_config_watcher.asidToWatch == -1)
+ {
+ VERIFY(0 == adsp_current_process_getASID((unsigned int *)&log_config_watcher.asidToWatch));
+ len = strlen(fileExtension) + strlen(__TOSTR__(INT_MAX));
+ VERIFY(NULL != (log_config_watcher.asidFileToWatch = malloc(sizeof(char) * len)));
+ snprintf(log_config_watcher.asidFileToWatch, len, "%d%s", log_config_watcher.asidToWatch, fileExtension);
+ VERIFY_IPRINTF("%s: Watching ASID file %s\n", log_config_watcher.fileToWatch, log_config_watcher.asidFileToWatch);
+ }
+
+ VERIFY_IPRINTF("%s: %s %d.\n", log_config_watcher.fileToWatch, event->name, event->mask);
+ if ((event->mask & IN_CREATE) || (event->mask & IN_MODIFY))
+ {
+ VERIFY_IPRINTF("%s: File %s created.\n", log_config_watcher.fileToWatch, event->name);
+ if (0 != readLogConfigFromEvent(event))
+ {
+ VERIFY_EPRINTF("%s: Error reading config file %s", log_config_watcher.fileToWatch, log_config_watcher.paths[i].data);
+ }
+ }
+ else if (event->mask & IN_DELETE)
+ {
+ VERIFY_IPRINTF("%s: File %s deleted.\n", log_config_watcher.fileToWatch, event->name);
+ if (0 != resetLogConfigFromEvent(event))
+ {
+ VERIFY_EPRINTF("%s: Error resetting FARF runtime log config", log_config_watcher.fileToWatch);
+ }
+ }
+ }
+
+ i += EVENT_SIZE + event->len;
+ }
+ }
+ }
+bail:
+ if (nErr != 0)
+ {
+ VERIFY_EPRINTF("%s: Error in file watcher thread. Runtime FARF will not work for this process !", log_config_watcher.fileToWatch);
+ }
+ return NULL;
+}
+
+void deinitFileWatcher()
+{
+ int i = 0;
+ uint64 stop = 10;
+
+ /* Destroy the file watcher thread */
+ log_config_watcher.stopThread = 1;
+ write(log_config_watcher.event_fd, &stop, sizeof(uint64));
+
+ pthread_join(log_config_watcher.thread, NULL);
+
+ if (log_config_watcher.fileToWatch)
+ {
+ free(log_config_watcher.fileToWatch);
+ }
+
+ if (log_config_watcher.asidFileToWatch)
+ {
+ free(log_config_watcher.asidFileToWatch);
+ }
+
+ if (log_config_watcher.pidFileToWatch)
+ {
+ free(log_config_watcher.pidFileToWatch);
+ }
+
+ if (log_config_watcher.wd)
+ {
+ for (i = 0; i < log_config_watcher.numPaths; ++i)
+ {
+ if (log_config_watcher.wd[i] != 0)
+ {
+ inotify_rm_watch(log_config_watcher.fd, log_config_watcher.wd[i]);
+ }
+ }
+ free(log_config_watcher.wd);
+ log_config_watcher.wd = NULL;
+ }
+
+ if (log_config_watcher.paths)
+ {
+ for (i = 0; i < log_config_watcher.numPaths; ++i)
+ {
+ if (log_config_watcher.paths[i].data)
+ {
+ free(log_config_watcher.paths[i].data);
+ log_config_watcher.paths[i].data = NULL;
+ }
+ }
+ free(log_config_watcher.paths);
+ log_config_watcher.paths = NULL;
+ }
+
+ if (log_config_watcher.fd != 0)
+ {
+ close(log_config_watcher.fd);
+ log_config_watcher.fd = 0;
+ }
+
+ log_config_watcher.numPaths = 0;
+}
+
+int initFileWatcher()
+{
+ int nErr = 0;
+ const char *fileExtension = ".farf";
+ uint32 len = 0;
+ uint16 maxPathLen = 0;
+ int i = 0;
+ char *name = NULL;
+
+ log_config_watcher.asidToWatch = 0;
+ VERIFY(NULL != (name = std_basename(__progname)));
+
+ len = strlen(name) + strlen(fileExtension) + 1;
+ VERIFY(NULL != (log_config_watcher.fileToWatch = malloc(sizeof(char) * len)));
+ snprintf(log_config_watcher.fileToWatch, len, "%s%s", name, fileExtension);
+
+ len = strlen(fileExtension) + strlen(__TOSTR__(INT_MAX));
+ VERIFY(NULL != (log_config_watcher.pidFileToWatch = malloc(sizeof(char) * len)));
+ snprintf(log_config_watcher.pidFileToWatch, len, "%d%s", getpid(), fileExtension);
+
+ VERIFY_IPRINTF("%s: Watching PID file: %s\n", log_config_watcher.fileToWatch, log_config_watcher.pidFileToWatch);
+
+ log_config_watcher.fd = inotify_init();
+ if (log_config_watcher.fd < 0)
+ {
+ nErr = -1;
+ VERIFY_EPRINTF("Error in inotify_init. errno = %d\n", errno);
+ goto bail;
+ }
+
+ /* Duplicate the fd, so we can use it to quit polling */
+ log_config_watcher.event_fd = eventfd(0, 0);
+ if (log_config_watcher.event_fd < 0)
+ {
+ nErr = -1;
+ VERIFY_EPRINTF("Error in dup. errno = %d\n", errno);
+ goto bail;
+ }
+ VERIFY_IPRINTF("fd = %d dupfd=%d\n", log_config_watcher.fd, log_config_watcher.event_fd);
+
+ /* Get the required size */
+ apps_std_get_search_paths_with_env("ADSP_LIBRARY_PATH", ";", NULL, 0,
+ &log_config_watcher.numPaths, &maxPathLen);
+
+ maxPathLen += + 1;
+
+ /* Allocate memory */
+ VERIFY(NULL != (log_config_watcher.paths
+ = malloc(sizeof(_cstring1_t) * log_config_watcher.numPaths)));
+ VERIFY(NULL != (log_config_watcher.wd
+ = malloc(sizeof(int) * log_config_watcher.numPaths)));
+
+ for (i = 0; i < log_config_watcher.numPaths; ++i)
+ {
+ VERIFY(NULL != (log_config_watcher.paths[i].data
+ = malloc(sizeof(char) * maxPathLen)));
+ log_config_watcher.paths[i].dataLen = maxPathLen;
+ }
+
+ /* Get the paths */
+ VERIFY(0 == apps_std_get_search_paths_with_env("ADSP_LIBRARY_PATH", ";",
+ log_config_watcher.paths, log_config_watcher.numPaths, &len, &maxPathLen));
+
+ maxPathLen += 1;
+
+ VERIFY_IPRINTF("%s: Watching folders:\n", log_config_watcher.fileToWatch);
+ for (i = 0; i < log_config_watcher.numPaths; ++i)
+ {
+ /* Watch for creation, deletion and modification of files in path */
+ VERIFY_IPRINTF("%s: %s\n", log_config_watcher.fileToWatch, log_config_watcher.paths[i].data);
+ VERIFY(0 < (log_config_watcher.wd[i] = inotify_add_watch(log_config_watcher.fd,
+ log_config_watcher.paths[i].data, IN_CREATE | IN_DELETE)));
+ }
+
+ /* Create a thread to watch for file changes */
+ log_config_watcher.asidToWatch = -1;
+ log_config_watcher.stopThread = 0;
+ pthread_create(&log_config_watcher.thread, NULL, file_watcher_thread, NULL);
+bail:
+ if (nErr != 0)
+ {
+ VERIFY_EPRINTF("%s: Failed to register with inotify. Runtime FARF will not work for the process %s!", log_config_watcher.fileToWatch, name);
+ deinitFileWatcher();
+ }
+
+ return nErr;
+}
+
+static int fastrpc_apps_user_init()
+{
+ pthread_mutex_init(&fdlist.mut, 0);
+ QList_Ctor(&fdlist.ql);
+ rpcmem_init();
+ apps_mem_init();
+ apps_std_init();
+ return 0;
+}
+
+int listener_deinit();
+static int fastrpc_apps_user_deinit()
+{
+ int olddev = gdev;
+
+
+ VERIFY_EPRINTF("exit:");
+ free_init_mem();
+ if (olddev != -1)
+ {
+ adsp_current_process_exit();
+ listener_deinit();
+ gdev = -1;
+ VERIFY_EPRINTF("exit: closing %s, rpc errors are expected.\n", FASTRPC_DEVICE);
+ close(olddev);
+ }
+ if (tlsKey)
+ {
+ pthread_key_delete(tlsKey);
+ tlsKey = 0;
+ }
+
+ apps_mem_deinit();
+ apps_std_deinit();
+ rpcmem_deinit();
+ pthread_mutex_destroy(&fdlist.mut);
+ return 0;
+}
+
+SHARED_OBJECT_API_ENTRY(fastrpc_apps_user_init, fastrpc_apps_user_deinit);
+
+int remote_handle_invoke(remote_handle handle, uint32_t sc, remote_arg *pra)
+{
+ struct fastrpc_invoke invoke;
+ struct fastrpc_invoke_args *args;
+ int bufs, i, req, nErr = 0;
+ int dev = open_dev(0);
+ VERIFY(dev != -1);
+ invoke.handle = handle;
+ invoke.sc = sc;
+
+ bufs = REMOTE_SCALARS_LENGTH(sc);
+
+ args = malloc(bufs * sizeof(*args));
+ if (!args)
+ return -ENOMEM;
+
+ invoke.args = (__u64)(uintptr_t)args;
+
+ for (i = 0; i < bufs; i++)
+ {
+ args[i].length = pra[i].buf.nLen;
+ args[i].ptr = (__u64)(uintptr_t)pra[i].buf.pv;
+
+ if (pra[i].buf.nLen)
+ {
+ args[i].fd = fdlist_fd_to_buf(pra[i].buf.pv);
+ }
+ else
+ {
+ args[i].fd = -1;
+ }
+ }
+ req = FASTRPC_IOCTL_INVOKE;
+
+ if (0 == pthread_getspecific(tlsKey))
+ {
+ pthread_setspecific(tlsKey, (void *)1);
+ }
+
+ nErr = ioctl(dev, req, (unsigned long)&invoke);
+bail:
+ return nErr;
+}
+
+int listener_geteventfd(int *fd);
+int remote_handle_open(const char *name, remote_handle *ph)
+{
+ char dlerrstr[255];
+ int dlerr = 0, nErr = 0;
+ if (!std_strcmp(name, ITRANSPORT_PREFIX "geteventfd"))
+ {
+ return listener_geteventfd((int *)ph);
+ }
+ if (!std_strcmp(name, ITRANSPORT_PREFIX "attachguestos"))
+ {
+ int dev = open_dev(1);
+ return dev == -1;
+ }
+ VERIFY(0 == (nErr = remotectl_open(name, (int *)ph, dlerrstr, sizeof(dlerrstr), &dlerr)));
+
+ VERIFY(0 == (nErr = dlerr));
+bail:
+ if (dlerr != 0)
+ {
+ VERIFY_EPRINTF("adsp dlopen error: %s %s", name, dlerrstr);
+ }
+ return nErr;
+}
+
+int remote_handle_close(remote_handle h)
+{
+ char dlerrstr[255];
+ int dlerr = 0, nErr = 0;
+ VERIFY(0 == (nErr = remotectl_close(h, dlerrstr, sizeof(dlerrstr), &dlerr)));
+ VERIFY(0 == (nErr = dlerr));
+bail:
+ return nErr;
+}
+
+int remote_mmap64(int fd, uint32_t flags, uintptr_t vaddrin, int64_t size, uintptr_t *vaddrout)
+{
+ int nErr = 0;
+ struct fastrpc_ioctl_mmap mmap;
+ int dev = open_dev(0);
+ if (dev == -1)
+ {
+ return -1;
+ }
+ mmap.fd = fd;
+ mmap.flags = flags;
+ mmap.vaddrin = vaddrin;
+ mmap.size = size;
+ VERIFY(0 == (nErr = ioctl(dev, FASTRPC_IOCTL_MMAP, (unsigned long)&mmap)));
+ *vaddrout = mmap.vaddrout;
+bail:
+ return nErr;
+}
+
+int remote_mmap(int fd, uint32_t flags, uint32_t vaddrin, int size, uint32_t *vaddrout)
+{
+ return remote_mmap64(fd, flags, (uintptr_t)vaddrin, (int64_t)size, (uintptr_t *)vaddrout);
+}
+
+int remote_munmap64(uintptr_t vaddrout, int64_t size)
+{
+ struct fastrpc_ioctl_munmap munmap;
+ int dev = open_dev(0);
+ if (dev == -1)
+ {
+ return -1;
+ }
+ munmap.vaddrout = vaddrout;
+ munmap.size = size;
+ return ioctl(dev, FASTRPC_IOCTL_MUNMAP, (unsigned long)&munmap);
+}
+
+int remote_munmap(uint32_t vaddrout, int size)
+{
+ return remote_munmap64((uintptr_t)vaddrout, (int64_t)size);
+}
+
+int remote_set_mode(uint32_t mode)
+{
+ int dev = open_dev(0);
+ if (dev == -1)
+ {
+ return -1;
+ }
+ return ioctl(dev, FASTRPC_IOCTL_SETMODE, mode);
+}
diff --git a/src/listener.c b/src/listener.c
new file mode 100644
index 0000000..5455195
--- /dev/null
+++ b/src/listener.c
@@ -0,0 +1,425 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#include "verify.h"
+#include "listener.h"
+#include "remote.h"
+#include "rpcmem.h"
+#include "adsp_listener.h"
+#include "listener_buf.h"
+#include "shared.h"
+#include "uthash.h"
+#include "AEEstd.h"
+
+#define LOGL(format, ...) VERIFY_PRINT_INFO(format, ##__VA_ARGS__)
+#include "mod_table_imp.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/eventfd.h>
+
+#ifndef VERIFY_PRINT_ERROR
+#define VERIFY_PRINT_ERROR
+#endif
+
+struct listener
+{
+ pthread_t thread;
+ struct mod_table mt;
+ int eventfd;
+};
+
+static struct listener gMe = {0};
+
+#define MAX_BUFS 250
+struct invoke_bufs
+{
+ adsp_listener_buffer outbufs[MAX_BUFS];
+ adsp_listener_buffer inbufs[MAX_BUFS];
+ int inbufLenReqs[MAX_BUFS];
+ int outbufLenReqs[MAX_BUFS];
+ remote_arg args[2 * MAX_BUFS];
+};
+
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_remotectl_open)(const char *name, uint32 *handle, char *dlStr, int dlerrorLen, int *dlErr) __QAIC_IMPL_ATTRIBUTE
+{
+ struct listener *me = &gMe;
+ return mod_table_open_imp(&me->mt, name, handle, dlStr, dlerrorLen, dlErr);
+}
+
+__QAIC_IMPL_EXPORT int __QAIC_IMPL(apps_remotectl_close)(uint32 handle, char *errStr, int errStrLen, int *dlErr) __QAIC_IMPL_ATTRIBUTE
+{
+ struct listener *me = &gMe;
+ mod_table_close_imp(&me->mt, handle, errStr, errStrLen, dlErr);
+ return 0;
+}
+
+#define RPC_FREEIF(heapid, buf) \
+do {\
+ if(heapid == -1) {\
+ FREEIF(buf);\
+ } else {\
+ if(buf) {\
+ rpcmem_free(buf);\
+ buf = 0;\
+ }\
+ }\
+} while (0)
+
+static __inline void *rpcmem_realloc(int heapid, uint32 flags, void *buf, int oldsize, int size)
+{
+ if (heapid == -1)
+ {
+ return REALLOC(buf, size);
+ }
+ else
+ {
+ void *bufnew = rpcmem_alloc(heapid, flags, size);
+ if (buf && bufnew)
+ {
+ memmove(bufnew, buf, oldsize);
+ rpcmem_free(buf);
+ }
+ return bufnew;
+ }
+}
+
+
+extern int adsp_current_process_exit(void);
+static void *listener(void *arg)
+{
+ struct listener *me = (struct listener *)arg;
+ int numOutBufs = 0;
+ int nErr = 0;
+ adsp_listener_invoke_ctx ctx = 0;
+ struct invoke_bufs *bufs = 0;
+ boolean bNeedMore;
+ int result = -1;
+ adsp_listener_remote_handle handle;
+ uint32 sc, ii, inBufsAllocated = 0;
+ const char *eheap = getenv("ADSP_LISTENER_HEAP_ID");
+ int heapid = eheap == 0 ? -1 : atoi(eheap);
+ const char *eflags = getenv("ADSP_LISTENER_HEAP_FLAGS");
+ uint32 flags = eflags == 0 ? 0 : atoi(eflags);
+ eventfd_t event = 0xff;
+
+ VERIFY_EPRINTF("listener using ion heap: %d\n", heapid);
+
+ VERIFY(0 != (bufs = rpcmem_realloc(heapid, flags, 0, 0, sizeof(*bufs))));
+ memset(bufs, 0, sizeof(*bufs));
+
+ do
+ {
+invoke:
+ bNeedMore = FALSE;
+ sc = 0xffffffff;
+ if (result != 0)
+ {
+ numOutBufs = 0;
+ }
+ nErr = __QAIC_HEADER(adsp_listener_next_invoke)(
+ ctx, result, bufs->outbufs, numOutBufs, &ctx,
+ &handle, &sc, bufs->inbufs, inBufsAllocated,
+ bufs->inbufLenReqs, MAX_BUFS, bufs->outbufLenReqs, MAX_BUFS);
+ if (nErr)
+ {
+ VERIFY_EPRINTF("listener protocol failure %d\n", nErr);
+ VERIFY(0 == (nErr = __QAIC_HEADER(adsp_listener_next_invoke)(
+ ctx, nErr, 0, 0, &ctx,
+ &handle, &sc, bufs->inbufs, inBufsAllocated,
+ bufs->inbufLenReqs, MAX_BUFS, bufs->outbufLenReqs, MAX_BUFS)));
+ }
+
+ if (MAX_BUFS < REMOTE_SCALARS_INBUFS(sc) || MAX_BUFS < REMOTE_SCALARS_OUTBUFS(sc))
+ {
+ result = - 8;
+ goto invoke;
+ }
+ for (ii = 0; ii < REMOTE_SCALARS_INBUFS(sc); ++ii)
+ {
+ if (bufs->inbufs[ii].dataLen < bufs->inbufLenReqs[ii])
+ {
+ if (0 != bufs->inbufLenReqs[ii])
+ {
+ bufs->inbufs[ii].data = rpcmem_realloc(heapid, flags, bufs->inbufs[ii].data, bufs->inbufs[ii].dataLen, bufs->inbufLenReqs[ii]);
+ if (0 == bufs->inbufs[ii].data)
+ {
+ bufs->inbufs[ii].dataLen = 0;
+ result = -8;
+ goto invoke;
+ }
+ }
+ bufs->inbufs[ii].dataLen = bufs->inbufLenReqs[ii];
+ inBufsAllocated = STD_MAX(inBufsAllocated, ii + 1);
+ bNeedMore = TRUE;
+ }
+ bufs->args[ii].buf.pv = bufs->inbufs[ii].data;
+ bufs->args[ii].buf.nLen = bufs->inbufLenReqs[ii];
+ }
+ for (ii = 0; ii < REMOTE_SCALARS_OUTBUFS(sc); ++ii)
+ {
+ if (bufs->outbufs[ii].dataLen < bufs->outbufLenReqs[ii])
+ {
+ if (0 != bufs->outbufLenReqs[ii])
+ {
+ bufs->outbufs[ii].data = rpcmem_realloc(heapid, flags, bufs->outbufs[ii].data, bufs->outbufs[ii].dataLen, bufs->outbufLenReqs[ii]);
+ if (0 == bufs->outbufs[ii].data)
+ {
+ result = -8;
+ goto invoke;
+ }
+ }
+ bufs->outbufs[ii].dataLen = bufs->outbufLenReqs[ii];
+ }
+ bufs->args[ii + REMOTE_SCALARS_INBUFS(sc)].buf.pv = bufs->outbufs[ii].data;
+ bufs->args[ii + REMOTE_SCALARS_INBUFS(sc)].buf.nLen = bufs->outbufLenReqs[ii];
+ }
+ numOutBufs = REMOTE_SCALARS_OUTBUFS(sc);
+ if (bNeedMore)
+ {
+ assert(inBufsAllocated >= REMOTE_SCALARS_INBUFS(sc));
+ if (0 != (result = __QAIC_HEADER(adsp_listener_invoke_get_in_bufs)(ctx, bufs->inbufs,
+ REMOTE_SCALARS_INBUFS(sc))))
+ {
+ VERIFY_EPRINTF("adsp_listener_invoke_get_in_bufs failed %d\n", result);
+ goto invoke;
+ }
+ }
+
+ result = mod_table_handle_invoke(&me->mt, handle, sc, bufs->args);
+ }
+ while (1);
+bail:
+ for (ii = 0; ii < MAX_BUFS && bufs; ++ii)
+ {
+ RPC_FREEIF(heapid, bufs->outbufs[ii].data);
+ RPC_FREEIF(heapid, bufs->inbufs[ii].data);
+ }
+ RPC_FREEIF(heapid, bufs);
+ if (nErr)
+ {
+ VERIFY_EPRINTF("listener thread exiting with code %d\n", nErr);
+ if (0 != adsp_current_process_exit())
+ {
+ VERIFY_EPRINTF("listener thread failed to cleanly shutdown. This is ok durring process exit.\n");
+ }
+ }
+ eventfd_write(me->eventfd, event);
+ return (void *)(uintptr_t)nErr;
+}
+
+static int listener_start_thread(struct listener *me)
+{
+ return pthread_create(&me->thread, 0, listener, (void *)me);
+}
+
+static void *listener2(void *arg)
+{
+ struct listener *me = (struct listener *)arg;
+ int nErr = 0;
+ adsp_listener_invoke_ctx ctx = 0;
+ uint8 *outBufs = 0;
+ int outBufsLen = 0, outBufsCapacity = 0;
+ uint8 *inBufs = 0;
+ int inBufsLen = 0, inBufsLenReq = 0;
+ int result = -1;
+ adsp_listener_remote_handle handle = -1;
+ uint32 sc = 0;
+ const char *eheap = getenv("ADSP_LISTENER_HEAP_ID");
+ int heapid = eheap == 0 ? -1 : atoi(eheap);
+ const char *eflags = getenv("ADSP_LISTENER_HEAP_FLAGS");
+ uint32 flags = eflags == 0 ? 0 : atoi(eflags);
+ remote_arg args[512];
+ struct sbuf buf;
+ eventfd_t event = 0xff;
+
+ memset(args, 0, sizeof(args));
+ VERIFY_IPRINTF("listener using ion heap: %d\n", heapid);
+
+ do
+ {
+invoke:
+ sc = 0xffffffff;
+ if (result != 0)
+ {
+ outBufsLen = 0;
+ }
+ nErr = __QAIC_HEADER(adsp_listener_next2)(
+ ctx, result, outBufs, outBufsLen,
+ &ctx, &handle, &sc, inBufs, inBufsLen, &inBufsLenReq);
+ if (nErr)
+ {
+ VERIFY_EPRINTF("listener protocol failure %d\n", nErr);
+ VERIFY(0 == (nErr = __QAIC_HEADER(adsp_listener_next2)(
+ ctx, nErr, 0, 0,
+ &ctx, &handle, &sc, inBufs, inBufsLen,
+ &inBufsLenReq)));
+ }
+ if (inBufsLenReq > inBufsLen)
+ {
+ void *buf;
+ int req;
+ int oldLen = inBufsLen;
+ int size = _SBUF_ALIGN(inBufsLenReq, 8);
+ if (0 == (buf = rpcmem_realloc(heapid, flags, inBufs, inBufsLen, size)))
+ {
+ result = -10;
+ VERIFY_EPRINTF("rpcmem_realloc failed");
+ goto invoke;
+ }
+ inBufs = buf;
+ inBufsLen = size;
+ if (0 != (result = __QAIC_HEADER(adsp_listener_get_in_bufs2)(ctx, oldLen,
+ inBufs + oldLen,
+ inBufsLen - oldLen, &req)))
+ {
+ VERIFY_EPRINTF("adsp_listener_invoke_get_in_bufs2 failed %d", result);
+ goto invoke;
+ }
+ if (req > inBufsLen)
+ {
+ result = -13;
+ VERIFY_EPRINTF("adsp_listener_invoke_get_in_bufs2 failed %d", result);
+ goto invoke;
+ }
+ }
+ if (REMOTE_SCALARS_INHANDLES(sc) + REMOTE_SCALARS_OUTHANDLES(sc) > 0)
+ {
+ result = -9;
+ goto invoke;
+ }
+
+ sbuf_init(&buf, 0, inBufs, inBufsLen);
+ unpack_in_bufs(&buf, args, REMOTE_SCALARS_INBUFS(sc));
+ unpack_out_lens(&buf, args + REMOTE_SCALARS_INBUFS(sc), REMOTE_SCALARS_OUTBUFS(sc));
+
+ sbuf_init(&buf, 0, 0, 0);
+ pack_out_bufs(&buf, args + REMOTE_SCALARS_INBUFS(sc), REMOTE_SCALARS_OUTBUFS(sc));
+ outBufsLen = sbuf_needed(&buf);
+
+ if (outBufsLen > outBufsCapacity)
+ {
+ void *buf;
+ int size = _SBUF_ALIGN(outBufsLen, 8);
+ if (0 == (buf = rpcmem_realloc(heapid, flags, outBufs, outBufsCapacity, size)))
+ {
+ result = -11;
+ VERIFY_EPRINTF("listener rpcmem_realloc failed");
+ goto invoke;
+ }
+ outBufs = buf;
+ outBufsLen = size;
+ outBufsCapacity = size;
+ }
+ sbuf_init(&buf, 0, outBufs, outBufsLen);
+ pack_out_bufs(&buf, args + REMOTE_SCALARS_INBUFS(sc), REMOTE_SCALARS_OUTBUFS(sc));
+
+ result = mod_table_handle_invoke(&me->mt, handle, sc, args);
+ }
+ while (1);
+bail:
+ RPC_FREEIF(heapid, outBufs);
+ RPC_FREEIF(heapid, inBufs);
+ if (nErr)
+ {
+ VERIFY_EPRINTF("listener thread exiting with code %d\n", nErr);
+ if (0 != adsp_current_process_exit())
+ {
+ VERIFY_EPRINTF("listener thread failed to cleanly shutdown. This is ok durring process exit.\n");
+ }
+ }
+ eventfd_write(me->eventfd, event);
+ return (void *)(uintptr_t)nErr;
+}
+static int listener_start_thread2(struct listener *me)
+{
+ return pthread_create(&me->thread, 0, listener2, (void *)me);
+}
+
+extern int apps_console_skel_invoke(uint32 _sc, remote_arg *_pra);
+extern int apps_remotectl_skel_invoke(uint32 _sc, remote_arg *_pra);
+extern int apps_std_skel_invoke(uint32 _sc, remote_arg *_pra);
+extern int apps_mem_skel_invoke(uint32 _sc, remote_arg *_pra);
+
+#include "adsp_listener_stub.c"
+
+int listener_init(void)
+{
+ int nErr = 0;
+ struct listener *me = &gMe;
+ VERIFY(0 == mod_table_ctor_imp(&me->mt));
+ VERIFY(0 == mod_table_register_const_handle_imp(&me->mt, 0, "apps_remotectl", apps_remotectl_skel_invoke));
+ VERIFY(0 == mod_table_register_static_imp(&me->mt, "apps_std", apps_std_skel_invoke));
+ VERIFY(0 == mod_table_register_static_imp(&me->mt, "apps_mem", apps_mem_skel_invoke));
+ VERIFY(-1 != (me->eventfd = eventfd(0, 0)));
+ nErr = __QAIC_HEADER(adsp_listener_init2)();
+ if (AEE_EUNSUPPORTED == nErr)
+ {
+ VERIFY_EPRINTF("listener2 initialization error falling back to listener1 %d\n", nErr);
+ VERIFY(0 == (nErr = __QAIC_HEADER(adsp_listener_init)()));
+ VERIFY(0 == listener_start_thread(me));
+ }
+ else if (0 == nErr)
+ {
+ VERIFY_IPRINTF("listener2 initialized\n");
+ VERIFY(0 == listener_start_thread2(me));
+ }
+bail:
+ if (nErr)
+ {
+ VERIFY_EPRINTF("listener initialization error %d\n", nErr);
+ }
+ return nErr;
+}
+
+void listener_deinit(void)
+{
+ struct listener *me = &gMe;
+ VERIFY_IPRINTF("listener joining to exit");
+ pthread_join(me->thread, 0);
+ VERIFY_IPRINTF("listener joined");
+ mod_table_dtor_imp(&me->mt);
+ close(me->eventfd);
+ me->eventfd = -1;
+}
+
+int listener_geteventfd(int *fd)
+{
+ struct listener *me = &gMe;
+ int nErr = 0;
+ VERIFY(-1 != me->eventfd);
+ *fd = me->eventfd;
+bail:
+ return nErr;
+}
+
diff --git a/src/remotectl_stub.c b/src/remotectl_stub.c
new file mode 100644
index 0000000..3b4ee21
--- /dev/null
+++ b/src/remotectl_stub.c
@@ -0,0 +1,639 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef _REMOTECTL_STUB_H
+#define _REMOTECTL_STUB_H
+#include "remotectl.h"
+#include "remote.h"
+#include <string.h>
+#ifndef ALLOCATOR_H
+#define ALLOCATOR_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef struct _heap _heap;
+struct _heap
+{
+ _heap *pPrev;
+ const char *loc;
+ uint64_t buf;
+};
+
+typedef struct allocator
+{
+ _heap *pheap;
+ uint8_t *stack;
+ uint8_t *stackEnd;
+ int nSize;
+} allocator;
+
+static __inline int _heap_alloc(_heap **ppa, const char *loc, int size, void **ppbuf)
+{
+ _heap *pn = 0;
+ pn = malloc(size + sizeof(_heap) - sizeof(uint64_t));
+ if (pn != 0)
+ {
+ pn->pPrev = *ppa;
+ pn->loc = loc;
+ *ppa = pn;
+ *ppbuf = (void *) & (pn->buf);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+#define _ALIGN_SIZE(x, y) (((x) + (y-1)) & ~(y-1))
+
+
+static __inline int allocator_alloc(allocator *me,
+ const char *loc,
+ int size,
+ unsigned int al,
+ void **ppbuf)
+{
+ if (size < 0)
+ {
+ return -1;
+ }
+ else if (size == 0)
+ {
+ *ppbuf = 0;
+ return 0;
+ }
+ if ((_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size) < (uintptr_t)me->stack + me->nSize)
+ {
+ *ppbuf = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al);
+ me->stackEnd = (uint8_t *)_ALIGN_SIZE((uintptr_t)me->stackEnd, al) + size;
+ return 0;
+ }
+ else
+ {
+ return _heap_alloc(&me->pheap, loc, size, ppbuf);
+ }
+}
+
+
+static __inline void allocator_deinit(allocator *me)
+{
+ _heap *pa = me->pheap;
+ while (pa != 0)
+ {
+ _heap *pn = pa;
+ const char *loc = pn->loc;
+ (void)loc;
+ pa = pn->pPrev;
+ free(pn);
+ }
+}
+
+static __inline void allocator_init(allocator *me, uint8_t *stack, int stackSize)
+{
+ me->stack = stack;
+ me->stackEnd = stack + stackSize;
+ me->nSize = stackSize;
+ me->pheap = 0;
+}
+
+
+#endif // ALLOCATOR_H
+
+#ifndef SLIM_H
+#define SLIM_H
+
+#include <stdint.h>
+
+//a C data structure for the idl types that can be used to implement
+//static and dynamic language bindings fairly efficiently.
+//
+//the goal is to have a minimal ROM and RAM footprint and without
+//doing too many allocations. A good way to package these things seemed
+//like the module boundary, so all the idls within one module can share
+//all the type references.
+
+
+#define PARAMETER_IN 0x0
+#define PARAMETER_OUT 0x1
+#define PARAMETER_INOUT 0x2
+#define PARAMETER_ROUT 0x3
+#define PARAMETER_INROUT 0x4
+
+//the types that we get from idl
+#define TYPE_OBJECT 0x0
+#define TYPE_INTERFACE 0x1
+#define TYPE_PRIMITIVE 0x2
+#define TYPE_ENUM 0x3
+#define TYPE_STRING 0x4
+#define TYPE_WSTRING 0x5
+#define TYPE_STRUCTURE 0x6
+#define TYPE_UNION 0x7
+#define TYPE_ARRAY 0x8
+#define TYPE_SEQUENCE 0x9
+
+//these require the pack/unpack to recurse
+//so it's a hint to those languages that can optimize in cases where
+//recursion isn't necessary.
+#define TYPE_COMPLEX_STRUCTURE (0x10 | TYPE_STRUCTURE)
+#define TYPE_COMPLEX_UNION (0x10 | TYPE_UNION)
+#define TYPE_COMPLEX_ARRAY (0x10 | TYPE_ARRAY)
+#define TYPE_COMPLEX_SEQUENCE (0x10 | TYPE_SEQUENCE)
+
+
+typedef struct Type Type;
+
+#define INHERIT_TYPE\
+ int32_t nativeSize; /*in the simple case its the same as wire size and alignment*/\
+ union {\
+ struct {\
+ const uintptr_t p1;\
+ const uintptr_t p2;\
+ } _cast;\
+ struct {\
+ uint32_t iid;\
+ uint32_t bNotNil;\
+ } object;\
+ struct {\
+ const Type *arrayType;\
+ int32_t nItems;\
+ } array;\
+ struct {\
+ const Type *seqType;\
+ int32_t nMaxLen;\
+ } seqSimple; \
+ struct {\
+ uint32_t bFloating;\
+ uint32_t bSigned;\
+ } prim; \
+ const SequenceType* seqComplex;\
+ const UnionType *unionType;\
+ const StructType *structType;\
+ int32_t stringMaxLen;\
+ uint8_t bInterfaceNotNil;\
+ } param;\
+ uint8_t type;\
+ uint8_t nativeAlignment\
+
+typedef struct UnionType UnionType;
+typedef struct StructType StructType;
+typedef struct SequenceType SequenceType;
+struct Type
+{
+ INHERIT_TYPE;
+};
+
+struct SequenceType
+{
+ const Type *seqType;
+ uint32_t nMaxLen;
+ uint32_t inSize;
+ uint32_t routSizePrimIn;
+ uint32_t routSizePrimROut;
+};
+
+//byte offset from the start of the case values for
+//this unions case value array. it MUST be aligned
+//at the alignment requrements for the descriptor
+//
+//if negative it means that the unions cases are
+//simple enumerators, so the value read from the descriptor
+//can be used directly to find the correct case
+typedef union CaseValuePtr CaseValuePtr;
+union CaseValuePtr
+{
+ const uint8_t *value8s;
+ const uint16_t *value16s;
+ const uint32_t *value32s;
+ const uint64_t *value64s;
+};
+
+//these are only used in complex cases
+//so I pulled them out of the type definition as references to make
+//the type smaller
+struct UnionType
+{
+ const Type *descriptor;
+ uint32_t nCases;
+ const CaseValuePtr caseValues;
+ const Type *const *cases;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+ uint8_t inCaseAlignment;
+ uint8_t routCaseAlignmentPrimIn;
+ uint8_t routCaseAlignmentPrimROut;
+ uint8_t nativeCaseAlignment;
+ uint8_t bDefaultCase;
+};
+
+struct StructType
+{
+ uint32_t nMembers;
+ const Type *const *members;
+ int32_t inSize;
+ int32_t routSizePrimIn;
+ int32_t routSizePrimROut;
+ uint8_t inAlignment;
+ uint8_t routAlignmentPrimIn;
+ uint8_t routAlignmentPrimROut;
+};
+
+typedef struct Parameter Parameter;
+struct Parameter
+{
+ INHERIT_TYPE;
+ uint8_t mode;
+ uint8_t bNotNil;
+};
+
+#define SLIM_SCALARS_IS_DYNAMIC(u) (((u) & 0x00ffffff) == 0x00ffffff)
+
+typedef struct Method Method;
+struct Method
+{
+ uint32_t uScalars; //no method index
+ int32_t primInSize;
+ int32_t primROutSize;
+ int maxArgs;
+ int numParams;
+ const Parameter *const *params;
+ uint8_t primInAlignment;
+ uint8_t primROutAlignment;
+};
+
+typedef struct Interface Interface;
+
+struct Interface
+{
+ int nMethods;
+ const Method *const *methodArray;
+ int nIIds;
+ const uint32_t *iids;
+ const uint16_t *methodStringArray;
+ const uint16_t *methodStrings;
+ const char *strings;
+};
+
+
+#endif //SLIM_H
+
+
+#ifndef _REMOTECTL_SLIM_H
+#define _REMOTECTL_SLIM_H
+#include "remote.h"
+#include <stdint.h>
+
+#ifndef __QAIC_SLIM
+#define __QAIC_SLIM(ff) ff
+#endif
+#ifndef __QAIC_SLIM_EXPORT
+#define __QAIC_SLIM_EXPORT
+#endif
+
+static const Type types[1];
+static const Type types[1] = {{0x1, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x1}};
+static const Parameter parameters[5] = {{0x8, {{(const uintptr_t)0x0, 0}}, 4, 0x4, 0, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)1}}, 2, 0x4, 3, 0}, {0x8, {{(const uintptr_t) &(types[0]), (const uintptr_t)0x0}}, 9, 0x4, 3, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)1}}, 2, 0x4, 0, 0}, {0x4, {{(const uintptr_t)0, (const uintptr_t)0}}, 2, 0x4, 0, 0}};
+static const Parameter *const parameterArrays[9] = {(&(parameters[0])), (&(parameters[1])), (&(parameters[2])), (&(parameters[1])), (&(parameters[3])), (&(parameters[2])), (&(parameters[1])), (&(parameters[4])), (&(parameters[4]))};
+static const Method methods[3] = {{REMOTE_SCALARS_MAKEX(0, 0, 0x2, 0x2, 0x0, 0x0), 0x8, 0x8, 6, 4, (&(parameterArrays[0])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x2, 0x0, 0x0), 0x8, 0x4, 5, 3, (&(parameterArrays[4])), 0x4, 0x4}, {REMOTE_SCALARS_MAKEX(0, 0, 0x1, 0x0, 0x0, 0x0), 0x8, 0x0, 2, 2, (&(parameterArrays[7])), 0x4, 0x0}};
+static const Method *const methodArrays[3] = {&(methods[0]), &(methods[1]), &(methods[2])};
+static const char strings[60] = "grow_heap\0phyAddr\0dlerror\0handle\0nSize\0close\0nErr\0name\0open\0";
+static const uint16_t methodStrings[12] = {55, 50, 26, 18, 45, 39, 26, 18, 45, 0, 10, 33};
+static const uint16_t methodStringsArrays[3] = {0, 5, 9};
+__QAIC_SLIM_EXPORT const Interface __QAIC_SLIM(remotectl_slim) = {3, &(methodArrays[0]), 0, 0, &(methodStringsArrays [0]), methodStrings, strings};
+#endif //_REMOTECTL_SLIM_H
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wpragmas"
+#pragma GCC diagnostic ignored "-Wuninitialized"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#ifndef __QAIC_REMOTE
+#define __QAIC_REMOTE(ff) ff
+#endif //__QAIC_REMOTE
+
+#ifndef __QAIC_HEADER
+#define __QAIC_HEADER(ff) ff
+#endif //__QAIC_HEADER
+
+#ifndef __QAIC_HEADER_EXPORT
+#define __QAIC_HEADER_EXPORT
+#endif // __QAIC_HEADER_EXPORT
+
+#ifndef __QAIC_HEADER_ATTRIBUTE
+#define __QAIC_HEADER_ATTRIBUTE
+#endif // __QAIC_HEADER_ATTRIBUTE
+
+#ifndef __QAIC_IMPL
+#define __QAIC_IMPL(ff) ff
+#endif //__QAIC_IMPL
+
+#ifndef __QAIC_IMPL_EXPORT
+#define __QAIC_IMPL_EXPORT
+#endif // __QAIC_IMPL_EXPORT
+
+#ifndef __QAIC_IMPL_ATTRIBUTE
+#define __QAIC_IMPL_ATTRIBUTE
+#endif // __QAIC_IMPL_ATTRIBUTE
+
+#ifndef __QAIC_STUB
+#define __QAIC_STUB(ff) ff
+#endif //__QAIC_STUB
+
+#ifndef __QAIC_STUB_EXPORT
+#define __QAIC_STUB_EXPORT
+#endif // __QAIC_STUB_EXPORT
+
+#ifndef __QAIC_STUB_ATTRIBUTE
+#define __QAIC_STUB_ATTRIBUTE
+#endif // __QAIC_STUB_ATTRIBUTE
+
+#ifndef __QAIC_SKEL
+#define __QAIC_SKEL(ff) ff
+#endif //__QAIC_SKEL__
+
+#ifndef __QAIC_SKEL_EXPORT
+#define __QAIC_SKEL_EXPORT
+#endif // __QAIC_SKEL_EXPORT
+
+#ifndef __QAIC_SKEL_ATTRIBUTE
+#define __QAIC_SKEL_ATTRIBUTE
+#endif // __QAIC_SKEL_ATTRIBUTE
+
+#ifdef __QAIC_DEBUG__
+#ifndef __QAIC_DBG_PRINTF__
+#define __QAIC_DBG_PRINTF__( ee ) do { printf ee ; } while(0)
+#endif
+#else
+#define __QAIC_DBG_PRINTF__( ee ) (void)0
+#endif
+
+
+#define _OFFSET(src, sof) ((void*)(((char*)(src)) + (sof)))
+
+#define _COPY(dst, dof, src, sof, sz) \
+ do {\
+ struct __copy { \
+ char ar[sz]; \
+ };\
+ *(struct __copy*)_OFFSET(dst, dof) = *(struct __copy*)_OFFSET(src, sof);\
+ } while (0)
+
+#define _ASSIGN(dst, src, sof) \
+ do {\
+ dst = OFFSET(src, sof); \
+ } while (0)
+
+#define _STD_STRLEN_IF(str) (str == 0 ? 0 : strlen(str))
+
+#include "AEEStdErr.h"
+
+#define _TRY(ee, func) \
+ do { \
+ if (AEE_SUCCESS != ((ee) = func)) {\
+ __QAIC_DBG_PRINTF__((__FILE_LINE__ ": error: %d\n", (int)(ee)));\
+ goto ee##bail;\
+ } \
+ } while (0)
+
+#define _CATCH(exception) exception##bail: if (exception != AEE_SUCCESS)
+
+#define _ASSERT(nErr, ff) _TRY(nErr, 0 == (ff) ? AEE_EBADPARM : AEE_SUCCESS)
+
+#ifdef __QAIC_DEBUG__
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, allocator_alloc(pal, __FILE_LINE__, size, alignment, (void**)&pv))
+#else
+#define _ALLOCATE(nErr, pal, size, alignment, pv) _TRY(nErr, allocator_alloc(pal, 0, size, alignment, (void**)&pv))
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _const_remotectl_handle
+#define _const_remotectl_handle ((remote_handle)-1)
+#endif //_const_remotectl_handle
+
+static void _remotectl_pls_dtor(void *data)
+{
+ remote_handle *ph = (remote_handle *)data;
+ if (_const_remotectl_handle != *ph)
+ {
+ (void)__QAIC_REMOTE(remote_handle_close)(*ph);
+ *ph = _const_remotectl_handle;
+ }
+}
+
+static int _remotectl_pls_ctor(void *ctx, void *data)
+{
+ remote_handle *ph = (remote_handle *)data;
+ *ph = _const_remotectl_handle;
+ if (*ph == (remote_handle) - 1)
+ {
+ return __QAIC_REMOTE(remote_handle_open)((const char *)ctx, ph);
+ }
+ return 0;
+}
+
+#if (defined __qdsp6__) || (defined __hexagon__)
+#pragma weak adsp_pls_add_lookup
+extern int adsp_pls_add_lookup(uint32_t type, uint32_t key, int size, int (*ctor)(void *ctx, void *data), void *ctx, void (*dtor)(void *ctx), void **ppo);
+#pragma weak HAP_pls_add_lookup
+extern int HAP_pls_add_lookup(uint32_t type, uint32_t key, int size, int (*ctor)(void *ctx, void *data), void *ctx, void (*dtor)(void *ctx), void **ppo);
+
+__QAIC_STUB_EXPORT remote_handle _remotectl_handle(void)
+{
+ remote_handle *ph;
+ if (adsp_pls_add_lookup)
+ {
+ if (0 == adsp_pls_add_lookup((uint32_t)_remotectl_handle, 0, sizeof(*ph), _remotectl_pls_ctor, "remotectl", _remotectl_pls_dtor, (void **)&ph))
+ {
+ return *ph;
+ }
+ return (remote_handle) - 1;
+ }
+ else if (HAP_pls_add_lookup)
+ {
+ if (0 == HAP_pls_add_lookup((uint32_t)_remotectl_handle, 0, sizeof(*ph), _remotectl_pls_ctor, "remotectl", _remotectl_pls_dtor, (void **)&ph))
+ {
+ return *ph;
+ }
+ return (remote_handle) - 1;
+ }
+ return (remote_handle) - 1;
+}
+
+#else //__qdsp6__ || __hexagon__
+
+uint32_t _remotectl_atomic_CompareAndExchange(uint32_t *volatile puDest, uint32_t uExchange, uint32_t uCompare);
+
+#ifdef _WIN32
+#include "Windows.h"
+uint32_t _remotectl_atomic_CompareAndExchange(uint32_t *volatile puDest, uint32_t uExchange, uint32_t uCompare)
+{
+ return (uint32_t)InterlockedCompareExchange((volatile LONG *)puDest, (LONG)uExchange, (LONG)uCompare);
+}
+#elif __GNUC__
+uint32_t _remotectl_atomic_CompareAndExchange(uint32_t *volatile puDest, uint32_t uExchange, uint32_t uCompare)
+{
+ return __sync_val_compare_and_swap(puDest, uCompare, uExchange);
+}
+#endif //_WIN32
+
+
+__QAIC_STUB_EXPORT remote_handle _remotectl_handle(void)
+{
+ static remote_handle handle = _const_remotectl_handle;
+ if ((remote_handle) - 1 != handle)
+ {
+ return handle;
+ }
+ else
+ {
+ remote_handle tmp;
+ int nErr = _remotectl_pls_ctor("remotectl", (void *)&tmp);
+ if (nErr)
+ {
+ return (remote_handle) - 1;
+ }
+ if (((remote_handle) - 1 != handle) || ((remote_handle) - 1 != (remote_handle)_remotectl_atomic_CompareAndExchange((uint32_t *)&handle, (uint32_t)tmp, (uint32_t) - 1)))
+ {
+ _remotectl_pls_dtor(&tmp);
+ }
+ return handle;
+ }
+}
+
+#endif //__qdsp6__
+
+__QAIC_STUB_EXPORT int __QAIC_STUB(remotectl_skel_invoke)(uint32_t _sc, remote_arg *_pra) __QAIC_STUB_ATTRIBUTE
+{
+ return __QAIC_REMOTE(remote_handle_invoke)(_remotectl_handle(), _sc, _pra);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+static __inline int _stub_method(remote_handle _handle, uint32_t _mid, char *_in0[1], uint32_t _rout1[1], char *_rout2[1], uint32_t _rout2Len[1], uint32_t _rout3[1])
+{
+ uint32_t _in0Len[1];
+ int _numIn[1];
+ remote_arg _pra[4];
+ uint32_t _primIn[2];
+ uint32_t _primROut[2];
+ remote_arg *_praIn;
+ remote_arg *_praROut;
+ int _nErr = 0;
+ _numIn[0] = 1;
+ _pra[0].buf.pv = (void *)_primIn;
+ _pra[0].buf.nLen = sizeof(_primIn);
+ _pra[(_numIn[0] + 1)].buf.pv = (void *)_primROut;
+ _pra[(_numIn[0] + 1)].buf.nLen = sizeof(_primROut);
+ _in0Len[0] = (1 + strlen(_in0[0]));
+ _COPY(_primIn, 0, _in0Len, 0, 4);
+ _praIn = (_pra + 1);
+ _praIn[0].buf.pv = _in0[0];
+ _praIn[0].buf.nLen = (1 * _in0Len[0]);
+ _COPY(_primIn, 4, _rout2Len, 0, 4);
+ _praROut = (_praIn + _numIn[0] + 1);
+ _praROut[0].buf.pv = _rout2[0];
+ _praROut[0].buf.nLen = (1 * _rout2Len[0]);
+ _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 2, 2, 0, 0), _pra));
+ _COPY(_rout1, 0, _primROut, 0, 4);
+ _COPY(_rout3, 0, _primROut, 4, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(remotectl_open)(const char *name, int *handle, char *dlerror, int dlerrorLen, int *nErr) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 0;
+ return _stub_method(_remotectl_handle(), _mid, (char **)&name, (uint32_t *)handle, (char **)&dlerror, (uint32_t *)&dlerrorLen, (uint32_t *)nErr);
+}
+static __inline int _stub_method_1(remote_handle _handle, uint32_t _mid, uint32_t _in0[1], char *_rout1[1], uint32_t _rout1Len[1], uint32_t _rout2[1])
+{
+ int _numIn[1];
+ remote_arg _pra[3];
+ uint32_t _primIn[2];
+ uint32_t _primROut[1];
+ remote_arg *_praIn;
+ remote_arg *_praROut;
+ int _nErr = 0;
+ _numIn[0] = 0;
+ _pra[0].buf.pv = (void *)_primIn;
+ _pra[0].buf.nLen = sizeof(_primIn);
+ _pra[(_numIn[0] + 1)].buf.pv = (void *)_primROut;
+ _pra[(_numIn[0] + 1)].buf.nLen = sizeof(_primROut);
+ _COPY(_primIn, 0, _in0, 0, 4);
+ _COPY(_primIn, 4, _rout1Len, 0, 4);
+ _praIn = (_pra + 1);
+ _praROut = (_praIn + _numIn[0] + 1);
+ _praROut[0].buf.pv = _rout1[0];
+ _praROut[0].buf.nLen = (1 * _rout1Len[0]);
+ _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 1, 2, 0, 0), _pra));
+ _COPY(_rout2, 0, _primROut, 0, 4);
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(remotectl_close)(int handle, char *dlerror, int dlerrorLen, int *nErr) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 1;
+ return _stub_method_1(_remotectl_handle(), _mid, (uint32_t *)&handle, (char **)&dlerror, (uint32_t *)&dlerrorLen, (uint32_t *)nErr);
+}
+static __inline int _stub_method_2(remote_handle _handle, uint32_t _mid, uint32_t _in0[1], uint32_t _in1[1])
+{
+ remote_arg _pra[1];
+ uint32_t _primIn[2];
+ int _nErr = 0;
+ _pra[0].buf.pv = (void *)_primIn;
+ _pra[0].buf.nLen = sizeof(_primIn);
+ _COPY(_primIn, 0, _in0, 0, 4);
+ _COPY(_primIn, 4, _in1, 0, 4);
+ _TRY(_nErr, __QAIC_REMOTE(remote_handle_invoke)(_handle, REMOTE_SCALARS_MAKEX(0, _mid, 1, 0, 0, 0), _pra));
+ _CATCH(_nErr) {}
+ return _nErr;
+}
+__QAIC_STUB_EXPORT int __QAIC_STUB(remotectl_grow_heap)(uint32 phyAddr, uint32 nSize) __QAIC_STUB_ATTRIBUTE
+{
+ uint32_t _mid = 2;
+ return _stub_method_2(_remotectl_handle(), _mid, (uint32_t *)&phyAddr, (uint32_t *)&nSize);
+}
+#ifdef __cplusplus
+}
+#endif
+#endif //_REMOTECTL_STUB_H
diff --git a/src/rpcmem.c b/src/rpcmem.c
new file mode 100644
index 0000000..a2504eb
--- /dev/null
+++ b/src/rpcmem.c
@@ -0,0 +1,175 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#include "rpcmem.h"
+#include "verify.h"
+#include "fastrpc_internal.h"
+#include "AEEQList.h"
+#include "AEEstd.h"
+#include "apps_std.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <errno.h>
+
+#define FASTRPC_DEVICE "/dev/fastrpc-adsp"
+
+#define PAGE_SIZE 4096
+#define PAGE_MASK ~((uintptr_t)PAGE_SIZE - 1)
+
+static QList rpclst;
+static pthread_mutex_t rpcmt;
+struct rpc_info
+{
+ QNode qn;
+ void *buf;
+ void *aligned_buf;
+ int size;
+ int fd;
+};
+
+extern int open_dev(int attach);
+static int rpcmem_open_dev()
+{
+ return open_dev(0);
+}
+
+void rpcmem_init()
+{
+ int fd;
+ QList_Ctor(&rpclst);
+ pthread_mutex_init(&rpcmt, 0);
+}
+
+void rpcmem_deinit()
+{
+ pthread_mutex_destroy(&rpcmt);
+}
+
+int rpcmem_to_fd(void *po)
+{
+ struct rpc_info *rinfo, *rfree = 0;
+ QNode *pn, *pnn;
+
+ pthread_mutex_lock(&rpcmt);
+ QLIST_NEXTSAFE_FOR_ALL(&rpclst, pn, pnn)
+ {
+ rinfo = STD_RECOVER_REC(struct rpc_info, qn, pn);
+ if (rinfo->aligned_buf == po)
+ {
+ rfree = rinfo;
+ break;
+ }
+ }
+ pthread_mutex_unlock(&rpcmt);
+
+ if (rfree)
+ return rfree->fd;
+
+ return -1;
+}
+
+void *rpcmem_alloc(int heapid, uint32 flags, int size)
+{
+ struct rpc_info *rinfo;
+ struct fastrpc_alloc_dma_buf buf;
+ int nErr = 0;
+ (void)heapid;
+ (void)flags;
+ int dev = rpcmem_open_dev();
+
+ VERIFY(0 != (rinfo = calloc(1, sizeof(*rinfo))));
+
+ buf.size = size + PAGE_SIZE;
+ buf.fd = -1;
+ buf.flags = 0;
+
+ VERIFY((0 == ioctl(dev, FASTRPC_IOCTL_ALLOC_DMA_BUFF, (unsigned long)&buf)) || errno == ENOTTY);
+ VERIFY(0 != (rinfo->buf = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, buf.fd, 0)));
+ rinfo->fd = buf.fd;
+ rinfo->aligned_buf = (void *)(((uintptr_t)rinfo->buf /*+ PAGE_SIZE*/) & PAGE_MASK);
+ rinfo->aligned_buf = rinfo->buf;
+ rinfo->size = size;
+ pthread_mutex_lock(&rpcmt);
+ QList_AppendNode(&rpclst, &rinfo->qn);
+ pthread_mutex_unlock(&rpcmt);
+
+ return rinfo->aligned_buf;
+bail:
+ if (nErr)
+ {
+ if (rinfo)
+ {
+ if (rinfo->buf)
+ {
+ free(rinfo->buf);
+ }
+ free(rinfo);
+ }
+ }
+ return 0;
+}
+
+void rpcmem_free(void *po)
+{
+ struct rpc_info *rinfo, *rfree = 0;
+ QNode *pn, *pnn;
+ int nErr = 0;
+
+ pthread_mutex_lock(&rpcmt);
+ QLIST_NEXTSAFE_FOR_ALL(&rpclst, pn, pnn)
+ {
+ rinfo = STD_RECOVER_REC(struct rpc_info, qn, pn);
+ if (rinfo->aligned_buf == po)
+ {
+ rfree = rinfo;
+ QNode_Dequeue(&rinfo->qn);
+ break;
+ }
+ }
+ pthread_mutex_unlock(&rpcmt);
+ if (rfree)
+ {
+ int dev = rpcmem_open_dev(0);
+
+ VERIFY((0 == ioctl(dev, FASTRPC_IOCTL_FREE_DMA_BUFF, (unsigned long)&rfree->fd)) || errno == ENOTTY);
+ munmap(rfree->buf, rfree->size);
+ free(rfree);
+ }
+bail:
+ return;
+
+}
diff --git a/src/smath.c b/src/smath.c
new file mode 100644
index 0000000..75d2e71
--- /dev/null
+++ b/src/smath.c
@@ -0,0 +1,56 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#include "AEEStdDef.h"
+#include "AEEsmath.h"
+
+
+static int32 ToInt(int64 a)
+{
+ return (a > MAX_INT32 ? MAX_INT32 :
+ a < MIN_INT32 ? MIN_INT32 :
+ (int32)a);
+}
+
+int smath_Add(int a, int b)
+{
+ return ToInt((int64)a + (int64)b);
+}
+
+int smath_Sub(int a, int b)
+{
+ return ToInt((int64)a - (int64)b);
+}
+
+int smath_Mul(int a, int b)
+{
+ return ToInt((int64)a * (int64)b);
+}
+
diff --git a/src/std.c b/src/std.c
new file mode 100644
index 0000000..276594e
--- /dev/null
+++ b/src/std.c
@@ -0,0 +1,481 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <wchar.h>
+#include <libgen.h>
+#include "AEEstd.h"
+#include "version.h"
+
+
+int std_getversion(char *pcDst, int nDestSize)
+{
+ return std_strlcpy(pcDst, VERSION_STRING, nDestSize);
+}
+
+
+char std_tolower(char c)
+{
+ return tolower(c);
+}
+
+char std_toupper(char c)
+{
+ return toupper(c);
+}
+
+
+static __inline int x_casecmp(unsigned char c1, unsigned char c2)
+{
+ int diff = c1 - c2;
+ if (c1 >= 'A' && c1 <= 'Z')
+ {
+ diff += 32;
+ }
+ if (c2 >= 'A' && c2 <= 'Z')
+ {
+ diff -= 32;
+ }
+ return diff;
+}
+
+
+int std_strlen(const char *sStart)
+{
+ return strlen(sStart);
+}
+
+int std_strncmp(const char *s1, const char *s2, int n)
+{
+ return strncmp(s1, s2, n);
+}
+
+int std_strcmp(const char *s1, const char *s2)
+{
+ return strcmp(s1, s2);
+}
+
+int std_strnicmp(const char *s1, const char *s2, int n)
+{
+ return strncasecmp(s1, s2, n);
+}
+
+int std_stricmp(const char *s1, const char *s2)
+{
+ return std_strnicmp(s1, s2, MAX_INT32);
+}
+
+int std_strlcpy(char *pcDst, const char *cpszSrc, int nDestSize)
+{
+ int nLen = std_strlen(cpszSrc);
+
+ if (0 < nDestSize)
+ {
+ int n;
+
+ n = STD_MIN(nLen, nDestSize - 1);
+ (void)std_memmove(pcDst, cpszSrc, n);
+
+ pcDst[n] = 0;
+ }
+
+ return nLen;
+}
+
+int std_strlcat(char *pcDst, const char *cpszSrc, int nDestSize)
+{
+ int nLen = 0;
+
+ while ((nLen < nDestSize) && (0 != pcDst[nLen]))
+ {
+ ++nLen;
+ }
+
+ return nLen + std_strlcpy(pcDst + nLen, cpszSrc, nDestSize - nLen);
+}
+
+char *std_strstr(const char *cpszHaystack, const char *cpszNeedle)
+{
+ return strstr(cpszHaystack, cpszNeedle);
+}
+
+
+int std_memcmp(const void *p1, const void *p2, int length)
+{
+ return memcmp(p1, p2, length);
+}
+
+int std_wstrlen(const AECHAR *s)
+{
+ return wcslen((const wchar_t *)s);
+}
+
+
+int std_wstrlcpy(AECHAR *pwcDst, const AECHAR *cpwszSrc, int nDestSize)
+{
+ int nLen = std_wstrlen(cpwszSrc);
+
+ if (0 < nDestSize)
+ {
+ int n;
+
+ n = STD_MIN(nLen, nDestSize - 1);
+ /* call memmove, in case n is larger than 1G */
+ (void)memmove(pwcDst, cpwszSrc, ((size_t)n)*sizeof(AECHAR));
+
+ pwcDst[n] = 0;
+ }
+
+ return nLen;
+}
+
+int std_wstrlcat(AECHAR *pwcDst, const AECHAR *cpwszSrc, int nDestSize)
+{
+ int nLen = 0;
+
+ while ((nLen < nDestSize) && (0 != pwcDst[nLen]))
+ {
+ ++nLen;
+ }
+
+ return nLen + std_wstrlcpy(pwcDst + nLen, cpwszSrc, nDestSize - nLen);
+}
+
+char *std_strchrend(const char *cpsz, char c)
+{
+ while (*cpsz && *cpsz != c)
+ {
+ ++cpsz;
+ }
+ return (char *)cpsz;
+}
+
+char *std_strchr(const char *cpszSrch, int c)
+{
+ return strchr(cpszSrch, c);
+}
+
+void *std_memstr(const char *cpHaystack, const char *cpszNeedle,
+ int nHaystackLen)
+{
+ int nLen = 0;
+
+ /* Handle empty needle string as a special case */
+ if ('\0' == *cpszNeedle)
+ {
+ return (char *)cpHaystack;
+ }
+
+ /* Find the first character of the needle string in the haystack string */
+ while (nLen < nHaystackLen)
+ {
+ if (cpHaystack[nLen] == *cpszNeedle)
+ {
+ /* check if the rest of the string matches */
+ const char *cpNeedle = cpszNeedle;
+ int nRetIndex = nLen;
+ do
+ {
+ if ('\0' == *++cpNeedle)
+ {
+ /* Found a match */
+ return (void *)(cpHaystack + nRetIndex);
+ }
+ nLen++;
+ }
+ while (cpHaystack[nLen] == *cpNeedle);
+ }
+ else
+ {
+ nLen++;
+ }
+ }
+
+ return 0;
+}
+
+void *std_memchrend(const void *p, int c, int nLen)
+{
+ const char *cpc = (const char *)p + nLen;
+ int i = -nLen;
+
+ if (nLen > 0)
+ {
+ do
+ {
+ if (cpc[i] == c)
+ {
+ break;
+ }
+ }
+ while (++i);
+ }
+ return (void *)(cpc + i);
+}
+
+void *std_memchr(const void *s, int c, int n)
+{
+ return memchr(s, c, n);
+}
+
+void *std_memrchr(const void *p, int c, int nLen)
+{
+ const char *cpc = (const char *)p - 1;
+
+ if (nLen > 0)
+ {
+ do
+ {
+ if (cpc[nLen] == c)
+ {
+ return (void *)(cpc + nLen);
+ }
+ }
+ while (--nLen);
+ }
+
+ return 0;
+}
+
+
+char *std_strrchr(const char *cpsz, int c)
+{
+ return std_memrchr(cpsz, c, std_strlen(cpsz) + 1);
+}
+
+
+void *std_memrchrbegin(const void *p, int c, int n)
+{
+ void *pOut = std_memrchr(p, c, n);
+
+ return (pOut ? pOut : (void *)p);
+}
+
+
+/* WARNING: nLen must be >0 */
+
+static char *x_scanbytes(const char *pcBuf, const char *cpszChars,
+ int nLen, unsigned char cStop, boolean bTestEqual)
+{
+ int n;
+ unsigned a[8];
+
+ /* Initialize bit mask based on the input flag that specifies whether
+ we are looking for a character that matches "any" or "none"
+ of the characters in the search string */
+
+#define ENTRY(c) a[((c)&7)] /* c's bit lives here */
+#define SHIFT(c) ((c)>>3) /* c's bit is shifted by this much */
+
+ if (bTestEqual)
+ {
+ std_memset(a, 0, STD_SIZEOF(a));
+ do
+ {
+ ENTRY(cStop) |= (0x80000000U >> SHIFT(cStop));
+ cStop = (unsigned char) * cpszChars++;
+ }
+ while (cStop);
+ }
+ else
+ {
+ std_memset(a, 0xFF, STD_SIZEOF(a));
+
+ while (0 != (cStop = (unsigned char) * cpszChars++))
+ {
+ ENTRY(cStop) ^= (0x80000000U >> SHIFT(cStop));
+ }
+ }
+
+ /* Search buffer */
+
+ pcBuf += nLen;
+ n = -nLen;
+ do
+ {
+ unsigned char uc = (unsigned char)pcBuf[n];
+ /* testing for negative after shift is quicker than comparison */
+ if ((int)(ENTRY(uc) << SHIFT(uc)) < 0)
+ {
+ break;
+ }
+ }
+ while (++n);
+
+ return (char *)(pcBuf + n);
+}
+
+
+void *std_memchrsend(const void *pBuf, const char *cpszChars, int nLen)
+{
+ if (nLen <= 0)
+ {
+ return (void *)pBuf;
+ }
+ if ('\0' == *cpszChars)
+ {
+ return (char *)pBuf + nLen;
+ }
+
+ return x_scanbytes((const char *)pBuf, cpszChars + 1, nLen,
+ (unsigned char) * cpszChars, TRUE);
+}
+
+
+char *std_strchrsend(const char *cpszSrch, const char *cpszChars)
+{
+ return x_scanbytes(cpszSrch, cpszChars, MAX_INT32, '\0', TRUE);
+}
+
+
+char *std_strchrs(const char *cpszSrch, const char *cpszChars)
+{
+ const char *pc = std_strchrsend(cpszSrch, cpszChars);
+
+ return (*pc ? (char *)pc : 0);
+}
+
+
+char *std_striends(const char *cpsz, const char *cpszSuffix)
+{
+ int nOffset = std_strlen(cpsz) - std_strlen(cpszSuffix);
+
+ if ((0 <= nOffset) &&
+ (0 == std_stricmp(cpsz + nOffset, cpszSuffix)))
+ {
+
+ return (char *)(cpsz + nOffset);
+ }
+
+ return 0;
+}
+
+
+char *std_strends(const char *cpsz, const char *cpszSuffix)
+{
+ int nOffset = std_strlen(cpsz) - std_strlen(cpszSuffix);
+
+ if ((0 <= nOffset) &&
+ (0 == std_strcmp(cpsz + nOffset, cpszSuffix)))
+ {
+
+ return (char *)(cpsz + nOffset);
+ }
+
+ return 0;
+}
+
+char *std_strbegins(const char *cpsz, const char *cpszPrefix)
+{
+ for (;;)
+ {
+ if ('\0' == *cpszPrefix)
+ {
+ return (char *)cpsz;
+ }
+
+ if (*cpszPrefix != *cpsz)
+ {
+ return 0;
+ }
+
+ ++cpszPrefix;
+ ++cpsz;
+ }
+ /* not reached */
+}
+
+char *std_stribegins(const char *cpsz, const char *cpszPrefix)
+{
+ for (;;)
+ {
+ if ('\0' == *cpszPrefix)
+ {
+ return (char *)cpsz;
+ }
+
+ if (x_casecmp((unsigned char)*cpszPrefix, (unsigned char)*cpsz))
+ {
+ return 0;
+ }
+
+ ++cpszPrefix;
+ ++cpsz;
+ }
+ /* not reached */
+}
+
+int std_strcspn(const char *cpszSrch, const char *cpszChars)
+{
+ const char *pc = x_scanbytes(cpszSrch, cpszChars, MAX_INT32, '\0', TRUE);
+
+ return (pc - cpszSrch);
+}
+
+int std_strspn(const char *cpszSrch, const char *cpszChars)
+{
+ const char *pc = x_scanbytes(cpszSrch, cpszChars, MAX_INT32, '\0', FALSE);
+
+ return (pc - cpszSrch);
+}
+
+int std_wstrncmp(const AECHAR *s1, const AECHAR *s2, int nLen)
+{
+ return wcsncmp((const wchar_t *)s1, (const wchar_t *)s2, nLen);
+}
+
+int std_wstrcmp(const AECHAR *s1, const AECHAR *s2)
+{
+ return std_wstrncmp(s1, s2, MAX_INT32);
+}
+
+AECHAR *std_wstrchr(const AECHAR *cpwszText, AECHAR ch)
+{
+ return (AECHAR *)(wcschr((const wchar_t *)cpwszText, ch));
+}
+
+AECHAR *std_wstrrchr(const AECHAR *cpwszText, AECHAR ch)
+{
+ const AECHAR *p = 0;
+
+ do
+ {
+ if (*cpwszText == ch)
+ {
+ p = cpwszText;
+ }
+ }
+ while (*cpwszText++ != (AECHAR)0);
+
+ return (AECHAR *)p;
+}
+
diff --git a/src/std_SwapBytes.c b/src/std_SwapBytes.c
new file mode 100644
index 0000000..8a99a89
--- /dev/null
+++ b/src/std_SwapBytes.c
@@ -0,0 +1,214 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#include "AEEstd.h"
+#include "AEEsmath.h"
+
+static int xMinSize(int a, int b)
+{
+ if (b < a)
+ {
+ a = b;
+ }
+ return (a >= 0 ? a : 0);
+}
+
+static void xMoveBytes(byte *pbDest, const byte *pbSrc, int cb)
+{
+ if (pbDest != pbSrc)
+ {
+ (void) std_memmove(pbDest, pbSrc, cb);
+ }
+}
+
+#ifdef AEE_BIGENDIAN
+# define STD_COPY std_CopyBE
+# define STD_COPY_SWAP std_CopyLE
+#else
+# define STD_COPY std_CopyLE
+# define STD_COPY_SWAP std_CopyBE
+#endif
+
+/* This function implements the case
+ where host ordering != target byte ordering. */
+int STD_COPY_SWAP(void *pvDest, int nDestSize,
+ const void *pvSrc, int nSrcSize,
+ const char *pszFields)
+{
+ byte *pbDest = (byte *)pvDest;
+ byte *pbSrc = (byte *)pvSrc;
+ int cbCopied = xMinSize(nDestSize, nSrcSize);
+ const char *pszNextField;
+ int cb, nSize;
+
+ nSize = 0;
+
+ pszNextField = pszFields;
+
+ for (cb = cbCopied; cb > 0; cb -= nSize)
+ {
+ char ch;
+
+ ch = *pszNextField++;
+ if ('\0' == ch)
+ {
+ ch = *pszFields;
+ pszNextField = pszFields + 1;
+ }
+
+ if (ch == 'S')
+ {
+
+ /* S = 2 bytes */
+
+ nSize = 2;
+ if (cb < nSize)
+ {
+ break;
+ }
+ else
+ {
+ byte by = pbSrc[0];
+ pbDest[0] = pbSrc[1];
+ pbDest[1] = by;
+ }
+ }
+ else if (ch == 'L')
+ {
+
+ /* L = 4 bytes */
+
+ nSize = 4;
+ if (cb < nSize)
+ {
+ break;
+ }
+ else
+ {
+ byte by = pbSrc[0];
+ pbDest[0] = pbSrc[3];
+ pbDest[3] = by;
+ by = pbSrc[1];
+ pbDest[1] = pbSrc[2];
+ pbDest[2] = by;
+ }
+ }
+ else if (ch == 'Q')
+ {
+
+ // Q = 8 bytes
+
+ nSize = 8;
+ if (cb < nSize)
+ {
+ break;
+ }
+ else
+ {
+ byte by = pbSrc[0];
+ pbDest[0] = pbSrc[7];
+ pbDest[7] = by;
+ by = pbSrc[1];
+ pbDest[1] = pbSrc[6];
+ pbDest[6] = by;
+ by = pbSrc[2];
+ pbDest[2] = pbSrc[5];
+ pbDest[5] = by;
+ by = pbSrc[3];
+ pbDest[3] = pbSrc[4];
+ pbDest[4] = by;
+ }
+ }
+ else
+ {
+
+ /* None of the above => read decimal and copy without swap */
+
+ if (ch >= '0' && ch <= '9')
+ {
+ nSize = (int)(ch - '0');
+ while ((ch = *pszNextField) >= '0' && ch <= '9')
+ {
+ nSize = nSize * 10 + (int)(ch - '0');
+ ++pszNextField;
+ }
+ /* Check bounds & ensure progress */
+ if (nSize > cb || nSize <= 0)
+ {
+ nSize = cb;
+ }
+ }
+ else
+ {
+ /* Unexpected character: copy rest of data */
+ nSize = cb;
+ }
+
+ xMoveBytes(pbDest, pbSrc, nSize);
+ }
+
+ pbDest += nSize;
+ pbSrc += nSize;
+ }
+
+ if (cb > 0)
+ {
+
+ /* Swap could not be completed: 0 < cb < nSize <= 8 */
+
+ byte byBuf[8];
+
+ /* If entire value is available in source, use swapped version */
+ if (nSrcSize - (pbSrc - (byte *)pvSrc) >= nSize)
+ {
+ int i;
+ for (i = 0; i < cb; ++i)
+ {
+ byBuf[i] = pbSrc[nSize - 1 - i];
+ }
+ pbSrc = byBuf;
+ }
+ std_memmove(pbDest, pbSrc, cb);
+ }
+
+ return cbCopied;
+}
+
+/* This function implements the case
+ where host ordering == target byte order */
+int STD_COPY(void *pvDest, int nDestSize,
+ const void *pvSrc, int nSrcSize,
+ const char *pszFields)
+{
+ int cb = xMinSize(nDestSize, nSrcSize);
+ (void)pszFields;
+ xMoveBytes(pvDest, pvSrc, cb);
+ return cb;
+}
diff --git a/src/std_dtoa.c b/src/std_dtoa.c
new file mode 100644
index 0000000..880f3c6
--- /dev/null
+++ b/src/std_dtoa.c
@@ -0,0 +1,496 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#include "AEEStdDef.h"
+#include "AEEstd.h"
+#include "AEEStdErr.h"
+#include "std_dtoa.h"
+#include "math.h"
+
+#define FAILED(b) ( (b) != AEE_SUCCESS ? TRUE : FALSE )
+#define CLEANUP_ON_ERROR(b,l) if( FAILED( b ) ) { goto l; }
+#define FP_POW_10(n) fp_pow_10(n)
+
+/* Returns the number of leading zeroes in a uint32.
+ This is a naive implementation that uses binary search. This could be
+ replaced by an optimized inline assembly code. */
+static __inline uint32 std_dtoa_clz32(uint32 ulVal)
+{
+ if ((int)ulVal <= 0)
+ {
+ return (ulVal == 0) ? 32 : 0;
+ }
+ else
+ {
+ uint32 uRet = 28;
+ uint32 uTmp = 0;
+ uTmp = (ulVal > 0xFFFF) * 16;
+ ulVal >>= uTmp, uRet -= uTmp;
+ uTmp = (ulVal > 0xFF) * 8;
+ ulVal >>= uTmp, uRet -= uTmp;
+ uTmp = (ulVal > 0xF) * 4;
+ ulVal >>= uTmp, uRet -= uTmp;
+ return uRet + ((0x55AF >> (ulVal * 2)) & 3);
+ }
+}
+
+/* Returns the number of leading zeroes in a uint64. */
+static __inline uint32 std_dtoa_clz64(uint64 ulVal)
+
+{
+ uint32 ulCount = 0;
+
+ if (!(ulVal >> 32))
+ {
+ ulCount += 32;
+ }
+ else
+ {
+ ulVal >>= 32;
+ }
+
+ return ulCount + std_dtoa_clz32((uint32)ulVal);
+}
+
+double fp_pow_10(int nPow)
+{
+ double dRet = 1.0;
+ int nI = 0;
+ boolean bNegative = FALSE;
+ double aTablePos[] = { 0, 1e1, 1e2, 1e4, 1e8, 1e16, 1e32, 1e64, 1e128,
+ 1e256
+ };
+ double aTableNeg[] = { 0, 1e-1, 1e-2, 1e-4, 1e-8, 1e-16, 1e-32, 1e-64, 1e-128,
+ 1e-256
+ };
+ double *pTable = aTablePos;
+ int nTableSize = STD_ARRAY_SIZE(aTablePos);
+
+ if (0 == nPow)
+ {
+ return 1.0;
+ }
+
+ if (nPow < 0)
+ {
+ bNegative = TRUE;
+ nPow = -nPow;
+ pTable = aTableNeg;
+ nTableSize = STD_ARRAY_SIZE(aTableNeg);
+ }
+
+ for (nI = 1; nPow && (nI < nTableSize); nI++)
+ {
+ if (nPow & 1)
+ {
+ dRet *= pTable[nI];
+ }
+
+ nPow >>= 1;
+ }
+
+ if (nPow)
+ {
+ /* Overflow. Trying to compute a large power value. */
+ uint64 ulInf = STD_DTOA_FP_POSITIVE_INF;
+ dRet = bNegative ? 0 : UINT64_TO_DOUBLE(ulInf);
+ }
+
+ return dRet;
+}
+
+/* Rounds dNumber to the specified precision nPrecision.
+ For example:
+ fp_round(2.34553, 3) = 2.346
+ fp_round(2.34553, 4) = 2.3455 */
+double fp_round(double dNumber, int nPrecision)
+{
+ double dResult = dNumber;
+ double dRoundingFactor = FP_POW_10(-nPrecision) * 0.5;
+
+ if (dNumber < 0)
+ {
+ dResult = dNumber - dRoundingFactor;
+ }
+ else
+ {
+ dResult = dNumber + dRoundingFactor;
+ }
+
+ return dResult;
+}
+
+/* Finds the integer part of the log_10( dNumber ).
+ The function assumes that dNumber != 0. */
+int fp_log_10(double dNumber)
+{
+ /* Absorb the negative sign */
+ if (dNumber < 0)
+ {
+ dNumber = -dNumber;
+ }
+
+ return (int)(floor(log10(dNumber)));
+}
+
+/* Evaluates the input floating-point number dNumber to check for
+ following special cases: NaN, +/-Infinity.
+ The evaluation is based on the IEEE Standard 754 for Floating Point Numbers. */
+int fp_check_special_cases(double dNumber, FloatingPointType *pNumberType)
+{
+ int nError = AEE_SUCCESS;
+ FloatingPointType NumberType = FP_TYPE_UNKOWN;
+ uint64 ullValue = 0;
+ uint64 ullSign = 0;
+ int64 n64Exponent = 0;
+ uint64 ullMantissa = 0;
+
+ ullValue = DOUBLE_TO_UINT64(dNumber);
+
+ /* Extract the sign, exponent and mantissa */
+ ullSign = FP_SIGN(ullValue);
+ n64Exponent = FP_EXPONENT_BIASED(ullValue);
+ ullMantissa = FP_MANTISSA_DENORM(ullValue);
+
+ /* Rules for special cases are listed below:
+ For Infinity, the following needs to be true:
+ 1. Exponent should have all bits set to 1.
+ 2. Mantissa should have all bits set to 0.
+
+ For NaN, the following needs to be true:
+ 1. Exponent should have all bits set to 1.
+ 2. Mantissa should be non-zero.
+ Note that we do not differentiate between QNaNs and SNaNs. */
+
+ if (STD_DTOA_DP_INFINITY_EXPONENT_ID == n64Exponent)
+ {
+ if (0 == ullMantissa)
+ {
+ /* Inifinity. */
+ if (ullSign)
+ {
+ NumberType = FP_TYPE_NEGATIVE_INF;
+ }
+ else
+ {
+ NumberType = FP_TYPE_POSITIVE_INF;
+ }
+ }
+ else
+ {
+ /* NaN */
+ NumberType = FP_TYPE_NAN;
+ }
+ }
+ else
+ {
+ /* A normal number */
+ NumberType = FP_TYPE_GENERAL;
+ }
+
+ /* Set the output value */
+ *pNumberType = NumberType;
+
+ return nError;
+}
+
+int std_dtoa_decimal(double dNumber, int nPrecision,
+ char acIntegerPart[ STD_DTOA_FORMAT_INTEGER_SIZE ],
+ char acFractionPart[ STD_DTOA_FORMAT_FRACTION_SIZE ])
+{
+ int nError = AEE_SUCCESS;
+ boolean bNegativeNumber = FALSE;
+ double dIntegerPart = 0.0;
+ double dFractionPart = 0.0;
+ double dTempIp = 0.0;
+ double dTempFp = 0.0;
+ int nMaxIntDigs = STD_DTOA_FORMAT_INTEGER_SIZE;
+ uint32 ulI = 0;
+ int nIntStartPos = 0;
+
+ /* Optimization: Special case an input of 0. */
+ if (0.0 == dNumber)
+ {
+ acIntegerPart[0] = '0';
+ acIntegerPart[1] = '\0';
+
+ for (ulI = 0; (ulI < STD_DTOA_FORMAT_FRACTION_SIZE - 1) && (nPrecision > 0);
+ ulI++, nPrecision--)
+ {
+ acFractionPart[ulI] = '0';
+ }
+ acFractionPart[ ulI ] = '\0';
+
+ goto bail;
+ }
+
+ /* Absorb the negative sign */
+ if (dNumber < 0)
+ {
+ acIntegerPart[0] = '-';
+ nIntStartPos = 1;
+ dNumber = -dNumber;
+ bNegativeNumber = TRUE;
+ }
+
+ /* Split the input number into it's integer and fraction parts. */
+ dFractionPart = modf(dNumber, &dIntegerPart);
+
+ /* First up, convert the integer part */
+ if (0.0 == dIntegerPart)
+ {
+ acIntegerPart[ nIntStartPos ] = '0';
+ }
+ else
+ {
+ double dRoundingConst = FP_POW_10(-STD_DTOA_PRECISION_ROUNDING_VALUE);
+ int nIntDigs = 0;
+ int nI = 0;
+
+ /* Compute the number of digits in the integer part of the number*/
+ nIntDigs = fp_log_10(dIntegerPart) + 1;
+
+ /* For negative numbers, a '-' sign has already been written. */
+ if (TRUE == bNegativeNumber)
+ {
+ nIntDigs++;
+ }
+
+ /* Check for overflow */
+ if (nIntDigs >= nMaxIntDigs)
+ {
+ /* Overflow!
+ Note that currently, we return a simple AEE_EFAILED for all
+ errors. */
+ nError = AEE_EFAILED;
+ goto bail;
+ }
+
+ /* Null Terminate the string */
+ acIntegerPart[ nIntDigs ] = '\0';
+
+ for (nI = nIntDigs - 1; nI >= nIntStartPos; nI--)
+ {
+ dIntegerPart = dIntegerPart / 10.0;
+ dTempFp = modf(dIntegerPart, &dTempIp);
+
+ /* Round it to the a specific precision */
+ dTempFp = dTempFp + dRoundingConst;
+
+ /* Convert the digit to a character */
+ acIntegerPart[ nI ] = (int)(dTempFp * 10) + '0';
+ if (!MY_ISDIGIT(acIntegerPart[ nI ]))
+ {
+ /* Overflow!
+ Note that currently, we return a simple AEE_EFAILED for all
+ errors. */
+ nError = AEE_EFAILED;
+ goto bail;
+ }
+ dIntegerPart = dTempIp;
+ }
+ }
+
+ /* Just a double check for integrity sake. This should ideally never happen.
+ Out of bounds scenario. That is, the integer part of the input number is
+ too large. */
+ if (dIntegerPart != 0.0)
+ {
+ /* Note that currently, we return a simple AEE_EFAILED for all
+ errors. */
+ nError = AEE_EFAILED;
+ goto bail;
+ }
+
+ /* Now, convert the fraction part */
+ for (ulI = 0; (nPrecision > 0) && (ulI < STD_DTOA_FORMAT_FRACTION_SIZE - 1);
+ nPrecision--, ulI++)
+ {
+ if (0.0 == dFractionPart)
+ {
+ acFractionPart[ ulI ] = '0';
+ }
+ else
+ {
+ double dRoundingValue = FP_POW_10(-(nPrecision +
+ STD_DTOA_PRECISION_ROUNDING_VALUE));
+ acFractionPart[ ulI ] = (int)((dFractionPart + dRoundingValue) * 10.0) + '0';
+ if (!MY_ISDIGIT(acFractionPart[ ulI ]))
+ {
+ /* Overflow!
+ Note that currently, we return a simple AEE_EFAILED for all
+ errors. */
+ nError = AEE_EFAILED;
+ goto bail;
+ }
+
+ dFractionPart = (dFractionPart * 10.0) -
+ (int)((dFractionPart + FP_POW_10(-nPrecision - 6)) * 10.0);
+ }
+ }
+
+
+bail:
+
+ return nError;
+}
+
+int std_dtoa_hex(double dNumber, int nPrecision, char cFormat,
+ char acIntegerPart[ STD_DTOA_FORMAT_INTEGER_SIZE ],
+ char acFractionPart[ STD_DTOA_FORMAT_FRACTION_SIZE ],
+ int *pnExponent)
+{
+ int nError = AEE_SUCCESS;
+ uint64 ullMantissa = 0;
+ uint64 ullSign = 0;
+ int64 n64Exponent = 0;
+ static const char HexDigitsU[] = "0123456789ABCDEF";
+ static const char HexDigitsL[] = "0123456789abcde";
+ boolean bFirstDigit = TRUE;
+ int nI = 0;
+ int nF = 0;
+ uint64 ullValue = DOUBLE_TO_UINT64(dNumber);
+ int nManShift = 0;
+ const char *pcDigitArray = (cFormat == 'A') ? HexDigitsU : HexDigitsL;
+ boolean bPrecisionSpecified = TRUE;
+
+ /* If no precision is specified, then set the precision to be fairly
+ large. */
+ if (nPrecision < 0)
+ {
+ nPrecision = STD_DTOA_FORMAT_FRACTION_SIZE;
+ bPrecisionSpecified = FALSE;
+ }
+ else
+ {
+ bPrecisionSpecified = TRUE;
+ }
+
+ /* Extract the sign, exponent and mantissa */
+ ullSign = FP_SIGN(ullValue);
+ n64Exponent = FP_EXPONENT(ullValue);
+ ullMantissa = FP_MANTISSA(ullValue);
+
+ /* Write out the sign */
+ if (ullSign)
+ {
+ acIntegerPart[ nI++ ] = '-';
+ }
+
+ /* Optimization: Special case an input of 0 */
+ if (0.0 == dNumber)
+ {
+ acIntegerPart[0] = '0';
+ acIntegerPart[1] = '\0';
+
+ for (nF = 0; (nF < STD_DTOA_FORMAT_FRACTION_SIZE - 1) && (nPrecision > 0);
+ nF++, nPrecision--)
+ {
+ acFractionPart[nF] = '0';
+ }
+ acFractionPart[nF] = '\0';
+
+ goto bail;
+ }
+
+ /* The mantissa is in lower 53 bits (52 bits + an implicit 1).
+ If we are dealing with a denormalized number, then the implicit 1
+ is absent. The above macros would have then set that bit to 0.
+ Shift the mantisaa on to the highest bits. */
+
+ if (0 == (n64Exponent + STD_DTOA_DP_EXPONENT_BIAS))
+ {
+ /* DENORMALIZED NUMBER.
+ A denormalized number is of the form:
+ 0.bbb...bbb x 2^Exponent
+ Shift the mantissa to the higher bits while discarding the leading 0 */
+ ullMantissa <<= 12;
+
+ /* Lets update the exponent so as to make sure that the first hex value
+ in the mantissa is non-zero, i.e., at least one of the first 4 bits is
+ non-zero. */
+ nManShift = std_dtoa_clz64(ullMantissa) - 3;
+ if (nManShift > 0)
+ {
+ ullMantissa <<= nManShift;
+ n64Exponent -= nManShift;
+ }
+ }
+ else
+ {
+ /* NORMALIZED NUMBER.
+ A normalized number has the following form:
+ 1.bbb...bbb x 2^Exponent
+ Shift the mantissa to the higher bits while retaining the leading 1 */
+ ullMantissa <<= 11;
+ }
+
+ /* Now, lets get the decimal point out of the picture by shifting the
+ exponent by 1. */
+ n64Exponent++;
+
+ /* Read the mantissa four bits at a time to form the hex output */
+ for (nI = 0, nF = 0, bFirstDigit = TRUE; ullMantissa != 0;
+ ullMantissa <<= 4)
+ {
+ uint64 ulHexVal = ullMantissa & 0xF000000000000000uLL;
+ ulHexVal >>= 60;
+ if (bFirstDigit)
+ {
+ // Write to the integral part of the number
+ acIntegerPart[ nI++ ] = pcDigitArray[ulHexVal];
+ bFirstDigit = FALSE;
+ }
+ else if (nF < nPrecision)
+ {
+ // Write to the fractional part of the number
+ acFractionPart[ nF++ ] = pcDigitArray[ulHexVal];
+ }
+ }
+
+ /* Pad the fraction with trailing zeroes upto the specified precision */
+ for (; bPrecisionSpecified && (nF < nPrecision); nF++)
+ {
+ acFractionPart[ nF ] = '0';
+ }
+
+ /* Now the output is of the form;
+ h.hhh x 2^Exponent
+ where h is a non-zero hexadecimal number.
+ But we were dealing with a binary fraction 0.bbb...bbb x 2^Exponent.
+ Therefore, we need to subtract 4 from the exponent (since the shift
+ was to the base 16 and the exponent is to the base 2). */
+ n64Exponent -= 4;
+ *pnExponent = (int)n64Exponent;
+
+bail:
+ return nError;
+}
+
diff --git a/src/std_dtoa.h b/src/std_dtoa.h
new file mode 100644
index 0000000..5a439b6
--- /dev/null
+++ b/src/std_dtoa.h
@@ -0,0 +1,113 @@
+/*==============================================================================
+ * Copyright (c) 2009,2013 QUALCOMM Technologies Inc. All Rights Reserved.
+ * Qualcomm Technologies Confidential and Proprietary
+==============================================================================*/
+
+#ifndef STD_DTOA_H
+#define STD_DTOA_H
+
+//
+// Constant Definitions
+//
+
+// For floating point numbers, the range of a double precision number is
+// approximately +/- 10 ^ 308.25 as per the IEEE Standard 754.
+// As such, the maximum size of the integer portion of the
+// string is assumed to be 311 (309 + sign + \0). The maximum
+// size of the fractional part is assumed to be 100. Thus, the
+// maximum size of the string that would contain the number
+// after conversion is safely assumed to be 420 (including any
+// prefix, the null character and exponent specifiers 'e').
+//
+// The buffers that contain the converted integer and the fraction parts of
+// the float are safely assumed to be of size 310.
+#define STD_DTOA_FORMAT_FLOAT_SIZE 420
+#define STD_DTOA_FORMAT_INTEGER_SIZE 311
+#define STD_DTOA_FORMAT_FRACTION_SIZE 100
+
+// Constants for operations on the IEEE 754 representation of double
+// precision floating point numbers.
+#define STD_DTOA_DP_SIGN_SHIFT_COUNT 63
+#define STD_DTOA_DP_EXPONENT_SHIFT_COUNT 52
+#define STD_DTOA_DP_EXPONENT_MASK 0x7ff
+#define STD_DTOA_DP_EXPONENT_BIAS 1023
+#define STD_DTOA_DP_MANTISSA_MASK ( ( (uint64)1 << 52 ) - 1 )
+#define STD_DTOA_DP_INFINITY_EXPONENT_ID 0x7FF
+#define STD_DTOA_DP_MAX_EXPONENT 1023
+#define STD_DTOA_DP_MIN_EXPONENT_NORM -1022
+#define STD_DTOA_DP_MIN_EXPONENT_DENORM -1074
+#define STD_DTOA_DP_MAX_EXPONENT_DEC 308
+#define STD_DTOA_DP_MIN_EXPONENT_DEC_DENORM -323
+
+#define STD_DTOA_PRECISION_ROUNDING_VALUE 4
+#define STD_DTOA_DEFAULT_FLOAT_PRECISION 6
+
+#define STD_DTOA_NEGATIVE_INF_UPPER_CASE "-INF"
+#define STD_DTOA_NEGATIVE_INF_LOWER_CASE "-inf"
+#define STD_DTOA_POSITIVE_INF_UPPER_CASE "INF"
+#define STD_DTOA_POSITIVE_INF_LOWER_CASE "inf"
+#define STD_DTOA_NAN_UPPER_CASE "NAN"
+#define STD_DTOA_NAN_LOWER_CASE "nan"
+#define STD_DTOA_FP_POSITIVE_INF 0x7FF0000000000000uLL
+#define STD_DTOA_FP_NEGATIVE_INF 0xFFF0000000000000uLL
+#define STD_DTOA_FP_SNAN 0xFFF0000000000001uLL
+#define STD_DTOA_FP_QNAN 0xFFFFFFFFFFFFFFFFuLL
+
+//
+// Useful Macros
+//
+
+#define MY_ISDIGIT(c) ( ( (c) >= '0' ) && ( (c) <= '9' ) )
+#define FP_EXPONENT(u) ( ( ( (u) >> STD_DTOA_DP_EXPONENT_SHIFT_COUNT ) \
+ & STD_DTOA_DP_EXPONENT_MASK ) - STD_DTOA_DP_EXPONENT_BIAS )
+#define FP_EXPONENT_BIASED(u) ( ( (u) >> STD_DTOA_DP_EXPONENT_SHIFT_COUNT ) \
+ & STD_DTOA_DP_EXPONENT_MASK )
+#define FP_MANTISSA_NORM(u) ( ( (u) & STD_DTOA_DP_MANTISSA_MASK ) | \
+ ( (uint64)1 << STD_DTOA_DP_EXPONENT_SHIFT_COUNT ) )
+#define FP_MANTISSA_DENORM(u) ( (u) & STD_DTOA_DP_MANTISSA_MASK )
+#define FP_MANTISSA(u) ( FP_EXPONENT_BIASED(u) ? FP_MANTISSA_NORM(u) : \
+ FP_MANTISSA_DENORM(u) )
+#define FP_SIGN(u) ( (u) >> STD_DTOA_DP_SIGN_SHIFT_COUNT )
+#define DOUBLE_TO_UINT64(d) ( *( (uint64*) &(d) ) )
+#define DOUBLE_TO_INT64(d) ( *( (int64*) &(d) ) )
+#define UINT64_TO_DOUBLE(u) ( *( (double*) &(u) ) )
+
+//
+// Type Definitions
+//
+
+typedef enum
+{
+ FP_TYPE_UNKOWN = 0,
+ FP_TYPE_NEGATIVE_INF,
+ FP_TYPE_POSITIVE_INF,
+ FP_TYPE_NAN,
+ FP_TYPE_GENERAL,
+} FloatingPointType;
+
+//
+// Function Declarations
+//
+
+#ifdef __cplusplus
+extern "C" {
+#endif // #ifdef __cplusplus
+
+double fp_pow_10( int nPow );
+double fp_round( double dNumber, int nPrecision );
+int fp_log_10( double dNumber );
+int fp_check_special_cases( double dNumber, FloatingPointType* pNumberType );
+int std_dtoa_decimal( double dNumber, int nPrecision,
+ char acIntegerPart[ STD_DTOA_FORMAT_INTEGER_SIZE ],
+ char acFractionPart[ STD_DTOA_FORMAT_FRACTION_SIZE ] );
+int std_dtoa_hex( double dNumber, int nPrecision, char cFormat,
+ char acIntegerPart[ STD_DTOA_FORMAT_INTEGER_SIZE ],
+ char acFractionPart[ STD_DTOA_FORMAT_FRACTION_SIZE ],
+ int* pnExponent );
+
+#ifdef __cplusplus
+}
+#endif // #ifdef __cplusplus
+
+#endif // STD_DTOA_H
+
diff --git a/src/std_mem.c b/src/std_mem.c
new file mode 100644
index 0000000..430b45a
--- /dev/null
+++ b/src/std_mem.c
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+#include <string.h>
+#include "AEEstd.h"
+
+void *std_memset(void *p, int c, int nLen)
+{
+ if (nLen < 0)
+ {
+ return p;
+ }
+ return memset(p, c, (size_t)nLen);
+}
+
+void *std_memmove(void *pTo, const void *cpFrom, int nLen)
+{
+ if (nLen <= 0)
+ {
+ return pTo;
+ }
+ return memmove(pTo, cpFrom, (size_t)nLen);
+}
+
diff --git a/src/std_path.c b/src/std_path.c
new file mode 100644
index 0000000..0e82f5c
--- /dev/null
+++ b/src/std_path.c
@@ -0,0 +1,167 @@
+/*
+* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+* POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "AEEstd.h"
+#include "AEEBufBound.h"
+#include <string.h>
+int std_makepath(const char *cpszDir, const char *cpszFile,
+ char *pszOut, int nOutLen)
+{
+ BufBound bb;
+
+ BufBound_Init(&bb, pszOut, nOutLen);
+ BufBound_Puts(&bb, cpszDir);
+
+ if (('\0' != cpszDir[0]) && /* non-empty dir */
+ ('/' != cpszDir[std_strlen(cpszDir) - 1])) /* no slash at end of dir */
+ {
+ BufBound_Putc(&bb, '/');
+ }
+ if ('/' == cpszFile[0])
+ {
+ cpszFile++;
+ }
+
+ BufBound_Puts(&bb, cpszFile);
+ BufBound_ForceNullTerm(&bb);
+ return BufBound_Wrote(&bb) - 1;
+}
+
+char *std_splitpath(const char *cpszPath, const char *cpszDir)
+{
+ const char *cpsz = cpszPath;
+
+ while (!('\0' == cpszDir[0] ||
+ ('/' == cpszDir[0] && '\0' == cpszDir[1])))
+ {
+
+ if (*cpszDir != *cpsz)
+ {
+ return 0;
+ }
+
+ ++cpsz;
+ ++cpszDir;
+ }
+</